This is an automated email from the ASF dual-hosted git repository. tabish pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/qpid-protonj2.git
The following commit(s) were added to refs/heads/main by this push: new aa3538e5 PROTON-2885 Improve the test matchers to allow stacking aa3538e5 is described below commit aa3538e589c2429ab20f584491ed5f4dc3fad1ba Author: Timothy Bish <tabish...@gmail.com> AuthorDate: Tue Apr 15 19:43:29 2025 -0400 PROTON-2885 Improve the test matchers to allow stacking Allow stacking of withOfferedCapability and withDesiredCapability in a simillar way that withProperty handles it for the Open, Begin and Attach matchers. --- .../driver/expectations/AttachExpectation.java | 140 +++++++----- .../test/driver/expectations/BeginExpectation.java | 107 +++++---- .../test/driver/expectations/OpenExpectation.java | 108 +++++---- .../test/driver/matchers/ArrayContentsMatcher.java | 200 +++++++++++++++++ .../driver/matchers/transport/AttachMatcher.java | 49 ++++- .../driver/matchers/transport/BeginMatcher.java | 39 ++++ .../driver/matchers/transport/OpenMatcher.java | 39 ++++ .../protonj2/test/driver/ReceiverHandlingTest.java | 36 +++ .../driver/matcher/ArrayContainsMatcherTest.java | 244 +++++++++++++++++++++ .../driver/matcher/MapContentsMatcherTest.java | 4 +- 10 files changed, 817 insertions(+), 149 deletions(-) diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AttachExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AttachExpectation.java index ad076921..1705ba2c 100644 --- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AttachExpectation.java +++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/AttachExpectation.java @@ -20,7 +20,6 @@ import static org.hamcrest.CoreMatchers.anyOf; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.collection.ArrayMatching.hasItemInArray; import java.nio.ByteBuffer; import java.util.Arrays; @@ -43,7 +42,6 @@ import org.apache.qpid.protonj2.test.driver.codec.messaging.TerminusDurability; import org.apache.qpid.protonj2.test.driver.codec.messaging.TerminusExpiryPolicy; import org.apache.qpid.protonj2.test.driver.codec.primitives.Binary; import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol; -import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedByte; import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger; import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong; import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedShort; @@ -53,7 +51,6 @@ import org.apache.qpid.protonj2.test.driver.codec.transport.DeliveryState; import org.apache.qpid.protonj2.test.driver.codec.transport.ReceiverSettleMode; import org.apache.qpid.protonj2.test.driver.codec.transport.Role; import org.apache.qpid.protonj2.test.driver.codec.transport.SenderSettleMode; -import org.apache.qpid.protonj2.test.driver.codec.util.TypeMapper; import org.apache.qpid.protonj2.test.driver.matchers.JmsNoLocalByIdDescribedType; import org.apache.qpid.protonj2.test.driver.matchers.JmsSelectorByIdDescribedType; import org.apache.qpid.protonj2.test.driver.matchers.messaging.SourceMatcher; @@ -252,83 +249,96 @@ public class AttachExpectation extends AbstractExpectation<Attach> { //----- Type specific with methods that perform simple equals checks public AttachExpectation withName(String name) { - return withName(equalTo(name)); + matcher.withName(name); + return this; } public AttachExpectation withHandle(int handle) { - return withHandle(equalTo(UnsignedInteger.valueOf(handle))); + matcher.withHandle(handle); + return this; } public AttachExpectation withHandle(long handle) { - return withHandle(equalTo(UnsignedInteger.valueOf(handle))); + matcher.withHandle(handle); + return this; } public AttachExpectation withHandle(UnsignedInteger handle) { - return withHandle(equalTo(handle)); + matcher.withHandle(handle); + return this; } public AttachExpectation withRole(boolean role) { - return withRole(equalTo(role)); + matcher.withRole(role); + return this; } public AttachExpectation withRole(Boolean role) { - return withRole(equalTo(role)); + matcher.withRole(role); + return this; } public AttachExpectation withRole(Role role) { - return withRole(equalTo(role.getValue())); + matcher.withRole(role); + return this; } public AttachExpectation ofSender() { - return withRole(equalTo(Role.SENDER.getValue())); + return withRole(Role.SENDER); } public AttachExpectation ofReceiver() { - return withRole(equalTo(Role.RECEIVER.getValue())); + return withRole(Role.RECEIVER); } public AttachExpectation withSndSettleMode(byte sndSettleMode) { - return withSndSettleMode(equalTo(UnsignedByte.valueOf(sndSettleMode))); + matcher.withSndSettleMode(sndSettleMode); + return this; } public AttachExpectation withSndSettleMode(Byte sndSettleMode) { - return withSndSettleMode(sndSettleMode == null ? nullValue() : equalTo(UnsignedByte.valueOf(sndSettleMode.byteValue()))); + matcher.withSndSettleMode(sndSettleMode); + return this; } public AttachExpectation withSndSettleMode(SenderSettleMode sndSettleMode) { - return withSndSettleMode(sndSettleMode == null ? nullValue() : equalTo(sndSettleMode.getValue())); + matcher.withSndSettleMode(sndSettleMode); + return this; } public AttachExpectation withSenderSettleModeMixed() { - return withSndSettleMode(equalTo(SenderSettleMode.MIXED.getValue())); + return withSndSettleMode(SenderSettleMode.MIXED); } public AttachExpectation withSenderSettleModeSettled() { - return withSndSettleMode(equalTo(SenderSettleMode.SETTLED.getValue())); + return withSndSettleMode(SenderSettleMode.SETTLED); } public AttachExpectation withSenderSettleModeUnsettled() { - return withSndSettleMode(equalTo(SenderSettleMode.UNSETTLED.getValue())); + return withSndSettleMode(SenderSettleMode.UNSETTLED); } public AttachExpectation withRcvSettleMode(byte rcvSettleMode) { - return withRcvSettleMode(equalTo(UnsignedByte.valueOf(rcvSettleMode))); + matcher.withRcvSettleMode(rcvSettleMode); + return this; } public AttachExpectation withRcvSettleMode(Byte rcvSettleMode) { - return withRcvSettleMode(rcvSettleMode == null ? nullValue() : equalTo(UnsignedByte.valueOf(rcvSettleMode.byteValue()))); + matcher.withRcvSettleMode(rcvSettleMode); + return this; } public AttachExpectation withRcvSettleMode(ReceiverSettleMode rcvSettleMode) { - return withRcvSettleMode(rcvSettleMode == null ? nullValue() : equalTo(rcvSettleMode.getValue())); + matcher.withRcvSettleMode(rcvSettleMode); + return this; } public AttachExpectation withReceiverSettlesFirst() { - return withRcvSettleMode(equalTo(ReceiverSettleMode.FIRST.getValue())); + return withRcvSettleMode(ReceiverSettleMode.FIRST); } public AttachExpectation withReceiverSettlesSecond() { - return withRcvSettleMode(equalTo(ReceiverSettleMode.SECOND.getValue())); + return withRcvSettleMode(ReceiverSettleMode.SECOND); } public AttachSourceMatcher withSource() { @@ -385,72 +395,98 @@ public class AttachExpectation extends AbstractExpectation<Attach> { } public AttachExpectation withUnsettled(Map<Binary, DeliveryState> unsettled) { - // TODO - Need to match on the driver types for DeliveryState - return withUnsettled(equalTo(unsettled)); + matcher.withUnsettled(unsettled); + return this; } public AttachExpectation withIncompleteUnsettled(boolean incomplete) { - return withIncompleteUnsettled(equalTo(incomplete)); + matcher.withIncompleteUnsettled(incomplete); + return this; } public AttachExpectation withInitialDeliveryCount(int initialDeliveryCount) { - return withInitialDeliveryCount(equalTo(UnsignedInteger.valueOf(initialDeliveryCount))); + matcher.withInitialDeliveryCount(initialDeliveryCount); + return this; } public AttachExpectation withInitialDeliveryCount(long initialDeliveryCount) { - return withInitialDeliveryCount(equalTo(UnsignedInteger.valueOf(initialDeliveryCount))); + matcher.withInitialDeliveryCount(initialDeliveryCount); + return this; } public AttachExpectation withInitialDeliveryCount(UnsignedInteger initialDeliveryCount) { - return withInitialDeliveryCount(equalTo(initialDeliveryCount)); + matcher.withInitialDeliveryCount(initialDeliveryCount); + return this; } public AttachExpectation withMaxMessageSize(long maxMessageSize) { - return withMaxMessageSize(equalTo(UnsignedLong.valueOf(maxMessageSize))); + matcher.withMaxMessageSize(maxMessageSize); + return this; } public AttachExpectation withMaxMessageSize(UnsignedLong maxMessageSize) { - return withMaxMessageSize(equalTo(maxMessageSize)); + matcher.withMaxMessageSize(maxMessageSize); + return this; } public AttachExpectation withOfferedCapabilities(Symbol... offeredCapabilities) { - return withOfferedCapabilities(equalTo(offeredCapabilities)); + matcher.withOfferedCapabilities(offeredCapabilities); + return this; } public AttachExpectation withOfferedCapabilities(String... offeredCapabilities) { - return withOfferedCapabilities(equalTo(TypeMapper.toSymbolArray(offeredCapabilities))); + matcher.withOfferedCapabilities(offeredCapabilities); + return this; } - public AttachExpectation withOfferedCapability(Symbol offeredCapability) { - return withOfferedCapabilities(hasItemInArray(offeredCapability)); + public AttachExpectation withDesiredCapabilities(Symbol... desiredCapabilities) { + matcher.withDesiredCapabilities(desiredCapabilities); + return this; } - public AttachExpectation withOfferedCapability(String offeredCapability) { - return withOfferedCapabilities(hasItemInArray(Symbol.valueOf(offeredCapability))); + public AttachExpectation withDesiredCapabilities(String... desiredCapabilities) { + matcher.withDesiredCapabilities(desiredCapabilities); + return this; } - public AttachExpectation withDesiredCapabilities(Symbol... desiredCapabilities) { - return withDesiredCapabilities(equalTo(desiredCapabilities)); + public AttachExpectation withPropertiesMap(Map<Symbol, Object> properties) { + matcher.withPropertiesMap(properties); + return this; } - public AttachExpectation withDesiredCapabilities(String... desiredCapabilities) { - return withDesiredCapabilities(equalTo(TypeMapper.toSymbolArray(desiredCapabilities))); + public AttachExpectation withProperties(Map<String, Object> properties) { + matcher.withProperties(properties); + return this; + } + + public AttachExpectation withProperty(String key, Object value) { + matcher.withProperty(key, value); + return this; + } + + public AttachExpectation withProperty(Symbol key, Object value) { + matcher.withProperty(key, value); + return this; } public AttachExpectation withDesiredCapability(Symbol desiredCapability) { - return withDesiredCapabilities(hasItemInArray(desiredCapability)); + matcher.withDesiredCapability(desiredCapability); + return this; } public AttachExpectation withDesiredCapability(String desiredCapability) { - return withDesiredCapabilities(hasItemInArray(Symbol.valueOf(desiredCapability))); + matcher.withDesiredCapability(desiredCapability); + return this; } - public AttachExpectation withPropertiesMap(Map<Symbol, Object> properties) { - return withProperties(equalTo(properties)); + public AttachExpectation withOfferedCapability(Symbol offeredCapability) { + matcher.withOfferedCapability(offeredCapability); + return this; } - public AttachExpectation withProperties(Map<String, Object> properties) { - return withProperties(equalTo(TypeMapper.toSymbolKeyedMap(properties))); + public AttachExpectation withOfferedCapability(String offeredCapability) { + matcher.withOfferedCapability(offeredCapability); + return this; } //----- Matcher based with methods for more complex validation @@ -530,16 +566,6 @@ public class AttachExpectation extends AbstractExpectation<Attach> { return this; } - public AttachExpectation withProperty(String key, Object value) { - matcher.withProperty(key, value); - return this; - } - - public AttachExpectation withProperty(Symbol key, Object value) { - matcher.withProperty(key, value); - return this; - } - @Override protected Matcher<ListDescribedType> getExpectationMatcher() { return matcher; diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/BeginExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/BeginExpectation.java index 1521527e..511eb868 100644 --- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/BeginExpectation.java +++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/BeginExpectation.java @@ -17,10 +17,8 @@ package org.apache.qpid.protonj2.test.driver.expectations; import static org.hamcrest.CoreMatchers.anyOf; -import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.collection.ArrayMatching.hasItemInArray; import java.nio.ByteBuffer; import java.util.Map; @@ -35,7 +33,6 @@ import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol; import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger; import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedShort; import org.apache.qpid.protonj2.test.driver.codec.transport.Begin; -import org.apache.qpid.protonj2.test.driver.codec.util.TypeMapper; import org.apache.qpid.protonj2.test.driver.matchers.transport.BeginMatcher; import org.hamcrest.Matcher; @@ -118,99 +115,133 @@ public class BeginExpectation extends AbstractExpectation<Begin> { //----- Type specific with methods that perform simple equals checks public BeginExpectation withRemoteChannel(int remoteChannel) { - return withRemoteChannel(equalTo(UnsignedShort.valueOf((short) remoteChannel))); + matcher.withRemoteChannel(remoteChannel); + return this; } public BeginExpectation withRemoteChannel(UnsignedShort remoteChannel) { - return withRemoteChannel(equalTo(remoteChannel)); + matcher.withRemoteChannel(remoteChannel); + return this; } public BeginExpectation withNextOutgoingId(int nextOutgoingId) { - return withNextOutgoingId(equalTo(UnsignedInteger.valueOf(nextOutgoingId))); + matcher.withNextOutgoingId(nextOutgoingId); + return this; } public BeginExpectation withNextOutgoingId(long nextOutgoingId) { - return withNextOutgoingId(equalTo(UnsignedInteger.valueOf(nextOutgoingId))); + matcher.withNextOutgoingId(nextOutgoingId); + return this; } public BeginExpectation withNextOutgoingId(UnsignedInteger nextOutgoingId) { - return withNextOutgoingId(equalTo(nextOutgoingId)); + matcher.withNextOutgoingId(nextOutgoingId); + return this; } public BeginExpectation withIncomingWindow(int incomingWindow) { - return withIncomingWindow(equalTo(UnsignedInteger.valueOf(incomingWindow))); + matcher.withIncomingWindow(incomingWindow); + return this; } public BeginExpectation withIncomingWindow(long incomingWindow) { - return withIncomingWindow(equalTo(UnsignedInteger.valueOf(incomingWindow))); + matcher.withIncomingWindow(incomingWindow); + return this; } public BeginExpectation withIncomingWindow(UnsignedInteger incomingWindow) { - return withIncomingWindow(equalTo(incomingWindow)); + matcher.withIncomingWindow(incomingWindow); + return this; } public BeginExpectation withOutgoingWindow(int outgoingWindow) { - return withOutgoingWindow(equalTo(UnsignedInteger.valueOf(outgoingWindow))); + matcher.withOutgoingWindow(outgoingWindow); + return this; } public BeginExpectation withOutgoingWindow(long outgoingWindow) { - return withOutgoingWindow(equalTo(UnsignedInteger.valueOf(outgoingWindow))); + matcher.withOutgoingWindow(outgoingWindow); + return this; } public BeginExpectation withOutgoingWindow(UnsignedInteger outgoingWindow) { - return withOutgoingWindow(equalTo(outgoingWindow)); + matcher.withOutgoingWindow(outgoingWindow); + return this; } public BeginExpectation withHandleMax(int handleMax) { - return withHandleMax(equalTo(UnsignedInteger.valueOf(handleMax))); + matcher.withHandleMax(handleMax); + return this; } public BeginExpectation withHandleMax(long handleMax) { - return withHandleMax(equalTo(UnsignedInteger.valueOf(handleMax))); + matcher.withHandleMax(handleMax); + return this; } public BeginExpectation withHandleMax(UnsignedInteger handleMax) { - return withHandleMax(equalTo(handleMax)); + matcher.withHandleMax(handleMax); + return this; } public BeginExpectation withOfferedCapabilities(String... offeredCapabilities) { - return withOfferedCapabilities(equalTo(TypeMapper.toSymbolArray(offeredCapabilities))); + matcher.withOfferedCapabilities(offeredCapabilities); + return this; } public BeginExpectation withOfferedCapabilities(Symbol... offeredCapabilities) { - return withOfferedCapabilities(equalTo(offeredCapabilities)); + matcher.withOfferedCapabilities(offeredCapabilities); + return this; } - public BeginExpectation withOfferedCapability(Symbol offeredCapability) { - return withOfferedCapabilities(hasItemInArray(offeredCapability)); + public BeginExpectation withDesiredCapabilities(String... desiredCapabilities) { + matcher.withDesiredCapabilities(desiredCapabilities); + return this; } - public BeginExpectation withOfferedCapability(String offeredCapability) { - return withOfferedCapabilities(hasItemInArray(Symbol.valueOf(offeredCapability))); + public BeginExpectation withDesiredCapabilities(Symbol... desiredCapabilities) { + matcher.withDesiredCapabilities(desiredCapabilities); + return this; } - public BeginExpectation withDesiredCapabilities(String... desiredCapabilities) { - return withDesiredCapabilities(equalTo(TypeMapper.toSymbolArray(desiredCapabilities))); + public BeginExpectation withPropertiesMap(Map<Symbol, Object> properties) { + matcher.withPropertiesMap(properties); + return this; } - public BeginExpectation withDesiredCapabilities(Symbol... desiredCapabilities) { - return withDesiredCapabilities(equalTo(desiredCapabilities)); + public BeginExpectation withProperties(Map<String, Object> properties) { + matcher.withProperties(properties); + return this; + } + + public BeginExpectation withProperty(String key, Object value) { + matcher.withProperty(key, value); + return this; + } + + public BeginExpectation withProperty(Symbol key, Object value) { + matcher.withProperty(key, value); + return this; } public BeginExpectation withDesiredCapability(Symbol desiredCapability) { - return withDesiredCapabilities(hasItemInArray(desiredCapability)); + matcher.withDesiredCapability(desiredCapability); + return this; } public BeginExpectation withDesiredCapability(String desiredCapability) { - return withDesiredCapabilities(hasItemInArray(Symbol.valueOf(desiredCapability))); + matcher.withDesiredCapability(desiredCapability); + return this; } - public BeginExpectation withPropertiesMap(Map<Symbol, Object> properties) { - return withProperties(equalTo(properties)); + public BeginExpectation withOfferedCapability(Symbol offeredCapability) { + matcher.withOfferedCapability(offeredCapability); + return this; } - public BeginExpectation withProperties(Map<String, Object> properties) { - return withProperties(equalTo(TypeMapper.toSymbolKeyedMap(properties))); + public BeginExpectation withOfferedCapability(String offeredCapability) { + matcher.withOfferedCapability(offeredCapability); + return this; } //----- Matcher based with methods for more complex validation @@ -255,16 +286,6 @@ public class BeginExpectation extends AbstractExpectation<Begin> { return this; } - public BeginExpectation withProperty(String key, Object value) { - matcher.withProperty(key, value); - return this; - } - - public BeginExpectation withProperty(Symbol key, Object value) { - matcher.withProperty(key, value); - return this; - } - @Override protected Matcher<ListDescribedType> getExpectationMatcher() { return matcher; diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/OpenExpectation.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/OpenExpectation.java index 20c8a0a5..5f5bcbfb 100644 --- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/OpenExpectation.java +++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/expectations/OpenExpectation.java @@ -16,7 +16,6 @@ */ package org.apache.qpid.protonj2.test.driver.expectations; -import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.collection.ArrayMatching.hasItemInArray; @@ -174,55 +173,68 @@ public class OpenExpectation extends AbstractExpectation<Open> { public OpenExpectation withContainerId(String container) { explicitlyNullContainerId = container == null; - return withContainerId(equalTo(container)); + matcher.withContainerId(container); + return this; } public OpenExpectation withHostname(String hostname) { - return withHostname(equalTo(hostname)); + matcher.withHostname(hostname); + return this; } public OpenExpectation withMaxFrameSize(int maxFrameSize) { - return withMaxFrameSize(equalTo(UnsignedInteger.valueOf(maxFrameSize))); + matcher.withMaxFrameSize(maxFrameSize); + return this; } public OpenExpectation withMaxFrameSize(long maxFrameSize) { - return withMaxFrameSize(equalTo(UnsignedInteger.valueOf(maxFrameSize))); + matcher.withMaxFrameSize(maxFrameSize); + return this; } public OpenExpectation withMaxFrameSize(UnsignedInteger maxFrameSize) { - return withMaxFrameSize(equalTo(maxFrameSize)); + matcher.withMaxFrameSize(maxFrameSize); + return this; } public OpenExpectation withChannelMax(short channelMax) { - return withChannelMax(equalTo(UnsignedShort.valueOf(channelMax))); + matcher.withChannelMax(channelMax); + return this; } public OpenExpectation withChannelMax(int channelMax) { - return withChannelMax(equalTo(UnsignedShort.valueOf(channelMax))); + matcher.withChannelMax(channelMax); + return this; } public OpenExpectation withChannelMax(UnsignedShort channelMax) { - return withChannelMax(equalTo(channelMax)); + matcher.withChannelMax(channelMax); + return this; } public OpenExpectation withIdleTimeOut(int idleTimeout) { - return withIdleTimeOut(equalTo(UnsignedInteger.valueOf(idleTimeout))); + matcher.withIdleTimeOut(idleTimeout); + return this; } public OpenExpectation withIdleTimeOut(long idleTimeout) { - return withIdleTimeOut(equalTo(UnsignedInteger.valueOf(idleTimeout))); + matcher.withIdleTimeOut(idleTimeout); + return this; } public OpenExpectation withIdleTimeOut(UnsignedInteger idleTimeout) { - return withIdleTimeOut(equalTo(idleTimeout)); + matcher.withIdleTimeOut(idleTimeout); + return this; } public OpenExpectation withOutgoingLocales(String... outgoingLocales) { - return withOutgoingLocales(equalTo(TypeMapper.toSymbolArray(outgoingLocales))); + matcher.withOutgoingLocales(outgoingLocales); + return this; } public OpenExpectation withOutgoingLocales(Symbol... outgoingLocales) { - return withOutgoingLocales(equalTo(outgoingLocales)); + matcher.withOutgoingLocales(outgoingLocales); + return this; } public OpenExpectation withOutgoingLocale(String outgoingLocale) { @@ -234,11 +246,13 @@ public class OpenExpectation extends AbstractExpectation<Open> { } public OpenExpectation withIncomingLocales(String... incomingLocales) { - return withIncomingLocales(equalTo(TypeMapper.toSymbolArray(incomingLocales))); + matcher.withIncomingLocales(incomingLocales); + return this; } public OpenExpectation withIncomingLocales(Symbol... incomingLocales) { - return withIncomingLocales(equalTo(incomingLocales)); + matcher.withIncomingLocales(incomingLocales); + return this; } public OpenExpectation withIncomingLocale(String incomingLocale) { @@ -250,43 +264,63 @@ public class OpenExpectation extends AbstractExpectation<Open> { } public OpenExpectation withOfferedCapabilities(String... offeredCapabilities) { - return withOfferedCapabilities(equalTo(TypeMapper.toSymbolArray(offeredCapabilities))); + matcher.withOfferedCapabilities(offeredCapabilities); + return this; } public OpenExpectation withOfferedCapabilities(Symbol... offeredCapabilities) { - return withOfferedCapabilities(equalTo(offeredCapabilities)); + matcher.withOfferedCapabilities(offeredCapabilities); + return this; } - public OpenExpectation withOfferedCapability(Symbol offeredCapability) { - return withOfferedCapabilities(hasItemInArray(offeredCapability)); + public OpenExpectation withDesiredCapabilities(String... desiredCapabilities) { + matcher.withDesiredCapabilities(desiredCapabilities); + return this; } - public OpenExpectation withOfferedCapability(String offeredCapability) { - return withOfferedCapabilities(hasItemInArray(Symbol.valueOf(offeredCapability))); + public OpenExpectation withDesiredCapabilities(Symbol... desiredCapabilities) { + matcher.withDesiredCapabilities(desiredCapabilities); + return this; } - public OpenExpectation withDesiredCapabilities(String... desiredCapabilities) { - return withDesiredCapabilities(equalTo(TypeMapper.toSymbolArray(desiredCapabilities))); + public OpenExpectation withPropertiesMap(Map<Symbol, Object> properties) { + matcher.withPropertiesMap(properties); + return this; } - public OpenExpectation withDesiredCapabilities(Symbol... desiredCapabilities) { - return withDesiredCapabilities(equalTo(desiredCapabilities)); + public OpenExpectation withProperties(Map<String, Object> properties) { + matcher.withProperties(properties); + return this; + } + + public OpenExpectation withProperty(String key, Object value) { + matcher.withProperty(key, value); + return this; + } + + public OpenExpectation withProperty(Symbol key, Object value) { + matcher.withProperty(key, value); + return this; } public OpenExpectation withDesiredCapability(Symbol desiredCapability) { - return withDesiredCapabilities(hasItemInArray(desiredCapability)); + matcher.withDesiredCapability(desiredCapability); + return this; } public OpenExpectation withDesiredCapability(String desiredCapability) { - return withDesiredCapabilities(hasItemInArray(Symbol.valueOf(desiredCapability))); + matcher.withDesiredCapability(desiredCapability); + return this; } - public OpenExpectation withPropertiesMap(Map<Symbol, Object> properties) { - return withProperties(equalTo(properties)); + public OpenExpectation withOfferedCapability(Symbol offeredCapability) { + matcher.withOfferedCapability(offeredCapability); + return this; } - public OpenExpectation withProperties(Map<String, Object> properties) { - return withProperties(equalTo(TypeMapper.toSymbolKeyedMap(properties))); + public OpenExpectation withOfferedCapability(String offeredCapability) { + matcher.withOfferedCapability(offeredCapability); + return this; } //----- Matcher based with methods for more complex validation @@ -341,16 +375,6 @@ public class OpenExpectation extends AbstractExpectation<Open> { return this; } - public OpenExpectation withProperty(String key, Object value) { - matcher.withProperty(key, value); - return this; - } - - public OpenExpectation withProperty(Symbol key, Object value) { - matcher.withProperty(key, value); - return this; - } - @Override protected Matcher<ListDescribedType> getExpectationMatcher() { return matcher; diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/ArrayContentsMatcher.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/ArrayContentsMatcher.java new file mode 100644 index 00000000..6155a965 --- /dev/null +++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/ArrayContentsMatcher.java @@ -0,0 +1,200 @@ +/* + * 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 java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; + +/** + * Matcher used to compare Array instance either for full or partial contents + * matches. + * + * @param <E> The value type used to define the Array entry. + */ +public class ArrayContentsMatcher<E> extends TypeSafeMatcher<E[]> { + + public enum MatcherMode { + /** + * As long as all the added expected entries match the array is considered + * to be matching. + */ + PARTIAL_MATCH, + /** + * As long as both Arrays have the same contents (and size) the Array is + * considered to be matching. + */ + CONTENTS_MATCH, + /** + * The contents and size of the Array must match the expectations but + * also the order of Array entries iterated over must match the order + * of the expectations as they were added. + */ + EXACT_MATCH + } + + private final List<E> expectedContents = new ArrayList<>(); + + private MatcherMode mode; + private String mismatchDescription; + + /** + * Creates a matcher that matches if any of the expected entries is found + */ + public ArrayContentsMatcher() { + this(MatcherMode.PARTIAL_MATCH); + } + + /** + * Creates a matcher that matches if the expected entries are the only entries + * in the array but doesn't check order. + * + * @param entries + * The entries that must be matched. + */ + public ArrayContentsMatcher(Collection<E> entries) { + this(MatcherMode.CONTENTS_MATCH); + + entries.forEach((e) -> addExpectedEntry(e)); + } + + /** + * Creates a matcher that matches if the expected entries are the only entries + * in the array but doesn't check order. + * + * @param entries + * The entries that must be matched. + * @param strictOrder + * Controls if order also considered when matching. + */ + public ArrayContentsMatcher(Collection<E> entries, boolean strictOrder) { + this(strictOrder ? MatcherMode.EXACT_MATCH : MatcherMode.CONTENTS_MATCH); + + entries.forEach((e) -> addExpectedEntry(e)); + } + + /** + * Creates a new array contents matcher with the given strict setting. + * <p> + * When in strict mode the contents must match both in the entry values and the + * number of entries expected vs the number of entries in the given array. + * + * @param mode + * The matcher mode to use when performing the match. + */ + public ArrayContentsMatcher(MatcherMode mode) { + this.mode = mode; + } + + @Override + public void describeTo(Description description) { + description.appendText(mismatchDescription); + } + + @Override + protected boolean matchesSafely(E[] array) { + switch (mode) { + case CONTENTS_MATCH: + return performContentsOnlyMatch(array); + case EXACT_MATCH: + return performInOrderContentsMatch(array); + case PARTIAL_MATCH: + default: + return performPartialMatch(array); + } + } + + private boolean performArrayInvariantsCheck(E[] array) { + if (array.length == 0 && !expectedContents.isEmpty()) { + mismatchDescription = String.format("Expecting an empty array but got an array of size %s instead", expectedContents.size()); + return false; + } else if (array.length > 0 && expectedContents.isEmpty()) { + mismatchDescription = String.format("Expecting array of size %s but got an empty array instead", expectedContents.size()); + return false; + } else if (array.length != expectedContents.size()) { + mismatchDescription = String.format("Expecting array with %s items but got a array of size %s instead", + expectedContents.size(), array.length); + return false; + } else { + return true; + } + } + + private boolean performInOrderContentsMatch(E[] array) { + if (!performArrayInvariantsCheck(array)) { + return false; + } + + final List<E> elements = Arrays.asList(array); + final Iterator<E> elementsIterator = elements.iterator(); + + for (E expectedEntry : expectedContents) { + E arrayEntry = elementsIterator.next(); + + if (!Objects.equals(expectedEntry, arrayEntry)) { + mismatchDescription = String.format( + "Expected to find a value matching %s but got %s", expectedEntry, arrayEntry); + return false; + } + } + + return true; + } + + private boolean performContentsOnlyMatch(E[] array) { + if (!performArrayInvariantsCheck(array)) { + return false; + } + + return performPartialMatch(array); + } + + private boolean performPartialMatch(E[] array) { + final List<E> elements = new ArrayList<>(Arrays.asList(array)); + + for (E expectedEntry : expectedContents) { + final int index = elements.indexOf(expectedEntry); + + if (index < 0) { + mismatchDescription = String.format("Expected to find an entry matching %s but it wasn't found in the array", expectedEntry); + return false; + } + + // Remove the found item, if a duplicate value is expected it must also exist and not match on this one. + elements.remove(index); + } + + return true; + } + + public void addExpectedEntry(E value) { + expectedContents.add(value); + } + + /** + * @return true if the Arrays must match as equal or if only some contents need to match. + */ + public boolean isStrictEaulityMatching() { + return mode.ordinal() > MatcherMode.PARTIAL_MATCH.ordinal(); + } +} diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/AttachMatcher.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/AttachMatcher.java index 55a2cf87..f1613e4e 100644 --- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/AttachMatcher.java +++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/AttachMatcher.java @@ -25,7 +25,6 @@ import org.apache.qpid.protonj2.test.driver.codec.messaging.Source; import org.apache.qpid.protonj2.test.driver.codec.messaging.Target; import org.apache.qpid.protonj2.test.driver.codec.primitives.Binary; import org.apache.qpid.protonj2.test.driver.codec.primitives.Symbol; -import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedByte; import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger; import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedLong; import org.apache.qpid.protonj2.test.driver.codec.transactions.Coordinator; @@ -35,6 +34,7 @@ import org.apache.qpid.protonj2.test.driver.codec.transport.ReceiverSettleMode; import org.apache.qpid.protonj2.test.driver.codec.transport.Role; import org.apache.qpid.protonj2.test.driver.codec.transport.SenderSettleMode; import org.apache.qpid.protonj2.test.driver.codec.util.TypeMapper; +import org.apache.qpid.protonj2.test.driver.matchers.ArrayContentsMatcher; import org.apache.qpid.protonj2.test.driver.matchers.ListDescribedTypeMatcher; import org.apache.qpid.protonj2.test.driver.matchers.MapContentsMatcher; import org.apache.qpid.protonj2.test.driver.matchers.messaging.SourceMatcher; @@ -47,6 +47,12 @@ public class AttachMatcher extends ListDescribedTypeMatcher { // Only used if singular 'withProperty' API is used private MapContentsMatcher<Symbol, Object> propertiesMatcher; + // Only used if singular 'withDesiredCapabilitiy' API is used + private ArrayContentsMatcher<Symbol> desiredCapabilitiesMatcher; + + // Only used if singular 'withOfferedCapability' API is used + private ArrayContentsMatcher<Symbol> offeredCapabilitiesMatcher; + public AttachMatcher() { super(Attach.Field.values().length, Attach.DESCRIPTOR_CODE, Attach.DESCRIPTOR_SYMBOL); } @@ -87,11 +93,11 @@ public class AttachMatcher extends ListDescribedTypeMatcher { } public AttachMatcher withSndSettleMode(byte sndSettleMode) { - return withSndSettleMode(equalTo(SenderSettleMode.valueOf(sndSettleMode))); + return withSndSettleMode(equalTo(SenderSettleMode.valueOf(sndSettleMode).getValue())); } public AttachMatcher withSndSettleMode(Byte sndSettleMode) { - return withSndSettleMode(sndSettleMode == null ? nullValue() : equalTo(UnsignedByte.valueOf(sndSettleMode.byteValue()))); + return withSndSettleMode(sndSettleMode == null ? nullValue() : equalTo(SenderSettleMode.valueOf(sndSettleMode).getValue())); } public AttachMatcher withSndSettleMode(SenderSettleMode sndSettleMode) { @@ -99,11 +105,11 @@ public class AttachMatcher extends ListDescribedTypeMatcher { } public AttachMatcher withRcvSettleMode(byte rcvSettleMode) { - return withRcvSettleMode(equalTo(ReceiverSettleMode.valueOf(rcvSettleMode))); + return withRcvSettleMode(equalTo(ReceiverSettleMode.valueOf(rcvSettleMode).getValue())); } public AttachMatcher withRcvSettleMode(Byte rcvSettleMode) { - return withRcvSettleMode(rcvSettleMode == null ? nullValue() : equalTo(UnsignedByte.valueOf(rcvSettleMode.byteValue()))); + return withRcvSettleMode(rcvSettleMode == null ? nullValue() : equalTo(ReceiverSettleMode.valueOf(rcvSettleMode).getValue())); } public AttachMatcher withRcvSettleMode(ReceiverSettleMode rcvSettleMode) { @@ -138,6 +144,7 @@ public class AttachMatcher extends ListDescribedTypeMatcher { } public AttachMatcher withUnsettled(Map<Binary, DeliveryState> unsettled) { + // TODO - Need to match on the driver types for DeliveryState return withUnsettled(equalTo(unsettled)); } @@ -166,18 +173,22 @@ public class AttachMatcher extends ListDescribedTypeMatcher { } public AttachMatcher withOfferedCapabilities(Symbol... offeredCapabilities) { + offeredCapabilitiesMatcher = null; // Clear these as this overrides anything else return withOfferedCapabilities(equalTo(offeredCapabilities)); } public AttachMatcher withOfferedCapabilities(String... offeredCapabilities) { + offeredCapabilitiesMatcher = null; // Clear these as this overrides anything else return withOfferedCapabilities(equalTo(TypeMapper.toSymbolArray(offeredCapabilities))); } public AttachMatcher withDesiredCapabilities(Symbol... desiredCapabilities) { + desiredCapabilitiesMatcher = null; // Clear these as this overrides anything else return withDesiredCapabilities(equalTo(desiredCapabilities)); } public AttachMatcher withDesiredCapabilities(String... desiredCapabilities) { + desiredCapabilitiesMatcher = null; // Clear these as this overrides anything else return withDesiredCapabilities(equalTo(TypeMapper.toSymbolArray(desiredCapabilities))); } @@ -204,6 +215,34 @@ public class AttachMatcher extends ListDescribedTypeMatcher { return withProperties(propertiesMatcher); } + public AttachMatcher withDesiredCapability(String value) { + return withDesiredCapability(Symbol.valueOf(value)); + } + + public AttachMatcher withDesiredCapability(Symbol value) { + if (desiredCapabilitiesMatcher == null) { + desiredCapabilitiesMatcher = new ArrayContentsMatcher<Symbol>(); + } + + desiredCapabilitiesMatcher.addExpectedEntry(value); + + return withDesiredCapabilities(desiredCapabilitiesMatcher); + } + + public AttachMatcher withOfferedCapability(String value) { + return withOfferedCapability(Symbol.valueOf(value)); + } + + public AttachMatcher withOfferedCapability(Symbol value) { + if (offeredCapabilitiesMatcher == null) { + offeredCapabilitiesMatcher = new ArrayContentsMatcher<Symbol>(); + } + + offeredCapabilitiesMatcher.addExpectedEntry(value); + + return withOfferedCapabilities(offeredCapabilitiesMatcher); + } + //----- Matcher based with methods for more complex validation public AttachMatcher withName(Matcher<?> m) { diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/BeginMatcher.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/BeginMatcher.java index 7acd6d0d..08d3ee2b 100644 --- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/BeginMatcher.java +++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/BeginMatcher.java @@ -25,6 +25,7 @@ import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger; import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedShort; import org.apache.qpid.protonj2.test.driver.codec.transport.Begin; import org.apache.qpid.protonj2.test.driver.codec.util.TypeMapper; +import org.apache.qpid.protonj2.test.driver.matchers.ArrayContentsMatcher; import org.apache.qpid.protonj2.test.driver.matchers.ListDescribedTypeMatcher; import org.apache.qpid.protonj2.test.driver.matchers.MapContentsMatcher; import org.hamcrest.Matcher; @@ -34,6 +35,12 @@ public class BeginMatcher extends ListDescribedTypeMatcher { // Only used if singular 'withProperty' API is used private MapContentsMatcher<Symbol, Object> propertiesMatcher; + // Only used if singular 'withDesiredCapabilitiy' API is used + private ArrayContentsMatcher<Symbol> desiredCapabilitiesMatcher; + + // Only used if singular 'withOfferedCapability' API is used + private ArrayContentsMatcher<Symbol> offeredCapabilitiesMatcher; + public BeginMatcher() { super(Begin.Field.values().length, Begin.DESCRIPTOR_CODE, Begin.DESCRIPTOR_SYMBOL); } @@ -102,18 +109,22 @@ public class BeginMatcher extends ListDescribedTypeMatcher { } public BeginMatcher withOfferedCapabilities(String... offeredCapabilities) { + offeredCapabilitiesMatcher = null; // Clear these as this overrides anything else return withOfferedCapabilities(equalTo(TypeMapper.toSymbolArray(offeredCapabilities))); } public BeginMatcher withOfferedCapabilities(Symbol... offeredCapabilities) { + offeredCapabilitiesMatcher = null; // Clear these as this overrides anything else return withOfferedCapabilities(equalTo(offeredCapabilities)); } public BeginMatcher withDesiredCapabilities(String... desiredCapabilities) { + desiredCapabilitiesMatcher = null; // Clear these as this overrides anything else return withDesiredCapabilities(equalTo(TypeMapper.toSymbolArray(desiredCapabilities))); } public BeginMatcher withDesiredCapabilities(Symbol... desiredCapabilities) { + desiredCapabilitiesMatcher = null; // Clear these as this overrides anything else return withDesiredCapabilities(equalTo(desiredCapabilities)); } @@ -140,6 +151,34 @@ public class BeginMatcher extends ListDescribedTypeMatcher { return withProperties(propertiesMatcher); } + public BeginMatcher withDesiredCapability(String value) { + return withDesiredCapability(Symbol.valueOf(value)); + } + + public BeginMatcher withDesiredCapability(Symbol value) { + if (desiredCapabilitiesMatcher == null) { + desiredCapabilitiesMatcher = new ArrayContentsMatcher<Symbol>(); + } + + desiredCapabilitiesMatcher.addExpectedEntry(value); + + return withDesiredCapabilities(desiredCapabilitiesMatcher); + } + + public BeginMatcher withOfferedCapability(String value) { + return withOfferedCapability(Symbol.valueOf(value)); + } + + public BeginMatcher withOfferedCapability(Symbol value) { + if (offeredCapabilitiesMatcher == null) { + offeredCapabilitiesMatcher = new ArrayContentsMatcher<Symbol>(); + } + + offeredCapabilitiesMatcher.addExpectedEntry(value); + + return withOfferedCapabilities(offeredCapabilitiesMatcher); + } + //----- Matcher based with methods for more complex validation public BeginMatcher withRemoteChannel(Matcher<?> m) { diff --git a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/OpenMatcher.java b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/OpenMatcher.java index 7b747d99..ddc21285 100644 --- a/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/OpenMatcher.java +++ b/protonj2-test-driver/src/main/java/org/apache/qpid/protonj2/test/driver/matchers/transport/OpenMatcher.java @@ -25,6 +25,7 @@ import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedInteger; import org.apache.qpid.protonj2.test.driver.codec.primitives.UnsignedShort; import org.apache.qpid.protonj2.test.driver.codec.transport.Open; import org.apache.qpid.protonj2.test.driver.codec.util.TypeMapper; +import org.apache.qpid.protonj2.test.driver.matchers.ArrayContentsMatcher; import org.apache.qpid.protonj2.test.driver.matchers.ListDescribedTypeMatcher; import org.apache.qpid.protonj2.test.driver.matchers.MapContentsMatcher; import org.hamcrest.Matcher; @@ -34,6 +35,12 @@ public class OpenMatcher extends ListDescribedTypeMatcher { // Only used if singular 'withProperty' API is used private MapContentsMatcher<Symbol, Object> propertiesMatcher; + // Only used if singular 'withDesiredCapabilitiy' API is used + private ArrayContentsMatcher<Symbol> desiredCapabilitiesMatcher; + + // Only used if singular 'withOfferedCapability' API is used + private ArrayContentsMatcher<Symbol> offeredCapabilitiesMatcher; + public OpenMatcher() { super(Open.Field.values().length, Open.DESCRIPTOR_CODE, Open.DESCRIPTOR_SYMBOL); } @@ -106,18 +113,22 @@ public class OpenMatcher extends ListDescribedTypeMatcher { } public OpenMatcher withOfferedCapabilities(String... offeredCapabilities) { + offeredCapabilitiesMatcher = null; // Clear these as this overrides anything else return withOfferedCapabilities(equalTo(TypeMapper.toSymbolArray(offeredCapabilities))); } public OpenMatcher withOfferedCapabilities(Symbol... offeredCapabilities) { + offeredCapabilitiesMatcher = null; // Clear these as this overrides anything else return withOfferedCapabilities(equalTo(offeredCapabilities)); } public OpenMatcher withDesiredCapabilities(String... desiredCapabilities) { + desiredCapabilitiesMatcher = null; // Clear these as this overrides anything else return withDesiredCapabilities(equalTo(TypeMapper.toSymbolArray(desiredCapabilities))); } public OpenMatcher withDesiredCapabilities(Symbol... desiredCapabilities) { + desiredCapabilitiesMatcher = null; // Clear these as this overrides anything else return withDesiredCapabilities(equalTo(desiredCapabilities)); } @@ -144,6 +155,34 @@ public class OpenMatcher extends ListDescribedTypeMatcher { return withProperties(propertiesMatcher); } + public OpenMatcher withDesiredCapability(String value) { + return withDesiredCapability(Symbol.valueOf(value)); + } + + public OpenMatcher withDesiredCapability(Symbol value) { + if (desiredCapabilitiesMatcher == null) { + desiredCapabilitiesMatcher = new ArrayContentsMatcher<Symbol>(); + } + + desiredCapabilitiesMatcher.addExpectedEntry(value); + + return withDesiredCapabilities(desiredCapabilitiesMatcher); + } + + public OpenMatcher withOfferedCapability(String value) { + return withOfferedCapability(Symbol.valueOf(value)); + } + + public OpenMatcher withOfferedCapability(Symbol value) { + if (offeredCapabilitiesMatcher == null) { + offeredCapabilitiesMatcher = new ArrayContentsMatcher<Symbol>(); + } + + offeredCapabilitiesMatcher.addExpectedEntry(value); + + return withOfferedCapabilities(offeredCapabilitiesMatcher); + } + //----- Matcher based with methods for more complex validation public OpenMatcher withContainerId(Matcher<?> m) { diff --git a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/ReceiverHandlingTest.java b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/ReceiverHandlingTest.java index d468c8a4..2ba07f57 100644 --- a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/ReceiverHandlingTest.java +++ b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/ReceiverHandlingTest.java @@ -379,6 +379,42 @@ class ReceiverHandlingTest extends TestPeerTestsBase { } } + @Test + public void testSTackedOfferedAndDesiredCapabilityMatching() throws Exception { + try (ProtonTestServer peer = new ProtonTestServer(); + ProtonTestClient client = new ProtonTestClient()) { + + peer.expectAMQPHeader().respondWithAMQPHeader(); + peer.expectOpen().respond(); + peer.expectBegin().respond(); + peer.expectAttach().ofSender().respondInKind(); + peer.expectEnd().respond(); + peer.start(); + + URI remoteURI = peer.getServerURI(); + + LOG.info("Test started, peer listening on: {}", remoteURI); + + client.connect(remoteURI.getHost(), remoteURI.getPort()); + client.expectAMQPHeader(); + client.expectOpen(); + client.expectBegin(); + client.expectAttach().ofReceiver().withOfferedCapability("a") // Should fail unless stacking isn't done + .withOfferedCapability("c"); + client.expectEnd(); + client.remoteAMQPHeader().now(); + client.remoteOpen().now(); + client.remoteBegin().now(); + client.remoteAttach().ofSender().withDesiredCapabilities("test", "c", "b") + .now(); + client.remoteEnd().now(); + + assertThrows(AssertionError.class, () -> client.waitForScriptToComplete(30, TimeUnit.SECONDS)); + + peer.waitForScriptToComplete(5, TimeUnit.SECONDS); + } + } + @Test public void testInKindAttachResponseOffersCapabilitiesDesired() throws Exception { try (ProtonTestServer peer = new ProtonTestServer(); diff --git a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matcher/ArrayContainsMatcherTest.java b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matcher/ArrayContainsMatcherTest.java new file mode 100644 index 00000000..497feb33 --- /dev/null +++ b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matcher/ArrayContainsMatcherTest.java @@ -0,0 +1,244 @@ +/* + * 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.matcher; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.apache.qpid.protonj2.test.driver.matchers.ArrayContentsMatcher; +import org.apache.qpid.protonj2.test.driver.matchers.ArrayContentsMatcher.MatcherMode; +import org.junit.jupiter.api.Test; + +/** + * Test custom array contents matcher + */ +public class ArrayContainsMatcherTest { + + @Test + public void testEmptyArraysAreEqualInAllModes() { + final String[] array = new String[0]; + + ArrayContentsMatcher<String> matcher1 = new ArrayContentsMatcher<>(MatcherMode.PARTIAL_MATCH); + ArrayContentsMatcher<String> matcher2 = new ArrayContentsMatcher<>(MatcherMode.CONTENTS_MATCH); + ArrayContentsMatcher<String> matcher3 = new ArrayContentsMatcher<>(MatcherMode.EXACT_MATCH); + + assertTrue(matcher1.matches(array)); + assertTrue(matcher2.matches(array)); + assertTrue(matcher3.matches(array)); + } + + @Test + public void testNullValueMatchPartial() { + doTestNullValueMatches(MatcherMode.PARTIAL_MATCH); + } + + @Test + public void testNullValueMatchContents() { + doTestNullValueMatches(MatcherMode.CONTENTS_MATCH); + } + + @Test + public void testNullValueMatchExact() { + doTestNullValueMatches(MatcherMode.EXACT_MATCH); + } + + protected void doTestNullValueMatches(MatcherMode mode) { + final String[] array = new String[1]; + + ArrayContentsMatcher<String> matcher = new ArrayContentsMatcher<>(mode); + + matcher.addExpectedEntry(null); + + assertTrue(matcher.matches(array)); + } + + @Test + public void testNullValueMissingMatchPartial() { + doTestNullValueMatches(MatcherMode.PARTIAL_MATCH); + } + + @Test + public void testNullValueMissingMatchContents() { + doTestNullValueMatches(MatcherMode.CONTENTS_MATCH); + } + + @Test + public void testNullValueMissingMatchExact() { + doTestNullValueMatches(MatcherMode.EXACT_MATCH); + } + + protected void doTestNullValueMissingMatches(MatcherMode mode) { + final String[] array = new String[1]; + + array[0] = "A"; + + ArrayContentsMatcher<String> matcher = new ArrayContentsMatcher<>(mode); + + matcher.addExpectedEntry(null); + + assertFalse(matcher.matches(array)); + } + + @Test + public void testArrayEqualsWhenTheyAre() { + final String[] array = new String[3]; + + array[0] = "A"; + array[1] = "B"; + array[2] = "C"; + + ArrayContentsMatcher<String> matcher = new ArrayContentsMatcher<>(MatcherMode.EXACT_MATCH); + + matcher.addExpectedEntry("A"); + matcher.addExpectedEntry("B"); + matcher.addExpectedEntry("C"); + + assertTrue(matcher.matches(array)); + + matcher.addExpectedEntry("D"); + + assertFalse(matcher.matches(array)); + } + + @Test + public void testArrayEqualsWhenTheyAreNotForContents() { + final String[] array = new String[3]; + + array[0] = "A"; + array[1] = "B"; + array[2] = "C"; + + ArrayContentsMatcher<String> matcher = new ArrayContentsMatcher<>(MatcherMode.CONTENTS_MATCH); + + matcher.addExpectedEntry("A"); + assertFalse(matcher.matches(array)); + + matcher.addExpectedEntry("C"); + assertFalse(matcher.matches(array)); + + matcher.addExpectedEntry("B"); + assertTrue(matcher.matches(array)); // finally equal + + matcher.addExpectedEntry("D"); + assertFalse(matcher.matches(array)); + } + + @Test + public void testArrayContentsMustBeInOrderForExactMatcher() { + final String[] array = new String[3]; + + array[0] = "A"; + array[1] = "C"; + array[2] = "B"; + + ArrayContentsMatcher<String> matcher = new ArrayContentsMatcher<>(MatcherMode.EXACT_MATCH); + + matcher.addExpectedEntry("A"); + matcher.addExpectedEntry("B"); + matcher.addExpectedEntry("C"); + + assertFalse(matcher.matches(array)); + + array[1] = "B"; + array[2] = "C"; + + assertTrue(matcher.matches(array)); + } + + @Test + public void testArrayEqualsWhenItContainsTheValueExpectedButAlsoOthers() { + final String[] array = new String[5]; + + array[0] = "A"; + array[1] = "C"; + array[2] = "B"; + array[3] = "D"; + array[4] = "E"; + + ArrayContentsMatcher<String> matcher = new ArrayContentsMatcher<>(MatcherMode.PARTIAL_MATCH); + + matcher.addExpectedEntry("A"); + matcher.addExpectedEntry("B"); + matcher.addExpectedEntry("C"); + + assertTrue(matcher.matches(array)); + } + + @Test + public void testExactMatchFailsWhenMoreElementsThanExpected() { + final String[] array = new String[5]; + + array[0] = "A"; + array[1] = "B"; + array[2] = "B"; + array[3] = "C"; + array[4] = "C"; + + ArrayContentsMatcher<String> matcher = new ArrayContentsMatcher<>(MatcherMode.EXACT_MATCH); + + matcher.addExpectedEntry("A"); + matcher.addExpectedEntry("B"); + matcher.addExpectedEntry("C"); + + assertFalse(matcher.matches(array)); + } + + @Test + public void testPartialMatchNeedsAllRepeatedEntries() { + final String[] array = new String[6]; + + array[0] = "A"; + array[1] = "B"; + array[2] = "B"; + array[3] = "C"; + array[4] = "C"; + array[5] = "D"; + + ArrayContentsMatcher<String> matcher = new ArrayContentsMatcher<>(MatcherMode.PARTIAL_MATCH); + + matcher.addExpectedEntry("B"); + matcher.addExpectedEntry("C"); + matcher.addExpectedEntry("B"); + matcher.addExpectedEntry("C"); + matcher.addExpectedEntry("D"); + + assertTrue(matcher.matches(array)); + + array[5] = "E"; + + assertFalse(matcher.matches(array)); + } + + @Test + public void testArrayNotLargeEnoughForContentsMatch() { + final String[] array = new String[6]; + + array[0] = "A"; + array[1] = "B"; + array[2] = "C"; + + ArrayContentsMatcher<String> matcher = new ArrayContentsMatcher<>(MatcherMode.CONTENTS_MATCH); + + matcher.addExpectedEntry("A"); + matcher.addExpectedEntry("C"); + matcher.addExpectedEntry("B"); + matcher.addExpectedEntry("C"); + matcher.addExpectedEntry("D"); + + assertFalse(matcher.matches(array)); + } +} diff --git a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matcher/MapContentsMatcherTest.java b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matcher/MapContentsMatcherTest.java index f33162c7..04eb14d6 100644 --- a/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matcher/MapContentsMatcherTest.java +++ b/protonj2-test-driver/src/test/java/org/apache/qpid/protonj2/test/driver/matcher/MapContentsMatcherTest.java @@ -91,7 +91,7 @@ public class MapContentsMatcherTest { } @Test - public void testMapEqualsWhenTheyAreNotForContensts() { + public void testMapEqualsWhenTheyAreNotForContents() { final Map<String, String> map = new HashMap<>(); map.put("one", "1"); @@ -111,7 +111,7 @@ public class MapContentsMatcherTest { } @Test - public void testMapEqualsWhenTheyAreNotForContensts2() { + public void testMapEqualsWhenTheyAreNotForContents2() { final Map<String, String> map = new LinkedHashMap<>(); map.put("one", "1"); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org