/** * Copyright (C) 2014-2019 Expedia Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hotels.plunger.asserts; import static java.lang.String.format; import java.lang.reflect.Type; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.hamcrest.Description; import org.hamcrest.TypeSafeDiagnosingMatcher; import cascading.tuple.Fields; import cascading.tuple.TupleEntry; class TupleEntryMatcher extends TypeSafeDiagnosingMatcher<TupleEntry> { private final TupleEntry expected; TupleEntryMatcher(TupleEntry expected) { if (expected == null) { throw new IllegalArgumentException( "expected cannot be null. Consider using org.hamcrest.CoreMatchers.nullValue() instead."); } this.expected = expected; } @Override public void describeTo(Description description) { description.appendText("TupleEntries should be identical"); } @Override protected boolean matchesSafely(TupleEntry actual, Description description) { Set<Comparable<?>> actualNames = extractFieldNames(actual.getFields()); Set<Comparable<?>> expectedNames = extractFieldNames(expected.getFields()); Set<Comparable<?>> allNames = new HashSet<Comparable<?>>(); allNames.addAll(actualNames); allNames.addAll(expectedNames); boolean result = true; for (Comparable<?> name : allNames) { Fields field = new Fields(name); if (!actual.getFields().contains(field)) { description.appendText(format("%s was expected, but was not present%n", name)); result = false; continue; } if (!expected.getFields().contains(field)) { description.appendText(format("%s was not expected, but was present%n", name)); result = false; continue; } int actualPos = actual.getFields().getPos(name); int expectedPos = expected.getFields().getPos(name); if (actualPos != expectedPos) { description.appendText(format("%s expected position was %s, but was %s%n", name, expectedPos, actualPos)); result = false; } Type actualType = actual.getFields().getType(name); Type expectedType = expected.getFields().getType(name); if (!equal(actualType, expectedType)) { description.appendText(format("%s expected type was %s, but was %s%n", name, expectedType, actualType)); result = false; continue; } Object actualValue = actual.getObject(name); Object expectedValue = expected.getObject(name); if (!equal(actualValue, expectedValue)) { description.appendText(format("%s expected value was '%s', but was '%s'%n", name, expectedValue, actualValue)); result = false; } } return result; } private static boolean equal(Object o1, Object o2) { return o1 == o2 || o1 != null && o1.equals(o2); } private static Set<Comparable<?>> extractFieldNames(Fields fields) { Set<Comparable<?>> names = new HashSet<Comparable<?>>(); @SuppressWarnings("unchecked") Iterator<Comparable<?>> iterator = fields.iterator(); while (iterator.hasNext()) { names.add(iterator.next()); } return names; } }