blob: 68a7e58f96e53c53c2f5c1dde9e43fc7a5027492 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.qpid.protonj2.test.driver.matchers;
import static org.hamcrest.MatcherAssert.assertThat;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.qpid.protonj2.test.driver.codec.ListDescribedType;
import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol;
import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
/**
* Matcher used to validate that received described types match expectations.
*/
public abstract class ListDescribedTypeMatcher extends TypeSafeMatcher<ListDescribedType> {
private String mismatchTextAddition;
private final int numFields;
private final UnsignedLong descriptorCode;
private final Symbol descriptorSymbol;
protected final Map<Enum<?>, Matcher<?>> fieldMatchers = new LinkedHashMap<>();
public ListDescribedTypeMatcher(int numFields, UnsignedLong code, Symbol symbol) {
this.descriptorCode = code;
this.descriptorSymbol = symbol;
this.numFields = numFields;
}
public ListDescribedTypeMatcher addFieldMatcher(Enum<?> field, Matcher<?> matcher) {
if (field.ordinal() > numFields) {
throw new IllegalArgumentException("Field enum supplied exceeds number of fields in type");
}
fieldMatchers.put(field, matcher);
return this;
}
@Override
public void describeTo(Description description) {
description.appendText(getDescribedTypeClass().getSimpleName() + " which matches: ").appendValue(fieldMatchers);
}
@Override
protected boolean matchesSafely(ListDescribedType received) {
try {
Object descriptor = received.getDescriptor();
if (!descriptorCode.equals(descriptor) && !descriptorSymbol.equals(descriptor)) {
mismatchTextAddition = "Descriptor mismatch";
return false;
}
for (Map.Entry<Enum<?>, Matcher<?>> entry : fieldMatchers.entrySet()) {
@SuppressWarnings("unchecked")
Matcher<Object> matcher = (Matcher<Object>) entry.getValue();
assertThat("Field " + entry.getKey() + " value should match",
received.getFieldValue(entry.getKey().ordinal()), matcher);
}
} catch (AssertionError ae) {
mismatchTextAddition = "AssertionFailure: " + ae.getMessage();
return false;
}
return true;
}
@Override
protected void describeMismatchSafely(ListDescribedType item, Description mismatchDescription) {
mismatchDescription.appendText("\nActual form: ").appendValue(item);
mismatchDescription.appendText("\nExpected descriptor: ")
.appendValue(descriptorSymbol)
.appendText(" / ")
.appendValue(descriptorCode);
if (mismatchTextAddition != null) {
mismatchDescription.appendText("\nAdditional info: ").appendValue(mismatchTextAddition);
}
}
protected abstract Class<?> getDescribedTypeClass();
}