aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Duffin <paulduffin@google.com>2017-02-24 13:32:52 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-02-24 13:32:52 +0000
commit0d446c0a6f5ab27bf24d8e046f1d03ce40f09594 (patch)
tree873cd708d3c6fb36684c53bc506ff3940c3ec3f0
parenta7b13a9be885f7471bd449ddaa57ff7a92114c0b (diff)
parentf324aac9e2d9c977fcf8e0033a6a7846a62db4df (diff)
downloadhamcrest-0d446c0a6f5ab27bf24d8e046f1d03ce40f09594.tar.gz
am: f324aac9e2 Change-Id: I12d85f17def51bf7047dd664b941ea1cdb2bfc92
-rw-r--r--BUILDING.txt19
-rw-r--r--CHANGES.txt135
-rw-r--r--LICENSE.txt2
-rw-r--r--README.android1
-rw-r--r--README.md63
-rw-r--r--README.version15
-rw-r--r--build.gradle109
-rw-r--r--build.xml.original289
-rw-r--r--doc/images/logo.jpgbin0 -> 8454 bytes
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/BaseDescription.java271
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/BaseMatcher.java9
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/Condition.java69
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/CoreMatchers.java419
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/CustomMatcher.java37
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/CustomTypeSafeMatcher.java39
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/Description.java133
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/DiagnosingMatcher.java21
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/Factory.java9
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/FeatureMatcher.java54
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/Matcher.java34
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/MatcherAssert.java51
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/SelfDescribing.java2
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/StringDescription.java123
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/TypeSafeDiagnosingMatcher.java69
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/TypeSafeMatcher.java81
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/AllOf.java50
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/AnyOf.java50
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/CombinableMatcher.java82
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/DescribedAs.java124
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/Every.java44
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/Is.java64
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/IsAnything.java41
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/IsCollectionContaining.java133
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/IsEqual.java82
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/IsInstanceOf.java81
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/IsNot.java36
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/IsNull.java61
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/IsSame.java39
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/ShortcutCombination.java33
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/StringContains.java46
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/StringEndsWith.java42
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/StringStartsWith.java40
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/core/SubstringMatcher.java44
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/internal/ArrayIterator.java43
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/internal/NullSafety.java18
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/internal/ReflectiveTypeFinder.java70
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/internal/SelfDescribingValue.java1
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/internal/SelfDescribingValueIterator.java7
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/internal/package.html5
-rw-r--r--hamcrest-core/src/main/java/org/hamcrest/package.html9
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/AbstractMatcherTest.java77
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/BaseDescriptionTest.java78
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/BaseMatcherTest.java26
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/CustomMatcherTest.java20
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/CustomTypeSafeMatcherTest.java41
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/FeatureMatcherTest.java68
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/MatcherAssertTest.java96
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/NullDescriptionTest.java18
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/TypeSafeMatcherTest.java40
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/AllOfTest.java63
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/AnyOfTest.java56
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/CombinableTest.java68
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/DescribedAsTest.java49
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/EveryTest.java43
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/IsAnythingTest.java35
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/IsCollectionContainingTest.java107
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/IsEqualTest.java143
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/IsInstanceOfTest.java69
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/IsNotTest.java42
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/IsNullTest.java43
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/IsSameTest.java48
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/IsTest.java51
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/SampleBaseClass.java24
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/SampleSubClass.java9
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/StringContainsTest.java43
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/StringEndsWithTest.java45
-rw-r--r--hamcrest-core/src/test/java/org/hamcrest/core/StringStartsWithTest.java46
-rw-r--r--hamcrest-library/LICENSE.txt27
-rw-r--r--hamcrest-library/README.android1
-rw-r--r--hamcrest-library/build.gradle13
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/Matchers.java1845
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsArray.java45
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayContaining.java51
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayContainingInAnyOrder.java112
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayContainingInOrder.java89
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayWithSize.java59
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsCollectionContaining.java65
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsCollectionWithSize.java50
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsEmptyCollection.java53
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsEmptyIterable.java48
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsIn.java98
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableContainingInAnyOrder.java154
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableContainingInOrder.java153
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableContainingInRelativeOrder.java117
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableWithSize.java53
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsMapContaining.java119
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/collection/IsMapWithSize.java60
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/comparator/ComparatorMatcherBuilder.java178
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/io/FileMatchers.java107
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/number/BigDecimalCloseTo.java63
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/number/IsCloseTo.java41
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/number/IsGreaterThan.java26
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/number/IsNaN.java38
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/number/OrderingComparison.java79
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/number/OrderingComparisons.java38
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/object/HasToString.java52
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/object/IsCompatibleType.java18
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/object/IsEventFrom.java49
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/text/IsBlankString.java55
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/text/IsEmptyString.java77
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/text/IsEqualIgnoringCase.java96
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/text/IsEqualIgnoringWhiteSpace.java139
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/text/MatchesPattern.java41
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/text/StringContains.java29
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/text/StringContainsInOrder.java69
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/text/StringEndsWith.java29
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/text/StringStartsWith.java29
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/text/SubstringMatcher.java31
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/text/X.java18
-rw-r--r--hamcrest-library/src/main/java/org/hamcrest/xml/HasXPath.java163
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/beans/HasPropertyTest.java48
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/beans/HasPropertyWithValueTest.java139
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/beans/SamePropertyValuesAsTest.java98
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayContainingInAnyOrderTest.java43
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayContainingInOrderTest.java45
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayContainingTest.java72
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayTest.java59
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayWithSizeTest.java36
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsCollectionWithSizeTest.java77
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsEmptyCollectionTest.java45
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsEmptyIterableTest.java44
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsInTest.java44
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableContainingInAnyOrderTest.java54
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableContainingInOrderTest.java77
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableContainingInRelativeOrderTest.java93
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableWithSizeTest.java37
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsMapContainingKeyTest.java84
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsMapContainingTest.java58
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsMapContainingValueTest.java46
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/collection/IsMapWithSizeTest.java82
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/comparator/ComparatorMatcherBuilderTest.java128
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/comparator/ComparatorMatcherTest.java87
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/io/FileMatchersTest.java93
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/number/BigDecimalCloseToTest.java45
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/number/IsCloseToTest.java32
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/number/IsNanTest.java43
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/number/OrderingComparisonTest.java80
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/object/HasToStringTest.java55
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/object/IsCompatibleTypeTest.java58
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/object/IsEventFromTest.java52
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/object/MatchesPatternTest.java59
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/text/IsBlankStringTest.java55
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/text/IsEmptyStringTest.java55
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/text/IsEqualIgnoringCaseTest.java62
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/text/IsEqualIgnoringWhiteSpaceTest.java51
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/text/StringContainsInOrderTest.java30
-rw-r--r--hamcrest-library/src/test/java/org/hamcrest/xml/HasXPathTest.java147
157 files changed, 10354 insertions, 1483 deletions
diff --git a/BUILDING.txt b/BUILDING.txt
new file mode 100644
index 0000000..8d6ee82
--- /dev/null
+++ b/BUILDING.txt
@@ -0,0 +1,19 @@
+ **********************
+********************* Building Hamcrest *********************
+ **********************
+
+--[ Build requirements ]-------------------------------------
+
+* JDK 1.7
+
+* Gradle
+
+--[ Building from the command line ]-------------------------
+
+Execute the default ant target:
+ ./gradlew clean build javadoc
+
+This will do a full clean build, run all tests and (if
+successful) package up a distribution. The resulting builds
+reside in the 'build' directory.
+
diff --git a/CHANGES.txt b/CHANGES.txt
new file mode 100644
index 0000000..f0a392b
--- /dev/null
+++ b/CHANGES.txt
@@ -0,0 +1,135 @@
+== Version 2.0.0.0 ==
+
+A new beginning...
+
+* Upgraded to Java 7
+
+* Build with Gradle
+
+* Publish a single jar java-hamcrest-x.x.x.x.jar
+
+* Removed deprecated methods from previous release
+
+* Improve mismatch description of hasItem/hasItems
+
+* General improvements to mismatch descriptions
+
+* Several JavaDoc improvements and corrections
+
+* Fix gh issue #69 - Iterable contains in order is null-safe
+
+* Fix gh issue #59 - added equalToObject() (i.e. unchecked) method
+
+* Fix gh issue #25 - arrayContaining(null, null) cause NullPointerException
+
+* Fix gh issue #36 - string matching on regular expressions
+
+* Fix gh issue #8 - isCloseTo() shows wrong delta in mismatch description
+
+* Fix issue 131 - Implement IsEmptyMap, IsMapWithSize
+
+* Fix issue 155 - Deprecated several matcher factory methods of the for "isXyz"
+
+* Fix issue 187 - IsArray.describeMismatchSafely() should use Matcher.describeMismatch
+
+* Fix issue 155 - Add Matcher implementation for files
+
+* Fix issue 59 - add untyped version of equalTo, named equalToObject
+
+* Fix issue 69 - fix NPE in IsIterableContainingInOrder
+
+* Fix issue 75 - address doclint errors reported in JDK 1.8
+
+== Version 1.3: Released July 09 2012 ==
+
+* Introduce Condition class to ease the implementation of multi-step matches
+
+* Upgrade qdox (included in the generator) to the latest stable version
+
+* Correct inadvertent deprecation of the Is.isA factory method
+
+* Fix issue 179 - AllOf does not output mismatch description
+
+* Fix issue 177 - Introduced closeTo matcher for BigDecimals
+
+* Fix issue 152 - Factory classes missing from matchers.xml
+
+* Fix issue 144 - OrderingComparison doesn't describe mismatch of comparables that return values other than (-1,0,1)
+
+* Fix issue 134 - DescribedAs does not delegate describeMismatch
+
+* Fix issue 106 - deprecation warning when writing custom matchers
+
+* Fix issue 101 - Added theInstance alias for sameInstance factory method
+
+== Version 1.3 RC2: Released October 22 2010 ==
+
+* Added FeatureMatcher
+
+* distinguish between instanceOf() and any()
+
+== Version 1.2: Released May 16 2009 ==
+
+* Added mismatch reporting
+
+* Added WithSamePropertyValuesAs matcher
+
+* Moved any() from IsAnything to IsInstanceOf. It now checks the type of the matched object
+
+* Moved MatcherAssert from integration to core
+
+* Tightened up generics.
+
+* Added IsMapContainingKey and IsMapContainingValue matchers to resolve a
+ generics bug in hasKey and hasValue static factories previously declared
+ in IsMapContaining (ngd)
+
+* Added IsCollectionOnlyContaining and IsArrayOnlyContaining which matches
+ collections (and arrays) where all match a given matcher. E.g onlyContains(3,4,5)
+ or onlyContains(lessThan(9))
+
+* text module moved to separate project, hamcrest-text-patterns
+
+* added more colection matchers: xContainingInAnyOrder, xContainingInOrder, xWithSize
+
+* new text Matcher: IsEmptyString
+
+* hamcrest generator uses method return type
+
+== Version 1.1: Released Jun 30 2007 ==
+
+* Hamcrest Generator now includes JavaDoc and parameter names in generated code
+ by using QDox to parse the source code.
+
+* Created hamcrest-core.jar (and removed hamcrest-api.jar).
+ Moved core set of matchers (and, eq, not, etc)
+ to this package to make it more practical for external libraries
+ to embed Hamcrest.
+
+* Created CoreMatchers (static import sugar) in hamcrest-core.jar.
+
+* StringBuilder can use any Appendable (not just StringBuffer).
+
+* Added sensible toString() method to BaseMatcher.
+
+* Created StringDescription.asString() alias (because toString() caused issues
+ with static imports).
+
+* Relaxed isInstanceOf() matcher generic type so it can be used on any kind of
+ object. e.g. assertThat(someUnknownObject, isInstanceOf(String.class));
+
+* Added any(Class<T>), null(Class<T>) and notNull(Class<T>) matchers, which returns
+ Matcher<T>. Helpful when the compiler struggles with type inference.
+
+* Modified anyOf() and allOf() to accept mixed-types.
+
+* TypeSafeMatcher.matchesSafely() is now public.
+
+* Generator recognizes @Factory methods that return subclass of Matcher.
+ (Fix by David Saff)
+
+== Version 1.0: Released Dec 15 2006 ==
+
+Initial release.
+* Support for namespaces in HasXPath
+* Bug fix for matching empty elements with HasXPath
diff --git a/LICENSE.txt b/LICENSE.txt
index 5ebe92c..71806dd 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,6 +1,6 @@
BSD License
-Copyright (c) 2000-2006, www.hamcrest.org
+Copyright (c) 2000-20014 www.hamcrest.org
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/README.android b/README.android
deleted file mode 100644
index a1bbfd2..0000000
--- a/README.android
+++ /dev/null
@@ -1 +0,0 @@
-unmodified source obtained from http://code.google.com/p/hamcrest/downloads/detail?name=hamcrest-core-1.1.jar&can=2&q=,
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c1e1e0f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,63 @@
+![JavaHamcrest](http://hamcrest.org/images/logo.jpg)
+
+[![Build Status](https://travis-ci.org/hamcrest/JavaHamcrest.png?branch=master)](https://travis-ci.org/hamcrest/JavaHamcrest)
+
+Java Hamcrest
+=============
+Licensed under [BSD License][].
+
+What is Hamcrest?
+-----------------
+Hamcrest is a library of matchers, which can be combined in to create flexible expressions of intent in tests.
+They've also been used for other purposes.
+
+Downloads
+---------
+You can obtain Hamcrest binaries from [maven central][], or from [google code downloads][].
+
+Extensions
+----------
+
+For Hamcrest extension projects see the [hamcrest extensions page][].
+
+Documentation
+-------------
+Documentation can be found on the [Hamcrest site](http://hamcrest.org).
+
+Reporting Bugs/Issues
+---------------------
+If you find an issue with Java Hamcrest, please report it via the
+[GitHub issue tracker](https://github.com/hamcrest/JavaHamcrest/issues),
+after first checking that it hasn't been raised already.
+
+Source
+------
+To build, please read BUILDING.txt
+
+Acknowledgements
+----------------
+Developers:
+
+ * Joe Walnes
+ * Nat Pryce
+ * Steve Freeman
+
+Contributors:
+
+ * Robert Chatley
+ * Tom White
+ * Neil Dunn
+ * Dan North
+ * Magne Rasmussen
+ * David Saff
+ * Tom Denley
+
+Also, thanks to everyone who has worked on DynaMock, nMock, jMock, EasyMock and MiniMock! These libraries inspired Hamcrest.
+
+
+[logo]: https://raw.github.com/hamcrest/JavaHamcrest/master/doc/images/logo.jpg
+[website]: https://github.com/hamcrest/JavaHamcrest
+[BSD License]: http://opensource.org/licenses/BSD-3-Clause
+[Maven central]: http://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.hamcrest
+[hamcrest extensions page]: https://github.com/hamcrest/JavaHamcrest/wiki/Related-Projects
+[GitHub issue tracker]: https://github.com/hamcrest/JavaHamcrest/issues
diff --git a/README.version b/README.version
new file mode 100644
index 0000000..660cee5
--- /dev/null
+++ b/README.version
@@ -0,0 +1,15 @@
+URL: https://github.com/hamcrest/JavaHamcrest/archive/f540af9fd49f33cc07b3446a8895c7b51cbf0944.zip
+Version: f540af9fd49f33cc07b3446a8895c7b51cbf0944
+BugComponent: 40416
+
+Version f540af9fd49f33cc07b3446a8895c7b51cbf0944 was chosen because it is the
+point at which v2.0.0.0 and master diverge. There are only about 7 commits
+on v2.0.0.0 which are not on master but they do conflict with some changes in
+master. Those changes appear to be relatively minor and while it is not clear
+what the future holds for Hamcrest given that it has had no activity since June
+2016 it seems unnecessary to take those extra 7 commits given the potential for
+conflicts in future upgrades.
+
+Local Changes:
+ Remove hamcrest-library/src/main/java/org/hamcrest/beans/ as Android does not support java.beans.
+ \ No newline at end of file
diff --git a/build.gradle b/build.gradle
index b169d73..cd23be2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,9 +1,116 @@
+import static org.gradle.api.JavaVersion.VERSION_1_7
+
apply plugin: 'java'
+apply plugin: 'maven'
+apply plugin: 'signing'
+
+sourceCompatibility = VERSION_1_7
+targetCompatibility = VERSION_1_7
+archivesBaseName = "java-hamcrest"
+
+group = "org.hamcrest"
+version = "2.0.0.0"
+
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ testCompile(group: 'junit', name: 'junit', version: '4.12') {
+ transitive = false
+ }
+}
sourceSets {
main {
java {
- srcDirs = ['src']
+ srcDirs 'hamcrest-core/src/main/java', 'hamcrest-library/src/main/java'
+ }
+
+ }
+ test {
+ java {
+ srcDirs 'hamcrest-core/src/test/java', 'hamcrest-library/src/test/java'
+ }
+ }
+}
+
+jar {
+ manifest {
+ attributes 'Implementation-Title': 'hamcrest-all',
+ 'Implementation-Vendor': 'hamcrest.org',
+ 'Implementation-Version': version
+ }
+}
+
+task sourcesJar(type: Jar) {
+ classifier = 'sources'
+ from sourceSets.main.allSource
+}
+
+task javadocJar(type: Jar) {
+ classifier = 'javadoc'
+ from javadoc
+}
+
+artifacts {
+ archives sourcesJar, javadocJar
+}
+
+signing {
+ required { gradle.taskGraph.hasTask("uploadArchives") }
+ sign configurations.archives
+}
+
+uploadArchives {
+ if (hasProperty('ossrhUsername') && hasProperty('ossrhPassword')) {
+ repositories {
+ mavenDeployer {
+ beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
+
+ repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
+ authentication(userName: ossrhUsername, password: ossrhPassword)
+ }
+
+ snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
+ authentication(userName: ossrhUsername, password: ossrhPassword)
+ }
+
+ pom.project {
+ name 'Java Hamcrest'
+ packaging 'jar'
+ description 'Hamcrest matcher library for Java'
+ url 'http://hamcrest.org/JavaHamcrest/'
+
+ scm {
+ connection 'git@github.com:hamcrest/JavaHamcrest.git'
+ url 'https://github.com/hamcrest/JavaHamcrest'
+ }
+
+ licenses {
+ license {
+ name 'BSD Licence 3'
+ url 'http://opensource.org/licenses/BSD-3-Clause'
+ }
+ }
+
+ developers {
+ developer {
+ id 'joewalnes'
+ name 'Joe Walnes'
+ }
+ developer {
+ id 'npryce'
+ name 'Nat Pryce'
+ }
+ developer {
+ id 'sf105'
+ name 'Steve Freeman'
+ }
+ }
+ }
+ }
}
}
}
diff --git a/build.xml.original b/build.xml.original
new file mode 100644
index 0000000..95662ee
--- /dev/null
+++ b/build.xml.original
@@ -0,0 +1,289 @@
+<project name="hamcrest" default="all">
+
+ <property name="version" value="SNAPSHOT" description="Version number to use in build files"/>
+ <property name="haltonfailure" value="true" description="Whether to halt the build if the tests fail"/>
+ <property name="debug" value="true" description="Whether to build with debug information"/>
+ <property name="javaversion" value="1.5" description="Java version to target"/>
+ <tstamp><format property="build.timestamp" pattern="yyyy-MM-dd HH:mm:ss" timezone="GMT"/></tstamp>
+ <taskdef name="junit" classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask" classpath="lib/integration/ant-junit-1.8.4.jar"/>
+
+
+ <target name="all" depends="clean, bigjar, javadoc" description="Performs clean build, runs tests and packages for distribution"/>
+
+ <target name="clean" description="Clean up all built files">
+ <delete dir="build"/>
+ </target>
+
+ <target name="api" description="Build Hamcrest APIs">
+ <path id="cp-hamcrest-api-main" path=""/>
+ <path id="cp-hamcrest-api-test" path=""/>
+ <compile-module modulename="hamcrest-api"/>
+ <jar-module modulename="hamcrest-api"/>
+ <test-module modulename="hamcrest-api"/>
+ </target>
+
+ <target name="generator" depends="api" description="Build code generator tool">
+ <path id="cp-hamcrest-generator-main" path="lib/generator/qdox-2.0-M2.jar;build/hamcrest-api-${version}.jar"/>
+ <path id="cp-hamcrest-generator-test" path=""/>
+ <compile-module modulename="hamcrest-generator"/>
+ <jar-module modulename="hamcrest-generator"/>
+ <test-module modulename="hamcrest-generator"/>
+
+ <!-- Include QDox classes in hamcrest-generator.jar using JarJar to place classes under a different package -->
+ <taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="lib/generator/jarjar-1.3.jar"/>
+ <copy file="build/hamcrest-generator-${version}.jar" tofile="build/hamcrest-generator-${version}-nodep.jar"/>
+ <jarjar jarfile="build/hamcrest-generator-${version}.jar">
+ <zipfileset src="build/hamcrest-generator-${version}-nodep.jar"/>
+ <zipfileset src="lib/generator/qdox-2.0-M2.jar"/>
+ <rule pattern="com.thoughtworks.qdox.**" result="org.hamcrest.generator.qdox.@1"/>
+ </jarjar>
+ </target>
+
+ <target name="core" depends="generator" description="Build core Hamcrest library">
+ <path id="cp-hamcrest-core-main" path="build/hamcrest-api-${version}.jar"/>
+ <path id="cp-hamcrest-core-test" path=""/>
+ <compile-module modulename="hamcrest-core"/>
+ <generate-module-factory modulename="hamcrest-core" configurationfile="hamcrest-core/core-matchers.xml" targetclass="org.hamcrest.CoreMatchers" sources="hamcrest-core/src/main/java"/>
+ <jar-module modulename="hamcrest-core"/>
+ <test-module modulename="hamcrest-core"/>
+ </target>
+
+ <target name="library" depends="core" description="Build library of matchers">
+ <path id="cp-hamcrest-library-main" path="build/hamcrest-api-${version}.jar;build/hamcrest-core-${version}.jar"/>
+ <path id="cp-hamcrest-library-test" path="build/hamcrest-core-${version}-tests.jar"/>
+ <compile-module modulename="hamcrest-library"/>
+ <generate-module-factory modulename="hamcrest-library" configurationfile="hamcrest-library/matchers.xml" targetclass="org.hamcrest.Matchers" sources="hamcrest-core/src/main/java,hamcrest-library/src/main/java"/>
+ <jar-module modulename="hamcrest-library"/>
+ <test-module modulename="hamcrest-library"/>
+ </target>
+
+ <target name="integration" depends="library" description="Build integration with external tools">
+ <path id="cp-hamcrest-integration-main">
+ <fileset file="build/hamcrest-api-${version}.jar"/>
+ <fileset file="build/hamcrest-core-${version}.jar"/>
+ <fileset file="build/hamcrest-library-${version}.jar"/>
+ <fileset dir="lib/integration" includes="**/*.jar"/>
+ </path>
+ <path id="cp-hamcrest-integration-test" path="build/hamcrest-core-${version}-tests.jar"/>
+ <compile-module modulename="hamcrest-integration"/>
+ <jar-module modulename="hamcrest-integration"/>
+ <test-module modulename="hamcrest-integration"/>
+ </target>
+
+ <target name="examples" depends="core, library, integration" description="Build and run unit tests.">
+ <path id="cp-hamcrest-examples-main">
+ <fileset file="build/hamcrest-api-${version}.jar"/>
+ <fileset file="build/hamcrest-core-${version}.jar"/>
+ <fileset file="build/hamcrest-library-${version}.jar"/>
+ <fileset file="build/hamcrest-integration-${version}.jar"/>
+ <fileset dir="lib/integration" includes="**/*.jar"/>
+ </path>
+ <compile-module modulename="hamcrest-examples"/>
+ <jar-module modulename="hamcrest-examples"/>
+ </target>
+
+ <target name="bigjar" depends="core,library,integration,generator" description="Build composite jars">
+ <!-- Bundle api into core jar -->
+ <copy todir="build/temp/hamcrest-core-${version}.jar.contents">
+ <fileset dir="build/temp/hamcrest-api-${version}.jar.contents"/>
+ </copy>
+ <copy todir="build/temp/hamcrest-core-${version}-sources.jar.contents">
+ <fileset dir="build/temp/hamcrest-api-${version}-sources.jar.contents"/>
+ </copy>
+ <jar-module modulename="hamcrest-core"/>
+
+ <!-- Bundle core, library, integration, and generator into all jar-->
+ <copy todir="build/temp/hamcrest-all-${version}.jar.contents">
+ <fileset dir="build/temp/hamcrest-core-${version}.jar.contents"/>
+ <fileset dir="build/temp/hamcrest-library-${version}.jar.contents"/>
+ <fileset dir="build/temp/hamcrest-integration-${version}.jar.contents"/>
+ <fileset dir="build/temp/hamcrest-generator-${version}.jar.contents"/>
+ </copy>
+ <copy todir="build/temp/hamcrest-all-${version}-sources.jar.contents">
+ <fileset dir="build/temp/hamcrest-core-${version}-sources.jar.contents"/>
+ <fileset dir="build/temp/hamcrest-library-${version}-sources.jar.contents"/>
+ <fileset dir="build/temp/hamcrest-integration-${version}-sources.jar.contents"/>
+ <fileset dir="build/temp/hamcrest-generator-${version}-sources.jar.contents"/>
+ </copy>
+ <path id="cp-hamcrest-all-main">
+ <path refid="cp-hamcrest-core-main"/>
+ <path refid="cp-hamcrest-library-main"/>
+ <path refid="cp-hamcrest-integration-main"/>
+ <path refid="cp-hamcrest-generator-main"/>
+ </path>
+ <jar-module modulename="hamcrest-all"/>
+ </target>
+
+ <target name="javadoc" depends="bigjar" description="build javadoc jars">
+ <javadoc-module modulename="hamcrest-generator"/>
+ <javadoc-module modulename="hamcrest-core"/>
+ <javadoc-module modulename="hamcrest-library"/>
+ <javadoc-module modulename="hamcrest-integration"/>
+ <javadoc-module modulename="hamcrest-all"/>
+ </target>
+
+ <target name="bundle" description="Create a release bundle for deployment to maven central" depends="clean, javadoc">
+ <copy todir="build">
+ <fileset dir="pom" includes="*.pom"/>
+ <filterset><filter token="VERSION" value="${version}"/></filterset>
+ <mapper type="regexp" from="(.*)\.pom" to="\1-${version}.pom"/>
+ </copy>
+
+ <sign target="hamcrest-parent-${version}.pom"/>
+ <jar-bundle modulename="hamcrest-parent"/>
+
+ <bundle-module modulename="hamcrest-core"/>
+ <bundle-module modulename="hamcrest-generator"/>
+ <bundle-module modulename="hamcrest-library"/>
+ <bundle-module modulename="hamcrest-integration"/>
+ <bundle-module modulename="hamcrest-all"/>
+ </target>
+
+ <macrodef name="make-manifest">
+ <attribute name="modulename" description="Name of the module"/>
+ <sequential>
+ <mkdir dir="build/temp/@{modulename}-${version}.jar.manifest"/>
+ <manifest file="build/temp/@{modulename}-${version}.jar.manifest/MANIFEST.MF">
+ <attribute name="Implementation-Title" value="@{modulename}"/>
+ <attribute name="Implementation-Vendor" value="hamcrest.org"/>
+ <attribute name="Implementation-Version" value="${version}"/>
+ <attribute name="Built-By" value="${user.name}"/>
+ <attribute name="Built-Date" value="${build.timestamp}"/>
+ </manifest>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="compile-module">
+ <attribute name="modulename" description="Name of the module to jar"/>
+ <sequential>
+ <compile-content srcdir="@{modulename}/src/main/java" jarname="@{modulename}-${version}" classpathref="cp-@{modulename}-main" />
+ <path id="cp-@{modulename}-test-complete">
+ <path path="lib/integration/junit-dep-4.11.jar"/>
+ <path refid="cp-@{modulename}-main"/>
+ <path refid="cp-@{modulename}-test"/>
+ <path path="build/temp/@{modulename}-${version}.jar.contents"/>
+ </path>
+ <compile-content srcdir="@{modulename}/src/test/java" jarname="@{modulename}-${version}-tests" classpathref="cp-@{modulename}-test-complete" />
+ </sequential>
+ </macrodef>
+
+ <macrodef name="compile-content">
+ <attribute name="srcdir"/>
+ <attribute name="jarname" description="Name of the jar whose content is being compiled (without .jar suffix)"/>
+ <attribute name="classpathref"/>
+ <sequential>
+ <mkdir dir="build/temp/@{jarname}-sources.jar.contents"/>
+ <copy failonerror="false" todir="build/temp/@{jarname}-sources.jar.contents">
+ <fileset dir="@{srcdir}"/>
+ </copy>
+ <mkdir dir="build/temp/@{jarname}.jar.contents"/>
+ <javac srcdir="build/temp/@{jarname}-sources.jar.contents"
+ destdir="build/temp/@{jarname}.jar.contents"
+ debug="${debug}" source="${javaversion}" target="${javaversion}" includeantruntime="false">
+ <classpath refid="@{classpathref}"/>
+ </javac>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="jar-module">
+ <attribute name="modulename" description="Name of the module to jar"/>
+ <sequential>
+ <make-manifest modulename="@{modulename}"/>
+ <jar-module-component modulename="@{modulename}"/>
+ <jar-module-component modulename="@{modulename}" suffix="-tests"/>
+ <jar-module-component modulename="@{modulename}" suffix="-sources"/>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="jar-module-component">
+ <attribute name="modulename" description="Name of the module to jar"/>
+ <attribute name="suffix" default="" description="Name of the module to jar"/>
+ <sequential>
+ <copy file="LICENSE.txt" todir="build/temp/@{modulename}-${version}@{suffix}.jar.contents/META-INF"/>
+ <jar jarfile="build/@{modulename}-${version}@{suffix}.jar" manifest="build/temp/@{modulename}-${version}.jar.manifest/MANIFEST.MF">
+ <fileset dir="build/temp/@{modulename}-${version}@{suffix}.jar.contents"/>
+ </jar>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="generate-module-factory" description="Generate one class with all static imports">
+ <attribute name="modulename" description="Name of the module to jar"/>
+ <attribute name="configurationfile" description="xml configuration file"/>
+ <attribute name="targetclass" description="factory class to generate"/>
+ <attribute name="sources" description="comma-separated source directories"/>
+ <sequential>
+ <mkdir dir="build/temp/@{modulename}/generated-code"/>
+ <java classname="org.hamcrest.generator.config.XmlConfigurator" fork="yes" failonerror="yes">
+ <classpath path="build/hamcrest-generator-${version}.jar"/>
+ <classpath refid="cp-@{modulename}-main"/>
+ <classpath path="build/temp/@{modulename}-${version}.jar.contents"/>
+ <arg value="@{configurationfile}"/>
+ <arg value="@{sources}"/>
+ <arg value="@{targetclass}"/>
+ <arg value="build/temp/@{modulename}/generated-code"/>
+ </java>
+
+ <copy todir="build/temp/@{modulename}-${version}-sources.jar.contents">
+ <fileset dir="build/temp/@{modulename}/generated-code"/>
+ </copy>
+ <compile-module modulename="@{modulename}"/>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="test-module" description="run unit tests.">
+ <attribute name="modulename" description="Name of the module to test"/>
+ <sequential>
+ <mkdir dir="build/temp/@{modulename}/test-wrk"/>
+ <junit printsummary="no" forkmode="once" tempdir="build/temp/@{modulename}/test-wrk" haltonfailure="${haltonfailure}" dir="@{modulename}">
+ <formatter type="brief" usefile="no"/>
+ <classpath refid="cp-@{modulename}-test-complete"/>
+ <classpath path="build/@{modulename}-${version}-tests.jar"/>
+ <batchtest fork="yes" todir="${build.dir}/testreport">
+ <zipfileset src="build/@{modulename}-${version}-tests.jar">
+ <include name="org/hamcrest/**/*Test.class"/>
+ <exclude name="**/Abstract*.class"/>
+ </zipfileset>
+ </batchtest>
+ </junit>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="javadoc-module" description="Generate javadoc for a module and build a Jar">
+ <attribute name="modulename" description="Name of the module to document"/>
+ <sequential>
+ <javadoc packagenames="org.hamcrest.*" sourcepath="build/temp/@{modulename}-${version}-sources.jar.contents"
+ destdir="build/temp/@{modulename}-${version}-javadoc.jar.contents" author="true" version="true"
+ use="true" windowtitle="Hamcrest" source="${javaversion}" failonerror="yes" defaultexcludes="yes">
+ <classpath refid="cp-@{modulename}-main"/>
+ </javadoc>
+ <jar-module-component modulename="@{modulename}" suffix="-javadoc"/>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="bundle-module" description="Generate maven bundle jar for a module">
+ <attribute name="modulename" description="Name of the module to bundle"/>
+ <sequential>
+ <sign target="@{modulename}-${version}.pom"/>
+ <sign target="@{modulename}-${version}.jar"/>
+ <sign target="@{modulename}-${version}-javadoc.jar"/>
+ <sign target="@{modulename}-${version}-sources.jar"/>
+ <jar-bundle modulename="@{modulename}"/>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="jar-bundle" description="Jar maven bundle contents">
+ <attribute name="modulename" description="Name of the module to create bundle jar for"/>
+ <sequential>
+ <jar destfile="build/maven-bundle-@{modulename}.jar">
+ <fileset dir="build"><include name="@{modulename}-${version}*"/></fileset>
+ </jar>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="sign" description="Sign a file with a gpg key">
+ <attribute name="target" description="Name of the resource to sign"/>
+ <sequential>
+ <exec executable="gpg" dir="build"><arg value="-ab"/><arg value="@{target}"/></exec>
+ </sequential>
+ </macrodef>
+</project>
diff --git a/doc/images/logo.jpg b/doc/images/logo.jpg
new file mode 100644
index 0000000..efd750d
--- /dev/null
+++ b/doc/images/logo.jpg
Binary files differ
diff --git a/hamcrest-core/src/main/java/org/hamcrest/BaseDescription.java b/hamcrest-core/src/main/java/org/hamcrest/BaseDescription.java
index 4c98e5f..6e62e69 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/BaseDescription.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/BaseDescription.java
@@ -1,127 +1,144 @@
-package org.hamcrest;
-
-import static java.lang.String.valueOf;
-
-import java.util.Arrays;
-import java.util.Iterator;
-
-import org.hamcrest.internal.ArrayIterator;
-import org.hamcrest.internal.SelfDescribingValueIterator;
-
-/**
- * A {@link Description} that is stored as a string.
- */
-public abstract class BaseDescription implements Description {
- public Description appendText(String text) {
- append(text);
- return this;
- }
-
- public Description appendDescriptionOf(SelfDescribing value) {
- value.describeTo(this);
- return this;
- }
-
- public Description appendValue(Object value) {
- if (value == null) {
- append("null");
- } else if (value instanceof String) {
- toJavaSyntax((String) value);
- } else if (value instanceof Character) {
- append('"');
- toJavaSyntax((Character) value);
- append('"');
- } else if (value instanceof Short) {
- append('<');
- append(valueOf(value));
- append("s>");
- } else if (value instanceof Long) {
- append('<');
- append(valueOf(value));
- append("L>");
- } else if (value instanceof Float) {
- append('<');
- append(valueOf(value));
- append("F>");
- } else if (value.getClass().isArray()) {
- appendValueList("[",", ","]", new ArrayIterator(value));
- } else {
- append('<');
- append(valueOf(value));
- append('>');
- }
- return this;
- }
-
- public <T> Description appendValueList(String start, String separator, String end, T... values) {
- return appendValueList(start, separator, end, Arrays.asList(values));
- }
-
- public <T> Description appendValueList(String start, String separator, String end, Iterable<T> values) {
- return appendValueList(start, separator, end, values.iterator());
- }
-
- private <T> Description appendValueList(String start, String separator, String end, Iterator<T> values) {
- return appendList(start, separator, end, new SelfDescribingValueIterator<T>(values));
- }
-
- public Description appendList(String start, String separator, String end, Iterable<? extends SelfDescribing> values) {
- return appendList(start, separator, end, values.iterator());
- }
-
- private Description appendList(String start, String separator, String end, Iterator<? extends SelfDescribing> i) {
- boolean separate = false;
-
- append(start);
- while (i.hasNext()) {
- if (separate) append(separator);
- appendDescriptionOf(i.next());
- separate = true;
- }
- append(end);
-
- return this;
- }
-
-
- /** Append the String <var>str</var> to the description.
- * The default implementation passes every character to {@link #append(char)}.
- * Override in subclasses to provide an efficient implementation.
- */
- protected void append(String str) {
- for (int i = 0; i < str.length(); i++) {
- append(str.charAt(i));
- }
- }
-
- /** Append the char <var>c</var> to the description.
- */
- protected abstract void append(char c);
-
- private void toJavaSyntax(String unformatted) {
- append('"');
- for (int i = 0; i < unformatted.length(); i++) {
- toJavaSyntax(unformatted.charAt(i));
- }
- append('"');
- }
-
- private void toJavaSyntax(char ch) {
- switch (ch) {
- case '"':
- append("\\\"");
- break;
- case '\n':
- append("\\n");
- break;
- case '\r':
- append("\\r");
- break;
- case '\t':
- append("\\t");
- break;
- default:
- append(ch);
- }
- }
-}
+package org.hamcrest;
+
+import org.hamcrest.internal.ArrayIterator;
+import org.hamcrest.internal.SelfDescribingValueIterator;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import static java.lang.String.valueOf;
+
+/**
+ * A {@link Description} that is stored as a string.
+ */
+public abstract class BaseDescription implements Description {
+
+ @Override
+ public Description appendText(String text) {
+ append(text);
+ return this;
+ }
+
+ @Override
+ public Description appendDescriptionOf(SelfDescribing value) {
+ value.describeTo(this);
+ return this;
+ }
+
+ @Override
+ public Description appendValue(Object value) {
+ if (value == null) {
+ append("null");
+ } else if (value instanceof String) {
+ toJavaSyntax((String) value);
+ } else if (value instanceof Character) {
+ append('"');
+ toJavaSyntax((Character) value);
+ append('"');
+ } else if (value instanceof Short) {
+ append('<');
+ append(descriptionOf(value));
+ append("s>");
+ } else if (value instanceof Long) {
+ append('<');
+ append(descriptionOf(value));
+ append("L>");
+ } else if (value instanceof Float) {
+ append('<');
+ append(descriptionOf(value));
+ append("F>");
+ } else if (value.getClass().isArray()) {
+ appendValueList("[",", ","]", new ArrayIterator(value));
+ } else {
+ append('<');
+ append(descriptionOf(value));
+ append('>');
+ }
+ return this;
+ }
+
+ private String descriptionOf(Object value) {
+ try {
+ return valueOf(value);
+ }
+ catch (Exception e) {
+ return value.getClass().getName() + "@" + Integer.toHexString(value.hashCode());
+ }
+ }
+
+ @Override
+ public <T> Description appendValueList(String start, String separator, String end, T... values) {
+ return appendValueList(start, separator, end, Arrays.asList(values));
+ }
+
+ @Override
+ public <T> Description appendValueList(String start, String separator, String end, Iterable<T> values) {
+ return appendValueList(start, separator, end, values.iterator());
+ }
+
+ private <T> Description appendValueList(String start, String separator, String end, Iterator<T> values) {
+ return appendList(start, separator, end, new SelfDescribingValueIterator<T>(values));
+ }
+
+ @Override
+ public Description appendList(String start, String separator, String end, Iterable<? extends SelfDescribing> values) {
+ return appendList(start, separator, end, values.iterator());
+ }
+
+ private Description appendList(String start, String separator, String end, Iterator<? extends SelfDescribing> i) {
+ boolean separate = false;
+
+ append(start);
+ while (i.hasNext()) {
+ if (separate) append(separator);
+ appendDescriptionOf(i.next());
+ separate = true;
+ }
+ append(end);
+
+ return this;
+ }
+
+ /**
+ * Append the String <var>str</var> to the description.
+ * The default implementation passes every character to {@link #append(char)}.
+ * Override in subclasses to provide an efficient implementation.
+ */
+ protected void append(String str) {
+ for (int i = 0; i < str.length(); i++) {
+ append(str.charAt(i));
+ }
+ }
+
+ /**
+ * Append the char <var>c</var> to the description.
+ */
+ protected abstract void append(char c);
+
+ private void toJavaSyntax(String unformatted) {
+ append('"');
+ for (int i = 0; i < unformatted.length(); i++) {
+ toJavaSyntax(unformatted.charAt(i));
+ }
+ append('"');
+ }
+
+ private void toJavaSyntax(char ch) {
+ switch (ch) {
+ case '"':
+ append("\\\"");
+ break;
+ case '\n':
+ append("\\n");
+ break;
+ case '\r':
+ append("\\r");
+ break;
+ case '\t':
+ append("\\t");
+ break;
+ default:
+ append(ch);
+ }
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/BaseMatcher.java b/hamcrest-core/src/main/java/org/hamcrest/BaseMatcher.java
index 3fdd6f7..484c101 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/BaseMatcher.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/BaseMatcher.java
@@ -1,5 +1,3 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
package org.hamcrest;
/**
@@ -12,11 +10,18 @@ public abstract class BaseMatcher<T> implements Matcher<T> {
/**
* @see Matcher#_dont_implement_Matcher___instead_extend_BaseMatcher_()
*/
+ @Override
+ @Deprecated
public final void _dont_implement_Matcher___instead_extend_BaseMatcher_() {
// See Matcher interface for an explanation of this method.
}
@Override
+ public void describeMismatch(Object item, Description description) {
+ description.appendText("was ").appendValue(item);
+ }
+
+ @Override
public String toString() {
return StringDescription.toString(this);
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/Condition.java b/hamcrest-core/src/main/java/org/hamcrest/Condition.java
new file mode 100644
index 0000000..02ce09e
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/Condition.java
@@ -0,0 +1,69 @@
+package org.hamcrest;
+
+/**
+ * A Condition implements part of a multi-step match. We sometimes need to write matchers
+ * that have a sequence of steps, where each step depends on the result of the previous
+ * step and we can stop processing as soon as a step fails. These classes provide
+ * infrastructure for writing such a sequence.
+ *
+ * Based on https://github.com/npryce/maybe-java
+ * @author Steve Freeman 2012 http://www.hamcrest.com
+ */
+
+public abstract class Condition<T> {
+ public static final NotMatched<Object> NOT_MATCHED = new NotMatched<Object>();
+
+ public interface Step<I, O> {
+ Condition<O> apply(I value, Description mismatch);
+ }
+
+ private Condition() { }
+
+ public abstract boolean matching(Matcher<T> match, String message);
+ public abstract <U> Condition<U> and(Step<? super T, U> mapping);
+
+ public final boolean matching(Matcher<T> match) { return matching(match, ""); }
+ public final <U> Condition<U> then(Step<? super T, U> mapping) { return and(mapping); }
+
+ @SuppressWarnings("unchecked")
+ public static <T> Condition<T> notMatched() {
+ return (Condition<T>) NOT_MATCHED;
+ }
+
+ public static <T> Condition<T> matched(final T theValue, final Description mismatch) {
+ return new Matched<T>(theValue, mismatch);
+ }
+
+ private static final class Matched<T> extends Condition<T> {
+ private final T theValue;
+ private final Description mismatch;
+
+ private Matched(T theValue, Description mismatch) {
+ this.theValue = theValue;
+ this.mismatch = mismatch;
+ }
+
+ @Override
+ public boolean matching(Matcher<T> matcher, String message) {
+ if (matcher.matches(theValue)) {
+ return true;
+ }
+ mismatch.appendText(message);
+ matcher.describeMismatch(theValue, mismatch);
+ return false;
+ }
+
+ @Override
+ public <U> Condition<U> and(Step<? super T, U> next) {
+ return next.apply(theValue, mismatch);
+ }
+ }
+
+ private static final class NotMatched<T> extends Condition<T> {
+ @Override public boolean matching(Matcher<T> match, String message) { return false; }
+
+ @Override public <U> Condition<U> and(Step<? super T, U> mapping) {
+ return notMatched();
+ }
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/CoreMatchers.java b/hamcrest-core/src/main/java/org/hamcrest/CoreMatchers.java
index 400a491..799a26a 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/CoreMatchers.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/CoreMatchers.java
@@ -1,24 +1,114 @@
-// Generated source.
package org.hamcrest;
+@SuppressWarnings("UnusedDeclaration")
public class CoreMatchers {
/**
- * Decorates another Matcher, retaining the behavior but allowing tests
- * to be slightly more expressive.
+ * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.Matcher<T> allOf(java.lang.Iterable<org.hamcrest.Matcher<? super T>> matchers) {
+ return org.hamcrest.core.AllOf.<T>allOf(matchers);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
+ */
+ @SafeVarargs
+ public static <T> org.hamcrest.Matcher<T> allOf(org.hamcrest.Matcher<? super T>... matchers) {
+ return org.hamcrest.core.AllOf.<T>allOf(matchers);
+ }
+
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ANY</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", anyOf(startsWith("foo"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.core.AnyOf<T> anyOf(java.lang.Iterable<org.hamcrest.Matcher<? super T>> matchers) {
+ return org.hamcrest.core.AnyOf.<T>anyOf(matchers);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ANY</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", anyOf(startsWith("foo"), containsString("Val")))</pre>
+ */
+ @SafeVarargs
+ public static <T> org.hamcrest.core.AnyOf<T> anyOf(org.hamcrest.Matcher<? super T>... matchers) {
+ return org.hamcrest.core.AnyOf.<T>anyOf(matchers);
+ }
+
+ /**
+ * Creates a matcher that matches when both of the specified matchers match the examined object.
+ * For example:
+ * <pre>assertThat("fab", both(containsString("a")).and(containsString("b")))</pre>
+ */
+ public static <LHS> org.hamcrest.core.CombinableMatcher.CombinableBothMatcher<LHS> both(org.hamcrest.Matcher<? super LHS> matcher) {
+ return org.hamcrest.core.CombinableMatcher.both(matcher);
+ }
+
+ /**
+ * Creates a matcher that matches when either of the specified matchers match the examined object.
+ * For example:
+ * <pre>assertThat("fan", either(containsString("a")).or(containsString("b")))</pre>
+ */
+ public static <LHS> org.hamcrest.core.CombinableMatcher.CombinableEitherMatcher<LHS> either(org.hamcrest.Matcher<? super LHS> matcher) {
+ return org.hamcrest.core.CombinableMatcher.either(matcher);
+ }
+
+ /**
+ * Wraps an existing matcher, overriding its description with that specified. All other functions are
+ * delegated to the decorated matcher, including its mismatch description.
+ * For example:
+ * <pre>describedAs("a big decimal equal to %0", equalTo(myBigDecimal), myBigDecimal.toPlainString())</pre>
+ *
+ * @param description
+ * the new description for the wrapped matcher
+ * @param matcher
+ * the matcher to wrap
+ * @param values
+ * optional values to insert into the tokenised description
+ */
+ public static <T> org.hamcrest.Matcher<T> describedAs(java.lang.String description, org.hamcrest.Matcher<T> matcher, java.lang.Object... values) {
+ return org.hamcrest.core.DescribedAs.describedAs(description, matcher, values);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that only matches when a single pass over the
+ * examined {@link Iterable} yields items that are all matched by the specified
+ * <code>itemMatcher</code>.
+ * For example:
+ * <pre>assertThat(Arrays.asList("bar", "baz"), everyItem(startsWith("ba")))</pre>
*
- * eg. assertThat(cheese, equalTo(smelly))
- * vs assertThat(cheese, is(equalTo(smelly)))
+ * @param itemMatcher
+ * the matcher to apply to every item provided by the examined {@link Iterable}
+ */
+ public static <U> org.hamcrest.Matcher<java.lang.Iterable<? extends U>> everyItem(org.hamcrest.Matcher<U> itemMatcher) {
+ return org.hamcrest.core.Every.everyItem(itemMatcher);
+ }
+
+ /**
+ * Decorates another Matcher, retaining its behaviour, but allowing tests
+ * to be slightly more expressive.
+ * For example:
+ * <pre>assertThat(cheese, is(equalTo(smelly)))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, equalTo(smelly))</pre>
*/
public static <T> org.hamcrest.Matcher<T> is(org.hamcrest.Matcher<T> matcher) {
return org.hamcrest.core.Is.is(matcher);
}
/**
- * This is a shortcut to the frequently used is(equalTo(x)).
- *
- * eg. assertThat(cheese, is(equalTo(smelly)))
- * vs assertThat(cheese, is(smelly))
+ * A shortcut to the frequently used <code>is(equalTo(x))</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(smelly))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(equalTo(smelly)))</pre>
*/
public static <T> org.hamcrest.Matcher<T> is(T value) {
return org.hamcrest.core.Is.is(value);
@@ -41,131 +131,334 @@ public class CoreMatchers {
}
/**
- * Inverts the rule.
+ * A shortcut to the frequently used <code>is(instanceOf(SomeClass.class))</code>.
+ * For example:
+ * <pre>assertThat(cheese, isA(Cheddar.class))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(instanceOf(Cheddar.class)))</pre>
*/
- public static <T> org.hamcrest.Matcher<T> not(org.hamcrest.Matcher<T> matcher) {
- return org.hamcrest.core.IsNot.not(matcher);
+ public static <T> org.hamcrest.Matcher<T> isA(java.lang.Class<T> type) {
+ return org.hamcrest.core.Is.isA(type);
}
/**
- * This is a shortcut to the frequently used not(equalTo(x)).
+ * Creates a matcher that always matches, regardless of the examined object.
+ */
+ public static org.hamcrest.Matcher<java.lang.Object> anything() {
+ return org.hamcrest.core.IsAnything.anything();
+ }
+
+ /**
+ * Creates a matcher that always matches, regardless of the examined object, but describes
+ * itself with the specified {@link String}.
*
- * eg. assertThat(cheese, is(not(equalTo(smelly))))
- * vs assertThat(cheese, is(not(smelly)))
+ * @param description
+ * a meaningful {@link String} used when describing itself
*/
- public static <T> org.hamcrest.Matcher<T> not(T value) {
- return org.hamcrest.core.IsNot.not(value);
+ public static org.hamcrest.Matcher<java.lang.Object> anything(java.lang.String description) {
+ return org.hamcrest.core.IsAnything.anything(description);
}
/**
- * Is the value equal to another value, as tested by the
- * {@link java.lang.Object#equals} invokedMethod?
+ * Creates a matcher for {@link Iterable}s that only matches when a single pass over the
+ * examined {@link Iterable} yields at least one item that is matched by the specified
+ * <code>itemMatcher</code>. Whilst matching, the traversal of the examined {@link Iterable}
+ * will stop as soon as a matching item is found.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), hasItem(startsWith("ba")))</pre>
+ *
+ * @param itemMatcher
+ * the matcher to apply to items provided by the examined {@link Iterable}
*/
- public static <T> org.hamcrest.Matcher<T> equalTo(T operand) {
- return org.hamcrest.core.IsEqual.equalTo(operand);
+ public static <T> org.hamcrest.Matcher<java.lang.Iterable<? super T>> hasItem(org.hamcrest.Matcher<? super T> itemMatcher) {
+ return org.hamcrest.core.IsCollectionContaining.<T>hasItem(itemMatcher);
}
/**
- * Is the value an instance of a particular type?
+ * Creates a matcher for {@link Iterable}s that only matches when a single pass over the
+ * examined {@link Iterable} yields at least one item that is equal to the specified
+ * <code>item</code>. Whilst matching, the traversal of the examined {@link Iterable}
+ * will stop as soon as a matching item is found.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), hasItem("bar"))</pre>
+ *
+ * @param item
+ * the item to compare against the items provided by the examined {@link Iterable}
*/
- public static org.hamcrest.Matcher<java.lang.Object> instanceOf(java.lang.Class<?> type) {
- return org.hamcrest.core.IsInstanceOf.instanceOf(type);
+ public static <T> org.hamcrest.Matcher<java.lang.Iterable<? super T>> hasItem(T item) {
+ return org.hamcrest.core.IsCollectionContaining.<T>hasItem(item);
}
/**
- * Evaluates to true only if ALL of the passed in matchers evaluate to true.
+ * Creates a matcher for {@link Iterable}s that matches when consecutive passes over the
+ * examined {@link Iterable} yield at least one item that is matched by the corresponding
+ * matcher from the specified <code>itemMatchers</code>. Whilst matching, each traversal of
+ * the examined {@link Iterable} will stop as soon as a matching item is found.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar", "baz"), hasItems(endsWith("z"), endsWith("o")))</pre>
+ *
+ * @param itemMatchers
+ * the matchers to apply to items provided by the examined {@link Iterable}
*/
- public static <T> org.hamcrest.Matcher<T> allOf(org.hamcrest.Matcher<? extends T>... matchers) {
- return org.hamcrest.core.AllOf.<T>allOf(matchers);
+ @SafeVarargs
+ public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems(org.hamcrest.Matcher<? super T>... itemMatchers) {
+ return org.hamcrest.core.IsCollectionContaining.<T>hasItems(itemMatchers);
}
/**
- * Evaluates to true only if ALL of the passed in matchers evaluate to true.
+ * Creates a matcher for {@link Iterable}s that matches when consecutive passes over the
+ * examined {@link Iterable} yield at least one item that is equal to the corresponding
+ * item from the specified <code>items</code>. Whilst matching, each traversal of the
+ * examined {@link Iterable} will stop as soon as a matching item is found.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar", "baz"), hasItems("baz", "foo"))</pre>
+ *
+ * @param items
+ * the items to compare against the items provided by the examined {@link Iterable}
*/
- public static <T> org.hamcrest.Matcher<T> allOf(java.lang.Iterable<org.hamcrest.Matcher<? extends T>> matchers) {
- return org.hamcrest.core.AllOf.allOf(matchers);
+ @SafeVarargs
+ public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems(T... items) {
+ return org.hamcrest.core.IsCollectionContaining.<T>hasItems(items);
}
/**
- * Evaluates to true if ANY of the passed in matchers evaluate to true.
+ * Creates a matcher that matches when the examined object is logically equal to the specified
+ * <code>operand</code>, as determined by calling the {@link java.lang.Object#equals} method on
+ * the <b>examined</b> object.
+ *
+ * <p>If the specified operand is <code>null</code> then the created matcher will only match if
+ * the examined object's <code>equals</code> method returns <code>true</code> when passed a
+ * <code>null</code> (which would be a violation of the <code>equals</code> contract), unless the
+ * examined object itself is <code>null</code>, in which case the matcher will return a positive
+ * match.</p>
+ *
+ * <p>The created matcher provides a special behaviour when examining <code>Array</code>s, whereby
+ * it will match if both the operand and the examined object are arrays of the same length and
+ * contain items that are equal to each other (according to the above rules) <b>in the same
+ * indexes</b>.</p>
+ * For example:
+ * <pre>
+ * assertThat("foo", equalTo("foo"));
+ * assertThat(new String[] {"foo", "bar"}, equalTo(new String[] {"foo", "bar"}));
+ * </pre>
*/
- public static <T> org.hamcrest.Matcher<T> anyOf(org.hamcrest.Matcher<? extends T>... matchers) {
- return org.hamcrest.core.AnyOf.<T>anyOf(matchers);
+ public static <T> org.hamcrest.Matcher<T> equalTo(T operand) {
+ return org.hamcrest.core.IsEqual.equalTo(operand);
}
/**
- * Evaluates to true if ANY of the passed in matchers evaluate to true.
+ * Creates an {@link org.hamcrest.core.IsEqual} matcher that does not enforce the values being
+ * compared to be of the same static type.
*/
- public static <T> org.hamcrest.Matcher<T> anyOf(java.lang.Iterable<org.hamcrest.Matcher<? extends T>> matchers) {
- return org.hamcrest.core.AnyOf.anyOf(matchers);
+ public static org.hamcrest.Matcher<java.lang.Object> equalToObject(java.lang.Object operand) {
+ return org.hamcrest.core.IsEqual.equalToObject(operand);
}
/**
- * Creates a new instance of IsSame
+ * Creates a matcher that matches when the examined object is an instance of the specified <code>type</code>,
+ * as determined by calling the {@link java.lang.Class#isInstance(Object)} method on that type, passing the
+ * the examined object.
*
- * @param object The predicate evaluates to true only when the argument is
- * this object.
+ * <p>The created matcher forces a relationship between specified type and the examined object, and should be
+ * used when it is necessary to make generics conform, for example in the JMock clause
+ * <code>with(any(Thing.class))</code></p>
+ * For example:
+ * <pre>assertThat(new Canoe(), instanceOf(Canoe.class));</pre>
*/
- public static <T> org.hamcrest.Matcher<T> sameInstance(T object) {
- return org.hamcrest.core.IsSame.sameInstance(object);
+ public static <T> org.hamcrest.Matcher<T> any(java.lang.Class<T> type) {
+ return org.hamcrest.core.IsInstanceOf.any(type);
}
/**
- * This matcher always evaluates to true.
+ * Creates a matcher that matches when the examined object is an instance of the specified <code>type</code>,
+ * as determined by calling the {@link java.lang.Class#isInstance(Object)} method on that type, passing the
+ * the examined object.
+ *
+ * <p>The created matcher assumes no relationship between specified type and the examined object.</p>
+ * For example:
+ * <pre>assertThat(new Canoe(), instanceOf(Paddlable.class));</pre>
*/
- public static <T> org.hamcrest.Matcher<T> anything() {
- return org.hamcrest.core.IsAnything.anything();
+ public static <T> org.hamcrest.Matcher<T> instanceOf(java.lang.Class<?> type) {
+ return org.hamcrest.core.IsInstanceOf.instanceOf(type);
}
/**
- * This matcher always evaluates to true.
+ * Creates a matcher that wraps an existing matcher, but inverts the logic by which
+ * it will match.
+ * For example:
+ * <pre>assertThat(cheese, is(not(equalTo(smelly))))</pre>
*
- * @param description A meaningful string used when describing itself.
+ * @param matcher
+ * the matcher whose sense should be inverted
*/
- public static <T> org.hamcrest.Matcher<T> anything(java.lang.String description) {
- return org.hamcrest.core.IsAnything.anything(description);
+ public static <T> org.hamcrest.Matcher<T> not(org.hamcrest.Matcher<T> matcher) {
+ return org.hamcrest.core.IsNot.not(matcher);
}
/**
- * This matcher always evaluates to true. With type inference.
+ * A shortcut to the frequently used <code>not(equalTo(x))</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(not(smelly)))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(not(equalTo(smelly))))</pre>
+ *
+ * @param value
+ * the value that any examined object should <b>not</b> equal
*/
- public static <T> org.hamcrest.Matcher<T> any(java.lang.Class<T> type) {
- return org.hamcrest.core.IsAnything.any(type);
+ public static <T> org.hamcrest.Matcher<T> not(T value) {
+ return org.hamcrest.core.IsNot.not(value);
}
/**
- * Matches if value is null.
+ * A shortcut to the frequently used <code>not(nullValue())</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(notNullValue()))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(not(nullValue())))</pre>
*/
- public static <T> org.hamcrest.Matcher<T> nullValue() {
+ public static org.hamcrest.Matcher<java.lang.Object> notNullValue() {
+ return org.hamcrest.core.IsNull.notNullValue();
+ }
+
+ /**
+ * A shortcut to the frequently used <code>not(nullValue(X.class)). Accepts a
+ * single dummy argument to facilitate type inference.</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(notNullValue(X.class)))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(not(nullValue(X.class))))</pre>
+ *
+ * @param type
+ * dummy parameter used to infer the generic type of the returned matcher
+ */
+ public static <T> org.hamcrest.Matcher<T> notNullValue(java.lang.Class<T> type) {
+ return org.hamcrest.core.IsNull.notNullValue(type);
+ }
+
+ /**
+ * Creates a matcher that matches if examined object is <code>null</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(nullValue())</pre>
+ */
+ public static org.hamcrest.Matcher<java.lang.Object> nullValue() {
return org.hamcrest.core.IsNull.nullValue();
}
/**
- * Matches if value is null. With type inference.
+ * Creates a matcher that matches if examined object is <code>null</code>. Accepts a
+ * single dummy argument to facilitate type inference.
+ * For example:
+ * <pre>assertThat(cheese, is(nullValue(Cheese.class))</pre>
+ *
+ * @param type
+ * dummy parameter used to infer the generic type of the returned matcher
*/
public static <T> org.hamcrest.Matcher<T> nullValue(java.lang.Class<T> type) {
return org.hamcrest.core.IsNull.nullValue(type);
}
/**
- * Matches if value is not null.
+ * Creates a matcher that matches only when the examined object is the same instance as
+ * the specified target object.
+ *
+ * @param target
+ * the target instance against which others should be assessed
*/
- public static <T> org.hamcrest.Matcher<T> notNullValue() {
- return org.hamcrest.core.IsNull.notNullValue();
+ public static <T> org.hamcrest.Matcher<T> sameInstance(T target) {
+ return org.hamcrest.core.IsSame.sameInstance(target);
}
/**
- * Matches if value is not null. With type inference.
+ * Creates a matcher that matches only when the examined object is the same instance as
+ * the specified target object.
+ *
+ * @param target
+ * the target instance against which others should be assessed
*/
- public static <T> org.hamcrest.Matcher<T> notNullValue(java.lang.Class<T> type) {
- return org.hamcrest.core.IsNull.notNullValue(type);
+ public static <T> org.hamcrest.Matcher<T> theInstance(T target) {
+ return org.hamcrest.core.IsSame.theInstance(target);
}
/**
- * Wraps an existing matcher and overrides the description when it fails.
+ * Creates a matcher that matches if the examined {@link String} contains the specified
+ * {@link String} anywhere.
+ * For example:
+ * <pre>assertThat("myStringOfNote", containsString("ring"))</pre>
+ *
+ * @param substring
+ * the substring that the returned matcher will expect to find within any examined string
*/
- public static <T> org.hamcrest.Matcher<T> describedAs(java.lang.String description, org.hamcrest.Matcher<T> matcher, java.lang.Object... values) {
- return org.hamcrest.core.DescribedAs.describedAs(description, matcher, values);
+ public static org.hamcrest.Matcher<java.lang.String> containsString(java.lang.String substring) {
+ return org.hamcrest.core.StringContains.containsString(substring);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined {@link String} contains the specified
+ * {@link String} anywhere, ignoring case.
+ * For example:
+ * <pre>assertThat("myStringOfNote", containsString("ring"))</pre>
+ *
+ * @param substring
+ * the substring that the returned matcher will expect to find within any examined string
+ */
+ public static org.hamcrest.Matcher<java.lang.String> containsStringIgnoringCase(java.lang.String substring) {
+ return org.hamcrest.core.StringContains.containsStringIgnoringCase(substring);
+ }
+
+ /**
+ * <p>
+ * Creates a matcher that matches if the examined {@link String} starts with the specified
+ * {@link String}.
+ * </p>
+ * For example:
+ * <pre>assertThat("myStringOfNote", startsWith("my"))</pre>
+ *
+ * @param prefix
+ * the substring that the returned matcher will expect at the start of any examined string
+ */
+ public static org.hamcrest.Matcher<java.lang.String> startsWith(java.lang.String prefix) {
+ return org.hamcrest.core.StringStartsWith.startsWith(prefix);
+ }
+
+ /**
+ * <p>
+ * Creates a matcher that matches if the examined {@link String} starts with the specified
+ * {@link String}, ignoring case
+ * </p>
+ * For example:
+ * <pre>assertThat("myStringOfNote", startsWith("my"))</pre>
+ *
+ * @param prefix
+ * the substring that the returned matcher will expect at the start of any examined string
+ */
+ public static org.hamcrest.Matcher<java.lang.String> startsWithIgnoringCase(java.lang.String prefix) {
+ return org.hamcrest.core.StringStartsWith.startsWithIgnoringCase(prefix);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined {@link String} ends with the specified
+ * {@link String}.
+ * For example:
+ * <pre>assertThat("myStringOfNote", endsWith("Note"))</pre>
+ *
+ * @param suffix
+ * the substring that the returned matcher will expect at the end of any examined string
+ */
+ public static org.hamcrest.Matcher<java.lang.String> endsWith(java.lang.String suffix) {
+ return org.hamcrest.core.StringEndsWith.endsWith(suffix);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined {@link String} ends with the specified
+ * {@link String}, ignoring case.
+ * For example:
+ * <pre>assertThat("myStringOfNote", endsWith("Note"))</pre>
+ *
+ * @param suffix
+ * the substring that the returned matcher will expect at the end of any examined string
+ */
+ public static org.hamcrest.Matcher<java.lang.String> endsWithIgnoringCase(java.lang.String suffix) {
+ return org.hamcrest.core.StringEndsWith.endsWithIgnoringCase(suffix);
}
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/CustomMatcher.java b/hamcrest-core/src/main/java/org/hamcrest/CustomMatcher.java
new file mode 100644
index 0000000..036a764
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/CustomMatcher.java
@@ -0,0 +1,37 @@
+package org.hamcrest;
+
+/**
+ * Utility class for writing one off matchers.
+ * For example:
+ * <pre>
+ * Matcher&lt;String&gt; aNonEmptyString = new CustomMatcher&lt;String&gt;("a non empty string") {
+ * public boolean matches(Object object) {
+ * return ((object instanceof String) &amp;&amp; !((String) object).isEmpty();
+ * }
+ * };
+ * </pre>
+ * <p>
+ * This class is designed for scenarios where an anonymous inner class
+ * matcher makes sense. It should not be used by API designers implementing
+ * matchers.
+ *
+ * @author Neil Dunn
+ * @see CustomTypeSafeMatcher for a type safe variant of this class that you probably
+ * want to use.
+ * @param <T> The type of object being matched.
+ */
+public abstract class CustomMatcher<T> extends BaseMatcher<T> {
+ private final String fixedDescription;
+
+ public CustomMatcher(String description) {
+ if (description == null) {
+ throw new IllegalArgumentException("Description should be non null!");
+ }
+ this.fixedDescription = description;
+ }
+
+ @Override
+ public final void describeTo(Description description) {
+ description.appendText(fixedDescription);
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/CustomTypeSafeMatcher.java b/hamcrest-core/src/main/java/org/hamcrest/CustomTypeSafeMatcher.java
new file mode 100644
index 0000000..7c5c46c
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/CustomTypeSafeMatcher.java
@@ -0,0 +1,39 @@
+package org.hamcrest;
+
+
+/**
+ * Utility class for writing one off matchers.
+ * For example:
+ * <pre>
+ * Matcher&lt;String&gt; aNonEmptyString = new CustomTypeSafeMatcher&lt;String&gt;("a non empty string") {
+ * public boolean matchesSafely(String string) {
+ * return !string.isEmpty();
+ * }
+ * public void describeMismatchSafely(String string, Description mismatchDescription) {
+ * mismatchDescription.appendText("was empty");
+ * }
+ * };
+ * </pre>
+ * This is a variant of {@link CustomMatcher} that first type checks
+ * the argument being matched. By the time {@link TypeSafeMatcher#matchesSafely} is
+ * is called the argument is guaranteed to be non-null and of the correct
+ * type.
+ *
+ * @author Neil Dunn
+ * @param <T> The type of object being matched
+ */
+public abstract class CustomTypeSafeMatcher<T> extends TypeSafeMatcher<T> {
+ private final String fixedDescription;
+
+ public CustomTypeSafeMatcher(String description) {
+ if (description == null) {
+ throw new IllegalArgumentException("Description must be non null!");
+ }
+ this.fixedDescription = description;
+ }
+
+ @Override
+ public final void describeTo(Description description) {
+ description.appendText(fixedDescription);
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/Description.java b/hamcrest-core/src/main/java/org/hamcrest/Description.java
index 36ddeda..73bfa38 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/Description.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/Description.java
@@ -1,44 +1,89 @@
-package org.hamcrest;
-
-/**
- * A description of a Matcher. A Matcher will describe itself to a description
- * which can later be used for reporting.
- *
- * @see Matcher#describeTo(Description)
- */
-public interface Description {
-
- /**
- * Appends some plain text to the description.
- */
- Description appendText(String text);
-
- /**
- * Appends the description of a {@link SelfDescribing} value to this description.
- */
- Description appendDescriptionOf(SelfDescribing value);
-
- /**
- * Appends an arbitary value to the description.
- */
- Description appendValue(Object value);
-
- /**
- * Appends a list of values to the description.
- */
- <T> Description appendValueList(String start, String separator, String end,
- T... values);
-
- /**
- * Appends a list of values to the description.
- */
- <T> Description appendValueList(String start, String separator, String end,
- Iterable<T> values);
-
- /**
- * Appends a list of {@link org.hamcrest.SelfDescribing} objects
- * to the description.
- */
- Description appendList(String start, String separator, String end,
- Iterable<? extends SelfDescribing> values);
-}
+package org.hamcrest;
+
+/**
+ * A description of a Matcher. A Matcher will describe itself to a description
+ * which can later be used for reporting.
+ *
+ * @see Matcher#describeTo(Description)
+ */
+public interface Description {
+ /**
+ * A description that consumes input but does nothing.
+ */
+ static final Description NONE = new NullDescription();
+
+ /**
+ * Appends some plain text to the description.
+ */
+ Description appendText(String text);
+
+ /**
+ * Appends the description of a {@link SelfDescribing} value to this description.
+ */
+ Description appendDescriptionOf(SelfDescribing value);
+
+ /**
+ * Appends an arbitrary value to the description.
+ */
+ Description appendValue(Object value);
+
+ /**
+ * Appends a list of values to the description.
+ */
+ <T> Description appendValueList(String start, String separator, String end,
+ T... values);
+
+ /**
+ * Appends a list of values to the description.
+ */
+ <T> Description appendValueList(String start, String separator, String end,
+ Iterable<T> values);
+
+ /**
+ * Appends a list of {@link org.hamcrest.SelfDescribing} objects
+ * to the description.
+ */
+ Description appendList(String start, String separator, String end,
+ Iterable<? extends SelfDescribing> values);
+
+
+ public static final class NullDescription implements Description {
+ @Override
+ public Description appendDescriptionOf(SelfDescribing value) {
+ return this;
+ }
+
+ @Override
+ public Description appendList(String start, String separator,
+ String end, Iterable<? extends SelfDescribing> values) {
+ return this;
+ }
+
+ @Override
+ public Description appendText(String text) {
+ return this;
+ }
+
+ @Override
+ public Description appendValue(Object value) {
+ return this;
+ }
+
+ @Override
+ public <T> Description appendValueList(String start, String separator,
+ String end, T... values) {
+ return this;
+ }
+
+ @Override
+ public <T> Description appendValueList(String start, String separator,
+ String end, Iterable<T> values) {
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "";
+ }
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/DiagnosingMatcher.java b/hamcrest-core/src/main/java/org/hamcrest/DiagnosingMatcher.java
new file mode 100644
index 0000000..f87de2d
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/DiagnosingMatcher.java
@@ -0,0 +1,21 @@
+package org.hamcrest;
+
+/**
+ * TODO(ngd): Document.
+ *
+ * @param <T>
+ */
+public abstract class DiagnosingMatcher<T> extends BaseMatcher<T> {
+
+ @Override
+ public final boolean matches(Object item) {
+ return matches(item, Description.NONE);
+ }
+
+ @Override
+ public final void describeMismatch(Object item, Description mismatchDescription) {
+ matches(item, mismatchDescription);
+ }
+
+ protected abstract boolean matches(Object item, Description mismatchDescription);
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/Factory.java b/hamcrest-core/src/main/java/org/hamcrest/Factory.java
index a8bf5f9..99a5132 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/Factory.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/Factory.java
@@ -1,17 +1,20 @@
package org.hamcrest;
-import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
/**
* Marks a Hamcrest static factory method so tools recognise them.
* A factory method is an equivalent to a named constructor.
- *
+ *
+ * @deprecated The code generator is no longer maintained. Write classes of syntactic sugar by hand.
* @author Joe Walnes
*/
@Retention(RUNTIME)
@Target({METHOD})
+@Deprecated
public @interface Factory {
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/FeatureMatcher.java b/hamcrest-core/src/main/java/org/hamcrest/FeatureMatcher.java
new file mode 100644
index 0000000..385cf99
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/FeatureMatcher.java
@@ -0,0 +1,54 @@
+package org.hamcrest;
+
+import org.hamcrest.internal.ReflectiveTypeFinder;
+
+/**
+ * Supporting class for matching a feature of an object. Implement <code>featureValueOf()</code>
+ * in a subclass to pull out the feature to be matched against.
+ *
+ * @param <T> The type of the object to be matched
+ * @param <U> The type of the feature to be matched
+ */
+public abstract class FeatureMatcher<T, U> extends TypeSafeDiagnosingMatcher<T> {
+ private static final ReflectiveTypeFinder TYPE_FINDER = new ReflectiveTypeFinder("featureValueOf", 1, 0);
+ private final Matcher<? super U> subMatcher;
+ private final String featureDescription;
+ private final String featureName;
+
+ /**
+ * Constructor
+ * @param subMatcher The matcher to apply to the feature
+ * @param featureDescription Descriptive text to use in describeTo
+ * @param featureName Identifying text for mismatch message
+ */
+ public FeatureMatcher(Matcher<? super U> subMatcher, String featureDescription, String featureName) {
+ super(TYPE_FINDER);
+ this.subMatcher = subMatcher;
+ this.featureDescription = featureDescription;
+ this.featureName = featureName;
+ }
+
+ /**
+ * Implement this to extract the interesting feature.
+ * @param actual the target object
+ * @return the feature to be matched
+ */
+ protected abstract U featureValueOf(T actual);
+
+ @Override
+ protected boolean matchesSafely(T actual, Description mismatch) {
+ final U featureValue = featureValueOf(actual);
+ if (!subMatcher.matches(featureValue)) {
+ mismatch.appendText(featureName).appendText(" ");
+ subMatcher.describeMismatch(featureValue, mismatch);
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public final void describeTo(Description description) {
+ description.appendText(featureDescription).appendText(" ")
+ .appendDescriptionOf(subMatcher);
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/Matcher.java b/hamcrest-core/src/main/java/org/hamcrest/Matcher.java
index fd10207..3ac1a53 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/Matcher.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/Matcher.java
@@ -1,32 +1,31 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
package org.hamcrest;
/**
+ * <p>
* A matcher over acceptable values.
* A matcher is able to describe itself to give feedback when it fails.
- * <p/>
+ * </p>
+ * <p>
* Matcher implementations should <b>NOT directly implement this interface</b>.
* Instead, <b>extend</b> the {@link BaseMatcher} abstract class,
* which will ensure that the Matcher API can grow to support
* new features and remain compatible with all Matcher implementations.
- * <p/>
- * For easy access to common Matcher implementations, use the static factory
- * methods in {@link CoreMatchers}.
+ * </p>
+ * <p>
+ * N.B. Well designed matchers should be immutable.
+ * </p>
*
- * @see CoreMatchers
* @see BaseMatcher
*/
-@SuppressWarnings({"unused", "UnusedDeclaration"})
public interface Matcher<T> extends SelfDescribing {
/**
* Evaluates the matcher for argument <var>item</var>.
- * <p/>
+ *
* This method matches against Object, instead of the generic type T. This is
* because the caller of the Matcher does not know at runtime what the type is
* (because of type erasure with Java generics). It is down to the implementations
- * to check the correct type.
+ * to check the correct type.
*
* @param item the object against which the matcher is evaluated.
* @return <code>true</code> if <var>item</var> matches, otherwise <code>false</code>.
@@ -34,6 +33,19 @@ public interface Matcher<T> extends SelfDescribing {
* @see BaseMatcher
*/
boolean matches(Object item);
+
+ /**
+ * Generate a description of why the matcher has not accepted the item.
+ * The description will be part of a larger description of why a matching
+ * failed, so it should be concise.
+ * This method assumes that <code>matches(item)</code> is false, but
+ * will not check this.
+ *
+ * @param item The item that the Matcher has rejected.
+ * @param mismatchDescription
+ * The description to be built or appended to.
+ */
+ void describeMismatch(Object item, Description mismatchDescription);
/**
* This method simply acts a friendly reminder not to implement Matcher directly and
@@ -42,6 +54,8 @@ public interface Matcher<T> extends SelfDescribing {
*
* @see Matcher for reasons why.
* @see BaseMatcher
+ * @deprecated to make
*/
+ @Deprecated
void _dont_implement_Matcher___instead_extend_BaseMatcher_();
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/MatcherAssert.java b/hamcrest-core/src/main/java/org/hamcrest/MatcherAssert.java
index 3eb234a..049e1df 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/MatcherAssert.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/MatcherAssert.java
@@ -1,24 +1,27 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
-package org.hamcrest;
-
-
-public class MatcherAssert {
- public static <T> void assertThat(T actual, Matcher<T> matcher) {
- assertThat("", actual, matcher);
- }
-
- public static <T> void assertThat(String reason, T actual, Matcher<T> matcher) {
- if (!matcher.matches(actual)) {
- Description description = new StringDescription();
- description.appendText(reason)
- .appendText("\nExpected: ")
- .appendDescriptionOf(matcher)
- .appendText("\n got: ")
- .appendValue(actual)
- .appendText("\n");
-
- throw new java.lang.AssertionError(description.toString());
- }
- }
-}
+package org.hamcrest;
+
+
+public class MatcherAssert {
+ public static <T> void assertThat(T actual, Matcher<? super T> matcher) {
+ assertThat("", actual, matcher);
+ }
+
+ public static <T> void assertThat(String reason, T actual, Matcher<? super T> matcher) {
+ if (!matcher.matches(actual)) {
+ Description description = new StringDescription();
+ description.appendText(reason)
+ .appendText("\nExpected: ")
+ .appendDescriptionOf(matcher)
+ .appendText("\n but: ");
+ matcher.describeMismatch(actual, description);
+
+ throw new AssertionError(description.toString());
+ }
+ }
+
+ public static void assertThat(String reason, boolean assertion) {
+ if (!assertion) {
+ throw new AssertionError(reason);
+ }
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/SelfDescribing.java b/hamcrest-core/src/main/java/org/hamcrest/SelfDescribing.java
index cd53070..06b361d 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/SelfDescribing.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/SelfDescribing.java
@@ -12,5 +12,5 @@ public interface SelfDescribing {
* @param description
* The description to be built or appended to.
*/
- void describeTo(Description description);
+ void describeTo(Description description);
} \ No newline at end of file
diff --git a/hamcrest-core/src/main/java/org/hamcrest/StringDescription.java b/hamcrest-core/src/main/java/org/hamcrest/StringDescription.java
index 66709ee..813c178 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/StringDescription.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/StringDescription.java
@@ -1,60 +1,63 @@
-package org.hamcrest;
-
-import java.io.IOException;
-
-/**
- * A {@link Description} that is stored as a string.
- */
-public class StringDescription extends BaseDescription {
- private final Appendable out;
-
- public StringDescription() {
- this(new StringBuilder());
- }
-
- public StringDescription(Appendable out) {
- this.out = out;
- }
-
- /**
- * Return the description of a {@link SelfDescribing} object as a String.
- *
- * @param selfDescribing
- * The object to be described.
- * @return
- * The description of the object.
- */
- public static String toString(SelfDescribing value) {
- return new StringDescription().appendDescriptionOf(value).toString();
- }
-
- /**
- * Alias for {@link #toString(SelfDescribing)}.
- */
- public static String asString(SelfDescribing selfDescribing) {
- return toString(selfDescribing);
- }
-
- protected void append(String str) {
- try {
- out.append(str);
- } catch (IOException e) {
- throw new RuntimeException("Could not write description", e);
- }
- }
-
- protected void append(char c) {
- try {
- out.append(c);
- } catch (IOException e) {
- throw new RuntimeException("Could not write description", e);
- }
- }
-
- /**
- * Returns the description as a string.
- */
- public String toString() {
- return out.toString();
- }
-}
+package org.hamcrest;
+
+import java.io.IOException;
+
+/**
+ * A {@link Description} that is stored as a string.
+ */
+public class StringDescription extends BaseDescription {
+ private final Appendable out;
+
+ public StringDescription() {
+ this(new StringBuilder());
+ }
+
+ public StringDescription(Appendable out) {
+ this.out = out;
+ }
+
+ /**
+ * Return the description of a {@link SelfDescribing} object as a String.
+ *
+ * @param selfDescribing
+ * The object to be described.
+ * @return
+ * The description of the object.
+ */
+ public static String toString(SelfDescribing selfDescribing) {
+ return new StringDescription().appendDescriptionOf(selfDescribing).toString();
+ }
+
+ /**
+ * Alias for {@link #toString(SelfDescribing)}.
+ */
+ public static String asString(SelfDescribing selfDescribing) {
+ return toString(selfDescribing);
+ }
+
+ @Override
+ protected void append(String str) {
+ try {
+ out.append(str);
+ } catch (IOException e) {
+ throw new RuntimeException("Could not write description", e);
+ }
+ }
+
+ @Override
+ protected void append(char c) {
+ try {
+ out.append(c);
+ } catch (IOException e) {
+ throw new RuntimeException("Could not write description", e);
+ }
+ }
+
+ /**
+ * Returns the description as a string.
+ */
+ @Override
+ public String toString() {
+ return out.toString();
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/TypeSafeDiagnosingMatcher.java b/hamcrest-core/src/main/java/org/hamcrest/TypeSafeDiagnosingMatcher.java
new file mode 100644
index 0000000..c204120
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/TypeSafeDiagnosingMatcher.java
@@ -0,0 +1,69 @@
+package org.hamcrest;
+
+import org.hamcrest.internal.ReflectiveTypeFinder;
+
+
+/**
+ * Convenient base class for Matchers that require a non-null value of a specific type
+ * and that will report why the received value has been rejected.
+ * This implements the null check, checks the type and then casts.
+ * To use, implement <pre>matchesSafely()</pre>.
+ *
+ * @param <T>
+ * @author Neil Dunn
+ * @author Nat Pryce
+ * @author Steve Freeman
+ */
+public abstract class TypeSafeDiagnosingMatcher<T> extends BaseMatcher<T> {
+ private static final ReflectiveTypeFinder TYPE_FINDER = new ReflectiveTypeFinder("matchesSafely", 2, 0);
+ private final Class<?> expectedType;
+
+ /**
+ * Subclasses should implement this. The item will already have been checked
+ * for the specific type and will never be null.
+ */
+ protected abstract boolean matchesSafely(T item, Description mismatchDescription);
+
+ /**
+ * Use this constructor if the subclass that implements <code>matchesSafely</code>
+ * is <em>not</em> the class that binds &lt;T&gt; to a type.
+ * @param expectedType The expectedType of the actual value.
+ */
+ protected TypeSafeDiagnosingMatcher(Class<?> expectedType) {
+ this.expectedType = expectedType;
+ }
+
+ /**
+ * Use this constructor if the subclass that implements <code>matchesSafely</code>
+ * is <em>not</em> the class that binds &lt;T&gt; to a type.
+ * @param typeFinder A type finder to extract the type
+ */
+ protected TypeSafeDiagnosingMatcher(ReflectiveTypeFinder typeFinder) {
+ this.expectedType = typeFinder.findExpectedType(getClass());
+ }
+
+ /**
+ * The default constructor for simple sub types
+ */
+ protected TypeSafeDiagnosingMatcher() {
+ this(TYPE_FINDER);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public final boolean matches(Object item) {
+ return item != null
+ && expectedType.isInstance(item)
+ && matchesSafely((T) item, new Description.NullDescription());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public final void describeMismatch(Object item, Description mismatchDescription) {
+ if (item == null || !expectedType.isInstance(item)) {
+ super.describeMismatch(item, mismatchDescription);
+ } else {
+ matchesSafely((T) item, mismatchDescription);
+ }
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/TypeSafeMatcher.java b/hamcrest-core/src/main/java/org/hamcrest/TypeSafeMatcher.java
index 7f18fd3..08dfce8 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/TypeSafeMatcher.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/TypeSafeMatcher.java
@@ -1,58 +1,85 @@
package org.hamcrest;
-import java.lang.reflect.Method;
+import org.hamcrest.internal.ReflectiveTypeFinder;
/**
* Convenient base class for Matchers that require a non-null value of a specific type.
* This simply implements the null check, checks the type and then casts.
*
* @author Joe Walnes
+ * @author Steve Freeman
+ * @author Nat Pryce
*/
public abstract class TypeSafeMatcher<T> extends BaseMatcher<T> {
-
- private Class expectedType;
+ private static final ReflectiveTypeFinder TYPE_FINDER = new ReflectiveTypeFinder("matchesSafely", 1, 0);
+
+ final private Class<?> expectedType;
/**
- * Subclasses should implement this. The item will already have been checked for
- * the specific type and will never be null.
+ * The default constructor for simple sub types
*/
- public abstract boolean matchesSafely(T item);
-
protected TypeSafeMatcher() {
- expectedType = findExpectedType(getClass());
+ this(TYPE_FINDER);
}
-
- private static Class<?> findExpectedType(Class<?> fromClass) {
- for (Class<?> c = fromClass; c != Object.class; c = c.getSuperclass()) {
- for (Method method : c.getDeclaredMethods()) {
- if (isMatchesSafelyMethod(method)) {
- return method.getParameterTypes()[0];
- }
- }
- }
-
- throw new Error("Cannot determine correct type for matchesSafely() method.");
+
+ /**
+ * Use this constructor if the subclass that implements <code>matchesSafely</code>
+ * is <em>not</em> the class that binds &lt;T&gt; to a type.
+ * @param expectedType The expectedType of the actual value.
+ */
+ protected TypeSafeMatcher(Class<?> expectedType) {
+ this.expectedType = expectedType;
}
- private static boolean isMatchesSafelyMethod(Method method) {
- return method.getName().equals("matchesSafely")
- && method.getParameterTypes().length == 1
- && !method.isSynthetic();
+ /**
+ * Use this constructor if the subclass that implements <code>matchesSafely</code>
+ * is <em>not</em> the class that binds &lt;T&gt; to a type.
+ * @param typeFinder A type finder to extract the type
+ */
+ protected TypeSafeMatcher(ReflectiveTypeFinder typeFinder) {
+ this.expectedType = typeFinder.findExpectedType(getClass());
}
+
+ /**
+ * Subclasses should implement this. The item will already have been checked for
+ * the specific type and will never be null.
+ */
+ protected abstract boolean matchesSafely(T item);
- protected TypeSafeMatcher(Class<T> expectedType) {
- this.expectedType = expectedType;
+ /**
+ * Subclasses should override this. The item will already have been checked for
+ * the specific type and will never be null.
+ */
+ protected void describeMismatchSafely(T item, Description mismatchDescription) {
+ super.describeMismatch(item, mismatchDescription);
}
-
+
/**
- * Method made final to prevent accidental override.
+ * Methods made final to prevent accidental override.
* If you need to override this, there's no point on extending TypeSafeMatcher.
* Instead, extend the {@link BaseMatcher}.
*/
+ @Override
@SuppressWarnings({"unchecked"})
public final boolean matches(Object item) {
return item != null
&& expectedType.isInstance(item)
&& matchesSafely((T) item);
}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ final public void describeMismatch(Object item, Description description) {
+ if (item == null) {
+ super.describeMismatch(null, description);
+ } else if (! expectedType.isInstance(item)) {
+ description.appendText("was a ")
+ .appendText(item.getClass().getName())
+ .appendText(" (")
+ .appendValue(item)
+ .appendText(")");
+ } else {
+ describeMismatchSafely((T)item, description);
+ }
+ }
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/AllOf.java b/hamcrest-core/src/main/java/org/hamcrest/core/AllOf.java
index f619a7d..2cbe2e3 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/core/AllOf.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/AllOf.java
@@ -1,51 +1,57 @@
package org.hamcrest.core;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Matcher;
import org.hamcrest.Description;
-import org.hamcrest.Factory;
+import org.hamcrest.DiagnosingMatcher;
+import org.hamcrest.Matcher;
import java.util.Arrays;
+import java.util.List;
/**
- * Calculates the logical conjunction of two matchers. Evaluation is
- * shortcut, so that the second matcher is not called if the first
- * matcher returns <code>false</code>.
+ * Calculates the logical conjunction of multiple matchers. Evaluation is shortcut, so
+ * subsequent matchers are not called if an earlier matcher returns <code>false</code>.
*/
-public class AllOf<T> extends BaseMatcher<T> {
- private final Iterable<Matcher<? extends T>> matchers;
+public class AllOf<T> extends DiagnosingMatcher<T> {
- public AllOf(Iterable<Matcher<? extends T>> matchers) {
+ private final Iterable<Matcher<? super T>> matchers;
+
+ public AllOf(Iterable<Matcher<? super T>> matchers) {
this.matchers = matchers;
}
- public boolean matches(Object o) {
- for (Matcher<? extends T> matcher : matchers) {
+ @Override
+ public boolean matches(Object o, Description mismatch) {
+ for (Matcher<? super T> matcher : matchers) {
if (!matcher.matches(o)) {
- return false;
+ mismatch.appendDescriptionOf(matcher).appendText(" ");
+ matcher.describeMismatch(o, mismatch);
+ return false;
}
}
return true;
}
+ @Override
public void describeTo(Description description) {
- description.appendList("(", " and ", ")", matchers);
+ description.appendList("(", " " + "and" + " ", ")", matchers);
}
/**
- * Evaluates to true only if ALL of the passed in matchers evaluate to true.
+ * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
*/
- @Factory
- public static <T> Matcher<T> allOf(Matcher<? extends T>... matchers) {
- return allOf(Arrays.asList(matchers));
+ public static <T> Matcher<T> allOf(Iterable<Matcher<? super T>> matchers) {
+ return new AllOf<>(matchers);
}
/**
- * Evaluates to true only if ALL of the passed in matchers evaluate to true.
+ * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
*/
- @Factory
- public static <T> Matcher<T> allOf(Iterable<Matcher<? extends T>> matchers) {
- return new AllOf<T>(matchers);
+ @SafeVarargs
+ public static <T> Matcher<T> allOf(Matcher<? super T>... matchers) {
+ return allOf((List) Arrays.asList(matchers));
}
-
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/AnyOf.java b/hamcrest-core/src/main/java/org/hamcrest/core/AnyOf.java
index e7e9181..106a473 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/core/AnyOf.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/AnyOf.java
@@ -1,51 +1,47 @@
package org.hamcrest.core;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Matcher;
import org.hamcrest.Description;
-import org.hamcrest.Factory;
+import org.hamcrest.Matcher;
import java.util.Arrays;
+import java.util.List;
/**
- * Calculates the logical disjunction of two matchers. Evaluation is
- * shortcut, so that the second matcher is not called if the first
- * matcher returns <code>true</code>.
+ * Calculates the logical disjunction of multiple matchers. Evaluation is shortcut, so
+ * subsequent matchers are not called if an earlier matcher returns <code>true</code>.
*/
-public class AnyOf<T> extends BaseMatcher<T> {
+public class AnyOf<T> extends ShortcutCombination<T> {
- private final Iterable<Matcher<? extends T>> matchers;
-
- public AnyOf(Iterable<Matcher<? extends T>> matchers) {
- this.matchers = matchers;
+ public AnyOf(Iterable<Matcher<? super T>> matchers) {
+ super(matchers);
}
+ @Override
public boolean matches(Object o) {
- for (Matcher<? extends T> matcher : matchers) {
- if (matcher.matches(o)) {
- return true;
- }
- }
- return false;
+ return matches(o, true);
}
+ @Override
public void describeTo(Description description) {
- description.appendList("(", " or ", ")", matchers);
+ describeTo(description, "or");
}
/**
- * Evaluates to true if ANY of the passed in matchers evaluate to true.
+ * Creates a matcher that matches if the examined object matches <b>ANY</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", anyOf(startsWith("foo"), containsString("Val")))</pre>
*/
- @Factory
- public static <T> Matcher<T> anyOf(Matcher<? extends T>... matchers) {
- return anyOf(Arrays.asList(matchers));
+ public static <T> AnyOf<T> anyOf(Iterable<Matcher<? super T>> matchers) {
+ return new AnyOf<>(matchers);
}
-
+
/**
- * Evaluates to true if ANY of the passed in matchers evaluate to true.
+ * Creates a matcher that matches if the examined object matches <b>ANY</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", anyOf(startsWith("foo"), containsString("Val")))</pre>
*/
- @Factory
- public static <T> Matcher<T> anyOf(Iterable<Matcher<? extends T>> matchers) {
- return new AnyOf<T>(matchers);
+ @SafeVarargs
+ public static <T> AnyOf<T> anyOf(Matcher<? super T>... matchers) {
+ return anyOf((List) Arrays.asList(matchers));
}
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/CombinableMatcher.java b/hamcrest-core/src/main/java/org/hamcrest/core/CombinableMatcher.java
new file mode 100644
index 0000000..2414bbb
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/CombinableMatcher.java
@@ -0,0 +1,82 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+
+import java.util.ArrayList;
+
+public class CombinableMatcher<T> extends TypeSafeDiagnosingMatcher<T> {
+ private final Matcher<? super T> matcher;
+
+ public CombinableMatcher(Matcher<? super T> matcher) {
+ this.matcher = matcher;
+ }
+
+ @Override
+ protected boolean matchesSafely(T item, Description mismatch) {
+ if (!matcher.matches(item)) {
+ matcher.describeMismatch(item, mismatch);
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendDescriptionOf(matcher);
+ }
+
+ public CombinableMatcher<T> and(Matcher<? super T> other) {
+ return new CombinableMatcher<T>(new AllOf<T>(templatedListWith(other)));
+ }
+
+ public CombinableMatcher<T> or(Matcher<? super T> other) {
+ return new CombinableMatcher<T>(new AnyOf<T>(templatedListWith(other)));
+ }
+
+ private ArrayList<Matcher<? super T>> templatedListWith(Matcher<? super T> other) {
+ ArrayList<Matcher<? super T>> matchers = new ArrayList<Matcher<? super T>>();
+ matchers.add(matcher);
+ matchers.add(other);
+ return matchers;
+ }
+
+ /**
+ * Creates a matcher that matches when both of the specified matchers match the examined object.
+ * For example:
+ * <pre>assertThat("fab", both(containsString("a")).and(containsString("b")))</pre>
+ */
+ public static <LHS> CombinableBothMatcher<LHS> both(Matcher<? super LHS> matcher) {
+ return new CombinableBothMatcher<LHS>(matcher);
+ }
+
+ public static final class CombinableBothMatcher<X> {
+ private final Matcher<? super X> first;
+ public CombinableBothMatcher(Matcher<? super X> matcher) {
+ this.first = matcher;
+ }
+ public CombinableMatcher<X> and(Matcher<? super X> other) {
+ return new CombinableMatcher<X>(first).and(other);
+ }
+ }
+
+ /**
+ * Creates a matcher that matches when either of the specified matchers match the examined object.
+ * For example:
+ * <pre>assertThat("fan", either(containsString("a")).or(containsString("b")))</pre>
+ */
+ public static <LHS> CombinableEitherMatcher<LHS> either(Matcher<? super LHS> matcher) {
+ return new CombinableEitherMatcher<LHS>(matcher);
+ }
+
+ public static final class CombinableEitherMatcher<X> {
+ private final Matcher<? super X> first;
+ public CombinableEitherMatcher(Matcher<? super X> matcher) {
+ this.first = matcher;
+ }
+ public CombinableMatcher<X> or(Matcher<? super X> other) {
+ return new CombinableMatcher<X>(first).or(other);
+ }
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/DescribedAs.java b/hamcrest-core/src/main/java/org/hamcrest/core/DescribedAs.java
index 7b8c151..2387609 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/core/DescribedAs.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/DescribedAs.java
@@ -1,55 +1,69 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
-package org.hamcrest.core;
-
-import java.util.regex.Pattern;
-
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
-import org.hamcrest.BaseMatcher;
-
-/**
- * Provides a custom description to another matcher.
- */
-public class DescribedAs<T> extends BaseMatcher<T> {
- private final String descriptionTemplate;
- private final Matcher<T> matcher;
- private final Object[] values;
-
- private final static Pattern ARG_PATTERN = Pattern.compile("%([0-9]+)");
-
- public DescribedAs(String descriptionTemplate, Matcher<T> matcher, Object[] values) {
- this.descriptionTemplate = descriptionTemplate;
- this.matcher = matcher;
- this.values = values.clone();
- }
-
- public boolean matches(Object o) {
- return matcher.matches(o);
- }
-
- public void describeTo(Description description) {
- java.util.regex.Matcher arg = ARG_PATTERN.matcher(descriptionTemplate);
-
- int textStart = 0;
- while (arg.find()) {
- description.appendText(descriptionTemplate.substring(textStart, arg.start()));
- int argIndex = Integer.parseInt(arg.group(1));
- description.appendValue(values[argIndex]);
- textStart = arg.end();
- }
-
- if (textStart < descriptionTemplate.length()) {
- description.appendText(descriptionTemplate.substring(textStart));
- }
- }
-
- /**
- * Wraps an existing matcher and overrides the description when it fails.
- */
- @Factory
- public static <T> Matcher<T> describedAs(String description, Matcher<T> matcher, Object... values) {
- return new DescribedAs<T>(description, matcher, values);
- }
-}
+package org.hamcrest.core;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+
+import java.util.regex.Pattern;
+
+import static java.lang.Integer.parseInt;
+
+/**
+ * Provides a custom description to another matcher.
+ */
+public class DescribedAs<T> extends BaseMatcher<T> {
+ private final String descriptionTemplate;
+ private final Matcher<T> matcher;
+ private final Object[] values;
+
+ private final static Pattern ARG_PATTERN = Pattern.compile("%([0-9]+)");
+
+ public DescribedAs(String descriptionTemplate, Matcher<T> matcher, Object[] values) {
+ this.descriptionTemplate = descriptionTemplate;
+ this.matcher = matcher;
+ this.values = values.clone();
+ }
+
+ @Override
+ public boolean matches(Object o) {
+ return matcher.matches(o);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ java.util.regex.Matcher arg = ARG_PATTERN.matcher(descriptionTemplate);
+
+ int textStart = 0;
+ while (arg.find()) {
+ description.appendText(descriptionTemplate.substring(textStart, arg.start()));
+ description.appendValue(values[parseInt(arg.group(1))]);
+ textStart = arg.end();
+ }
+
+ if (textStart < descriptionTemplate.length()) {
+ description.appendText(descriptionTemplate.substring(textStart));
+ }
+ }
+
+ @Override
+ public void describeMismatch(Object item, Description description) {
+ matcher.describeMismatch(item, description);
+ }
+
+ /**
+ * Wraps an existing matcher, overriding its description with that specified. All other functions are
+ * delegated to the decorated matcher, including its mismatch description.
+ * For example:
+ * <pre>describedAs("a big decimal equal to %0", equalTo(myBigDecimal), myBigDecimal.toPlainString())</pre>
+ *
+ * @param description
+ * the new description for the wrapped matcher
+ * @param matcher
+ * the matcher to wrap
+ * @param values
+ * optional values to insert into the tokenised description
+ */
+ public static <T> Matcher<T> describedAs(String description, Matcher<T> matcher, Object... values) {
+ return new DescribedAs<T>(description, matcher, values);
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/Every.java b/hamcrest-core/src/main/java/org/hamcrest/core/Every.java
new file mode 100644
index 0000000..757b7b4
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/Every.java
@@ -0,0 +1,44 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+
+public class Every<T> extends TypeSafeDiagnosingMatcher<Iterable<? extends T>> {
+ private final Matcher<? super T> matcher;
+
+ public Every(Matcher<? super T> matcher) {
+ this.matcher= matcher;
+ }
+
+ @Override
+ public boolean matchesSafely(Iterable<? extends T> collection, Description mismatchDescription) {
+ for (T t : collection) {
+ if (!matcher.matches(t)) {
+ mismatchDescription.appendText("an item ");
+ matcher.describeMismatch(t, mismatchDescription);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("every item is ").appendDescriptionOf(matcher);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that only matches when a single pass over the
+ * examined {@link Iterable} yields items that are all matched by the specified
+ * <code>itemMatcher</code>.
+ * For example:
+ * <pre>assertThat(Arrays.asList("bar", "baz"), everyItem(startsWith("ba")))</pre>
+ *
+ * @param itemMatcher
+ * the matcher to apply to every item provided by the examined {@link Iterable}
+ */
+ public static <U> Matcher<Iterable<? extends U>> everyItem(final Matcher<U> itemMatcher) {
+ return new Every<U>(itemMatcher);
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/Is.java b/hamcrest-core/src/main/java/org/hamcrest/core/Is.java
index f9152e9..ec22238 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/core/Is.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/Is.java
@@ -1,68 +1,76 @@
package org.hamcrest.core;
-import static org.hamcrest.core.IsInstanceOf.instanceOf;
-import static org.hamcrest.core.IsEqual.equalTo;
-import org.hamcrest.Factory;
-import org.hamcrest.Matcher;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
/**
- * Decorates another Matcher, retaining the behavior but allowing tests
+ * Decorates another Matcher, retaining the behaviour but allowing tests
* to be slightly more expressive.
*
- * eg. assertThat(cheese, equalTo(smelly))
- * vs assertThat(cheese, is(equalTo(smelly)))
+ * For example: assertThat(cheese, equalTo(smelly))
+ * vs. assertThat(cheese, is(equalTo(smelly)))
*/
public class Is<T> extends BaseMatcher<T> {
-
private final Matcher<T> matcher;
public Is(Matcher<T> matcher) {
this.matcher = matcher;
}
+ @Override
public boolean matches(Object arg) {
return matcher.matches(arg);
}
+ @Override
public void describeTo(Description description) {
description.appendText("is ").appendDescriptionOf(matcher);
}
-
+
+ @Override
+ public void describeMismatch(Object item, Description mismatchDescription) {
+ matcher.describeMismatch(item, mismatchDescription);
+ }
+
/**
- * Decorates another Matcher, retaining the behavior but allowing tests
+ * Decorates another Matcher, retaining its behaviour, but allowing tests
* to be slightly more expressive.
- *
- * eg. assertThat(cheese, equalTo(smelly))
- * vs assertThat(cheese, is(equalTo(smelly)))
+ * For example:
+ * <pre>assertThat(cheese, is(equalTo(smelly)))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, equalTo(smelly))</pre>
+ *
*/
- @Factory
public static <T> Matcher<T> is(Matcher<T> matcher) {
return new Is<T>(matcher);
}
/**
- * This is a shortcut to the frequently used is(equalTo(x)).
- *
- * eg. assertThat(cheese, is(equalTo(smelly)))
- * vs assertThat(cheese, is(smelly))
+ * A shortcut to the frequently used <code>is(equalTo(x))</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(smelly))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(equalTo(smelly)))</pre>
+ *
*/
- @Factory
public static <T> Matcher<T> is(T value) {
return is(equalTo(value));
}
/**
- * This is a shortcut to the frequently used is(instanceOf(SomeClass.class)).
- *
- * eg. assertThat(cheese, is(instanceOf(Cheddar.class)))
- * vs assertThat(cheese, is(Cheddar.class))
+ * A shortcut to the frequently used <code>is(instanceOf(SomeClass.class))</code>.
+ * For example:
+ * <pre>assertThat(cheese, isA(Cheddar.class))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(instanceOf(Cheddar.class)))</pre>
+ *
*/
- @Factory
- public static Matcher<Object> is(Class<?> type) {
- return is(instanceOf(type));
+ public static <T> Matcher<T> isA(Class<T> type) {
+ final Matcher<T> typeMatcher = instanceOf(type);
+ return is(typeMatcher);
}
-
}
-
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/IsAnything.java b/hamcrest-core/src/main/java/org/hamcrest/core/IsAnything.java
index c5ca49d..4c71a9b 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/core/IsAnything.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/IsAnything.java
@@ -1,11 +1,8 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
package org.hamcrest.core;
+import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
-import org.hamcrest.BaseMatcher;
/**
@@ -13,47 +10,41 @@ import org.hamcrest.BaseMatcher;
*/
public class IsAnything<T> extends BaseMatcher<T> {
- private final String description;
+ private final String message;
public IsAnything() {
this("ANYTHING");
}
- public IsAnything(String description) {
- this.description = description;
+ public IsAnything(String message) {
+ this.message = message;
}
+ @Override
public boolean matches(Object o) {
return true;
}
+ @Override
public void describeTo(Description description) {
- description.appendText(this.description);
+ description.appendText(message);
}
/**
- * This matcher always evaluates to true.
+ * Creates a matcher that always matches, regardless of the examined object.
*/
- @Factory
- public static <T> Matcher<T> anything() {
- return new IsAnything<T>();
+ public static Matcher<Object> anything() {
+ return new IsAnything<Object>();
}
/**
- * This matcher always evaluates to true.
+ * Creates a matcher that always matches, regardless of the examined object, but describes
+ * itself with the specified {@link String}.
*
- * @param description A meaningful string used when describing itself.
- */
- @Factory
- public static <T> Matcher<T> anything(String description) {
- return new IsAnything<T>(description);
- }
-
- /**
- * This matcher always evaluates to true. With type inference.
+ * @param description
+ * a meaningful {@link String} used when describing itself
*/
- @Factory
- public static <T> Matcher<T> any(@SuppressWarnings("unused")Class<T> type) {
- return new IsAnything<T>();
+ public static Matcher<Object> anything(String description) {
+ return new IsAnything<Object>(description);
}
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/IsCollectionContaining.java b/hamcrest-core/src/main/java/org/hamcrest/core/IsCollectionContaining.java
new file mode 100644
index 0000000..c55853d
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/IsCollectionContaining.java
@@ -0,0 +1,133 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.hamcrest.core.AllOf.allOf;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public class IsCollectionContaining<T> extends TypeSafeDiagnosingMatcher<Iterable<? super T>> {
+ private final Matcher<? super T> elementMatcher;
+
+ public IsCollectionContaining(Matcher<? super T> elementMatcher) {
+ this.elementMatcher = elementMatcher;
+ }
+
+ @Override
+ protected boolean matchesSafely(Iterable<? super T> collection, Description mismatchDescription) {
+ if (isEmpty(collection)) {
+ mismatchDescription.appendText("was empty");
+ return false;
+ }
+
+ for (Object item : collection) {
+ if (elementMatcher.matches(item)) {
+ return true;
+ }
+ }
+
+ mismatchDescription.appendText("mismatches were: [");
+ boolean isPastFirst = false;
+ for (Object item : collection) {
+ if (isPastFirst) {
+ mismatchDescription.appendText(", ");
+ }
+ elementMatcher.describeMismatch(item, mismatchDescription);
+ isPastFirst = true;
+ }
+ mismatchDescription.appendText("]");
+ return false;
+ }
+
+ private boolean isEmpty(Iterable<? super T> iterable) {
+ return ! iterable.iterator().hasNext();
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description
+ .appendText("a collection containing ")
+ .appendDescriptionOf(elementMatcher);
+ }
+
+
+ /**
+ * Creates a matcher for {@link Iterable}s that only matches when a single pass over the
+ * examined {@link Iterable} yields at least one item that is matched by the specified
+ * <code>itemMatcher</code>. Whilst matching, the traversal of the examined {@link Iterable}
+ * will stop as soon as a matching item is found.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), hasItem(startsWith("ba")))</pre>
+ *
+ * @param itemMatcher
+ * the matcher to apply to items provided by the examined {@link Iterable}
+ */
+ public static <T> Matcher<Iterable<? super T>> hasItem(Matcher<? super T> itemMatcher) {
+ return new IsCollectionContaining<>(itemMatcher);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that only matches when a single pass over the
+ * examined {@link Iterable} yields at least one item that is equal to the specified
+ * <code>item</code>. Whilst matching, the traversal of the examined {@link Iterable}
+ * will stop as soon as a matching item is found.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), hasItem("bar"))</pre>
+ *
+ * @param item
+ * the item to compare against the items provided by the examined {@link Iterable}
+ */
+ public static <T> Matcher<Iterable<? super T>> hasItem(T item) {
+ // Doesn't forward to hasItem() method so compiler can sort out generics.
+ return new IsCollectionContaining<>(equalTo(item));
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when consecutive passes over the
+ * examined {@link Iterable} yield at least one item that is matched by the corresponding
+ * matcher from the specified <code>itemMatchers</code>. Whilst matching, each traversal of
+ * the examined {@link Iterable} will stop as soon as a matching item is found.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar", "baz"), hasItems(endsWith("z"), endsWith("o")))</pre>
+ *
+ * @param itemMatchers
+ * the matchers to apply to items provided by the examined {@link Iterable}
+ */
+ @SafeVarargs
+ public static <T> Matcher<Iterable<T>> hasItems(Matcher<? super T>... itemMatchers) {
+ List<Matcher<? super Iterable<T>>> all = new ArrayList<>(itemMatchers.length);
+
+ for (Matcher<? super T> elementMatcher : itemMatchers) {
+ // Doesn't forward to hasItem() method so compiler can sort out generics.
+ all.add(new IsCollectionContaining<>(elementMatcher));
+ }
+
+ return allOf(all);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when consecutive passes over the
+ * examined {@link Iterable} yield at least one item that is equal to the corresponding
+ * item from the specified <code>items</code>. Whilst matching, each traversal of the
+ * examined {@link Iterable} will stop as soon as a matching item is found.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar", "baz"), hasItems("baz", "foo"))</pre>
+ *
+ * @param items
+ * the items to compare against the items provided by the examined {@link Iterable}
+ */
+ @SafeVarargs
+ public static <T> Matcher<Iterable<T>> hasItems(T... items) {
+ List<Matcher<? super Iterable<T>>> all = new ArrayList<>(items.length);
+ for (T item : items) {
+ all.add(hasItem(item));
+ }
+
+ return allOf(all);
+ }
+
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/IsEqual.java b/hamcrest-core/src/main/java/org/hamcrest/core/IsEqual.java
index b9f17c5..860e85e 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/core/IsEqual.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/IsEqual.java
@@ -1,11 +1,8 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
package org.hamcrest.core;
+import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
-import org.hamcrest.BaseMatcher;
import java.lang.reflect.Array;
@@ -15,42 +12,47 @@ import java.lang.reflect.Array;
* {@link java.lang.Object#equals} invokedMethod?
*/
public class IsEqual<T> extends BaseMatcher<T> {
- private final Object object;
+ private final Object expectedValue;
public IsEqual(T equalArg) {
- object = equalArg;
+ expectedValue = equalArg;
}
- public boolean matches(Object arg) {
- return areEqual(object, arg);
+ @Override
+ public boolean matches(Object actualValue) {
+ return areEqual(actualValue, expectedValue);
}
+ @Override
public void describeTo(Description description) {
- description.appendValue(object);
+ description.appendValue(expectedValue);
}
- private static boolean areEqual(Object o1, Object o2) {
- if (o1 == null || o2 == null) {
- return o1 == null && o2 == null;
- } else if (isArray(o1)) {
- return isArray(o2) && areArraysEqual(o1, o2);
- } else {
- return o1.equals(o2);
+ private static boolean areEqual(Object actual, Object expected) {
+ if (actual == null) {
+ return expected == null;
+ }
+
+ if (expected != null && isArray(actual)) {
+ return isArray(expected) && areArraysEqual(actual, expected);
}
+
+ return actual.equals(expected);
}
- private static boolean areArraysEqual(Object o1, Object o2) {
- return areArrayLengthsEqual(o1, o2)
- && areArrayElementsEqual(o1, o2);
+ private static boolean areArraysEqual(Object actualArray, Object expectedArray) {
+ return areArrayLengthsEqual(actualArray, expectedArray) && areArrayElementsEqual(actualArray, expectedArray);
}
- private static boolean areArrayLengthsEqual(Object o1, Object o2) {
- return Array.getLength(o1) == Array.getLength(o2);
+ private static boolean areArrayLengthsEqual(Object actualArray, Object expectedArray) {
+ return Array.getLength(actualArray) == Array.getLength(expectedArray);
}
- private static boolean areArrayElementsEqual(Object o1, Object o2) {
- for (int i = 0; i < Array.getLength(o1); i++) {
- if (!areEqual(Array.get(o1, i), Array.get(o2, i))) return false;
+ private static boolean areArrayElementsEqual(Object actualArray, Object expectedArray) {
+ for (int i = 0; i < Array.getLength(actualArray); i++) {
+ if (!areEqual(Array.get(actualArray, i), Array.get(expectedArray, i))) {
+ return false;
+ }
}
return true;
}
@@ -60,12 +62,36 @@ public class IsEqual<T> extends BaseMatcher<T> {
}
/**
- * Is the value equal to another value, as tested by the
- * {@link java.lang.Object#equals} invokedMethod?
+ * Creates a matcher that matches when the examined object is logically equal to the specified
+ * <code>operand</code>, as determined by calling the {@link java.lang.Object#equals} method on
+ * the <b>examined</b> object.
+ *
+ * <p>If the specified operand is <code>null</code> then the created matcher will only match if
+ * the examined object's <code>equals</code> method returns <code>true</code> when passed a
+ * <code>null</code> (which would be a violation of the <code>equals</code> contract), unless the
+ * examined object itself is <code>null</code>, in which case the matcher will return a positive
+ * match.</p>
+ *
+ * <p>The created matcher provides a special behaviour when examining <code>Array</code>s, whereby
+ * it will match if both the operand and the examined object are arrays of the same length and
+ * contain items that are equal to each other (according to the above rules) <b>in the same
+ * indexes</b>.</p>
+ * For example:
+ * <pre>
+ * assertThat("foo", equalTo("foo"));
+ * assertThat(new String[] {"foo", "bar"}, equalTo(new String[] {"foo", "bar"}));
+ * </pre>
+ *
*/
- @Factory
public static <T> Matcher<T> equalTo(T operand) {
return new IsEqual<T>(operand);
}
-
+
+ /**
+ * Creates an {@link org.hamcrest.core.IsEqual} matcher that does not enforce the values being
+ * compared to be of the same static type.
+ */
+ public static Matcher<Object> equalToObject(Object operand) {
+ return new IsEqual<Object>(operand);
+ }
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/IsInstanceOf.java b/hamcrest-core/src/main/java/org/hamcrest/core/IsInstanceOf.java
index df20824..5a508c9 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/core/IsInstanceOf.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/IsInstanceOf.java
@@ -1,44 +1,91 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
package org.hamcrest.core;
import org.hamcrest.Description;
+import org.hamcrest.DiagnosingMatcher;
import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
-import org.hamcrest.BaseMatcher;
/**
* Tests whether the value is an instance of a class.
+ * Classes of basic types will be converted to the relevant "Object" classes
*/
-public class IsInstanceOf extends BaseMatcher<Object> {
- private final Class<?> theClass;
+public class IsInstanceOf extends DiagnosingMatcher<Object> {
+ private final Class<?> expectedClass;
+ private final Class<?> matchableClass;
/**
* Creates a new instance of IsInstanceOf
*
- * @param theClass The predicate evaluates to true for instances of this class
+ * @param expectedClass The predicate evaluates to true for instances of this class
* or one of its subclasses.
*/
- public IsInstanceOf(Class<?> theClass) {
- this.theClass = theClass;
+ public IsInstanceOf(Class<?> expectedClass) {
+ this.expectedClass = expectedClass;
+ this.matchableClass = matchableClass(expectedClass);
+ }
+
+ private static Class<?> matchableClass(Class<?> expectedClass) {
+ if (boolean.class.equals(expectedClass)) return Boolean.class;
+ if (byte.class.equals(expectedClass)) return Byte.class;
+ if (char.class.equals(expectedClass)) return Character.class;
+ if (double.class.equals(expectedClass)) return Double.class;
+ if (float.class.equals(expectedClass)) return Float.class;
+ if (int.class.equals(expectedClass)) return Integer.class;
+ if (long.class.equals(expectedClass)) return Long.class;
+ if (short.class.equals(expectedClass)) return Short.class;
+ return expectedClass;
}
- public boolean matches(Object item) {
- return theClass.isInstance(item);
+ @Override
+ protected boolean matches(Object item, Description mismatch) {
+ if (null == item) {
+ mismatch.appendText("null");
+ return false;
+ }
+
+ if (!matchableClass.isInstance(item)) {
+ mismatch.appendValue(item).appendText(" is a " + item.getClass().getName());
+ return false;
+ }
+
+ return true;
}
+ @Override
public void describeTo(Description description) {
- description.appendText("an instance of ")
- .appendText(theClass.getName());
+ description.appendText("an instance of ").appendText(expectedClass.getName());
}
/**
- * Is the value an instance of a particular type?
+ * Creates a matcher that matches when the examined object is an instance of the specified <code>type</code>,
+ * as determined by calling the {@link java.lang.Class#isInstance(Object)} method on that type, passing the
+ * the examined object.
+ *
+ * <p>The created matcher assumes no relationship between specified type and the examined object.</p>
+ * For example:
+ * <pre>assertThat(new Canoe(), instanceOf(Paddlable.class));</pre>
+ *
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Matcher<T> instanceOf(Class<?> type) {
+ return (Matcher<T>) new IsInstanceOf(type);
+ }
+
+ /**
+ * Creates a matcher that matches when the examined object is an instance of the specified <code>type</code>,
+ * as determined by calling the {@link java.lang.Class#isInstance(Object)} method on that type, passing the
+ * the examined object.
+ *
+ * <p>The created matcher forces a relationship between specified type and the examined object, and should be
+ * used when it is necessary to make generics conform, for example in the JMock clause
+ * <code>with(any(Thing.class))</code></p>
+ * For example:
+ * <pre>assertThat(new Canoe(), instanceOf(Canoe.class));</pre>
+ *
*/
- @Factory
- public static Matcher<Object> instanceOf(Class<?> type) {
- return new IsInstanceOf(type);
+ @SuppressWarnings("unchecked")
+ public static <T> Matcher<T> any(Class<T> type) {
+ return (Matcher<T>) new IsInstanceOf(type);
}
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/IsNot.java b/hamcrest-core/src/main/java/org/hamcrest/core/IsNot.java
index cb6946c..d5cf9c0 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/core/IsNot.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/IsNot.java
@@ -1,49 +1,57 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
package org.hamcrest.core;
-import static org.hamcrest.core.IsEqual.equalTo;
+import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
-import org.hamcrest.BaseMatcher;
+
+import static org.hamcrest.core.IsEqual.equalTo;
/**
* Calculates the logical negation of a matcher.
*/
-public class IsNot<T> extends BaseMatcher<T> {
+public class IsNot<T> extends BaseMatcher<T> {
private final Matcher<T> matcher;
public IsNot(Matcher<T> matcher) {
this.matcher = matcher;
}
+ @Override
public boolean matches(Object arg) {
return !matcher.matches(arg);
}
+ @Override
public void describeTo(Description description) {
description.appendText("not ").appendDescriptionOf(matcher);
}
+
/**
- * Inverts the rule.
+ * Creates a matcher that wraps an existing matcher, but inverts the logic by which
+ * it will match.
+ * For example:
+ * <pre>assertThat(cheese, is(not(equalTo(smelly))))</pre>
+ *
+ * @param matcher
+ * the matcher whose sense should be inverted
*/
- @Factory
public static <T> Matcher<T> not(Matcher<T> matcher) {
return new IsNot<T>(matcher);
}
/**
- * This is a shortcut to the frequently used not(equalTo(x)).
- *
- * eg. assertThat(cheese, is(not(equalTo(smelly))))
- * vs assertThat(cheese, is(not(smelly)))
+ * A shortcut to the frequently used <code>not(equalTo(x))</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(not(smelly)))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(not(equalTo(smelly))))</pre>
+ *
+ * @param value
+ * the value that any examined object should <b>not</b> equal
*/
- @Factory
public static <T> Matcher<T> not(T value) {
return not(equalTo(value));
}
-
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/IsNull.java b/hamcrest-core/src/main/java/org/hamcrest/core/IsNull.java
index 737dcf2..9ebf080 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/core/IsNull.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/IsNull.java
@@ -1,55 +1,74 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
package org.hamcrest.core;
-import static org.hamcrest.core.IsNot.not;
+import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
-import org.hamcrest.BaseMatcher;
+
+import static org.hamcrest.core.IsNot.not;
/**
* Is the value null?
*/
public class IsNull<T> extends BaseMatcher<T> {
+ @Override
public boolean matches(Object o) {
return o == null;
}
+ @Override
public void describeTo(Description description) {
description.appendText("null");
}
/**
- * Matches if value is null.
+ * Creates a matcher that matches if examined object is <code>null</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(nullValue())</pre>
+ *
*/
- @Factory
- public static <T> Matcher<T> nullValue() {
- return new IsNull<T>();
+ public static Matcher<Object> nullValue() {
+ return new IsNull<Object>();
}
/**
- * Matches if value is not null.
+ * A shortcut to the frequently used <code>not(nullValue())</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(notNullValue()))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(not(nullValue())))</pre>
+ *
*/
- @Factory
- public static <T> Matcher<T> notNullValue() {
- return not(IsNull.<T>nullValue());
+ public static Matcher<Object> notNullValue() {
+ return not(nullValue());
}
/**
- * Matches if value is null. With type inference.
+ * Creates a matcher that matches if examined object is <code>null</code>. Accepts a
+ * single dummy argument to facilitate type inference.
+ * For example:
+ * <pre>assertThat(cheese, is(nullValue(Cheese.class))</pre>
+ *
+ * @param type
+ * dummy parameter used to infer the generic type of the returned matcher
*/
- @Factory
- public static <T> Matcher<T> nullValue(@SuppressWarnings("unused") Class<T> type) {
- return nullValue();
+ public static <T> Matcher<T> nullValue(Class<T> type) {
+ return new IsNull<T>();
}
/**
- * Matches if value is not null. With type inference.
+ * A shortcut to the frequently used <code>not(nullValue(X.class)). Accepts a
+ * single dummy argument to facilitate type inference.</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(notNullValue(X.class)))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(not(nullValue(X.class))))</pre>
+ *
+ * @param type
+ * dummy parameter used to infer the generic type of the returned matcher
+ *
*/
- @Factory
- public static <T> Matcher<T> notNullValue(@SuppressWarnings("unused") Class<T> type) {
- return notNullValue();
+ public static <T> Matcher<T> notNullValue(Class<T> type) {
+ return not(nullValue(type));
}
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/IsSame.java b/hamcrest-core/src/main/java/org/hamcrest/core/IsSame.java
index b3ad77e..cbc3971 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/core/IsSame.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/IsSame.java
@@ -1,11 +1,8 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
package org.hamcrest.core;
+import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
-import org.hamcrest.BaseMatcher;
/**
@@ -13,28 +10,42 @@ import org.hamcrest.BaseMatcher;
*/
public class IsSame<T> extends BaseMatcher<T> {
private final T object;
-
+
public IsSame(T object) {
this.object = object;
}
+ @Override
public boolean matches(Object arg) {
return arg == object;
}
+ @Override
public void describeTo(Description description) {
- description.appendText("same(") .appendValue(object) .appendText(")");
+ description.appendText("sameInstance(")
+ .appendValue(object)
+ .appendText(")");
}
-
+
/**
- * Creates a new instance of IsSame
+ * Creates a matcher that matches only when the examined object is the same instance as
+ * the specified target object.
*
- * @param object The predicate evaluates to true only when the argument is
- * this object.
+ * @param target
+ * the target instance against which others should be assessed
*/
- @Factory
- public static <T> Matcher<T> sameInstance(T object) {
- return new IsSame<T>(object);
+ public static <T> Matcher<T> sameInstance(T target) {
+ return new IsSame<T>(target);
+ }
+
+ /**
+ * Creates a matcher that matches only when the examined object is the same instance as
+ * the specified target object.
+ *
+ * @param target
+ * the target instance against which others should be assessed
+ */
+ public static <T> Matcher<T> theInstance(T target) {
+ return new IsSame<T>(target);
}
-
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/ShortcutCombination.java b/hamcrest-core/src/main/java/org/hamcrest/core/ShortcutCombination.java
new file mode 100644
index 0000000..30b33af
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/ShortcutCombination.java
@@ -0,0 +1,33 @@
+package org.hamcrest.core;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+
+abstract class ShortcutCombination<T> extends BaseMatcher<T> {
+
+ private final Iterable<Matcher<? super T>> matchers;
+
+ public ShortcutCombination(Iterable<Matcher<? super T>> matchers) {
+ this.matchers = matchers;
+ }
+
+ @Override
+ public abstract boolean matches(Object o);
+
+ @Override
+ public abstract void describeTo(Description description);
+
+ protected boolean matches(Object o, boolean shortcut) {
+ for (Matcher<? super T> matcher : matchers) {
+ if (matcher.matches(o) == shortcut) {
+ return shortcut;
+ }
+ }
+ return !shortcut;
+ }
+
+ public void describeTo(Description description, String operator) {
+ description.appendList("(", " " + operator + " ", ")", matchers);
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/StringContains.java b/hamcrest-core/src/main/java/org/hamcrest/core/StringContains.java
new file mode 100644
index 0000000..9e0a4ab
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/StringContains.java
@@ -0,0 +1,46 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+
+/**
+ * Tests if the argument is a string that contains a substring.
+ */
+public class StringContains extends SubstringMatcher {
+ public StringContains(boolean ignoringCase, String substring) {
+ super("containing", ignoringCase, substring);
+ }
+
+ @Override
+ protected boolean evalSubstringOf(String s) {
+ return converted(s).contains(converted(substring));
+ }
+
+ /**
+ * Creates a matcher that matches if the examined {@link String} contains the specified
+ * {@link String} anywhere.
+ * For example:
+ * <pre>assertThat("myStringOfNote", containsString("ring"))</pre>
+ *
+ * @param substring
+ * the substring that the returned matcher will expect to find within any examined string
+ *
+ */
+ public static Matcher<String> containsString(String substring) {
+ return new StringContains(false, substring);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined {@link String} contains the specified
+ * {@link String} anywhere, ignoring case.
+ * For example:
+ * <pre>assertThat("myStringOfNote", containsString("ring"))</pre>
+ *
+ * @param substring
+ * the substring that the returned matcher will expect to find within any examined string
+ *
+ */
+ public static Matcher<String> containsStringIgnoringCase(String substring) {
+ return new StringContains(true, substring);
+ }
+
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/StringEndsWith.java b/hamcrest-core/src/main/java/org/hamcrest/core/StringEndsWith.java
new file mode 100644
index 0000000..6a6d1a0
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/StringEndsWith.java
@@ -0,0 +1,42 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+
+/**
+ * Tests if the argument is a string that contains a substring.
+ */
+public class StringEndsWith extends SubstringMatcher {
+ public StringEndsWith(boolean ignoringCase, String substring) { super("ending with", ignoringCase, substring); }
+
+ @Override
+ protected boolean evalSubstringOf(String s) {
+ return converted(s).endsWith(converted(substring));
+ }
+
+ /**
+ * Creates a matcher that matches if the examined {@link String} ends with the specified
+ * {@link String}.
+ * For example:
+ * <pre>assertThat("myStringOfNote", endsWith("Note"))</pre>
+ *
+ * @param suffix
+ * the substring that the returned matcher will expect at the end of any examined string
+ */
+ public static Matcher<String> endsWith(String suffix) {
+ return new StringEndsWith(false, suffix);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined {@link String} ends with the specified
+ * {@link String}, ignoring case.
+ * For example:
+ * <pre>assertThat("myStringOfNote", endsWith("Note"))</pre>
+ *
+ * @param suffix
+ * the substring that the returned matcher will expect at the end of any examined string
+ */
+ public static Matcher<String> endsWithIgnoringCase(String suffix) {
+ return new StringEndsWith(true, suffix);
+ }
+
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/StringStartsWith.java b/hamcrest-core/src/main/java/org/hamcrest/core/StringStartsWith.java
new file mode 100644
index 0000000..fe7b990
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/StringStartsWith.java
@@ -0,0 +1,40 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+
+/**
+ * Tests if the argument is a string that contains a substring.
+ */
+public class StringStartsWith extends SubstringMatcher {
+ public StringStartsWith(boolean ignoringCase, String substring) { super("starting with", ignoringCase, substring); }
+
+ @Override
+ protected boolean evalSubstringOf(String s) { return converted(s).startsWith(converted(substring)); }
+
+ /**
+ * <p>
+ * Creates a matcher that matches if the examined {@link String} starts with the specified
+ * {@link String}.
+ * </p>
+ * For example:
+ * <pre>assertThat("myStringOfNote", startsWith("my"))</pre>
+ *
+ * @param prefix
+ * the substring that the returned matcher will expect at the start of any examined string
+ */
+ public static Matcher<String> startsWith(String prefix) { return new StringStartsWith(false, prefix); }
+
+ /**
+ * <p>
+ * Creates a matcher that matches if the examined {@link String} starts with the specified
+ * {@link String}, ignoring case
+ * </p>
+ * For example:
+ * <pre>assertThat("myStringOfNote", startsWith("my"))</pre>
+ *
+ * @param prefix
+ * the substring that the returned matcher will expect at the start of any examined string
+ */
+ public static Matcher<String> startsWithIgnoringCase(String prefix) { return new StringStartsWith(true, prefix); }
+
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/core/SubstringMatcher.java b/hamcrest-core/src/main/java/org/hamcrest/core/SubstringMatcher.java
new file mode 100644
index 0000000..85c6657
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/core/SubstringMatcher.java
@@ -0,0 +1,44 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+
+public abstract class SubstringMatcher extends TypeSafeMatcher<String> {
+
+ // TODO: Replace String with CharSequence to allow for easy interoperability between
+ // String, StringBuffer, StringBuilder, CharBuffer, etc (joe).
+
+ private final String relationship;
+ private final boolean ignoringCase;
+ protected final String substring;
+
+ protected SubstringMatcher(String relationship, boolean ignoringCase, String substring) {
+ this.relationship = relationship;
+ this.ignoringCase = ignoringCase;
+ this.substring = substring;
+ }
+
+ @Override
+ public boolean matchesSafely(String item) {
+ return evalSubstringOf(ignoringCase ? item.toLowerCase() :item);
+ }
+ @Override
+ public void describeMismatchSafely(String item, Description mismatchDescription) {
+ mismatchDescription.appendText("was \"").appendText(item).appendText("\"");
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("a string ")
+ .appendText(relationship)
+ .appendText(" ")
+ .appendValue(substring);
+ if (ignoringCase) {
+ description.appendText(" ignoring case");
+ }
+ }
+
+ protected String converted(String arg) { return ignoringCase ? arg.toLowerCase() : arg; }
+ protected abstract boolean evalSubstringOf(String string);
+
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/internal/ArrayIterator.java b/hamcrest-core/src/main/java/org/hamcrest/internal/ArrayIterator.java
index 093cdba..03e4c43 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/internal/ArrayIterator.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/internal/ArrayIterator.java
@@ -4,25 +4,28 @@ import java.lang.reflect.Array;
import java.util.Iterator;
public class ArrayIterator implements Iterator<Object> {
- private final Object array;
- private int currentIndex = 0;
-
- public ArrayIterator(Object array) {
- if (!array.getClass().isArray()) {
- throw new IllegalArgumentException("not an array");
- }
- this.array = array;
- }
-
- public boolean hasNext() {
- return currentIndex < Array.getLength(array);
- }
+ private final Object array;
+ private int currentIndex = 0;
+
+ public ArrayIterator(Object array) {
+ if (!array.getClass().isArray()) {
+ throw new IllegalArgumentException("not an array");
+ }
+ this.array = array;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return currentIndex < Array.getLength(array);
+ }
- public Object next() {
- return Array.get(array, currentIndex++);
- }
-
- public void remove() {
- throw new UnsupportedOperationException("cannot remove items from an array");
- }
+ @Override
+ public Object next() {
+ return Array.get(array, currentIndex++);
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("cannot remove items from an array");
+ }
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/internal/NullSafety.java b/hamcrest-core/src/main/java/org/hamcrest/internal/NullSafety.java
new file mode 100644
index 0000000..9310abf
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/internal/NullSafety.java
@@ -0,0 +1,18 @@
+package org.hamcrest.internal;
+
+import org.hamcrest.Matcher;
+import org.hamcrest.core.IsNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class NullSafety {
+ @SuppressWarnings("unchecked")
+ public static <E> List<Matcher<? super E>> nullSafe(Matcher<? super E>[] itemMatchers) {
+ final List<Matcher<? super E>> matchers = new ArrayList<Matcher<? super E>>(itemMatchers.length);
+ for (final Matcher<? super E> itemMatcher : itemMatchers) {
+ matchers.add((Matcher<? super E>) (itemMatcher == null ? IsNull.nullValue() : itemMatcher));
+ }
+ return matchers;
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/internal/ReflectiveTypeFinder.java b/hamcrest-core/src/main/java/org/hamcrest/internal/ReflectiveTypeFinder.java
new file mode 100644
index 0000000..ada74d6
--- /dev/null
+++ b/hamcrest-core/src/main/java/org/hamcrest/internal/ReflectiveTypeFinder.java
@@ -0,0 +1,70 @@
+/**
+ * The TypeSafe classes, and their descendants, need a mechanism to find out what type has been used as a parameter
+ * for the concrete matcher. Unfortunately, this type is lost during type erasure so we need to use reflection
+ * to get it back, by picking out the type of a known parameter to a known method.
+ * The catch is that, with bridging methods, this type is only visible in the class that actually implements
+ * the expected method, so the ReflectiveTypeFinder needs to be applied to that class or a subtype.
+ *
+ * For example, the abstract <code>TypeSafeDiagnosingMatcher&lt;T&gt;</code> defines an abstract method
+ * <pre>protected abstract boolean matchesSafely(T item, Description mismatchDescription);</pre>
+ * By default it uses <code>new ReflectiveTypeFinder("matchesSafely", 2, 0); </code> to find the
+ * parameterised type. If we create a <code>TypeSafeDiagnosingMatcher&lt;String&gt;</code>, the type
+ * finder will return <code>String.class</code>.
+ *
+ * A <code>FeatureMatcher</code> is an abstract subclass of <code>TypeSafeDiagnosingMatcher</code>.
+ * Although it has a templated implementation of <code>matchesSafely(&lt;T&gt;, Description);</code>, the
+ * actual run-time signature of this is <code>matchesSafely(Object, Description);</code>. Instead,
+ * we must find the type by reflecting on the concrete implementation of
+ * <pre>protected abstract U featureValueOf(T actual);</pre>
+ * a method which is declared in <code>FeatureMatcher</code>.
+ *
+ * In short, use this to extract a type from a method in the leaf class of a templated class hierarchy.
+ *
+ * @author Steve Freeman
+ * @author Nat Pryce
+ */
+package org.hamcrest.internal;
+
+import java.lang.reflect.Method;
+
+public class ReflectiveTypeFinder {
+ private final String methodName;
+ private final int expectedNumberOfParameters;
+ private final int typedParameter;
+
+ public ReflectiveTypeFinder(String methodName, int expectedNumberOfParameters, int typedParameter) {
+ this.methodName = methodName;
+ this.expectedNumberOfParameters = expectedNumberOfParameters;
+ this.typedParameter = typedParameter;
+ }
+
+ public Class<?> findExpectedType(Class<?> fromClass) {
+ for (Class<?> c = fromClass; c != Object.class; c = c.getSuperclass()) {
+ for (Method method : c.getDeclaredMethods()) {
+ if (canObtainExpectedTypeFrom(method)) {
+ return expectedTypeFrom(method);
+ }
+ }
+ }
+ throw new Error("Cannot determine correct type for " + methodName + "() method.");
+ }
+
+ /**
+ * @param method The method to examine.
+ * @return true if this method references the relevant type
+ */
+ protected boolean canObtainExpectedTypeFrom(Method method) {
+ return method.getName().equals(methodName)
+ && method.getParameterTypes().length == expectedNumberOfParameters
+ && !method.isSynthetic();
+ }
+
+
+ /**
+ * @param method The method from which to extract
+ * @return The type we're looking for
+ */
+ protected Class<?> expectedTypeFrom(Method method) {
+ return method.getParameterTypes()[typedParameter];
+ }
+}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/internal/SelfDescribingValue.java b/hamcrest-core/src/main/java/org/hamcrest/internal/SelfDescribingValue.java
index 0634527..6537018 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/internal/SelfDescribingValue.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/internal/SelfDescribingValue.java
@@ -10,6 +10,7 @@ public class SelfDescribingValue<T> implements SelfDescribing {
this.value = value;
}
+ @Override
public void describeTo(Description description) {
description.appendValue(value);
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/internal/SelfDescribingValueIterator.java b/hamcrest-core/src/main/java/org/hamcrest/internal/SelfDescribingValueIterator.java
index 58bedf6..bc8f8f4 100644
--- a/hamcrest-core/src/main/java/org/hamcrest/internal/SelfDescribingValueIterator.java
+++ b/hamcrest-core/src/main/java/org/hamcrest/internal/SelfDescribingValueIterator.java
@@ -1,9 +1,9 @@
package org.hamcrest.internal;
-import java.util.Iterator;
-
import org.hamcrest.SelfDescribing;
+import java.util.Iterator;
+
public class SelfDescribingValueIterator<T> implements Iterator<SelfDescribing> {
private Iterator<T> values;
@@ -11,14 +11,17 @@ public class SelfDescribingValueIterator<T> implements Iterator<SelfDescribing>
this.values = values;
}
+ @Override
public boolean hasNext() {
return values.hasNext();
}
+ @Override
public SelfDescribing next() {
return new SelfDescribingValue<T>(values.next());
}
+ @Override
public void remove() {
values.remove();
}
diff --git a/hamcrest-core/src/main/java/org/hamcrest/internal/package.html b/hamcrest-core/src/main/java/org/hamcrest/internal/package.html
deleted file mode 100644
index 1c9bf9d..0000000
--- a/hamcrest-core/src/main/java/org/hamcrest/internal/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
-<body>
- {@hide}
-</body>
-</html>
diff --git a/hamcrest-core/src/main/java/org/hamcrest/package.html b/hamcrest-core/src/main/java/org/hamcrest/package.html
deleted file mode 100644
index 143c704..0000000
--- a/hamcrest-core/src/main/java/org/hamcrest/package.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-<head>
-</head>
-<body>
- <p>The stable API defining Matcher and its associated interfaces and classes.
- Hamcrest sub-projects define their convenience classes in the org.hamcrest package.
- </p>
-</body>
-</html>
diff --git a/hamcrest-core/src/test/java/org/hamcrest/AbstractMatcherTest.java b/hamcrest-core/src/test/java/org/hamcrest/AbstractMatcherTest.java
new file mode 100644
index 0000000..22f823b
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/AbstractMatcherTest.java
@@ -0,0 +1,77 @@
+package org.hamcrest;
+
+import junit.framework.TestCase;
+import org.junit.Assert;
+
+public abstract class AbstractMatcherTest extends TestCase {
+
+ /**
+ * Create an instance of the Matcher so some generic safety-net tests can be run on it.
+ */
+ protected abstract Matcher<?> createMatcher();
+
+ public static <T> void assertMatches(Matcher<T> matcher, T arg) {
+ assertMatches("Expected match, but mismatched", matcher, arg);
+ }
+
+ public static <T> void assertMatches(String message, Matcher<T> matcher, T arg) {
+ if (!matcher.matches(arg)) {
+ Assert.fail(message + " because: '" + mismatchDescription(matcher, arg) + "'");
+ }
+ }
+
+ public static <T> void assertDoesNotMatch(Matcher<? super T> c, T arg) {
+ assertDoesNotMatch("Unexpected match", c, arg);
+ }
+
+ public static <T> void assertDoesNotMatch(String message, Matcher<? super T> c, T arg) {
+ Assert.assertFalse(message, c.matches(arg));
+ }
+
+ public static void assertDescription(String expected, Matcher<?> matcher) {
+ Description description = new StringDescription();
+ description.appendDescriptionOf(matcher);
+ Assert.assertEquals("Expected description", expected, description.toString().trim());
+ }
+
+ public static <T> void assertMismatchDescription(String expected, Matcher<? super T> matcher, T arg) {
+ Assert.assertFalse("Precondition: Matcher should not match item.", matcher.matches(arg));
+ Assert.assertEquals("Expected mismatch description", expected, mismatchDescription(matcher, arg));
+ }
+
+ public static void assertNullSafe(Matcher<?> matcher) {
+ try {
+ matcher.matches(null);
+ }
+ catch (Exception e) {
+ Assert.fail("Matcher was not null safe");
+ }
+ }
+
+ public static void assertUnknownTypeSafe(Matcher<?> matcher) {
+ try {
+ matcher.matches(new UnknownType());
+ }
+ catch (Exception e) {
+ Assert.fail("Matcher was not unknown type safe");
+ }
+ }
+
+ public static <T> String mismatchDescription(Matcher<? super T> matcher, T arg) {
+ Description description = new StringDescription();
+ matcher.describeMismatch(arg, description);
+ return description.toString().trim();
+ }
+
+ public void testIsNullSafe() {
+ assertNullSafe(createMatcher());
+ }
+
+ public void testCopesWithUnknownTypes() {
+ assertUnknownTypeSafe(createMatcher());
+ }
+
+ public static class UnknownType {
+ }
+
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/BaseDescriptionTest.java b/hamcrest-core/src/test/java/org/hamcrest/BaseDescriptionTest.java
new file mode 100644
index 0000000..8b70725
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/BaseDescriptionTest.java
@@ -0,0 +1,78 @@
+package org.hamcrest;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public final class BaseDescriptionTest {
+
+ private final StringBuilder result = new StringBuilder();
+
+ private final BaseDescription baseDescription = new BaseDescription() {
+ @Override protected void append(char c) {
+ result.append(c);
+ }
+ };
+
+ @Test public void
+ describesAppendedNullValue() {
+ baseDescription.appendValue(null);
+ assertEquals("null", result.toString());
+ }
+
+ @Test public void
+ quotesAppendedStringValue() {
+ baseDescription.appendValue("foo");
+ assertEquals("\"foo\"", result.toString());
+ }
+
+ @Test public void
+ quotesAppendedCharacterValue() {
+ baseDescription.appendValue('f');
+ assertEquals("\"f\"", result.toString());
+ }
+
+ @Test public void
+ bracketsAppendedShortValue() {
+ baseDescription.appendValue(Short.valueOf("2"));
+ assertEquals("<2s>", result.toString());
+ }
+
+ @Test public void
+ bracketsAppendedLongValue() {
+ baseDescription.appendValue(Long.valueOf("2"));
+ assertEquals("<2L>", result.toString());
+ }
+
+ @Test public void
+ bracketsAppendedFloatValue() {
+ baseDescription.appendValue(Float.valueOf("1.2"));
+ assertEquals("<1.2F>", result.toString());
+ }
+
+ @Test public void
+ describesAppendedArrayValue() {
+ baseDescription.appendValue(new String[] {"2", "3"});
+ assertEquals("[\"2\", \"3\"]", result.toString());
+ }
+
+ @Test public void
+ bracketsAppendedObjectValue() {
+ final Object value = new Object();
+ baseDescription.appendValue(value);
+ assertEquals("<" + value.toString() + ">", result.toString());
+ }
+
+ @Test public void
+ safelyDescribesAppendedValueOfObjectWhoseToStringThrowsAnException() {
+ final Object value = new Object() {
+ @Override public String toString() {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+ final String expected = value.getClass().getName() + "@" + Integer.toHexString(value.hashCode());
+ baseDescription.appendValue(value);
+ assertEquals("<" + expected + ">", result.toString());
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/BaseMatcherTest.java b/hamcrest-core/src/test/java/org/hamcrest/BaseMatcherTest.java
new file mode 100644
index 0000000..e663f04
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/BaseMatcherTest.java
@@ -0,0 +1,26 @@
+package org.hamcrest;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public final class BaseMatcherTest {
+
+ @Test
+ public void
+ describesItselfWithToStringMethod() {
+ Matcher<Object> someMatcher = new BaseMatcher<Object>() {
+ @Override
+ public boolean matches(Object item) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("SOME DESCRIPTION");
+ }
+ };
+
+ assertEquals("SOME DESCRIPTION", someMatcher.toString());
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/CustomMatcherTest.java b/hamcrest-core/src/test/java/org/hamcrest/CustomMatcherTest.java
new file mode 100644
index 0000000..08649f7
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/CustomMatcherTest.java
@@ -0,0 +1,20 @@
+package org.hamcrest;
+
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.assertDescription;
+
+public final class CustomMatcherTest {
+
+ @Test public void
+ usesStaticDescription() throws Exception {
+ Matcher<String> matcher = new CustomMatcher<String>("I match strings") {
+ @Override
+ public boolean matches(Object item) {
+ return (item instanceof String);
+ }
+ };
+
+ assertDescription("I match strings", matcher);
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/CustomTypeSafeMatcherTest.java b/hamcrest-core/src/test/java/org/hamcrest/CustomTypeSafeMatcherTest.java
new file mode 100644
index 0000000..2c86712
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/CustomTypeSafeMatcherTest.java
@@ -0,0 +1,41 @@
+package org.hamcrest;
+
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+
+public final class CustomTypeSafeMatcherTest {
+ private static final String STATIC_DESCRIPTION = "I match non empty strings";
+
+ private final Matcher<String> customMatcher = new CustomTypeSafeMatcher<String>(STATIC_DESCRIPTION) {
+ @Override
+ public boolean matchesSafely(String item) {
+ return false;
+ }
+
+ @Override
+ public void describeMismatchSafely(String item, Description mismatchDescription) {
+ mismatchDescription.appendText("an " + item);
+ }
+ };
+
+ @Test public void
+ usesStaticDescription() throws Exception {
+ assertDescription(STATIC_DESCRIPTION, customMatcher);
+ }
+
+ @Test public void
+ reportsMismatch() {
+ assertMismatchDescription("an item", customMatcher, "item");
+ }
+
+ @Test public void
+ isNullSafe() {
+ assertNullSafe(customMatcher);
+ }
+
+ @Test public void
+ copesWithUnknownTypes() {
+ assertUnknownTypeSafe(customMatcher);
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/FeatureMatcherTest.java b/hamcrest-core/src/test/java/org/hamcrest/FeatureMatcherTest.java
new file mode 100644
index 0000000..f0cbdd5
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/FeatureMatcherTest.java
@@ -0,0 +1,68 @@
+package org.hamcrest;
+
+import org.hamcrest.core.IsEqual;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.junit.Assert.assertEquals;
+
+public final class FeatureMatcherTest {
+ private final FeatureMatcher<Thingy, String> resultMatcher = resultMatcher();
+
+ @Test public void
+ matchesPartOfAnObject() {
+ assertMatches("feature", resultMatcher, new Thingy("bar"));
+ assertDescription("Thingy with result \"bar\"", resultMatcher);
+ }
+
+ @Test public void
+ mismatchesPartOfAnObject() {
+ assertMismatchDescription("result mismatch-description", resultMatcher, new Thingy("foo"));
+ }
+
+ @Test public void
+ doesNotThrowNullPointerException() {
+ assertMismatchDescription("was null", resultMatcher, null);
+ }
+
+ @Test public void
+ doesNotThrowClassCastException() {
+ resultMatcher.matches(new ShouldNotMatch());
+ StringDescription mismatchDescription = new StringDescription();
+ resultMatcher.describeMismatch(new ShouldNotMatch(), mismatchDescription);
+ assertEquals("was <ShouldNotMatch>", mismatchDescription.toString());
+ }
+
+ public static class Match extends IsEqual<String> {
+ public Match(String equalArg) { super(equalArg); }
+ @Override public void describeMismatch(Object item, Description description) {
+ description.appendText("mismatch-description");
+ }
+ }
+
+ public static class Thingy {
+ private final String result;
+
+ public Thingy(String result) {
+ this.result = result;
+ }
+
+ public String getResult() {
+ return result;
+ }
+ }
+
+ public static class ShouldNotMatch {
+ @Override public String toString() { return "ShouldNotMatch"; }
+ }
+
+ private static FeatureMatcher<Thingy, String> resultMatcher() {
+ return new FeatureMatcher<Thingy, String>(new Match("bar"), "Thingy with result", "result") {
+ @Override
+ public String featureValueOf(Thingy actual) {
+ return actual.getResult();
+ }
+ };
+ }
+
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/MatcherAssertTest.java b/hamcrest-core/src/test/java/org/hamcrest/MatcherAssertTest.java
new file mode 100644
index 0000000..b57c4d7
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/MatcherAssertTest.java
@@ -0,0 +1,96 @@
+package org.hamcrest;
+
+import org.junit.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.*;
+
+public final class MatcherAssertTest {
+
+ @Test public void
+ includesDescriptionOfTestedValueInErrorMessage() {
+ String expected = "expected";
+ String actual = "actual";
+
+ String expectedMessage = "identifier\nExpected: \"expected\"\n but: was \"actual\"";
+
+ try {
+ assertThat("identifier", actual, equalTo(expected));
+ }
+ catch (AssertionError e) {
+ assertTrue(e.getMessage().startsWith(expectedMessage));
+ return;
+ }
+
+ fail("should have failed");
+ }
+
+ @Test public void
+ descriptionCanBeElided() {
+ String expected = "expected";
+ String actual = "actual";
+
+ String expectedMessage = "\nExpected: \"expected\"\n but: was \"actual\"";
+
+ try {
+ assertThat(actual, equalTo(expected));
+ }
+ catch (AssertionError e) {
+ assertTrue(e.getMessage().startsWith(expectedMessage));
+ return;
+ }
+
+ fail("should have failed");
+ }
+
+ @Test public void
+ canTestBooleanDirectly() {
+ assertThat("success reason message", true);
+
+ try {
+ assertThat("failing reason message", false);
+ }
+ catch (AssertionError e) {
+ assertEquals("failing reason message", e.getMessage());
+ return;
+ }
+
+ fail("should have failed");
+ }
+
+ @Test public void
+ includesMismatchDescription() {
+ Matcher<String> matcherWithCustomMismatchDescription = new BaseMatcher<String>() {
+ @Override
+ public boolean matches(Object item) {
+ return false;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Something cool");
+ }
+
+ @Override
+ public void describeMismatch(Object item, Description mismatchDescription) {
+ mismatchDescription.appendText("Not cool");
+ }
+ };
+
+ String expectedMessage = "\nExpected: Something cool\n but: Not cool";
+
+ try {
+ assertThat("Value", matcherWithCustomMismatchDescription);
+ fail("should have failed");
+ }
+ catch (AssertionError e) {
+ assertEquals(expectedMessage, e.getMessage());
+ }
+ }
+
+ @Test public void
+ canAssertSubtypes() {
+ assertThat(1, equalTo((Number) 1));
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/NullDescriptionTest.java b/hamcrest-core/src/test/java/org/hamcrest/NullDescriptionTest.java
new file mode 100644
index 0000000..cccece0
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/NullDescriptionTest.java
@@ -0,0 +1,18 @@
+package org.hamcrest;
+
+import org.hamcrest.Description.NullDescription;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public final class NullDescriptionTest {
+
+ private final NullDescription nullDescription = new Description.NullDescription();
+
+ @Test public void
+ isUnchangedByAppendedText() {
+ nullDescription.appendText("myText");
+ assertEquals("", nullDescription.toString());
+ }
+
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/TypeSafeMatcherTest.java b/hamcrest-core/src/test/java/org/hamcrest/TypeSafeMatcherTest.java
new file mode 100644
index 0000000..e23bab8
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/TypeSafeMatcherTest.java
@@ -0,0 +1,40 @@
+package org.hamcrest;
+
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.assertMismatchDescription;
+import static org.junit.Assert.assertFalse;
+
+public final class TypeSafeMatcherTest {
+ private final Matcher<String> matcher = new TypeSafeMatcherSubclass();
+
+ public static class TypeSafeMatcherSubclass extends TypeSafeMatcher<String> {
+ @Override
+ public boolean matchesSafely(String item) {
+ return false;
+ }
+
+ @Override
+ public void describeMismatchSafely(String item, Description mismatchDescription) {
+ mismatchDescription.appendText("The mismatch");
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ }
+ }
+
+ @Test public void
+ canDetermineMatcherTypeFromProtectedMatchesSafelyMethod() {
+ assertFalse(matcher.matches(null));
+ assertFalse(matcher.matches(10));
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Test public void
+ describesMismatches() {
+ assertMismatchDescription("was null", matcher, null);
+ assertMismatchDescription("was a java.lang.Integer (<3>)", (Matcher)matcher, 3);
+ assertMismatchDescription("The mismatch", matcher, "a string");
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/AllOfTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/AllOfTest.java
new file mode 100644
index 0000000..4815002
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/AllOfTest.java
@@ -0,0 +1,63 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.core.AllOf.allOf;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.hamcrest.core.StringEndsWith.endsWith;
+import static org.hamcrest.core.StringStartsWith.startsWith;
+
+public final class AllOfTest {
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<String> matcher = allOf(equalTo("irrelevant"), startsWith("irr"));
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ evaluatesToTheTheLogicalConjunctionOfTwoOtherMatchers() {
+ Matcher<String> matcher = allOf(startsWith("goo"), endsWith("ood"));
+
+ assertMatches("didn't pass both sub-matchers", matcher, "good");
+ assertDoesNotMatch("didn't fail first sub-matcher", matcher, "mood");
+ assertDoesNotMatch("didn't fail second sub-matcher", matcher, "goon");
+ assertDoesNotMatch("didn't fail both sub-matchers", matcher, "fred");
+ }
+
+ @Test public void
+ evaluatesToTheTheLogicalConjunctionOfManyOtherMatchers() {
+ Matcher<String> matcher = allOf(startsWith("g"), startsWith("go"), endsWith("d"), startsWith("go"), startsWith("goo"));
+
+ assertMatches("didn't pass all sub-matchers", matcher, "good");
+ assertDoesNotMatch("didn't fail middle sub-matcher", matcher, "goon");
+ }
+
+ @Test public void
+ supportsMixedTypes() {
+ final Matcher<SampleSubClass> matcher = allOf(
+ equalTo(new SampleBaseClass("bad")),
+ is(notNullValue()),
+ equalTo(new SampleBaseClass("good")),
+ equalTo(new SampleSubClass("ugly")));
+
+ assertDoesNotMatch("didn't fail last sub-matcher", matcher, new SampleSubClass("good"));
+ }
+
+ @Test public void
+ hasAReadableDescription() {
+ assertDescription("(\"good\" and \"bad\" and \"ugly\")",
+ allOf(equalTo("good"), equalTo("bad"), equalTo("ugly")));
+ }
+
+ @Test public void
+ hasAMismatchDescriptionDescribingTheFirstFailingMatch() {
+ assertMismatchDescription("\"good\" was \"bad\"", allOf(equalTo("bad"), equalTo("good")), "bad");
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/AnyOfTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/AnyOfTest.java
new file mode 100644
index 0000000..11c053c
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/AnyOfTest.java
@@ -0,0 +1,56 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.core.AnyOf.anyOf;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.core.StringEndsWith.endsWith;
+import static org.hamcrest.core.StringStartsWith.startsWith;
+
+public final class AnyOfTest {
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<String> matcher = anyOf(equalTo("irrelevant"), startsWith("irr"));
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ evaluatesToTheTheLogicalDisjunctionOfTwoOtherMatchers() {
+ Matcher<String> matcher = anyOf(startsWith("goo"), endsWith("ood"));
+
+ assertMatches("didn't pass both sub-matchers", matcher, "good");
+ assertMatches("didn't pass second sub-matcher", matcher, "mood");
+ assertMatches("didn't pass first sub-matcher", matcher, "goon");
+ assertDoesNotMatch("didn't fail both sub-matchers", matcher, "flan");
+ }
+
+ @Test public void
+ evaluatesToTheTheLogicalDisjunctionOfManyOtherMatchers() {
+ Matcher<String> matcher = anyOf(startsWith("g"), startsWith("go"), endsWith("d"), startsWith("go"), startsWith("goo"));
+
+ assertMatches("didn't pass middle sub-matcher", matcher, "vlad");
+ assertDoesNotMatch("didn't fail all sub-matchers", matcher, "flan");
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test public void
+ supportsMixedTypes() {
+ final Matcher<SampleSubClass> matcher = anyOf(
+ equalTo(new SampleBaseClass("bad")),
+ equalTo(new SampleBaseClass("good")),
+ equalTo(new SampleSubClass("ugly")));
+
+ assertMatches("didn't pass middle sub-matcher", matcher, new SampleSubClass("good"));
+ }
+
+ @Test public void
+ hasAReadableDescription() {
+ assertDescription("(\"good\" or \"bad\" or \"ugly\")",
+ anyOf(equalTo("good"), equalTo("bad"), equalTo("ugly")));
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/CombinableTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/CombinableTest.java
new file mode 100644
index 0000000..e89c493
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/CombinableTest.java
@@ -0,0 +1,68 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.core.IsNull.notNullValue;
+
+public final class CombinableTest {
+ private static final CombinableMatcher<Integer> EITHER_3_OR_4 = CombinableMatcher.<Integer>either(equalTo(3)).or(equalTo(4));
+ private static final CombinableMatcher<Integer> NOT_3_AND_NOT_4 = CombinableMatcher.<Integer>both(not(equalTo(3))).and(not(equalTo(4)));
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ assertNullSafe(EITHER_3_OR_4);
+ assertNullSafe(NOT_3_AND_NOT_4);
+ assertUnknownTypeSafe(EITHER_3_OR_4);
+ assertUnknownTypeSafe(NOT_3_AND_NOT_4);
+ }
+
+ @Test public void
+ bothAcceptsAndRejects() {
+ assertMatches("both didn't pass", NOT_3_AND_NOT_4, 2);
+ assertDoesNotMatch("both didn't fail", NOT_3_AND_NOT_4, 3);
+ }
+
+ @Test public void
+ acceptsAndRejectsThreeAnds() {
+ CombinableMatcher<? super Integer> tripleAnd = NOT_3_AND_NOT_4.and(equalTo(2));
+
+ assertMatches("tripleAnd didn't pass", tripleAnd, 2);
+ assertDoesNotMatch("tripleAnd didn't fail", tripleAnd, 3);
+ }
+
+ @Test public void
+ bothDescribesItself() {
+ assertDescription("(not <3> and not <4>)", NOT_3_AND_NOT_4);
+ assertMismatchDescription("not <3> was <3>", NOT_3_AND_NOT_4, 3);
+ }
+
+ @Test public void
+ eitherAcceptsAndRejects() {
+ assertMatches("either didn't pass", EITHER_3_OR_4, 3);
+ assertDoesNotMatch("either didn't fail", EITHER_3_OR_4, 6);
+ }
+
+ @Test public void
+ acceptsAndRejectsThreeOrs() {
+ final CombinableMatcher<Integer> tripleOr = EITHER_3_OR_4.or(equalTo(11));
+
+ assertMatches("tripleOr didn't pass", tripleOr, 11);
+ assertDoesNotMatch("tripleOr didn't fail", tripleOr, 9);
+ }
+
+ @Test public void
+ eitherDescribesItself() {
+ assertDescription("(<3> or <4>)", EITHER_3_OR_4);
+ assertMismatchDescription("was <6>", EITHER_3_OR_4, 6);
+ }
+
+ @Test public void
+ picksUpTypeFromLeftHandSideOfExpression() {
+ @SuppressWarnings("unused")
+ Matcher<String> matcher = CombinableMatcher.both(equalTo("yellow")).and(notNullValue(String.class));
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/DescribedAsTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/DescribedAsTest.java
new file mode 100644
index 0000000..5c76af9
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/DescribedAsTest.java
@@ -0,0 +1,49 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.core.DescribedAs.describedAs;
+import static org.hamcrest.core.IsAnything.anything;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public final class DescribedAsTest {
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<Object> matcher = describedAs("irrelevant", anything());
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ overridesDescriptionOfOtherMatcherWithThatPassedToConstructor() {
+ Matcher<?> matcher = describedAs("my description", anything());
+
+ assertDescription("my description", matcher);
+ }
+
+ @Test public void
+ appendsValuesToDescription() {
+ Matcher<?> matcher = describedAs("value 1 = %0, value 2 = %1", anything(), 33, 97);
+
+ assertDescription("value 1 = <33>, value 2 = <97>", matcher);
+ }
+
+ @Test public void
+ celegatesMatchingToAnotherMatcher() {
+ Matcher<String> matcher = describedAs("irrelevant", equalTo("hi"));
+
+ assertMatches(matcher, "hi");
+ assertDoesNotMatch("matched", matcher, "oi");
+ }
+
+ @Test public void
+ delegatesMismatchDescriptionToAnotherMatcher() {
+ Matcher<Integer> matcher = describedAs("irrelevant", equalTo(2));
+
+ assertMismatchDescription("was <1>", matcher, 1);
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/EveryTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/EveryTest.java
new file mode 100644
index 0000000..e45e881
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/EveryTest.java
@@ -0,0 +1,43 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import java.util.ArrayList;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.core.StringContains.containsString;
+
+public final class EveryTest {
+
+ private final Matcher<Iterable<? extends String>> matcher = Every.everyItem(containsString("a"));
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ matchesOnlyWhenEveryItemMatches() {
+ assertMatches(matcher, asList("AaA", "BaB", "CaC"));
+ assertDoesNotMatch(matcher, asList("AaA", "BXB", "CaC"));
+ }
+
+ @Test public void
+ matchesEmptyLists() {
+ assertMatches("didn't match empty list", matcher, new ArrayList<String>());
+ }
+
+ @Test public void
+ describesItself() {
+ assertDescription("every item is a string containing \"a\"", matcher);
+ }
+
+ @Test public void
+ describesAMismatch() {
+ assertMismatchDescription("an item was \"BXB\"", matcher, asList("BXB"));
+ }
+}
+
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/IsAnythingTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/IsAnythingTest.java
new file mode 100644
index 0000000..4983bf7
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/IsAnythingTest.java
@@ -0,0 +1,35 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.assertDescription;
+import static org.hamcrest.AbstractMatcherTest.assertMatches;
+import static org.hamcrest.core.IsAnything.anything;
+
+public final class IsAnythingTest {
+
+ private final Matcher<Object> matcher = anything();
+
+ private static class CustomThing { }
+
+ @Test public void
+ alwaysEvaluatesToTrue() {
+ assertMatches("didn't match null", matcher, null);
+ assertMatches("didn't match Object", matcher, new Object());
+ assertMatches("didn't match custom object", matcher, new CustomThing());
+ assertMatches("didn't match String", matcher, "hi");
+ }
+
+ @Test public void
+ hasUsefulDefaultDescription() {
+ assertDescription("ANYTHING", matcher);
+ }
+
+ @Test public void
+ canOverrideDescription() {
+ String description = "description";
+ assertDescription(description, anything(description));
+ }
+
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/IsCollectionContainingTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/IsCollectionContainingTest.java
new file mode 100644
index 0000000..a9007cd
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/IsCollectionContainingTest.java
@@ -0,0 +1,107 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.core.IsCollectionContaining.hasItem;
+import static org.hamcrest.core.IsCollectionContaining.hasItems;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public final class IsCollectionContainingTest {
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<?> matcher = hasItem(equalTo("irrelevant"));
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ matchesACollectionThatContainsAnElementForTheGivenMatcher() {
+ final Matcher<Iterable<? super String>> itemMatcher = hasItem(equalTo("a"));
+
+ assertMatches("list containing 'a'", itemMatcher, asList("a", "b", "c"));
+ }
+
+ @Test public void
+ doesNotMatchCollectionWithoutAnElementForGivenMatcher() {
+ final Matcher<Iterable<? super String>> matcher = hasItem(mismatchable("a"));
+
+ assertMismatchDescription("mismatches were: [mismatched: b, mismatched: c]", matcher, asList("b", "c"));
+ assertMismatchDescription("was empty", matcher, new ArrayList<String>());
+ }
+
+ @Test public void
+ doesNotMatchNull() {
+ assertDoesNotMatch("doesn't match null", hasItem(equalTo("a")), null);
+ }
+
+ @Test public void
+ hasAReadableDescription() {
+ assertDescription("a collection containing mismatchable: a", hasItem(mismatchable("a")));
+ }
+
+ @Test public void
+ canMatchItemWhenCollectionHoldsSuperclass() { // Issue 24
+ final Set<Number> s = new HashSet<Number>();
+ s.add(2);
+
+ assertMatches(new IsCollectionContaining<Number>(new IsEqual<Number>(2)), s);
+ assertMatches(IsCollectionContaining.hasItem(2), s);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test public void
+ matchesMultipleItemsInCollection() {
+ final Matcher<Iterable<String>> matcher1 = hasItems(equalTo("a"), equalTo("b"), equalTo("c"));
+ assertMatches("list containing all items", matcher1, asList("a", "b", "c"));
+
+ final Matcher<Iterable<String>> matcher2 = hasItems("a", "b", "c");
+ assertMatches("list containing all items (without matchers)", matcher2, asList("a", "b", "c"));
+
+ final Matcher<Iterable<String>> matcher3 = hasItems(equalTo("a"), equalTo("b"), equalTo("c"));
+ assertMatches("list containing all items in any order", matcher3, asList("c", "b", "a"));
+
+ final Matcher<Iterable<String>> matcher4 = hasItems(equalTo("a"), equalTo("b"), equalTo("c"));
+ assertMatches("list containing all items plus others", matcher4, asList("e", "c", "b", "a", "d"));
+
+ final Matcher<Iterable<String>> matcher5 = hasItems(equalTo("a"), equalTo("b"), equalTo("c"));
+ assertDoesNotMatch("not match list unless it contains all items", matcher5, asList("e", "c", "b", "d")); // 'a' missing
+ }
+
+ @Test public void
+ reportsMismatchWithAReadableDescriptionForMultipleItems() {
+ final Matcher<Iterable<Integer>> matcher = hasItems(3, 4);
+
+ assertMismatchDescription("a collection containing <4> mismatches were: [was <1>, was <2>, was <3>]",
+ matcher, asList(1, 2, 3));
+ }
+
+ private static Matcher<? super String> mismatchable(final String string) {
+ return new TypeSafeDiagnosingMatcher<String>() {
+ @Override
+ protected boolean matchesSafely(String item, Description mismatchDescription) {
+ if (string.equals(item))
+ return true;
+
+ mismatchDescription.appendText("mismatched: " + item);
+ return false;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("mismatchable: " + string);
+ }
+ };
+ }
+}
+
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/IsEqualTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/IsEqualTest.java
new file mode 100644
index 0000000..9df73e4
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/IsEqualTest.java
@@ -0,0 +1,143 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.core.IsEqual.equalToObject;
+
+public final class IsEqualTest {
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<?> matcher = equalTo("irrelevant");
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ comparesObjectsUsingEqualsMethod() {
+ final Matcher<String> matcher1 = equalTo("hi");
+ assertMatches(matcher1, "hi");
+ assertDoesNotMatch(matcher1, "bye");
+ assertDoesNotMatch(matcher1, null);
+
+ final Matcher<Integer> matcher2 = equalTo(1);
+ assertMatches(matcher2, 1);
+ assertDoesNotMatch(matcher2, 2);
+ assertDoesNotMatch(matcher2, null);
+ }
+
+ @Test public void
+ canCompareNullValues() {
+ final Matcher<Object> matcher = equalTo(null);
+
+ assertMatches(matcher, null);
+ assertDoesNotMatch(matcher, 2);
+ assertDoesNotMatch(matcher, "hi");
+ assertDoesNotMatch(matcher, new String[] {"a", "b"});
+ }
+
+ @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
+ @Test public void
+ honoursIsEqualImplementationEvenWithNullValues() {
+ Object alwaysEqual = new Object() {
+ @Override
+ public boolean equals(Object obj) {
+ return true;
+ }
+ };
+ Object neverEqual = new Object() {
+ @Override
+ public boolean equals(Object obj) {
+ return false;
+ }
+ };
+
+ Matcher<Object> matcher = equalTo(null);
+
+ assertMatches(matcher, alwaysEqual);
+ assertDoesNotMatch(matcher, neverEqual);
+ }
+
+ @Test public void
+ comparesTheElementsOfAnObjectArray() {
+ String[] s1 = {"a", "b"};
+ String[] s2 = {"a", "b"};
+ String[] s3 = {"c", "d"};
+ String[] s4 = {"a", "b", "c", "d"};
+
+ final Matcher<String[]> matcher = equalTo(s1);
+ assertMatches(matcher, s1);
+ assertMatches(matcher, s2);
+ assertDoesNotMatch(matcher, s3);
+ assertDoesNotMatch(matcher, s4);
+ assertDoesNotMatch(matcher, null);
+ }
+
+ @Test public void
+ comparesTheElementsOfAnArrayOfPrimitiveTypes() {
+ int[] i1 = new int[]{1, 2};
+ int[] i2 = new int[]{1, 2};
+ int[] i3 = new int[]{3, 4};
+ int[] i4 = new int[]{1, 2, 3, 4};
+
+ final Matcher<int[]> matcher = equalTo(i1);
+ assertMatches(matcher, i1);
+ assertMatches(matcher, i2);
+ assertDoesNotMatch(matcher, i3);
+ assertDoesNotMatch(matcher, i4);
+ assertDoesNotMatch(matcher, null);
+ }
+
+ @Test public void
+ recursivelyTestsElementsOfArrays() {
+ int[][] i1 = new int[][]{{1, 2}, {3, 4}};
+ int[][] i2 = new int[][]{{1, 2}, {3, 4}};
+ int[][] i3 = new int[][]{{5, 6}, {7, 8}};
+ int[][] i4 = new int[][]{{1, 2, 3, 4}, {3, 4}};
+
+ final Matcher<int[][]> matcher = equalTo(i1);
+ assertMatches(matcher, i1);
+ assertMatches(matcher, i2);
+ assertDoesNotMatch(matcher, i3);
+ assertDoesNotMatch(matcher, i4);
+ assertDoesNotMatch(matcher, null);
+ }
+
+ @Test public void
+ hasUntypedVariant() {
+ Object original = 10;
+
+ assertMatches(equalToObject(10), original);
+ assertDoesNotMatch(equalToObject(0), original);
+ assertDoesNotMatch(equalToObject("10"), original);
+ assertDoesNotMatch(equalToObject(10), "10");
+ }
+
+ @Test public void
+ includesTheResultOfCallingToStringOnItsArgumentInTheDescription() {
+ final String argumentDescription = "ARGUMENT DESCRIPTION";
+ Object argument = new Object() {
+ @Override
+ public String toString() {
+ return argumentDescription;
+ }
+ };
+ assertDescription("<" + argumentDescription + ">", equalTo(argument));
+ }
+
+ @Test public void
+ returnsAnObviousDescriptionIfCreatedWithANestedMatcherByMistake() {
+ Matcher<? super String> innerMatcher = equalTo("NestedMatcher");
+ assertDescription("<" + innerMatcher.toString() + ">", equalTo(innerMatcher));
+ }
+
+ @Test public void
+ returnsGoodDescriptionIfCreatedWithNullReference() {
+ assertDescription("null", equalTo(null));
+ }
+}
+
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/IsInstanceOfTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/IsInstanceOfTest.java
new file mode 100644
index 0000000..8dd85af
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/IsInstanceOfTest.java
@@ -0,0 +1,69 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.core.IsInstanceOf.any;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+
+public final class IsInstanceOfTest {
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<?> matcher = instanceOf(Number.class);
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ evaluatesToTrueIfArgumentIsInstanceOfASpecificClass() {
+ final Matcher<Object> matcher = instanceOf(Number.class);
+
+ assertMatches(matcher, 1);
+ assertMatches(matcher, 1.1);
+ assertDoesNotMatch(matcher, null);
+ assertDoesNotMatch(matcher, new Object());
+ }
+
+ @Test public void
+ hasAReadableDescription() {
+ assertDescription("an instance of java.lang.Number", instanceOf(Number.class));
+ }
+
+ @Test public void
+ describesActualClassInMismatchMessage() {
+ assertMismatchDescription("\"some text\" is a java.lang.String", instanceOf(Number.class), "some text");
+ }
+
+ @Test public void
+ matchesPrimitiveTypes() {
+ assertMatches(any(boolean.class), true);
+ assertMatches(any(byte.class), (byte)1);
+ assertMatches(any(char.class), 'x');
+ assertMatches(any(double.class), 5.0);
+ assertMatches(any(float.class), 5.0f);
+ assertMatches(any(int.class), 2);
+ assertMatches(any(long.class), 4L);
+ assertMatches(any(short.class), (short)1);
+ }
+
+ @Test public void
+ instanceOfRequiresACastToReturnTheCorrectTypeForUseInJMock() {
+ @SuppressWarnings("unused")
+ Integer anInteger = (Integer)with(instanceOf(Integer.class));
+ }
+
+ @Test public void
+ anyWillReturnTheCorrectTypeForUseInJMock() {
+ @SuppressWarnings("unused")
+ Integer anInteger = with(any(Integer.class));
+ }
+
+
+ private static <T> T with(@SuppressWarnings("unused") Matcher<T> matcher) {
+ return null;
+ }
+}
+
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/IsNotTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/IsNotTest.java
new file mode 100644
index 0000000..79f4683
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/IsNotTest.java
@@ -0,0 +1,42 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.hamcrest.core.IsNot.not;
+
+public final class IsNotTest {
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<String> matcher = not("something");
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ evaluatesToTheTheLogicalNegationOfAnotherMatcher() {
+ final Matcher<String> matcher = not(equalTo("A"));
+
+ assertMatches(matcher, "B");
+ assertDoesNotMatch(matcher, "A");
+ }
+
+ @Test public void
+ providesConvenientShortcutForNotEqualTo() {
+ final Matcher<String> matcher = not("A");
+
+ assertMatches(matcher, "B");
+ assertDoesNotMatch(matcher, "A");
+ }
+
+ @Test public void
+ usesDescriptionOfNegatedMatcherWithPrefix() {
+ assertDescription("not an instance of java.lang.String", not(instanceOf(String.class)));
+ assertDescription("not \"A\"", not("A"));
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/IsNullTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/IsNullTest.java
new file mode 100644
index 0000000..74b046b
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/IsNullTest.java
@@ -0,0 +1,43 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.hamcrest.core.IsNull.nullValue;
+
+
+public final class IsNullTest {
+
+ private final Matcher<Object> nullMatcher = nullValue();
+ private final Matcher<Object> notNullMatcher = notNullValue();
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ assertNullSafe(nullMatcher);
+ assertUnknownTypeSafe(nullMatcher);
+
+ assertNullSafe(notNullMatcher);
+ assertUnknownTypeSafe(notNullMatcher);
+ }
+
+ @Test public void
+ evaluatesToTrueIfArgumentIsNull() {
+ assertMatches(nullMatcher, null);
+ assertDoesNotMatch(nullMatcher, new Object());
+
+ assertMatches(notNullMatcher, new Object());
+ assertDoesNotMatch(notNullMatcher, null);
+ }
+
+ @Test public void
+ supportsStaticTyping() {
+ requiresStringMatcher(nullValue(String.class));
+ requiresStringMatcher(notNullValue(String.class));
+ }
+
+ private void requiresStringMatcher(@SuppressWarnings("unused") Matcher<String> arg) {
+ // no-op
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/IsSameTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/IsSameTest.java
new file mode 100644
index 0000000..a4a2010
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/IsSameTest.java
@@ -0,0 +1,48 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.core.IsSame.sameInstance;
+import static org.hamcrest.core.IsSame.theInstance;
+
+
+public final class IsSameTest {
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<String> matcher = sameInstance("irrelevant");
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ evaluatesToTrueIfArgumentIsReferenceToASpecifiedObject() {
+ Object o1 = new Object();
+ Matcher<Object> matcher = sameInstance(o1);
+
+ assertMatches(matcher, o1);
+ assertDoesNotMatch(matcher, new Object());
+ }
+
+ @Test public void
+ alternativeFactoryMethodAlsoMatchesOnlyIfArgumentIsReferenceToASpecifiedObject() {
+ Object o1 = new Object();
+ Matcher<Object> matcher = theInstance(o1);
+
+ assertMatches(matcher, o1);
+ assertDoesNotMatch(matcher, new Object());
+ }
+
+ @Test public void
+ returnsReadableDescriptionFromToString() {
+ assertDescription("sameInstance(\"ARG\")", sameInstance("ARG"));
+ }
+
+ @Test public void
+ returnsReadableDescriptionFromToStringWhenInitialisedWithNull() {
+ assertDescription("sameInstance(null)", sameInstance(null));
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/IsTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/IsTest.java
new file mode 100644
index 0000000..6656e6d
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/IsTest.java
@@ -0,0 +1,51 @@
+package org.hamcrest.core;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.Is.isA;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public final class IsTest {
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<String> matcher = is("something");
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ matchesTheSameWayTheUnderlyingMatcherDoes() {
+ final Matcher<Boolean> matcher = is(equalTo(true));
+
+ assertMatches(matcher, true);
+ assertDoesNotMatch(matcher, false);
+ }
+
+ @Test public void
+ generatesIsPrefixInDescription() {
+ assertDescription("is <true>", is(equalTo(true)));
+ assertDescription("is \"A\"", is("A"));
+ }
+
+ @Test public void
+ providesConvenientShortcutForIsEqualTo() {
+ final Matcher<String> matcher = is("A");
+
+ assertMatches(matcher, "A");
+ assertDoesNotMatch(is("A"), "B");
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Test public void
+ providesConvenientShortcutForIsInstanceOf() {
+ final Matcher matcher = isA(Integer.class);
+ assertMatches(matcher, 1);
+ assertDoesNotMatch(matcher, new Object());
+ assertDoesNotMatch(matcher, null);
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/SampleBaseClass.java b/hamcrest-core/src/test/java/org/hamcrest/core/SampleBaseClass.java
new file mode 100644
index 0000000..baf4d8e
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/SampleBaseClass.java
@@ -0,0 +1,24 @@
+package org.hamcrest.core;
+
+public class SampleBaseClass {
+ String value;
+
+ public SampleBaseClass(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof SampleBaseClass && value.equals(((SampleBaseClass) obj).value);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/SampleSubClass.java b/hamcrest-core/src/test/java/org/hamcrest/core/SampleSubClass.java
new file mode 100644
index 0000000..bdaa160
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/SampleSubClass.java
@@ -0,0 +1,9 @@
+package org.hamcrest.core;
+
+public class SampleSubClass extends SampleBaseClass {
+
+ public SampleSubClass(String value) {
+ super(value);
+ }
+
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/StringContainsTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/StringContainsTest.java
new file mode 100644
index 0000000..93dd05c
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/StringContainsTest.java
@@ -0,0 +1,43 @@
+package org.hamcrest.core;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.core.StringContains.containsString;
+import static org.hamcrest.core.StringContains.containsStringIgnoringCase;
+
+
+public class StringContainsTest extends AbstractMatcherTest {
+ static final String EXCERPT = "EXCERPT";
+ final Matcher<String> stringContains = containsString(EXCERPT);
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return stringContains;
+ }
+
+ public void testMatchesSubstrings() {
+ assertMatches(stringContains, EXCERPT + "END");
+ assertMatches(stringContains, "START" + EXCERPT);
+ assertMatches(stringContains, "START" + EXCERPT + "END");
+ assertMatches(stringContains, EXCERPT);
+ assertDoesNotMatch(stringContains, EXCERPT.toLowerCase());
+ assertMatches(stringContains, EXCERPT + EXCERPT);
+ assertDoesNotMatch(stringContains, "XC");
+
+ assertMismatchDescription("was \"Something else\"", stringContains, "Something else");
+ assertDescription("a string containing \"EXCERPT\"", stringContains);
+ }
+
+ public void testMatchesSubstringsIgnoringCase() {
+ final Matcher<String> ignoringCase = containsStringIgnoringCase("ExCert");
+ assertMatches(ignoringCase, "eXcERT" + "END");
+ assertMatches(ignoringCase, "START" + "EXCert");
+ assertMatches(ignoringCase, "START" + "excERT" + "END");
+ assertMatches(ignoringCase, "eXCert" + "excErt");
+ assertDoesNotMatch(ignoringCase, "xc");
+
+ assertMismatchDescription("was \"Something else\"", ignoringCase, "Something else");
+ assertDescription("a string containing \"ExCert\" ignoring case", ignoringCase);
+ }
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/StringEndsWithTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/StringEndsWithTest.java
new file mode 100644
index 0000000..f482cbf
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/StringEndsWithTest.java
@@ -0,0 +1,45 @@
+package org.hamcrest.core;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.core.StringEndsWith.endsWith;
+import static org.hamcrest.core.StringEndsWith.endsWithIgnoringCase;
+
+
+public class StringEndsWithTest extends AbstractMatcherTest {
+ static final String EXCERPT = "EXCERPT";
+ final Matcher<String> stringEndsWith = endsWith(EXCERPT);
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return stringEndsWith;
+ }
+
+ public void testMatchesSubstringAtEnd() {
+ assertDoesNotMatch(stringEndsWith, EXCERPT + "END");
+ assertMatches(stringEndsWith, "START" + EXCERPT);
+ assertMatches(stringEndsWith, EXCERPT);
+ assertDoesNotMatch(stringEndsWith, EXCERPT.toLowerCase());
+ assertDoesNotMatch(stringEndsWith, "START" + EXCERPT + "END");
+ assertMatches(stringEndsWith, EXCERPT + EXCERPT);
+ assertDoesNotMatch(stringEndsWith, "EXCER");
+
+ assertMismatchDescription("was \"Something else\"", stringEndsWith, "Something else");
+ assertDescription("a string ending with \"EXCERPT\"", stringEndsWith);
+ }
+
+ public void testMatchesSubstringAtEndIngoringCase() {
+ final Matcher<String> ignoringCase = endsWithIgnoringCase("EXCERpt");
+ assertDoesNotMatch(ignoringCase, "eXCErpt" + "END");
+ assertMatches(ignoringCase, "START" + "EXceRpt");
+ assertMatches(ignoringCase, "EXcerPT");
+ assertDoesNotMatch(ignoringCase, "START" + "ExcERpt" + "END");
+ assertMatches(ignoringCase, "exCERpt" + "EXCerPt");
+ assertDoesNotMatch(ignoringCase, "ExcER");
+
+ assertMismatchDescription("was \"Something else\"", ignoringCase, "Something else");
+ assertDescription("a string ending with \"EXCERpt\" ignoring case", ignoringCase);
+ }
+
+}
diff --git a/hamcrest-core/src/test/java/org/hamcrest/core/StringStartsWithTest.java b/hamcrest-core/src/test/java/org/hamcrest/core/StringStartsWithTest.java
new file mode 100644
index 0000000..f093acb
--- /dev/null
+++ b/hamcrest-core/src/test/java/org/hamcrest/core/StringStartsWithTest.java
@@ -0,0 +1,46 @@
+package org.hamcrest.core;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.core.StringStartsWith.startsWith;
+import static org.hamcrest.core.StringStartsWith.startsWithIgnoringCase;
+
+
+public class StringStartsWithTest extends AbstractMatcherTest {
+ static final String EXCERPT = "EXCERPT";
+ final Matcher<String> stringStartsWith = startsWith(EXCERPT);
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return stringStartsWith;
+ }
+
+ public void testMatchesStringAtStart() {
+ assertMatches(stringStartsWith, EXCERPT + "END");
+ assertDoesNotMatch(stringStartsWith, "START" + EXCERPT);
+ assertDoesNotMatch(stringStartsWith, "START" + EXCERPT + "END");
+ assertMatches(stringStartsWith, EXCERPT);
+ assertDoesNotMatch(stringStartsWith, EXCERPT.toLowerCase());
+ assertMatches(stringStartsWith, EXCERPT + EXCERPT);
+ assertDoesNotMatch(stringStartsWith, "EXCER");
+
+ assertDescription("a string starting with \"EXCERPT\"", stringStartsWith);
+ assertMismatchDescription("was \"Something else\"", stringStartsWith, "Something else");
+ }
+
+ public void testMatchesStringAtStartIgnoringCase() {
+ final Matcher<String> ignoreCase = startsWithIgnoringCase("EXCerPT");
+
+ assertMatches(ignoreCase, "exCerPT" + "END");
+ assertDoesNotMatch(ignoreCase, "START" + "EXCerpt");
+ assertDoesNotMatch(ignoreCase, "START" + "EXcerpT" + "END");
+ assertMatches(ignoreCase, "excERPT");
+ assertMatches(ignoreCase, "ExcerPT" + "EXCerpt");
+ assertDoesNotMatch(ignoreCase, "ExcER");
+
+ assertDescription("a string starting with \"EXCerPT\" ignoring case", ignoreCase);
+ assertMismatchDescription("was \"Something else\"", ignoreCase, "Something else");
+ }
+
+}
diff --git a/hamcrest-library/LICENSE.txt b/hamcrest-library/LICENSE.txt
deleted file mode 100644
index 5ebe92c..0000000
--- a/hamcrest-library/LICENSE.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-BSD License
-
-Copyright (c) 2000-2006, www.hamcrest.org
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this list of
-conditions and the following disclaimer. Redistributions in binary form must reproduce
-the above copyright notice, this list of conditions and the following disclaimer in
-the documentation and/or other materials provided with the distribution.
-
-Neither the name of Hamcrest nor the names of its contributors may be used to endorse
-or promote products derived from this software without specific prior written
-permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
-SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
-WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGE.
diff --git a/hamcrest-library/README.android b/hamcrest-library/README.android
deleted file mode 100644
index dd099ed..0000000
--- a/hamcrest-library/README.android
+++ /dev/null
@@ -1 +0,0 @@
-Ssource obtained from https://hamcrest.googlecode.com/files/hamcrest-library-1.1.jar, with org.hamcrest.beans removed
diff --git a/hamcrest-library/build.gradle b/hamcrest-library/build.gradle
deleted file mode 100644
index 54ab15f..0000000
--- a/hamcrest-library/build.gradle
+++ /dev/null
@@ -1,13 +0,0 @@
-apply plugin: 'java'
-
-sourceSets {
- main {
- java {
- srcDirs = ['src']
- }
- }
-}
-
-dependencies {
- compile project(':hamcrest')
-}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/Matchers.java b/hamcrest-library/src/main/java/org/hamcrest/Matchers.java
index 2e82aa0..b04c45d 100644
--- a/hamcrest-library/src/main/java/org/hamcrest/Matchers.java
+++ b/hamcrest-library/src/main/java/org/hamcrest/Matchers.java
@@ -1,28 +1,204 @@
-// Generated source.
package org.hamcrest;
public class Matchers {
- /**
- * Decorates another Matcher, retaining the behavior but allowing tests
- * to be slightly more expressive.
- *
- * eg. assertThat(cheese, equalTo(smelly))
- * vs assertThat(cheese, is(equalTo(smelly)))
- */
- public static <T> org.hamcrest.Matcher<T> is(org.hamcrest.Matcher<T> matcher) {
- return org.hamcrest.core.Is.is(matcher);
- }
-
- /**
- * This is a shortcut to the frequently used is(equalTo(x)).
- *
- * eg. assertThat(cheese, is(equalTo(smelly)))
- * vs assertThat(cheese, is(smelly))
- */
- public static <T> org.hamcrest.Matcher<T> is(T value) {
- return org.hamcrest.core.Is.is(value);
- }
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.Matcher<T> allOf(java.lang.Iterable<org.hamcrest.Matcher<? super T>> matchers) {
+ return org.hamcrest.core.AllOf.<T>allOf(matchers);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.Matcher<T> allOf(org.hamcrest.Matcher<? super T>... matchers) {
+ return org.hamcrest.core.AllOf.<T>allOf(matchers);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.Matcher<T> allOf(org.hamcrest.Matcher<? super T> first, org.hamcrest.Matcher<? super T> second) {
+ return org.hamcrest.core.AllOf.<T>allOf(first, second);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.Matcher<T> allOf(org.hamcrest.Matcher<? super T> first, org.hamcrest.Matcher<? super T> second, org.hamcrest.Matcher<? super T> third) {
+ return org.hamcrest.core.AllOf.<T>allOf(first, second, third);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.Matcher<T> allOf(org.hamcrest.Matcher<? super T> first, org.hamcrest.Matcher<? super T> second, org.hamcrest.Matcher<? super T> third, org.hamcrest.Matcher<? super T> fourth) {
+ return org.hamcrest.core.AllOf.<T>allOf(first, second, third, fourth);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.Matcher<T> allOf(org.hamcrest.Matcher<? super T> first, org.hamcrest.Matcher<? super T> second, org.hamcrest.Matcher<? super T> third, org.hamcrest.Matcher<? super T> fourth, org.hamcrest.Matcher<? super T> fifth) {
+ return org.hamcrest.core.AllOf.<T>allOf(first, second, third, fourth, fifth);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ALL</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", allOf(startsWith("my"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.Matcher<T> allOf(org.hamcrest.Matcher<? super T> first, org.hamcrest.Matcher<? super T> second, org.hamcrest.Matcher<? super T> third, org.hamcrest.Matcher<? super T> fourth, org.hamcrest.Matcher<? super T> fifth, org.hamcrest.Matcher<? super T> sixth) {
+ return org.hamcrest.core.AllOf.<T>allOf(first, second, third, fourth, fifth, sixth);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ANY</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", anyOf(startsWith("foo"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.core.AnyOf<T> anyOf(java.lang.Iterable<org.hamcrest.Matcher<? super T>> matchers) {
+ return org.hamcrest.core.AnyOf.<T>anyOf(matchers);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ANY</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", anyOf(startsWith("foo"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.core.AnyOf<T> anyOf(org.hamcrest.Matcher<? super T>... matchers) {
+ return org.hamcrest.core.AnyOf.<T>anyOf(matchers);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ANY</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", anyOf(startsWith("foo"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.core.AnyOf<T> anyOf(org.hamcrest.Matcher<T> first, org.hamcrest.Matcher<? super T> second) {
+ return org.hamcrest.core.AnyOf.<T>anyOf(first, second);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ANY</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", anyOf(startsWith("foo"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.core.AnyOf<T> anyOf(org.hamcrest.Matcher<T> first, org.hamcrest.Matcher<? super T> second, org.hamcrest.Matcher<? super T> third) {
+ return org.hamcrest.core.AnyOf.<T>anyOf(first, second, third);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ANY</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", anyOf(startsWith("foo"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.core.AnyOf<T> anyOf(org.hamcrest.Matcher<T> first, org.hamcrest.Matcher<? super T> second, org.hamcrest.Matcher<? super T> third, org.hamcrest.Matcher<? super T> fourth) {
+ return org.hamcrest.core.AnyOf.<T>anyOf(first, second, third, fourth);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ANY</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", anyOf(startsWith("foo"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.core.AnyOf<T> anyOf(org.hamcrest.Matcher<T> first, org.hamcrest.Matcher<? super T> second, org.hamcrest.Matcher<? super T> third, org.hamcrest.Matcher<? super T> fourth, org.hamcrest.Matcher<? super T> fifth) {
+ return org.hamcrest.core.AnyOf.<T>anyOf(first, second, third, fourth, fifth);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined object matches <b>ANY</b> of the specified matchers.
+ * For example:
+ * <pre>assertThat("myValue", anyOf(startsWith("foo"), containsString("Val")))</pre>
+ */
+ public static <T> org.hamcrest.core.AnyOf<T> anyOf(org.hamcrest.Matcher<T> first, org.hamcrest.Matcher<? super T> second, org.hamcrest.Matcher<? super T> third, org.hamcrest.Matcher<? super T> fourth, org.hamcrest.Matcher<? super T> fifth, org.hamcrest.Matcher<? super T> sixth) {
+ return org.hamcrest.core.AnyOf.<T>anyOf(first, second, third, fourth, fifth, sixth);
+ }
+
+ /**
+ * Creates a matcher that matches when both of the specified matchers match the examined object.
+ * For example:
+ * <pre>assertThat("fab", both(containsString("a")).and(containsString("b")))</pre>
+ */
+ public static <LHS> org.hamcrest.core.CombinableMatcher.CombinableBothMatcher<LHS> both(org.hamcrest.Matcher<? super LHS> matcher) {
+ return org.hamcrest.core.CombinableMatcher.<LHS>both(matcher);
+ }
+
+ /**
+ * Creates a matcher that matches when either of the specified matchers match the examined object.
+ * For example:
+ * <pre>assertThat("fan", either(containsString("a")).or(containsString("b")))</pre>
+ */
+ public static <LHS> org.hamcrest.core.CombinableMatcher.CombinableEitherMatcher<LHS> either(org.hamcrest.Matcher<? super LHS> matcher) {
+ return org.hamcrest.core.CombinableMatcher.<LHS>either(matcher);
+ }
+
+ /**
+ * Wraps an existing matcher, overriding its description with that specified. All other functions are
+ * delegated to the decorated matcher, including its mismatch description.
+ * For example:
+ * <pre>describedAs("a big decimal equal to %0", equalTo(myBigDecimal), myBigDecimal.toPlainString())</pre>
+ *
+ * @param description
+ * the new description for the wrapped matcher
+ * @param matcher
+ * the matcher to wrap
+ * @param values
+ * optional values to insert into the tokenised description
+ */
+ public static <T> org.hamcrest.Matcher<T> describedAs(java.lang.String description, org.hamcrest.Matcher<T> matcher, java.lang.Object... values) {
+ return org.hamcrest.core.DescribedAs.<T>describedAs(description, matcher, values);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that only matches when a single pass over the
+ * examined {@link Iterable} yields items that are all matched by the specified
+ * <code>itemMatcher</code>.
+ * For example:
+ * <pre>assertThat(Arrays.asList("bar", "baz"), everyItem(startsWith("ba")))</pre>
+ *
+ * @param itemMatcher
+ * the matcher to apply to every item provided by the examined {@link Iterable}
+ */
+ public static <U> org.hamcrest.Matcher<java.lang.Iterable<? extends U>> everyItem(org.hamcrest.Matcher<U> itemMatcher) {
+ return org.hamcrest.core.Every.<U>everyItem(itemMatcher);
+ }
+
+ /**
+ * Decorates another Matcher, retaining its behaviour, but allowing tests
+ * to be slightly more expressive.
+ * For example:
+ * <pre>assertThat(cheese, is(equalTo(smelly)))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, equalTo(smelly))</pre>
+ */
+ public static <T> org.hamcrest.Matcher<T> is(org.hamcrest.Matcher<T> matcher) {
+ return org.hamcrest.core.Is.<T>is(matcher);
+ }
+
+ /**
+ * A shortcut to the frequently used <code>is(equalTo(x))</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(smelly))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(equalTo(smelly)))</pre>
+ */
+ public static <T> org.hamcrest.Matcher<T> is(T value) {
+ return org.hamcrest.core.Is.<T>is(value);
+ }
/**
* Provided to cause compile time error when used in preference to a possible runtime error if
@@ -40,275 +216,1370 @@ public class Matchers {
public static void is(java.lang.Class<?> type) {
}
- /**
- * Inverts the rule.
- */
- public static <T> org.hamcrest.Matcher<T> not(org.hamcrest.Matcher<T> matcher) {
- return org.hamcrest.core.IsNot.not(matcher);
- }
-
- /**
- * This is a shortcut to the frequently used not(equalTo(x)).
- *
- * eg. assertThat(cheese, is(not(equalTo(smelly))))
- * vs assertThat(cheese, is(not(smelly)))
- */
- public static <T> org.hamcrest.Matcher<T> not(T value) {
- return org.hamcrest.core.IsNot.not(value);
- }
-
- /**
- * Is the value equal to another value, as tested by the
- * {@link java.lang.Object#equals} invokedMethod?
- */
- public static <T> org.hamcrest.Matcher<T> equalTo(T operand) {
- return org.hamcrest.core.IsEqual.equalTo(operand);
- }
-
- /**
- * Is the value an instance of a particular type?
- */
- public static org.hamcrest.Matcher<java.lang.Object> instanceOf(java.lang.Class<?> type) {
- return org.hamcrest.core.IsInstanceOf.instanceOf(type);
- }
-
- /**
- * Evaluates to true only if ALL of the passed in matchers evaluate to true.
- */
- public static <T> org.hamcrest.Matcher<T> allOf(org.hamcrest.Matcher<? extends T>... matchers) {
- return org.hamcrest.core.AllOf.<T>allOf(matchers);
- }
-
- /**
- * Evaluates to true only if ALL of the passed in matchers evaluate to true.
- */
- public static <T> org.hamcrest.Matcher<T> allOf(java.lang.Iterable<org.hamcrest.Matcher<? extends T>> matchers) {
- return org.hamcrest.core.AllOf.allOf(matchers);
- }
-
- /**
- * Evaluates to true if ANY of the passed in matchers evaluate to true.
- */
- public static <T> org.hamcrest.Matcher<T> anyOf(org.hamcrest.Matcher<? extends T>... matchers) {
- return org.hamcrest.core.AnyOf.<T>anyOf(matchers);
- }
-
- /**
- * Evaluates to true if ANY of the passed in matchers evaluate to true.
- */
- public static <T> org.hamcrest.Matcher<T> anyOf(java.lang.Iterable<org.hamcrest.Matcher<? extends T>> matchers) {
- return org.hamcrest.core.AnyOf.anyOf(matchers);
- }
-
- /**
- * Creates a new instance of IsSame
- *
- * @param object The predicate evaluates to true only when the argument is
- * this object.
- */
- public static <T> org.hamcrest.Matcher<T> sameInstance(T object) {
- return org.hamcrest.core.IsSame.sameInstance(object);
- }
-
- /**
- * This matcher always evaluates to true.
- */
- public static <T> org.hamcrest.Matcher<T> anything() {
- return org.hamcrest.core.IsAnything.anything();
- }
-
- /**
- * This matcher always evaluates to true.
- *
- * @param description A meaningful string used when describing itself.
- */
- public static <T> org.hamcrest.Matcher<T> anything(java.lang.String description) {
- return org.hamcrest.core.IsAnything.anything(description);
- }
-
- /**
- * This matcher always evaluates to true. With type inference.
- */
- public static <T> org.hamcrest.Matcher<T> any(java.lang.Class<T> type) {
- return org.hamcrest.core.IsAnything.any(type);
- }
-
- /**
- * Matches if value is null.
- */
- public static <T> org.hamcrest.Matcher<T> nullValue() {
- return org.hamcrest.core.IsNull.nullValue();
- }
-
- /**
- * Matches if value is null. With type inference.
- */
- public static <T> org.hamcrest.Matcher<T> nullValue(java.lang.Class<T> type) {
- return org.hamcrest.core.IsNull.nullValue(type);
- }
-
- /**
- * Matches if value is not null.
- */
- public static <T> org.hamcrest.Matcher<T> notNullValue() {
- return org.hamcrest.core.IsNull.notNullValue();
- }
-
- /**
- * Matches if value is not null. With type inference.
- */
- public static <T> org.hamcrest.Matcher<T> notNullValue(java.lang.Class<T> type) {
- return org.hamcrest.core.IsNull.notNullValue(type);
- }
-
- /**
- * Wraps an existing matcher and overrides the description when it fails.
- */
- public static <T> org.hamcrest.Matcher<T> describedAs(java.lang.String description, org.hamcrest.Matcher<T> matcher, java.lang.Object... values) {
- return org.hamcrest.core.DescribedAs.describedAs(description, matcher, values);
- }
-
- public static <T> org.hamcrest.Matcher<T[]> hasItemInArray(org.hamcrest.Matcher<T> elementMatcher) {
- return org.hamcrest.collection.IsArrayContaining.hasItemInArray(elementMatcher);
- }
-
- public static <T> org.hamcrest.Matcher<T[]> hasItemInArray(T element) {
- return org.hamcrest.collection.IsArrayContaining.hasItemInArray(element);
- }
-
- public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItem(T element) {
- return org.hamcrest.collection.IsCollectionContaining.hasItem(element);
- }
-
- public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItem(org.hamcrest.Matcher<? extends T> elementMatcher) {
- return org.hamcrest.collection.IsCollectionContaining.<T>hasItem(elementMatcher);
- }
-
- public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems(org.hamcrest.Matcher<? extends T>... elementMatchers) {
- return org.hamcrest.collection.IsCollectionContaining.<T>hasItems(elementMatchers);
- }
-
- public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems(T... elements) {
- return org.hamcrest.collection.IsCollectionContaining.hasItems(elements);
- }
-
- public static <K, V> org.hamcrest.Matcher<java.util.Map<K, V>> hasEntry(org.hamcrest.Matcher<K> keyMatcher, org.hamcrest.Matcher<V> valueMatcher) {
- return org.hamcrest.collection.IsMapContaining.hasEntry(keyMatcher, valueMatcher);
- }
-
- public static <K, V> org.hamcrest.Matcher<java.util.Map<K, V>> hasEntry(K key, V value) {
- return org.hamcrest.collection.IsMapContaining.hasEntry(key, value);
- }
-
- public static <K, V> org.hamcrest.Matcher<java.util.Map<K, V>> hasKey(org.hamcrest.Matcher<K> keyMatcher) {
- return org.hamcrest.collection.IsMapContaining.hasKey(keyMatcher);
- }
-
- public static <K, V> org.hamcrest.Matcher<java.util.Map<K, V>> hasKey(K key) {
- return org.hamcrest.collection.IsMapContaining.hasKey(key);
- }
-
- public static <K, V> org.hamcrest.Matcher<java.util.Map<K, V>> hasValue(org.hamcrest.Matcher<V> valueMatcher) {
- return org.hamcrest.collection.IsMapContaining.hasValue(valueMatcher);
- }
-
- public static <K, V> org.hamcrest.Matcher<java.util.Map<K, V>> hasValue(V value) {
- return org.hamcrest.collection.IsMapContaining.hasValue(value);
- }
-
- public static <T> org.hamcrest.Matcher<T> isIn(java.util.Collection<T> collection) {
- return org.hamcrest.collection.IsIn.isIn(collection);
- }
-
- public static <T> org.hamcrest.Matcher<T> isIn(T[] param1) {
- return org.hamcrest.collection.IsIn.isIn(param1);
- }
-
- public static <T> org.hamcrest.Matcher<T> isOneOf(T... elements) {
- return org.hamcrest.collection.IsIn.isOneOf(elements);
- }
-
- public static org.hamcrest.Matcher<java.lang.Double> closeTo(double operand, double error) {
- return org.hamcrest.number.IsCloseTo.closeTo(operand, error);
- }
-
- public static <T extends java.lang.Comparable<T>> org.hamcrest.Matcher<T> greaterThan(T value) {
- return org.hamcrest.number.OrderingComparisons.greaterThan(value);
- }
-
- public static <T extends java.lang.Comparable<T>> org.hamcrest.Matcher<T> greaterThanOrEqualTo(T value) {
- return org.hamcrest.number.OrderingComparisons.greaterThanOrEqualTo(value);
- }
-
- public static <T extends java.lang.Comparable<T>> org.hamcrest.Matcher<T> lessThan(T value) {
- return org.hamcrest.number.OrderingComparisons.lessThan(value);
- }
-
- public static <T extends java.lang.Comparable<T>> org.hamcrest.Matcher<T> lessThanOrEqualTo(T value) {
- return org.hamcrest.number.OrderingComparisons.lessThanOrEqualTo(value);
- }
-
- public static org.hamcrest.Matcher<java.lang.String> equalToIgnoringCase(java.lang.String string) {
- return org.hamcrest.text.IsEqualIgnoringCase.equalToIgnoringCase(string);
- }
-
- public static org.hamcrest.Matcher<java.lang.String> equalToIgnoringWhiteSpace(java.lang.String string) {
- return org.hamcrest.text.IsEqualIgnoringWhiteSpace.equalToIgnoringWhiteSpace(string);
- }
-
- public static org.hamcrest.Matcher<java.lang.String> containsString(java.lang.String substring) {
- return org.hamcrest.text.StringContains.containsString(substring);
- }
-
- public static org.hamcrest.Matcher<java.lang.String> endsWith(java.lang.String substring) {
- return org.hamcrest.text.StringEndsWith.endsWith(substring);
- }
-
- public static org.hamcrest.Matcher<java.lang.String> startsWith(java.lang.String substring) {
- return org.hamcrest.text.StringStartsWith.startsWith(substring);
- }
+ /**
+ * A shortcut to the frequently used <code>is(instanceOf(SomeClass.class))</code>.
+ * For example:
+ * <pre>assertThat(cheese, isA(Cheddar.class))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(instanceOf(Cheddar.class)))</pre>
+ */
+ public static <T> org.hamcrest.Matcher<T> isA(java.lang.Class<T> type) {
+ return org.hamcrest.core.Is.<T>isA(type);
+ }
+
+ /**
+ * Creates a matcher that always matches, regardless of the examined object.
+ */
+ public static org.hamcrest.Matcher<java.lang.Object> anything() {
+ return org.hamcrest.core.IsAnything.anything();
+ }
+
+ /**
+ * Creates a matcher that always matches, regardless of the examined object, but describes
+ * itself with the specified {@link String}.
+ *
+ * @param description
+ * a meaningful {@link String} used when describing itself
+ */
+ public static org.hamcrest.Matcher<java.lang.Object> anything(java.lang.String description) {
+ return org.hamcrest.core.IsAnything.anything(description);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that only matches when a single pass over the
+ * examined {@link Iterable} yields at least one item that is matched by the specified
+ * <code>itemMatcher</code>. Whilst matching, the traversal of the examined {@link Iterable}
+ * will stop as soon as a matching item is found.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), hasItem(startsWith("ba")))</pre>
+ *
+ * @param itemMatcher
+ * the matcher to apply to items provided by the examined {@link Iterable}
+ */
+ public static <T> org.hamcrest.Matcher<java.lang.Iterable<? super T>> hasItem(org.hamcrest.Matcher<? super T> itemMatcher) {
+ return org.hamcrest.core.IsCollectionContaining.<T>hasItem(itemMatcher);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that only matches when a single pass over the
+ * examined {@link Iterable} yields at least one item that is equal to the specified
+ * <code>item</code>. Whilst matching, the traversal of the examined {@link Iterable}
+ * will stop as soon as a matching item is found.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), hasItem("bar"))</pre>
+ *
+ * @param item
+ * the item to compare against the items provided by the examined {@link Iterable}
+ */
+ public static <T> org.hamcrest.Matcher<java.lang.Iterable<? super T>> hasItem(T item) {
+ return org.hamcrest.core.IsCollectionContaining.<T>hasItem(item);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when consecutive passes over the
+ * examined {@link Iterable} yield at least one item that is matched by the corresponding
+ * matcher from the specified <code>itemMatchers</code>. Whilst matching, each traversal of
+ * the examined {@link Iterable} will stop as soon as a matching item is found.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar", "baz"), hasItems(endsWith("z"), endsWith("o")))</pre>
+ *
+ * @param itemMatchers
+ * the matchers to apply to items provided by the examined {@link Iterable}
+ */
+ public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems(org.hamcrest.Matcher<? super T>... itemMatchers) {
+ return org.hamcrest.core.IsCollectionContaining.<T>hasItems(itemMatchers);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when consecutive passes over the
+ * examined {@link Iterable} yield at least one item that is equal to the corresponding
+ * item from the specified <code>items</code>. Whilst matching, each traversal of the
+ * examined {@link Iterable} will stop as soon as a matching item is found.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar", "baz"), hasItems("baz", "foo"))</pre>
+ *
+ * @param items
+ * the items to compare against the items provided by the examined {@link Iterable}
+ */
+ public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems(T... items) {
+ return org.hamcrest.core.IsCollectionContaining.<T>hasItems(items);
+ }
+
+ /**
+ * Creates a matcher that matches when the examined object is logically equal to the specified
+ * <code>operand</code>, as determined by calling the {@link java.lang.Object#equals} method on
+ * the <b>examined</b> object.
+ *
+ * <p>If the specified operand is <code>null</code> then the created matcher will only match if
+ * the examined object's <code>equals</code> method returns <code>true</code> when passed a
+ * <code>null</code> (which would be a violation of the <code>equals</code> contract), unless the
+ * examined object itself is <code>null</code>, in which case the matcher will return a positive
+ * match.</p>
+ *
+ * <p>The created matcher provides a special behaviour when examining <code>Array</code>s, whereby
+ * it will match if both the operand and the examined object are arrays of the same length and
+ * contain items that are equal to each other (according to the above rules) <b>in the same
+ * indexes</b>.</p>
+ * For example:
+ * <pre>
+ * assertThat("foo", equalTo("foo"));
+ * assertThat(new String[] {"foo", "bar"}, equalTo(new String[] {"foo", "bar"}));
+ * </pre>
+ */
+ public static <T> org.hamcrest.Matcher<T> equalTo(T operand) {
+ return org.hamcrest.core.IsEqual.<T>equalTo(operand);
+ }
+
+ /**
+ * Creates an {@link org.hamcrest.core.IsEqual} matcher that does not enforce the values being
+ * compared to be of the same static type.
+ */
+ public static org.hamcrest.Matcher<java.lang.Object> equalToObject(java.lang.Object operand) {
+ return org.hamcrest.core.IsEqual.equalToObject(operand);
+ }
+
+ /**
+ * Creates a matcher that matches when the examined object is an instance of the specified <code>type</code>,
+ * as determined by calling the {@link java.lang.Class#isInstance(Object)} method on that type, passing the
+ * the examined object.
+ *
+ * <p>The created matcher forces a relationship between specified type and the examined object, and should be
+ * used when it is necessary to make generics conform, for example in the JMock clause
+ * <code>with(any(Thing.class))</code></p>
+ * For example:
+ * <pre>assertThat(new Canoe(), instanceOf(Canoe.class));</pre>
+ */
+ public static <T> org.hamcrest.Matcher<T> any(java.lang.Class<T> type) {
+ return org.hamcrest.core.IsInstanceOf.<T>any(type);
+ }
+
+ /**
+ * Creates a matcher that matches when the examined object is an instance of the specified <code>type</code>,
+ * as determined by calling the {@link java.lang.Class#isInstance(Object)} method on that type, passing the
+ * the examined object.
+ *
+ * <p>The created matcher assumes no relationship between specified type and the examined object.</p>
+ * For example:
+ * <pre>assertThat(new Canoe(), instanceOf(Paddlable.class));</pre>
+ */
+ public static <T> org.hamcrest.Matcher<T> instanceOf(java.lang.Class<?> type) {
+ return org.hamcrest.core.IsInstanceOf.<T>instanceOf(type);
+ }
+
+ /**
+ * Creates a matcher that wraps an existing matcher, but inverts the logic by which
+ * it will match.
+ * For example:
+ * <pre>assertThat(cheese, is(not(equalTo(smelly))))</pre>
+ *
+ * @param matcher
+ * the matcher whose sense should be inverted
+ */
+ public static <T> org.hamcrest.Matcher<T> not(org.hamcrest.Matcher<T> matcher) {
+ return org.hamcrest.core.IsNot.<T>not(matcher);
+ }
+
+ /**
+ * A shortcut to the frequently used <code>not(equalTo(x))</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(not(smelly)))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(not(equalTo(smelly))))</pre>
+ *
+ * @param value
+ * the value that any examined object should <b>not</b> equal
+ */
+ public static <T> org.hamcrest.Matcher<T> not(T value) {
+ return org.hamcrest.core.IsNot.<T>not(value);
+ }
+
+ /**
+ * A shortcut to the frequently used <code>not(nullValue())</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(notNullValue()))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(not(nullValue())))</pre>
+ */
+ public static org.hamcrest.Matcher<java.lang.Object> notNullValue() {
+ return org.hamcrest.core.IsNull.notNullValue();
+ }
+
+ /**
+ * A shortcut to the frequently used <code>not(nullValue(X.class)). Accepts a
+ * single dummy argument to facilitate type inference.</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(notNullValue(X.class)))</pre>
+ * instead of:
+ * <pre>assertThat(cheese, is(not(nullValue(X.class))))</pre>
+ *
+ * @param type
+ * dummy parameter used to infer the generic type of the returned matcher
+ */
+ public static <T> org.hamcrest.Matcher<T> notNullValue(java.lang.Class<T> type) {
+ return org.hamcrest.core.IsNull.<T>notNullValue(type);
+ }
+
+ /**
+ * Creates a matcher that matches if examined object is <code>null</code>.
+ * For example:
+ * <pre>assertThat(cheese, is(nullValue())</pre>
+ */
+ public static org.hamcrest.Matcher<java.lang.Object> nullValue() {
+ return org.hamcrest.core.IsNull.nullValue();
+ }
+
+ /**
+ * Creates a matcher that matches if examined object is <code>null</code>. Accepts a
+ * single dummy argument to facilitate type inference.
+ * For example:
+ * <pre>assertThat(cheese, is(nullValue(Cheese.class))</pre>
+ *
+ * @param type
+ * dummy parameter used to infer the generic type of the returned matcher
+ */
+ public static <T> org.hamcrest.Matcher<T> nullValue(java.lang.Class<T> type) {
+ return org.hamcrest.core.IsNull.<T>nullValue(type);
+ }
+
+ /**
+ * Creates a matcher that matches only when the examined object is the same instance as
+ * the specified target object.
+ *
+ * @param target
+ * the target instance against which others should be assessed
+ */
+ public static <T> org.hamcrest.Matcher<T> sameInstance(T target) {
+ return org.hamcrest.core.IsSame.<T>sameInstance(target);
+ }
+
+ /**
+ * Creates a matcher that matches only when the examined object is the same instance as
+ * the specified target object.
+ *
+ * @param target
+ * the target instance against which others should be assessed
+ */
+ public static <T> org.hamcrest.Matcher<T> theInstance(T target) {
+ return org.hamcrest.core.IsSame.<T>theInstance(target);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined {@link String} contains the specified
+ * {@link String} anywhere.
+ * For example:
+ * <pre>assertThat("myStringOfNote", containsString("ring"))</pre>
+ *
+ * @param substring
+ * the substring that the returned matcher will expect to find within any examined string
+ */
+ public static org.hamcrest.Matcher<java.lang.String> containsString(java.lang.String substring) {
+ return org.hamcrest.core.StringContains.containsString(substring);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined {@link String} contains the specified
+ * {@link String} anywhere, ignoring case.
+ * For example:
+ * <pre>assertThat("myStringOfNote", containsString("ring"))</pre>
+ *
+ * @param substring
+ * the substring that the returned matcher will expect to find within any examined string
+ */
+ public static org.hamcrest.Matcher<java.lang.String> containsStringIgnoringCase(java.lang.String substring) {
+ return org.hamcrest.core.StringContains.containsStringIgnoringCase(substring);
+ }
+
+ /**
+ * <p>
+ * Creates a matcher that matches if the examined {@link String} starts with the specified
+ * {@link String}.
+ * </p>
+ * For example:
+ * <pre>assertThat("myStringOfNote", startsWith("my"))</pre>
+ *
+ * @param prefix
+ * the substring that the returned matcher will expect at the start of any examined string
+ */
+ public static org.hamcrest.Matcher<java.lang.String> startsWith(java.lang.String prefix) {
+ return org.hamcrest.core.StringStartsWith.startsWith(prefix);
+ }
+
+ /**
+ * <p>
+ * Creates a matcher that matches if the examined {@link String} starts with the specified
+ * {@link String}, ignoring case
+ * </p>
+ * For example:
+ * <pre>assertThat("myStringOfNote", startsWith("my"))</pre>
+ *
+ * @param prefix
+ * the substring that the returned matcher will expect at the start of any examined string
+ */
+ public static org.hamcrest.Matcher<java.lang.String> startsWithIgnoringCase(java.lang.String prefix) {
+ return org.hamcrest.core.StringStartsWith.startsWithIgnoringCase(prefix);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined {@link String} ends with the specified
+ * {@link String}.
+ * For example:
+ * <pre>assertThat("myStringOfNote", endsWith("Note"))</pre>
+ *
+ * @param suffix
+ * the substring that the returned matcher will expect at the end of any examined string
+ */
+ public static org.hamcrest.Matcher<java.lang.String> endsWith(java.lang.String suffix) {
+ return org.hamcrest.core.StringEndsWith.endsWith(suffix);
+ }
+
+ /**
+ * Creates a matcher that matches if the examined {@link String} ends with the specified
+ * {@link String}, ignoring case.
+ * For example:
+ * <pre>assertThat("myStringOfNote", endsWith("Note"))</pre>
+ *
+ * @param suffix
+ * the substring that the returned matcher will expect at the end of any examined string
+ */
+ public static org.hamcrest.Matcher<java.lang.String> endsWithIgnoringCase(java.lang.String suffix) {
+ return org.hamcrest.core.StringEndsWith.endsWithIgnoringCase(suffix);
+ }
+
+ /**
+ * Creates a matcher that matches arrays whose elements are satisfied by the specified matchers. Matches
+ * positively only if the number of matchers specified is equal to the length of the examined array and
+ * each matcher[i] is satisfied by array[i].
+ * For example:
+ * <pre>assertThat(new Integer[]{1,2,3}, is(array(equalTo(1), equalTo(2), equalTo(3))))</pre>
+ *
+ * @param elementMatchers
+ * the matchers that the elements of examined arrays should satisfy
+ */
+ public static <T> org.hamcrest.collection.IsArray<T> array(org.hamcrest.Matcher<? super T>... elementMatchers) {
+ return org.hamcrest.collection.IsArray.<T>array(elementMatchers);
+ }
+
+ /**
+ * Creates a matcher for arrays that matches when the examined array contains at least one item
+ * that is matched by the specified <code>elementMatcher</code>. Whilst matching, the traversal
+ * of the examined array will stop as soon as a matching element is found.
+ * For example:
+ * <pre>assertThat(new String[] {"foo", "bar"}, hasItemInArray(startsWith("ba")))</pre>
+ *
+ * @param elementMatcher
+ * the matcher to apply to elements in examined arrays
+ */
+ public static <T> org.hamcrest.Matcher<T[]> hasItemInArray(org.hamcrest.Matcher<? super T> elementMatcher) {
+ return org.hamcrest.collection.IsArrayContaining.<T>hasItemInArray(elementMatcher);
+ }
+
+ /**
+ * A shortcut to the frequently used <code>hasItemInArray(equalTo(x))</code>.
+ * For example:
+ * <pre>assertThat(hasItemInArray(x))</pre>
+ * instead of:
+ * <pre>assertThat(hasItemInArray(equalTo(x)))</pre>
+ *
+ * @param element
+ * the element that should be present in examined arrays
+ */
+ public static <T> org.hamcrest.Matcher<T[]> hasItemInArray(T element) {
+ return org.hamcrest.collection.IsArrayContaining.<T>hasItemInArray(element);
+ }
+
+ /**
+ * Creates a matcher for arrays that matches when each item in the examined array is
+ * logically equal to the corresponding item in the specified items. For a positive match,
+ * the examined array must be of the same length as the number of specified items.
+ * For example:
+ * <pre>assertThat(new String[]{"foo", "bar"}, contains("foo", "bar"))</pre>
+ *
+ * @param items
+ * the items that must equal the items within an examined array
+ */
+ public static <E> org.hamcrest.Matcher<E[]> arrayContaining(E... items) {
+ return org.hamcrest.collection.IsArrayContainingInOrder.<E>arrayContaining(items);
+ }
+
+ /**
+ * Creates a matcher for arrays that matches when each item in the examined array satisfies the
+ * corresponding matcher in the specified matchers. For a positive match, the examined array
+ * must be of the same length as the number of specified matchers.
+ * For example:
+ * <pre>assertThat(new String[]{"foo", "bar"}, contains(equalTo("foo"), equalTo("bar")))</pre>
+ *
+ * @param itemMatchers
+ * the matchers that must be satisfied by the items in the examined array
+ */
+ public static <E> org.hamcrest.Matcher<E[]> arrayContaining(org.hamcrest.Matcher<? super E>... itemMatchers) {
+ return org.hamcrest.collection.IsArrayContainingInOrder.<E>arrayContaining(itemMatchers);
+ }
+
+ /**
+ * Creates a matcher for arrays that matches when each item in the examined array satisfies the
+ * corresponding matcher in the specified list of matchers. For a positive match, the examined array
+ * must be of the same length as the specified list of matchers.
+ * For example:
+ * <pre>assertThat(new String[]{"foo", "bar"}, contains(Arrays.asList(equalTo("foo"), equalTo("bar"))))</pre>
+ *
+ * @param itemMatchers
+ * a list of matchers, each of which must be satisfied by the corresponding item in an examined array
+ */
+ public static <E> org.hamcrest.Matcher<E[]> arrayContaining(java.util.List<org.hamcrest.Matcher<? super E>> itemMatchers) {
+ return org.hamcrest.collection.IsArrayContainingInOrder.<E>arrayContaining(itemMatchers);
+ }
+
+ /**
+ * <p>
+ * Creates an order agnostic matcher for arrays that matches when each item in the
+ * examined array satisfies one matcher anywhere in the specified matchers.
+ * For a positive match, the examined array must be of the same length as the number of
+ * specified matchers.
+ * </p>
+ * <p>
+ * N.B. each of the specified matchers will only be used once during a given examination, so be
+ * careful when specifying matchers that may be satisfied by more than one entry in an examined
+ * array.
+ * </p>
+ * <p>
+ * For example:
+ * </p>
+ * <pre>assertThat(new String[]{"foo", "bar"}, arrayContainingInAnyOrder(equalTo("bar"), equalTo("foo")))</pre>
+ *
+ * @param itemMatchers
+ * a list of matchers, each of which must be satisfied by an entry in an examined array
+ */
+ public static <E> org.hamcrest.Matcher<E[]> arrayContainingInAnyOrder(org.hamcrest.Matcher<? super E>... itemMatchers) {
+ return org.hamcrest.collection.IsArrayContainingInAnyOrder.<E>arrayContainingInAnyOrder(itemMatchers);
+ }
+
+ /**
+ * <p>
+ * Creates an order agnostic matcher for arrays that matches when each item in the
+ * examined array satisfies one matcher anywhere in the specified collection of matchers.
+ * For a positive match, the examined array must be of the same length as the specified collection
+ * of matchers.
+ * </p>
+ * <p>
+ * N.B. each matcher in the specified collection will only be used once during a given
+ * examination, so be careful when specifying matchers that may be satisfied by more than
+ * one entry in an examined array.
+ * </p>
+ * <p>
+ * For example:
+ * </p>
+ * <pre>assertThat(new String[]{"foo", "bar"}, arrayContainingInAnyOrder(Arrays.asList(equalTo("bar"), equalTo("foo"))))</pre>
+ *
+ * @param itemMatchers
+ * a list of matchers, each of which must be satisfied by an item provided by an examined array
+ */
+ public static <E> org.hamcrest.Matcher<E[]> arrayContainingInAnyOrder(java.util.Collection<org.hamcrest.Matcher<? super E>> itemMatchers) {
+ return org.hamcrest.collection.IsArrayContainingInAnyOrder.<E>arrayContainingInAnyOrder(itemMatchers);
+ }
+
+ /**
+ * <p>Creates an order agnostic matcher for arrays that matches when each item in the
+ * examined array is logically equal to one item anywhere in the specified items.
+ * For a positive match, the examined array must be of the same length as the number of
+ * specified items.
+ * </p>
+ * <p>N.B. each of the specified items will only be used once during a given examination, so be
+ * careful when specifying items that may be equal to more than one entry in an examined
+ * array.
+ * </p>
+ * <p>
+ * For example:
+ * </p>
+ * <pre>assertThat(new String[]{"foo", "bar"}, containsInAnyOrder("bar", "foo"))</pre>
+ *
+ * @param items
+ * the items that must equal the entries of an examined array, in any order
+ */
+ public static <E> org.hamcrest.Matcher<E[]> arrayContainingInAnyOrder(E... items) {
+ return org.hamcrest.collection.IsArrayContainingInAnyOrder.<E>arrayContainingInAnyOrder(items);
+ }
+
+ /**
+ * Creates a matcher for arrays that matches when the <code>length</code> of the array
+ * satisfies the specified matcher.
+ * For example:
+ * <pre>assertThat(new String[]{"foo", "bar"}, arrayWithSize(equalTo(2)))</pre>
+ *
+ * @param sizeMatcher
+ * a matcher for the length of an examined array
+ */
+ public static <E> org.hamcrest.Matcher<E[]> arrayWithSize(org.hamcrest.Matcher<? super java.lang.Integer> sizeMatcher) {
+ return org.hamcrest.collection.IsArrayWithSize.<E>arrayWithSize(sizeMatcher);
+ }
+
+ /**
+ * Creates a matcher for arrays that matches when the <code>length</code> of the array
+ * equals the specified <code>size</code>.
+ * For example:
+ * <pre>assertThat(new String[]{"foo", "bar"}, arrayWithSize(2))</pre>
+ *
+ * @param size
+ * the length that an examined array must have for a positive match
+ */
+ public static <E> org.hamcrest.Matcher<E[]> arrayWithSize(int size) {
+ return org.hamcrest.collection.IsArrayWithSize.<E>arrayWithSize(size);
+ }
+
+ /**
+ * Creates a matcher for arrays that matches when the <code>length</code> of the array
+ * is zero.
+ * For example:
+ * <pre>assertThat(new String[0], emptyArray())</pre>
+ */
+ public static <E> org.hamcrest.Matcher<E[]> emptyArray() {
+ return org.hamcrest.collection.IsArrayWithSize.<E>emptyArray();
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Map}s that matches when the <code>size()</code> method returns
+ * a value that satisfies the specified matcher.
+ * For example:
+ * <pre>assertThat(myMap, is(aMapWithSize(equalTo(2))))</pre>
+ *
+ * @param sizeMatcher
+ * a matcher for the size of an examined {@link java.util.Map}
+ */
+ public static <K, V> org.hamcrest.Matcher<java.util.Map<? extends K,? extends V>> aMapWithSize(org.hamcrest.Matcher<? super java.lang.Integer> sizeMatcher) {
+ return org.hamcrest.collection.IsMapWithSize.<K,V>aMapWithSize(sizeMatcher);
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Map}s that matches when the <code>size()</code> method returns
+ * a value equal to the specified <code>size</code>.
+ * For example:
+ * <pre>assertThat(myMap, is(aMapWithSize(2)))</pre>
+ *
+ * @param size
+ * the expected size of an examined {@link java.util.Map}
+ */
+ public static <K, V> org.hamcrest.Matcher<java.util.Map<? extends K,? extends V>> aMapWithSize(int size) {
+ return org.hamcrest.collection.IsMapWithSize.<K,V>aMapWithSize(size);
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Map}s that matches when the <code>size()</code> method returns
+ * zero.
+ * For example:
+ * <pre>assertThat(myMap, is(anEmptyMap()))</pre>
+ */
+ public static <K, V> org.hamcrest.Matcher<java.util.Map<? extends K,? extends V>> anEmptyMap() {
+ return org.hamcrest.collection.IsMapWithSize.<K,V>anEmptyMap();
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Collection}s that matches when the <code>size()</code> method returns
+ * a value that satisfies the specified matcher.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), hasSize(equalTo(2)))</pre>
+ *
+ * @param sizeMatcher
+ * a matcher for the size of an examined {@link java.util.Collection}
+ */
+ public static <E> org.hamcrest.Matcher<java.util.Collection<? extends E>> hasSize(org.hamcrest.Matcher<? super java.lang.Integer> sizeMatcher) {
+ return org.hamcrest.collection.IsCollectionWithSize.<E>hasSize(sizeMatcher);
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Collection}s that matches when the <code>size()</code> method returns
+ * a value equal to the specified <code>size</code>.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), hasSize(2))</pre>
+ *
+ * @param size
+ * the expected size of an examined {@link java.util.Collection}
+ */
+ public static <E> org.hamcrest.Matcher<java.util.Collection<? extends E>> hasSize(int size) {
+ return org.hamcrest.collection.IsCollectionWithSize.<E>hasSize(size);
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Collection}s matching examined collections whose <code>isEmpty</code>
+ * method returns <code>true</code>.
+ * For example:
+ * <pre>assertThat(new ArrayList&lt;String&gt;(), is(empty()))</pre>
+ */
+ public static <E> org.hamcrest.Matcher<java.util.Collection<? extends E>> empty() {
+ return org.hamcrest.collection.IsEmptyCollection.<E>empty();
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Collection}s matching examined collections whose <code>isEmpty</code>
+ * method returns <code>true</code>.
+ * For example:
+ * <pre>assertThat(new ArrayList&lt;String&gt;(), is(emptyCollectionOf(String.class)))</pre>
+ *
+ * @param unusedToForceReturnType
+ * the type of the collection's content
+ */
+ public static <E> org.hamcrest.Matcher<java.util.Collection<E>> emptyCollectionOf(java.lang.Class<E> unusedToForceReturnType) {
+ return org.hamcrest.collection.IsEmptyCollection.<E>emptyCollectionOf(unusedToForceReturnType);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s matching examined iterables that yield no items.
+ * For example:
+ * <pre>assertThat(new ArrayList&lt;String&gt;(), is(emptyIterable()))</pre>
+ */
+ public static <E> org.hamcrest.Matcher<java.lang.Iterable<? extends E>> emptyIterable() {
+ return org.hamcrest.collection.IsEmptyIterable.<E>emptyIterable();
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s matching examined iterables that yield no items.
+ * For example:
+ * <pre>assertThat(new ArrayList&lt;String&gt;(), is(emptyIterableOf(String.class)))</pre>
+ *
+ * @param unusedToForceReturnType
+ * the type of the iterable's content
+ */
+ public static <E> org.hamcrest.Matcher<java.lang.Iterable<E>> emptyIterableOf(java.lang.Class<E> unusedToForceReturnType) {
+ return org.hamcrest.collection.IsEmptyIterable.<E>emptyIterableOf(unusedToForceReturnType);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields a series of items, each logically equal to the
+ * corresponding item in the specified items. For a positive match, the examined iterable
+ * must be of the same length as the number of specified items.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), contains("foo", "bar"))</pre>
+ *
+ * @param items
+ * the items that must equal the items provided by an examined {@link Iterable}
+ */
+ public static <E> org.hamcrest.Matcher<java.lang.Iterable<? extends E>> contains(E... items) {
+ return org.hamcrest.collection.IsIterableContainingInOrder.<E>contains(items);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields a single item that satisfies the specified matcher.
+ * For a positive match, the examined iterable must only yield one item.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo"), contains(equalTo("foo")))</pre>
+ *
+ * @param itemMatcher
+ * the matcher that must be satisfied by the single item provided by an
+ * examined {@link Iterable}
+ */
+ public static <E> org.hamcrest.Matcher<java.lang.Iterable<? extends E>> contains(org.hamcrest.Matcher<? super E> itemMatcher) {
+ return org.hamcrest.collection.IsIterableContainingInOrder.<E>contains(itemMatcher);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields a series of items, each satisfying the corresponding
+ * matcher in the specified matchers. For a positive match, the examined iterable
+ * must be of the same length as the number of specified matchers.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), contains(equalTo("foo"), equalTo("bar")))</pre>
+ *
+ * @param itemMatchers
+ * the matchers that must be satisfied by the items provided by an examined {@link Iterable}
+ */
+ public static <E> org.hamcrest.Matcher<java.lang.Iterable<? extends E>> contains(org.hamcrest.Matcher<? super E>... itemMatchers) {
+ return org.hamcrest.collection.IsIterableContainingInOrder.<E>contains(itemMatchers);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields a series of items, each satisfying the corresponding
+ * matcher in the specified list of matchers. For a positive match, the examined iterable
+ * must be of the same length as the specified list of matchers.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), contains(Arrays.asList(equalTo("foo"), equalTo("bar"))))</pre>
+ *
+ * @param itemMatchers
+ * a list of matchers, each of which must be satisfied by the corresponding item provided by
+ * an examined {@link Iterable}
+ */
+ public static <E> org.hamcrest.Matcher<java.lang.Iterable<? extends E>> contains(java.util.List<org.hamcrest.Matcher<? super E>> itemMatchers) {
+ return org.hamcrest.collection.IsIterableContainingInOrder.<E>contains(itemMatchers);
+ }
+
+ /**
+ * <p>
+ * Creates an order agnostic matcher for {@link Iterable}s that matches when a single pass over
+ * the examined {@link Iterable} yields a series of items, each satisfying one matcher anywhere
+ * in the specified matchers. For a positive match, the examined iterable must be of the same
+ * length as the number of specified matchers.
+ * </p>
+ * <p>
+ * N.B. each of the specified matchers will only be used once during a given examination, so be
+ * careful when specifying matchers that may be satisfied by more than one entry in an examined
+ * iterable.
+ * </p>
+ * <p>
+ * For example:
+ * </p>
+ * <pre>assertThat(Arrays.asList("foo", "bar"), containsInAnyOrder(equalTo("bar"), equalTo("foo")))</pre>
+ *
+ * @param itemMatchers
+ * a list of matchers, each of which must be satisfied by an item provided by an examined {@link Iterable}
+ */
+ public static <T> org.hamcrest.Matcher<java.lang.Iterable<? extends T>> containsInAnyOrder(org.hamcrest.Matcher<? super T>... itemMatchers) {
+ return org.hamcrest.collection.IsIterableContainingInAnyOrder.<T>containsInAnyOrder(itemMatchers);
+ }
+
+ /**
+ * <p>
+ * Creates an order agnostic matcher for {@link Iterable}s that matches when a single pass over
+ * the examined {@link Iterable} yields a series of items, each logically equal to one item
+ * anywhere in the specified items. For a positive match, the examined iterable
+ * must be of the same length as the number of specified items.
+ * </p>
+ * <p>
+ * N.B. each of the specified items will only be used once during a given examination, so be
+ * careful when specifying items that may be equal to more than one entry in an examined
+ * iterable.
+ * </p>
+ * <p>
+ * For example:
+ * </p>
+ * <pre>assertThat(Arrays.asList("foo", "bar"), containsInAnyOrder("bar", "foo"))</pre>
+ *
+ * @param items
+ * the items that must equal the items provided by an examined {@link Iterable} in any order
+ */
+ public static <T> org.hamcrest.Matcher<java.lang.Iterable<? extends T>> containsInAnyOrder(T... items) {
+ return org.hamcrest.collection.IsIterableContainingInAnyOrder.<T>containsInAnyOrder(items);
+ }
+
+ /**
+ * <p>
+ * Creates an order agnostic matcher for {@link Iterable}s that matches when a single pass over
+ * the examined {@link Iterable} yields a series of items, each satisfying one matcher anywhere
+ * in the specified collection of matchers. For a positive match, the examined iterable
+ * must be of the same length as the specified collection of matchers.
+ * </p>
+ * <p>
+ * N.B. each matcher in the specified collection will only be used once during a given
+ * examination, so be careful when specifying matchers that may be satisfied by more than
+ * one entry in an examined iterable.
+ * </p>
+ * <p>For example:</p>
+ * <pre>assertThat(Arrays.asList("foo", "bar"), containsInAnyOrder(Arrays.asList(equalTo("bar"), equalTo("foo"))))</pre>
+ *
+ * @param itemMatchers
+ * a list of matchers, each of which must be satisfied by an item provided by an examined {@link Iterable}
+ */
+ public static <T> org.hamcrest.Matcher<java.lang.Iterable<? extends T>> containsInAnyOrder(java.util.Collection<org.hamcrest.Matcher<? super T>> itemMatchers) {
+ return org.hamcrest.collection.IsIterableContainingInAnyOrder.<T>containsInAnyOrder(itemMatchers);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields a series of items, that contains items logically equal to the
+ * corresponding item in the specified items, in the same relative order
+ * For example:
+ * <pre>assertThat(Arrays.asList("a", "b", "c", "d", "e"), containsInRelativeOrder("b", "d"))</pre>
+ *
+ * @param items
+ * the items that must be contained within items provided by an examined {@link Iterable} in the same relative order
+ */
+ public static <E> org.hamcrest.Matcher<java.lang.Iterable<? extends E>> containsInRelativeOrder(E... items) {
+ return org.hamcrest.collection.IsIterableContainingInRelativeOrder.<E>containsInRelativeOrder(items);
+ }
- public static <T> org.hamcrest.Matcher<T> hasToString(org.hamcrest.Matcher<java.lang.String> toStringMatcher) {
- return org.hamcrest.object.HasToString.hasToString(toStringMatcher);
- }
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields a series of items, that each satisfying the corresponding
+ * matcher in the specified matchers, in the same relative order.
+ * For example:
+ * <pre>assertThat(Arrays.asList("a", "b", "c", "d", "e"), containsInRelativeOrder(equalTo("b"), equalTo("d")))</pre>
+ *
+ * @param itemMatchers
+ * the matchers that must be satisfied by the items provided by an examined {@link Iterable} in the same relative order
+ */
+ public static <E> org.hamcrest.Matcher<java.lang.Iterable<? extends E>> containsInRelativeOrder(org.hamcrest.Matcher<? super E>... itemMatchers) {
+ return org.hamcrest.collection.IsIterableContainingInRelativeOrder.<E>containsInRelativeOrder(itemMatchers);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields a series of items, that contains items satisfying the corresponding
+ * matcher in the specified list of matchers, in the same relative order.
+ * For example:
+ * <pre>assertThat(Arrays.asList("a", "b", "c", "d", "e"), contains(Arrays.asList(equalTo("b"), equalTo("d"))))</pre>
+ *
+ * @param itemMatchers
+ * a list of matchers, each of which must be satisfied by the items provided by
+ * an examined {@link Iterable} in the same relative order
+ */
+ public static <E> org.hamcrest.Matcher<java.lang.Iterable<? extends E>> containsInRelativeOrder(java.util.List<org.hamcrest.Matcher<? super E>> itemMatchers) {
+ return org.hamcrest.collection.IsIterableContainingInRelativeOrder.<E>containsInRelativeOrder(itemMatchers);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields an item count that satisfies the specified
+ * matcher.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), iterableWithSize(equalTo(2)))</pre>
+ *
+ * @param sizeMatcher
+ * a matcher for the number of items that should be yielded by an examined {@link Iterable}
+ */
+ public static <E> org.hamcrest.Matcher<java.lang.Iterable<E>> iterableWithSize(org.hamcrest.Matcher<? super java.lang.Integer> sizeMatcher) {
+ return org.hamcrest.collection.IsIterableWithSize.<E>iterableWithSize(sizeMatcher);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields an item count that is equal to the specified
+ * <code>size</code> argument.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), iterableWithSize(2))</pre>
+ *
+ * @param size
+ * the number of items that should be yielded by an examined {@link Iterable}
+ */
+ public static <E> org.hamcrest.Matcher<java.lang.Iterable<E>> iterableWithSize(int size) {
+ return org.hamcrest.collection.IsIterableWithSize.<E>iterableWithSize(size);
+ }
- public static <T> org.hamcrest.Matcher<java.lang.Class<?>> typeCompatibleWith(java.lang.Class<T> baseType) {
- return org.hamcrest.object.IsCompatibleType.typeCompatibleWith(baseType);
- }
+ /**
+ * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains
+ * at least one entry whose key satisfies the specified <code>keyMatcher</code> <b>and</b> whose
+ * value satisfies the specified <code>valueMatcher</code>.
+ * For example:
+ * <pre>assertThat(myMap, hasEntry(equalTo("bar"), equalTo("foo")))</pre>
+ *
+ * @param keyMatcher
+ * the key matcher that, in combination with the valueMatcher, must be satisfied by at least one entry
+ * @param valueMatcher
+ * the value matcher that, in combination with the keyMatcher, must be satisfied by at least one entry
+ */
+ public static <K, V> org.hamcrest.Matcher<java.util.Map<? extends K,? extends V>> hasEntry(org.hamcrest.Matcher<? super K> keyMatcher, org.hamcrest.Matcher<? super V> valueMatcher) {
+ return org.hamcrest.collection.IsMapContaining.<K,V>hasEntry(keyMatcher, valueMatcher);
+ }
- /**
- * Constructs an IsEventFrom Matcher that returns true for any object
- * derived from <var>eventClass</var> announced by <var>source</var>.
- */
- public static org.hamcrest.Matcher<java.util.EventObject> eventFrom(java.lang.Class<? extends java.util.EventObject> eventClass, java.lang.Object source) {
- return org.hamcrest.object.IsEventFrom.eventFrom(eventClass, source);
- }
+ /**
+ * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains
+ * at least one entry whose key equals the specified <code>key</code> <b>and</b> whose value equals the
+ * specified <code>value</code>.
+ * For example:
+ * <pre>assertThat(myMap, hasEntry("bar", "foo"))</pre>
+ *
+ * @param key
+ * the key that, in combination with the value, must be describe at least one entry
+ * @param value
+ * the value that, in combination with the key, must be describe at least one entry
+ */
+ public static <K, V> org.hamcrest.Matcher<java.util.Map<? extends K,? extends V>> hasEntry(K key, V value) {
+ return org.hamcrest.collection.IsMapContaining.<K,V>hasEntry(key, value);
+ }
- /**
- * Constructs an IsEventFrom Matcher that returns true for any object
- * derived from {@link java.util.EventObject} announced by <var>source
- * </var>.
- */
- public static org.hamcrest.Matcher<java.util.EventObject> eventFrom(java.lang.Object source) {
- return org.hamcrest.object.IsEventFrom.eventFrom(source);
- }
-
- /* android-changed REMOVE
- public static <T> org.hamcrest.Matcher<T> hasProperty(java.lang.String propertyName) {
- return org.hamcrest.beans.HasProperty.hasProperty(propertyName);
- }
-
- public static <T> org.hamcrest.Matcher<T> hasProperty(java.lang.String propertyName, org.hamcrest.Matcher value) {
- return org.hamcrest.beans.HasPropertyWithValue.hasProperty(propertyName, value);
- }
- */
-
- public static org.hamcrest.Matcher<org.w3c.dom.Node> hasXPath(java.lang.String xPath, org.hamcrest.Matcher<java.lang.String> valueMatcher) {
- return org.hamcrest.xml.HasXPath.hasXPath(xPath, valueMatcher);
- }
-
- public static org.hamcrest.Matcher<org.w3c.dom.Node> hasXPath(java.lang.String xPath) {
- return org.hamcrest.xml.HasXPath.hasXPath(xPath);
- }
+ /**
+ * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains
+ * at least one key that satisfies the specified matcher.
+ * For example:
+ * <pre>assertThat(myMap, hasKey(equalTo("bar")))</pre>
+ *
+ * @param keyMatcher
+ * the matcher that must be satisfied by at least one key
+ */
+ public static <K> org.hamcrest.Matcher<java.util.Map<? extends K,?>> hasKey(org.hamcrest.Matcher<? super K> keyMatcher) {
+ return org.hamcrest.collection.IsMapContaining.<K>hasKey(keyMatcher);
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains
+ * at least one key that is equal to the specified key.
+ * For example:
+ * <pre>assertThat(myMap, hasKey("bar"))</pre>
+ *
+ * @param key
+ * the key that satisfying maps must contain
+ */
+ public static <K> org.hamcrest.Matcher<java.util.Map<? extends K,?>> hasKey(K key) {
+ return org.hamcrest.collection.IsMapContaining.<K>hasKey(key);
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains
+ * at least one value that satisfies the specified valueMatcher.
+ * For example:
+ * <pre>assertThat(myMap, hasValue(equalTo("foo")))</pre>
+ *
+ * @param valueMatcher
+ * the matcher that must be satisfied by at least one value
+ */
+ public static <V> org.hamcrest.Matcher<java.util.Map<?,? extends V>> hasValue(org.hamcrest.Matcher<? super V> valueMatcher) {
+ return org.hamcrest.collection.IsMapContaining.<V>hasValue(valueMatcher);
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains
+ * at least one value that is equal to the specified value.
+ * For example:
+ * <pre>assertThat(myMap, hasValue("foo"))</pre>
+ *
+ * @param value
+ * the value that satisfying maps must contain
+ */
+ public static <V> org.hamcrest.Matcher<java.util.Map<?,? extends V>> hasValue(V value) {
+ return org.hamcrest.collection.IsMapContaining.<V>hasValue(value);
+ }
+
+ /**
+ * Creates a matcher that matches when the examined object is found within the
+ * specified collection.
+ * For example:
+ * <pre>assertThat("foo", is(in(Arrays.asList("bar", "foo"))))</pre>
+ *
+ * @param collection
+ * the collection in which matching items must be found
+ */
+ public static <T> org.hamcrest.Matcher<T> in(java.util.Collection<T> collection) {
+ return org.hamcrest.collection.IsIn.<T>in(collection);
+ }
+
+ /**
+ * Creates a matcher that matches when the examined object is found within the
+ * specified array.
+ * For example:
+ * <pre>assertThat("foo", is(in(new String[]{"bar", "foo"})))</pre>
+ *
+ * @param elements
+ * the array in which matching items must be found
+ */
+ public static <T> org.hamcrest.Matcher<T> in(T[] elements) {
+ return org.hamcrest.collection.IsIn.<T>in(elements);
+ }
+
+ /**
+ * Creates a matcher that matches when the examined object is found within the
+ * specified collection.
+ * For example:
+ * <pre>assertThat("foo", isIn(Arrays.asList("bar", "foo")))</pre>
+ *
+ * @deprecated use is(in(...)) instead
+ * @param collection
+ * the collection in which matching items must be found
+ */
+ public static <T> org.hamcrest.Matcher<T> isIn(java.util.Collection<T> collection) {
+ return org.hamcrest.collection.IsIn.<T>isIn(collection);
+ }
+
+ /**
+ * Creates a matcher that matches when the examined object is found within the
+ * specified array.
+ * For example:
+ * <pre>assertThat("foo", isIn(new String[]{"bar", "foo"}))</pre>
+ *
+ * @deprecated use is(in(...)) instead
+ * @param elements
+ * the array in which matching items must be found
+ */
+ public static <T> org.hamcrest.Matcher<T> isIn(T[] elements) {
+ return org.hamcrest.collection.IsIn.<T>isIn(elements);
+ }
+
+ /**
+ * Creates a matcher that matches when the examined object is equal to one of the
+ * specified elements.
+ * For example:
+ * <pre>assertThat("foo", isOneOf("bar", "foo"))</pre>
+ *
+ * @deprecated use is(oneOf(...)) instead
+ * @param elements
+ * the elements amongst which matching items will be found
+ */
+ public static <T> org.hamcrest.Matcher<T> isOneOf(T... elements) {
+ return org.hamcrest.collection.IsIn.<T>isOneOf(elements);
+ }
+
+ /**
+ * Creates a matcher that matches when the examined object is equal to one of the
+ * specified elements.
+ * For example:
+ * <pre>assertThat("foo", is(oneOf("bar", "foo")))</pre>
+ *
+ * @param elements
+ * the elements amongst which matching items will be found
+ */
+ public static <T> org.hamcrest.Matcher<T> oneOf(T... elements) {
+ return org.hamcrest.collection.IsIn.<T>oneOf(elements);
+ }
+
+ /**
+ * Creates a matcher of {@link Double}s that matches when an examined double is equal
+ * to the specified <code>operand</code>, within a range of +/- <code>error</code>.
+ * For example:
+ * <pre>assertThat(1.03, is(closeTo(1.0, 0.03)))</pre>
+ *
+ * @param operand
+ * the expected value of matching doubles
+ * @param error
+ * the delta (+/-) within which matches will be allowed
+ */
+ public static org.hamcrest.Matcher<java.lang.Double> closeTo(double operand, double error) {
+ return org.hamcrest.number.IsCloseTo.closeTo(operand, error);
+ }
+
+ /**
+ * Creates a matcher of {@link Double}s that matches when an examined double is not a number.
+ * For example:
+ * <pre>assertThat(Double.NaN, is(notANumber()))</pre>
+ */
+ public static org.hamcrest.Matcher<java.lang.Double> notANumber() {
+ return org.hamcrest.number.IsNaN.notANumber();
+ }
+
+ /**
+ * Creates a matcher of {@link java.math.BigDecimal}s that matches when an examined BigDecimal is equal
+ * to the specified <code>operand</code>, within a range of +/- <code>error</code>. The comparison for equality
+ * is done by BigDecimals {@link java.math.BigDecimal#compareTo(java.math.BigDecimal)} method.
+ * For example:
+ * <pre>assertThat(new BigDecimal("1.03"), is(closeTo(new BigDecimal("1.0"), new BigDecimal("0.03"))))</pre>
+ *
+ * @param operand
+ * the expected value of matching BigDecimals
+ * @param error
+ * the delta (+/-) within which matches will be allowed
+ */
+ public static org.hamcrest.Matcher<java.math.BigDecimal> closeTo(java.math.BigDecimal operand, java.math.BigDecimal error) {
+ return org.hamcrest.number.BigDecimalCloseTo.closeTo(operand, error);
+ }
+
+ /**
+ * Creates a matcher of {@link Comparable} object that matches when the examined object is
+ * equal to the specified value, as reported by the <code>compareTo</code> method of the
+ * <b>examined</b> object.
+ * For example:
+ * <pre>assertThat(1, comparesEqualTo(1))</pre>
+ *
+ * @param value the value which, when passed to the compareTo method of the examined object, should return zero
+ */
+ public static <T extends java.lang.Comparable<T>> org.hamcrest.Matcher<T> comparesEqualTo(T value) {
+ return org.hamcrest.number.OrderingComparison.<T>comparesEqualTo(value);
+ }
+
+ /**
+ * Creates a matcher of {@link Comparable} object that matches when the examined object is
+ * greater than the specified value, as reported by the <code>compareTo</code> method of the
+ * <b>examined</b> object.
+ * For example:
+ * <pre>assertThat(2, greaterThan(1))</pre>
+ *
+ * @param value the value which, when passed to the compareTo method of the examined object, should return greater
+ * than zero
+ */
+ public static <T extends java.lang.Comparable<T>> org.hamcrest.Matcher<T> greaterThan(T value) {
+ return org.hamcrest.number.OrderingComparison.<T>greaterThan(value);
+ }
+
+ /**
+ * Creates a matcher of {@link Comparable} object that matches when the examined object is
+ * greater than or equal to the specified value, as reported by the <code>compareTo</code> method
+ * of the <b>examined</b> object.
+ * For example:
+ * <pre>assertThat(1, greaterThanOrEqualTo(1))</pre>
+ *
+ * @param value the value which, when passed to the compareTo method of the examined object, should return greater
+ * than or equal to zero
+ */
+ public static <T extends java.lang.Comparable<T>> org.hamcrest.Matcher<T> greaterThanOrEqualTo(T value) {
+ return org.hamcrest.number.OrderingComparison.<T>greaterThanOrEqualTo(value);
+ }
+
+ /**
+ * Creates a matcher of {@link Comparable} object that matches when the examined object is
+ * less than the specified value, as reported by the <code>compareTo</code> method of the
+ * <b>examined</b> object.
+ * For example:
+ * <pre>assertThat(1, lessThan(2))</pre>
+ *
+ * @param value the value which, when passed to the compareTo method of the examined object, should return less
+ * than zero
+ */
+ public static <T extends java.lang.Comparable<T>> org.hamcrest.Matcher<T> lessThan(T value) {
+ return org.hamcrest.number.OrderingComparison.<T>lessThan(value);
+ }
+
+ /**
+ * Creates a matcher of {@link Comparable} object that matches when the examined object is
+ * less than or equal to the specified value, as reported by the <code>compareTo</code> method
+ * of the <b>examined</b> object.
+ * For example:
+ * <pre>assertThat(1, lessThanOrEqualTo(1))</pre>
+ *
+ * @param value the value which, when passed to the compareTo method of the examined object, should return less
+ * than or equal to zero
+ */
+ public static <T extends java.lang.Comparable<T>> org.hamcrest.Matcher<T> lessThanOrEqualTo(T value) {
+ return org.hamcrest.number.OrderingComparison.<T>lessThanOrEqualTo(value);
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string is equal to
+ * the specified expectedString, ignoring case.
+ * For example:
+ * <pre>assertThat("Foo", equalToIgnoringCase("FOO"))</pre>
+ *
+ * @param expectedString
+ * the expected value of matched strings
+ */
+ public static org.hamcrest.Matcher<java.lang.String> equalToIgnoringCase(java.lang.String expectedString) {
+ return org.hamcrest.text.IsEqualIgnoringCase.equalToIgnoringCase(expectedString);
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string is equal to
+ * the specified expectedString, when whitespace differences are (mostly) ignored. To be
+ * exact, the following whitespace rules are applied:
+ * <ul>
+ * <li>all leading and trailing whitespace of both the expectedString and the examined string are ignored</li>
+ * <li>any remaining whitespace, appearing within either string, is collapsed to a single space before comparison</li>
+ * </ul>
+ * For example:
+ * <pre>assertThat(" my\tfoo bar ", equalToIgnoringWhiteSpace(" my foo bar"))</pre>
+ *
+ * @param expectedString
+ * the expected value of matched strings
+ */
+ public static org.hamcrest.Matcher<java.lang.String> equalToIgnoringWhiteSpace(java.lang.String expectedString) {
+ return org.hamcrest.text.IsEqualIgnoringWhiteSpace.equalToIgnoringWhiteSpace(expectedString);
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string is <code>null</code>, or
+ * has zero length.
+ * For example:
+ * <pre>assertThat(((String)null), is(emptyOrNullString()))</pre>
+ */
+ public static org.hamcrest.Matcher<java.lang.String> emptyOrNullString() {
+ return org.hamcrest.text.IsEmptyString.emptyOrNullString();
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string has zero length.
+ * For example:
+ * <pre>assertThat("", is(emptyString()))</pre>
+ */
+ public static org.hamcrest.Matcher<java.lang.String> emptyString() {
+ return org.hamcrest.text.IsEmptyString.emptyString();
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string is <code>null</code>, or
+ * has zero length.
+ * For example:
+ * <pre>assertThat(((String)null), isEmptyOrNullString())</pre>
+ *
+ * @deprecated use is(emptyOrNullString()) instead
+ */
+ public static org.hamcrest.Matcher<java.lang.String> isEmptyOrNullString() {
+ return org.hamcrest.text.IsEmptyString.isEmptyOrNullString();
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string has zero length.
+ * For example:
+ * <pre>assertThat("", isEmptyString())</pre>
+ *
+ * @deprecated use is(emptyString()) instead
+ */
+ public static org.hamcrest.Matcher<java.lang.String> isEmptyString() {
+ return org.hamcrest.text.IsEmptyString.isEmptyString();
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string is <code>null</code>, or
+ * contains zero or more whitespace characters and nothing else.
+ * For example:
+ * <pre>assertThat(((String)null), is(blankOrNullString()))</pre>
+ */
+ public static org.hamcrest.Matcher<java.lang.String> blankOrNullString() {
+ return org.hamcrest.text.IsBlankString.blankOrNullString();
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string contains
+ * zero or more whitespace characters and nothing else.
+ * For example:
+ * <pre>assertThat(" ", is(blankString()))</pre>
+ */
+ public static org.hamcrest.Matcher<java.lang.String> blankString() {
+ return org.hamcrest.text.IsBlankString.blankString();
+ }
+
+ /**
+ * Creates a matcher of {@link java.lang.String} that matches when the examined string
+ * exactly matches the given {@link java.util.regex.Pattern}.
+ */
+ public static org.hamcrest.Matcher<java.lang.String> matchesPattern(java.util.regex.Pattern pattern) {
+ return org.hamcrest.text.MatchesPattern.matchesPattern(pattern);
+ }
+
+ /**
+ * Creates a matcher of {@link java.lang.String} that matches when the examined string
+ * exactly matches the given regular expression, treated as a {@link java.util.regex.Pattern}.
+ */
+ public static org.hamcrest.Matcher<java.lang.String> matchesPattern(java.lang.String regex) {
+ return org.hamcrest.text.MatchesPattern.matchesPattern(regex);
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string contains all of
+ * the specified substrings, considering the order of their appearance.
+ * For example:
+ * <pre>assertThat("myfoobarbaz", stringContainsInOrder(Arrays.asList("bar", "foo")))</pre>
+ * fails as "foo" occurs before "bar" in the string "myfoobarbaz"
+ *
+ * @param substrings
+ * the substrings that must be contained within matching strings
+ */
+ public static org.hamcrest.Matcher<java.lang.String> stringContainsInOrder(java.lang.Iterable<java.lang.String> substrings) {
+ return org.hamcrest.text.StringContainsInOrder.stringContainsInOrder(substrings);
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string contains all of
+ * the specified substrings, considering the order of their appearance.
+ * For example:
+ * <pre>assertThat("myfoobarbaz", stringContainsInOrder("bar", "foo"))</pre>
+ * fails as "foo" occurs before "bar" in the string "myfoobarbaz"
+ *
+ * @param substrings
+ * the substrings that must be contained within matching strings
+ */
+ public static org.hamcrest.Matcher<java.lang.String> stringContainsInOrder(java.lang.String... substrings) {
+ return org.hamcrest.text.StringContainsInOrder.stringContainsInOrder(substrings);
+ }
+
+ /**
+ * Creates a matcher that matches any examined object whose <code>toString</code> method
+ * returns a value that satisfies the specified matcher.
+ * For example:
+ * <pre>assertThat(true, hasToString(equalTo("TRUE")))</pre>
+ *
+ * @param toStringMatcher
+ * the matcher used to verify the toString result
+ */
+ public static <T> org.hamcrest.Matcher<T> hasToString(org.hamcrest.Matcher<? super java.lang.String> toStringMatcher) {
+ return org.hamcrest.object.HasToString.<T>hasToString(toStringMatcher);
+ }
+
+ /**
+ * Creates a matcher that matches any examined object whose <code>toString</code> method
+ * returns a value equalTo the specified string.
+ * For example:
+ * <pre>assertThat(true, hasToString("TRUE"))</pre>
+ *
+ * @param expectedToString
+ * the expected toString result
+ */
+ public static <T> org.hamcrest.Matcher<T> hasToString(java.lang.String expectedToString) {
+ return org.hamcrest.object.HasToString.<T>hasToString(expectedToString);
+ }
+
+ /**
+ * Creates a matcher of {@link Class} that matches when the specified baseType is
+ * assignable from the examined class.
+ * For example:
+ * <pre>assertThat(Integer.class, typeCompatibleWith(Number.class))</pre>
+ *
+ * @param baseType
+ * the base class to examine classes against
+ */
+ public static <T> org.hamcrest.Matcher<java.lang.Class<?>> typeCompatibleWith(java.lang.Class<T> baseType) {
+ return org.hamcrest.object.IsCompatibleType.<T>typeCompatibleWith(baseType);
+ }
+
+ /**
+ * Creates a matcher of {@link java.util.EventObject} that matches any object
+ * derived from <var>eventClass</var> announced by <var>source</var>.
+ * For example:
+ * <pre>assertThat(myEvent, is(eventFrom(PropertyChangeEvent.class, myBean)))</pre>
+ *
+ * @param eventClass
+ * the class of the event to match on
+ * @param source
+ * the source of the event
+ */
+ public static org.hamcrest.Matcher<java.util.EventObject> eventFrom(java.lang.Class<? extends java.util.EventObject> eventClass, java.lang.Object source) {
+ return org.hamcrest.object.IsEventFrom.eventFrom(eventClass, source);
+ }
+
+ /**
+ * Creates a matcher of {@link java.util.EventObject} that matches any EventObject
+ * announced by <var>source</var>.
+ * For example:
+ * <pre>assertThat(myEvent, is(eventFrom(myBean)))</pre>
+ *
+ * @param source
+ * the source of the event
+ */
+ public static org.hamcrest.Matcher<java.util.EventObject> eventFrom(java.lang.Object source) {
+ return org.hamcrest.object.IsEventFrom.eventFrom(source);
+ }
+
+ /**
+ * Creates a matcher of {@link org.w3c.dom.Node}s that matches when the examined node has a value at the
+ * specified <code>xPath</code> that satisfies the specified <code>valueMatcher</code>.
+ * For example:
+ * <pre>assertThat(xml, hasXPath("/root/something[2]/cheese", equalTo("Cheddar")))</pre>
+ *
+ * @param xPath
+ * the target xpath
+ * @param valueMatcher
+ * matcher for the value at the specified xpath
+ */
+ public static org.hamcrest.Matcher<org.w3c.dom.Node> hasXPath(java.lang.String xPath, org.hamcrest.Matcher<java.lang.String> valueMatcher) {
+ return org.hamcrest.xml.HasXPath.hasXPath(xPath, valueMatcher);
+ }
+
+ /**
+ * Creates a matcher of {@link org.w3c.dom.Node}s that matches when the examined node has a value at the
+ * specified <code>xPath</code>, within the specified <code>namespaceContext</code>, that satisfies
+ * the specified <code>valueMatcher</code>.
+ * For example:
+ * <pre>assertThat(xml, hasXPath("/root/something[2]/cheese", myNs, equalTo("Cheddar")))</pre>
+ *
+ * @param xPath
+ * the target xpath
+ * @param namespaceContext
+ * the namespace for matching nodes
+ * @param valueMatcher
+ * matcher for the value at the specified xpath
+ */
+ public static org.hamcrest.Matcher<org.w3c.dom.Node> hasXPath(java.lang.String xPath, javax.xml.namespace.NamespaceContext namespaceContext, org.hamcrest.Matcher<java.lang.String> valueMatcher) {
+ return org.hamcrest.xml.HasXPath.hasXPath(xPath, namespaceContext, valueMatcher);
+ }
+
+ /**
+ * Creates a matcher of {@link org.w3c.dom.Node}s that matches when the examined node contains a node
+ * at the specified <code>xPath</code>, with any content.
+ * For example:
+ * <pre>assertThat(xml, hasXPath("/root/something[2]/cheese"))</pre>
+ *
+ * @param xPath
+ * the target xpath
+ */
+ public static org.hamcrest.Matcher<org.w3c.dom.Node> hasXPath(java.lang.String xPath) {
+ return org.hamcrest.xml.HasXPath.hasXPath(xPath);
+ }
+
+ /**
+ * Creates a matcher of {@link org.w3c.dom.Node}s that matches when the examined node contains a node
+ * at the specified <code>xPath</code> within the specified namespace context, with any content.
+ * For example:
+ * <pre>assertThat(xml, hasXPath("/root/something[2]/cheese", myNs))</pre>
+ *
+ * @param xPath
+ * the target xpath
+ * @param namespaceContext
+ * the namespace for matching nodes
+ */
+ public static org.hamcrest.Matcher<org.w3c.dom.Node> hasXPath(java.lang.String xPath, javax.xml.namespace.NamespaceContext namespaceContext) {
+ return org.hamcrest.xml.HasXPath.hasXPath(xPath, namespaceContext);
+ }
}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsArray.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsArray.java
index 6a26ef1..38f5d91 100644
--- a/hamcrest-library/src/main/java/org/hamcrest/collection/IsArray.java
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsArray.java
@@ -1,18 +1,23 @@
package org.hamcrest.collection;
-import java.util.Arrays;
-
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
+import java.util.Arrays;
+
+/**
+ * Matcher for array whose elements satisfy a sequence of matchers.
+ * The array size must equal the number of element matchers.
+ */
public class IsArray<T> extends TypeSafeMatcher<T[]> {
- private final Matcher<T>[] elementMatchers;
+ private final Matcher<? super T>[] elementMatchers;
- public IsArray(Matcher<T>[] elementMatchers) {
+ public IsArray(Matcher<? super T>[] elementMatchers) {
this.elementMatchers = elementMatchers.clone();
}
+ @Override
public boolean matchesSafely(T[] array) {
if (array.length != elementMatchers.length) return false;
@@ -22,7 +27,24 @@ public class IsArray<T> extends TypeSafeMatcher<T[]> {
return true;
}
-
+
+ @Override
+ public void describeMismatchSafely(T[] actual, Description mismatchDescription) {
+ if (actual.length != elementMatchers.length) {
+ mismatchDescription.appendText("array length was ").appendValue(actual.length);
+ return;
+ }
+ for (int i = 0; i < actual.length; i++) {
+ if (!elementMatchers[i].matches(actual[i])) {
+ mismatchDescription.appendText("element ").appendValue(i).appendText(" ");
+ elementMatchers[i].describeMismatch(actual[i], mismatchDescription);
+ return;
+ }
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
public void describeTo(Description description) {
description.appendList(descriptionStart(), descriptionSeparator(), descriptionEnd(),
Arrays.asList(elementMatchers));
@@ -58,7 +80,18 @@ public class IsArray<T> extends TypeSafeMatcher<T[]> {
return "]";
}
- public static <T> IsArray<T> array(Matcher<T>... elementMatchers) {
+ /**
+ * Creates a matcher that matches arrays whose elements are satisfied by the specified matchers. Matches
+ * positively only if the number of matchers specified is equal to the length of the examined array and
+ * each matcher[i] is satisfied by array[i].
+ * For example:
+ * <pre>assertThat(new Integer[]{1,2,3}, is(array(equalTo(1), equalTo(2), equalTo(3))))</pre>
+ *
+ * @param elementMatchers
+ * the matchers that the elements of examined arrays should satisfy
+ */
+ public static <T> IsArray<T> array(Matcher<? super T>... elementMatchers) {
return new IsArray<T>(elementMatchers);
}
+
}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayContaining.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayContaining.java
index 76ddf9d..749c7c6 100644
--- a/hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayContaining.java
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayContaining.java
@@ -2,18 +2,23 @@ package org.hamcrest.collection;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
import org.hamcrest.TypeSafeMatcher;
+
+import java.util.Arrays;
+
import static org.hamcrest.core.IsEqual.equalTo;
+/**
+ * Matches if an array contains an item satisfying a nested matcher.
+ */
public class IsArrayContaining<T> extends TypeSafeMatcher<T[]> {
+ private final Matcher<? super T> elementMatcher;
- private final Matcher<T> elementMatcher;
-
- public IsArrayContaining(Matcher<T> elementMatcher) {
+ public IsArrayContaining(Matcher<? super T> elementMatcher) {
this.elementMatcher = elementMatcher;
}
+ @Override
public boolean matchesSafely(T[] array) {
for (T item : array) {
if (elementMatcher.matches(item)) {
@@ -22,21 +27,45 @@ public class IsArrayContaining<T> extends TypeSafeMatcher<T[]> {
}
return false;
}
+
+ @Override
+ public void describeMismatchSafely(T[] item, Description mismatchDescription) {
+ super.describeMismatch(Arrays.asList(item), mismatchDescription);
+ }
+ @Override
public void describeTo(Description description) {
description
- .appendText("an array containing ")
- .appendDescriptionOf(elementMatcher);
+ .appendText("an array containing ")
+ .appendDescriptionOf(elementMatcher);
}
- @Factory
- public static <T> Matcher<T[]> hasItemInArray(Matcher<T> elementMatcher) {
+ /**
+ * Creates a matcher for arrays that matches when the examined array contains at least one item
+ * that is matched by the specified <code>elementMatcher</code>. Whilst matching, the traversal
+ * of the examined array will stop as soon as a matching element is found.
+ * For example:
+ * <pre>assertThat(new String[] {"foo", "bar"}, hasItemInArray(startsWith("ba")))</pre>
+ *
+ * @param elementMatcher
+ * the matcher to apply to elements in examined arrays
+ */
+ public static <T> Matcher<T[]> hasItemInArray(Matcher<? super T> elementMatcher) {
return new IsArrayContaining<T>(elementMatcher);
}
- @Factory
+ /**
+ * A shortcut to the frequently used <code>hasItemInArray(equalTo(x))</code>.
+ * For example:
+ * <pre>assertThat(hasItemInArray(x))</pre>
+ * instead of:
+ * <pre>assertThat(hasItemInArray(equalTo(x)))</pre>
+ *
+ * @param element
+ * the element that should be present in examined arrays
+ */
public static <T> Matcher<T[]> hasItemInArray(T element) {
- return hasItemInArray(equalTo(element));
+ Matcher<? super T> matcher = equalTo(element);
+ return IsArrayContaining.<T>hasItemInArray(matcher);
}
-
}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayContainingInAnyOrder.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayContainingInAnyOrder.java
new file mode 100644
index 0000000..a3a93c1
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayContainingInAnyOrder.java
@@ -0,0 +1,112 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public class IsArrayContainingInAnyOrder<E> extends TypeSafeMatcher<E[]> {
+ private final IsIterableContainingInAnyOrder<E> iterableMatcher;
+ private final Collection<Matcher<? super E>> matchers;
+
+ public IsArrayContainingInAnyOrder(Collection<Matcher<? super E>> matchers) {
+ this.iterableMatcher = new IsIterableContainingInAnyOrder<E>(matchers);
+ this.matchers = matchers;
+ }
+
+ @Override
+ public boolean matchesSafely(E[] item) {
+ return iterableMatcher.matches(Arrays.asList(item));
+ }
+
+ @Override
+ public void describeMismatchSafely(E[] item, Description mismatchDescription) {
+ iterableMatcher.describeMismatch(Arrays.asList(item), mismatchDescription);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendList("[", ", ", "]", matchers)
+ .appendText(" in any order");
+ }
+
+ /**
+ * <p>
+ * Creates an order agnostic matcher for arrays that matches when each item in the
+ * examined array satisfies one matcher anywhere in the specified matchers.
+ * For a positive match, the examined array must be of the same length as the number of
+ * specified matchers.
+ * </p>
+ * <p>
+ * N.B. each of the specified matchers will only be used once during a given examination, so be
+ * careful when specifying matchers that may be satisfied by more than one entry in an examined
+ * array.
+ * </p>
+ * <p>
+ * For example:
+ * </p>
+ * <pre>assertThat(new String[]{"foo", "bar"}, arrayContainingInAnyOrder(equalTo("bar"), equalTo("foo")))</pre>
+ *
+ * @param itemMatchers
+ * a list of matchers, each of which must be satisfied by an entry in an examined array
+ */
+ public static <E> Matcher<E[]> arrayContainingInAnyOrder(Matcher<? super E>... itemMatchers) {
+ return arrayContainingInAnyOrder((List) Arrays.asList(itemMatchers));
+ }
+
+ /**
+ * <p>
+ * Creates an order agnostic matcher for arrays that matches when each item in the
+ * examined array satisfies one matcher anywhere in the specified collection of matchers.
+ * For a positive match, the examined array must be of the same length as the specified collection
+ * of matchers.
+ * </p>
+ * <p>
+ * N.B. each matcher in the specified collection will only be used once during a given
+ * examination, so be careful when specifying matchers that may be satisfied by more than
+ * one entry in an examined array.
+ * </p>
+ * <p>
+ * For example:
+ * </p>
+ * <pre>assertThat(new String[]{"foo", "bar"}, arrayContainingInAnyOrder(Arrays.asList(equalTo("bar"), equalTo("foo"))))</pre>
+ *
+ * @param itemMatchers
+ * a list of matchers, each of which must be satisfied by an item provided by an examined array
+ */
+ public static <E> Matcher<E[]> arrayContainingInAnyOrder(Collection<Matcher<? super E>> itemMatchers) {
+ return new IsArrayContainingInAnyOrder<E>(itemMatchers);
+ }
+
+ /**
+ * <p>Creates an order agnostic matcher for arrays that matches when each item in the
+ * examined array is logically equal to one item anywhere in the specified items.
+ * For a positive match, the examined array must be of the same length as the number of
+ * specified items.
+ * </p>
+ * <p>N.B. each of the specified items will only be used once during a given examination, so be
+ * careful when specifying items that may be equal to more than one entry in an examined
+ * array.
+ * </p>
+ * <p>
+ * For example:
+ * </p>
+ * <pre>assertThat(new String[]{"foo", "bar"}, containsInAnyOrder("bar", "foo"))</pre>
+ *
+ * @param items
+ * the items that must equal the entries of an examined array, in any order
+ */
+ public static <E> Matcher<E[]> arrayContainingInAnyOrder(E... items) {
+ List<Matcher<? super E>> matchers = new ArrayList<Matcher<? super E>>();
+ for (E item : items) {
+ matchers.add(equalTo(item));
+ }
+ return new IsArrayContainingInAnyOrder<E>(matchers);
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayContainingInOrder.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayContainingInOrder.java
new file mode 100644
index 0000000..849920a
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayContainingInOrder.java
@@ -0,0 +1,89 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+import org.hamcrest.internal.NullSafety;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public class IsArrayContainingInOrder<E> extends TypeSafeMatcher<E[]> {
+ private final Collection<Matcher<? super E>> matchers;
+ private final IsIterableContainingInOrder<E> iterableMatcher;
+
+ public IsArrayContainingInOrder(List<Matcher<? super E>> matchers) {
+ this.iterableMatcher = new IsIterableContainingInOrder<E>(matchers);
+ this.matchers = matchers;
+ }
+
+ @Override
+ public boolean matchesSafely(E[] item) {
+ return iterableMatcher.matches(asList(item));
+ }
+
+ @Override
+ public void describeMismatchSafely(E[] item, Description mismatchDescription) {
+ iterableMatcher.describeMismatch(asList(item), mismatchDescription);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendList("[", ", ", "]", matchers);
+ }
+
+ /**
+ * Creates a matcher for arrays that matches when each item in the examined array is
+ * logically equal to the corresponding item in the specified items. For a positive match,
+ * the examined array must be of the same length as the number of specified items.
+ * For example:
+ * <pre>assertThat(new String[]{"foo", "bar"}, contains("foo", "bar"))</pre>
+ *
+ * @param items
+ * the items that must equal the items within an examined array
+ */
+ public static <E> Matcher<E[]> arrayContaining(E... items) {
+ List<Matcher<? super E>> matchers = new ArrayList<Matcher<? super E>>();
+ for (E item : items) {
+ matchers.add(equalTo(item));
+ }
+ return arrayContaining(matchers);
+ }
+
+ /**
+ * Creates a matcher for arrays that matches when each item in the examined array satisfies the
+ * corresponding matcher in the specified matchers. For a positive match, the examined array
+ * must be of the same length as the number of specified matchers.
+ * For example:
+ * <pre>assertThat(new String[]{"foo", "bar"}, contains(equalTo("foo"), equalTo("bar")))</pre>
+ *
+ * @param itemMatchers
+ * the matchers that must be satisfied by the items in the examined array
+ */
+ public static <E> Matcher<E[]> arrayContaining(Matcher<? super E>... itemMatchers) {
+ //required for JDK 1.6
+ //noinspection RedundantTypeArguments
+ final List<Matcher<? super E>> nullSafeWithExplicitTypeMatchers = NullSafety.<E>nullSafe(itemMatchers);
+
+ return arrayContaining(nullSafeWithExplicitTypeMatchers);
+ }
+
+ /**
+ * Creates a matcher for arrays that matches when each item in the examined array satisfies the
+ * corresponding matcher in the specified list of matchers. For a positive match, the examined array
+ * must be of the same length as the specified list of matchers.
+ * For example:
+ * <pre>assertThat(new String[]{"foo", "bar"}, contains(Arrays.asList(equalTo("foo"), equalTo("bar"))))</pre>
+ *
+ * @param itemMatchers
+ * a list of matchers, each of which must be satisfied by the corresponding item in an examined array
+ */
+ public static <E> Matcher<E[]> arrayContaining(List<Matcher<? super E>> itemMatchers) {
+ return new IsArrayContainingInOrder<E>(itemMatchers);
+ }
+
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayWithSize.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayWithSize.java
new file mode 100644
index 0000000..b3a0b1f
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsArrayWithSize.java
@@ -0,0 +1,59 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.FeatureMatcher;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.core.DescribedAs.describedAs;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+/**
+ * Matches if array size satisfies a nested matcher.
+ */
+public class IsArrayWithSize<E> extends FeatureMatcher<E[], Integer> {
+ public IsArrayWithSize(Matcher<? super Integer> sizeMatcher) {
+ super(sizeMatcher, "an array with size","array size");
+ }
+
+ @Override
+ protected Integer featureValueOf(E[] actual) {
+ return actual.length;
+ }
+
+ /**
+ * Creates a matcher for arrays that matches when the <code>length</code> of the array
+ * satisfies the specified matcher.
+ * For example:
+ * <pre>assertThat(new String[]{"foo", "bar"}, arrayWithSize(equalTo(2)))</pre>
+ *
+ * @param sizeMatcher
+ * a matcher for the length of an examined array
+ */
+ public static <E> Matcher<E[]> arrayWithSize(Matcher<? super Integer> sizeMatcher) {
+ return new IsArrayWithSize<E>(sizeMatcher);
+ }
+
+ /**
+ * Creates a matcher for arrays that matches when the <code>length</code> of the array
+ * equals the specified <code>size</code>.
+ * For example:
+ * <pre>assertThat(new String[]{"foo", "bar"}, arrayWithSize(2))</pre>
+ *
+ * @param size
+ * the length that an examined array must have for a positive match
+ */
+ public static <E> Matcher<E[]> arrayWithSize(int size) {
+ return arrayWithSize(equalTo(size));
+ }
+
+ /**
+ * Creates a matcher for arrays that matches when the <code>length</code> of the array
+ * is zero.
+ * For example:
+ * <pre>assertThat(new String[0], emptyArray())</pre>
+ *
+ */
+ public static <E> Matcher<E[]> emptyArray() {
+ Matcher<E[]> isEmpty = arrayWithSize(0);
+ return describedAs("an empty array", isEmpty);
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsCollectionContaining.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsCollectionContaining.java
deleted file mode 100644
index ba98630..0000000
--- a/hamcrest-library/src/main/java/org/hamcrest/collection/IsCollectionContaining.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package org.hamcrest.collection;
-
-import static org.hamcrest.core.AllOf.allOf;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
-import org.hamcrest.TypeSafeMatcher;
-import static org.hamcrest.core.IsEqual.equalTo;
-
-import java.util.Collection;
-import java.util.ArrayList;
-
-public class IsCollectionContaining<T> extends TypeSafeMatcher<Iterable<T>> {
- private final Matcher<? extends T> elementMatcher;
-
- public IsCollectionContaining(Matcher<? extends T> elementMatcher) {
- this.elementMatcher = elementMatcher;
- }
-
- public boolean matchesSafely(Iterable<T> collection) {
- for (T item : collection) {
- if (elementMatcher.matches(item)){
- return true;
- }
- }
- return false;
- }
-
- public void describeTo(Description description) {
- description
- .appendText("a collection containing ")
- .appendDescriptionOf(elementMatcher);
- }
-
- @Factory
- public static <T> Matcher<Iterable<T>> hasItem(Matcher<? extends T> elementMatcher) {
- return new IsCollectionContaining<T>(elementMatcher);
- }
-
- @Factory
- public static <T> Matcher<Iterable<T>> hasItem(T element) {
- return hasItem(equalTo(element));
- }
-
- @Factory
- public static <T> Matcher<Iterable<T>> hasItems(Matcher<? extends T>... elementMatchers) {
- Collection<Matcher<? extends Iterable<T>>> all
- = new ArrayList<Matcher<? extends Iterable<T>>>(elementMatchers.length);
- for (Matcher<? extends T> elementMatcher : elementMatchers) {
- all.add(hasItem(elementMatcher));
- }
- return allOf(all);
- }
-
- @Factory
- public static <T> Matcher<Iterable<T>> hasItems(T... elements) {
- Collection<Matcher<? extends Iterable<T>>> all
- = new ArrayList<Matcher<? extends Iterable<T>>>(elements.length);
- for (T element : elements) {
- all.add(hasItem(element));
- }
- return allOf(all);
- }
-
-}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsCollectionWithSize.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsCollectionWithSize.java
new file mode 100644
index 0000000..f12f57c
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsCollectionWithSize.java
@@ -0,0 +1,50 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.FeatureMatcher;
+import org.hamcrest.Matcher;
+
+import java.util.Collection;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+
+/**
+ * Matches if collection size satisfies a nested matcher.
+ */
+public class IsCollectionWithSize<E> extends FeatureMatcher<Collection<? extends E>, Integer> {
+ public IsCollectionWithSize(Matcher<? super Integer> sizeMatcher) {
+ super(sizeMatcher, "a collection with size", "collection size");
+ }
+
+ @Override
+ protected Integer featureValueOf(Collection<? extends E> actual) {
+ return actual.size();
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Collection}s that matches when the <code>size()</code> method returns
+ * a value that satisfies the specified matcher.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), hasSize(equalTo(2)))</pre>
+ *
+ * @param sizeMatcher
+ * a matcher for the size of an examined {@link java.util.Collection}
+ */
+ public static <E> Matcher<Collection<? extends E>> hasSize(Matcher<? super Integer> sizeMatcher) {
+ return new IsCollectionWithSize<E>(sizeMatcher);
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Collection}s that matches when the <code>size()</code> method returns
+ * a value equal to the specified <code>size</code>.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), hasSize(2))</pre>
+ *
+ * @param size
+ * the expected size of an examined {@link java.util.Collection}
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public static <E> Matcher<Collection<? extends E>> hasSize(int size) {
+ return (Matcher)IsCollectionWithSize.hasSize(equalTo(size));
+ }
+
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsEmptyCollection.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsEmptyCollection.java
new file mode 100644
index 0000000..481b08c
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsEmptyCollection.java
@@ -0,0 +1,53 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+import java.util.Collection;
+
+/**
+ * Tests if collection is empty.
+ */
+public class IsEmptyCollection<E> extends TypeSafeMatcher<Collection<? extends E>> {
+
+ @Override
+ public boolean matchesSafely(Collection<? extends E> item) {
+ return item.isEmpty();
+ }
+
+ @Override
+ public void describeMismatchSafely(Collection<? extends E> item, Description mismatchDescription) {
+ mismatchDescription.appendValue(item);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("an empty collection");
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Collection}s matching examined collections whose <code>isEmpty</code>
+ * method returns <code>true</code>.
+ * For example:
+ * <pre>assertThat(new ArrayList&lt;String&gt;(), is(empty()))</pre>
+ *
+ */
+ public static <E> Matcher<Collection<? extends E>> empty() {
+ return new IsEmptyCollection<E>();
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Collection}s matching examined collections whose <code>isEmpty</code>
+ * method returns <code>true</code>.
+ * For example:
+ * <pre>assertThat(new ArrayList&lt;String&gt;(), is(emptyCollectionOf(String.class)))</pre>
+ *
+ * @param unusedToForceReturnType
+ * the type of the collection's content
+ */
+ @SuppressWarnings({"unchecked", "UnusedParameters"})
+ public static <E> Matcher<Collection<E>> emptyCollectionOf(Class<E> unusedToForceReturnType) {
+ return (Matcher)empty();
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsEmptyIterable.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsEmptyIterable.java
new file mode 100644
index 0000000..047e670
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsEmptyIterable.java
@@ -0,0 +1,48 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * Tests if collection is empty.
+ */
+public class IsEmptyIterable<E> extends TypeSafeMatcher<Iterable<? extends E>> {
+
+ @Override
+ public boolean matchesSafely(Iterable<? extends E> iterable) {
+ return !iterable.iterator().hasNext();
+ }
+ @Override
+ public void describeMismatchSafely(Iterable<? extends E> iter, Description mismatchDescription) {
+ mismatchDescription.appendValueList("[", ",", "]", iter);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("an empty iterable");
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s matching examined iterables that yield no items.
+ * For example:
+ * <pre>assertThat(new ArrayList&lt;String&gt;(), is(emptyIterable()))</pre>
+ *
+ */
+ public static <E> Matcher<Iterable<? extends E>> emptyIterable() {
+ return new IsEmptyIterable<E>();
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s matching examined iterables that yield no items.
+ * For example:
+ * <pre>assertThat(new ArrayList&lt;String&gt;(), is(emptyIterableOf(String.class)))</pre>
+ *
+ * @param unusedToForceReturnType
+ * the type of the iterable's content
+ */
+ @SuppressWarnings({"unchecked", "UnusedParameters"})
+ public static <E> Matcher<Iterable<E>> emptyIterableOf(Class<E> unusedToForceReturnType) {
+ return (Matcher)emptyIterable();
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsIn.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsIn.java
index 0a7bbb5..f030cab 100644
--- a/hamcrest-library/src/main/java/org/hamcrest/collection/IsIn.java
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsIn.java
@@ -1,13 +1,12 @@
package org.hamcrest.collection;
-import java.util.Arrays;
-import java.util.Collection;
-
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
-import org.hamcrest.Factory;
import org.hamcrest.Matcher;
+import java.util.Arrays;
+import java.util.Collection;
+
public class IsIn<T> extends BaseMatcher<T> {
private final Collection<T> collection;
@@ -19,27 +18,108 @@ public class IsIn<T> extends BaseMatcher<T> {
collection = Arrays.asList(elements);
}
+ @SuppressWarnings("SuspiciousMethodCalls")
+ @Override
public boolean matches(Object o) {
return collection.contains(o);
}
+ @Override
public void describeTo(Description buffer) {
buffer.appendText("one of ");
buffer.appendValueList("{", ", ", "}", collection);
}
- @Factory
+ /**
+ * Creates a matcher that matches when the examined object is found within the
+ * specified collection.
+ * For example:
+ * <pre>assertThat("foo", isIn(Arrays.asList("bar", "foo")))</pre>
+ *
+ * @deprecated use is(in(...)) instead
+ *
+ * @param collection
+ * the collection in which matching items must be found
+ *
+ */
+ @Deprecated
public static <T> Matcher<T> isIn(Collection<T> collection) {
- return new IsIn<T>(collection);
+ return in(collection);
}
- @Factory
+ /**
+ * Creates a matcher that matches when the examined object is found within the
+ * specified collection.
+ * For example:
+ * <pre>assertThat("foo", is(in(Arrays.asList("bar", "foo"))))</pre>
+ *
+ * @param collection
+ * the collection in which matching items must be found
+ *
+ */
+ public static <T> Matcher<T> in(Collection<T> collection) {
+ return new IsIn<T>(collection);
+ }
+
+ /**
+ * Creates a matcher that matches when the examined object is found within the
+ * specified array.
+ * For example:
+ * <pre>assertThat("foo", isIn(new String[]{"bar", "foo"}))</pre>
+ *
+ * @deprecated use is(in(...)) instead
+ *
+ * @param elements
+ * the array in which matching items must be found
+ *
+ */
+ @Deprecated
public static <T> Matcher<T> isIn(T[] elements) {
+ return in(elements);
+ }
+
+ /**
+ * Creates a matcher that matches when the examined object is found within the
+ * specified array.
+ * For example:
+ * <pre>assertThat("foo", is(in(new String[]{"bar", "foo"})))</pre>
+ *
+ * @param elements
+ * the array in which matching items must be found
+ *
+ */
+ public static <T> Matcher<T> in(T[] elements) {
return new IsIn<T>(elements);
}
- @Factory
+ /**
+ * Creates a matcher that matches when the examined object is equal to one of the
+ * specified elements.
+ * For example:
+ * <pre>assertThat("foo", isOneOf("bar", "foo"))</pre>
+ *
+ * @deprecated use is(oneOf(...)) instead
+ *
+ * @param elements
+ * the elements amongst which matching items will be found
+ *
+ */
+ @Deprecated
public static <T> Matcher<T> isOneOf(T... elements) {
- return isIn(elements);
+ return oneOf(elements);
+ }
+
+ /**
+ * Creates a matcher that matches when the examined object is equal to one of the
+ * specified elements.
+ * For example:
+ * <pre>assertThat("foo", is(oneOf("bar", "foo")))</pre>
+ *
+ * @param elements
+ * the elements amongst which matching items will be found
+ *
+ */
+ public static <T> Matcher<T> oneOf(T... elements) {
+ return in(elements);
}
}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableContainingInAnyOrder.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableContainingInAnyOrder.java
new file mode 100644
index 0000000..6f2fc47
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableContainingInAnyOrder.java
@@ -0,0 +1,154 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public class IsIterableContainingInAnyOrder<T> extends TypeSafeDiagnosingMatcher<Iterable<? extends T>> {
+ private final Collection<Matcher<? super T>> matchers;
+
+ public IsIterableContainingInAnyOrder(Collection<Matcher<? super T>> matchers) {
+ this.matchers = matchers;
+ }
+
+ @Override
+ protected boolean matchesSafely(Iterable<? extends T> items, Description mismatchDescription) {
+ final Matching<T> matching = new Matching<T>(matchers, mismatchDescription);
+ for (T item : items) {
+ if (! matching.matches(item)) {
+ return false;
+ }
+ }
+
+ return matching.isFinished(items);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("iterable with items ")
+ .appendList("[", ", ", "]", matchers)
+ .appendText(" in any order");
+ }
+
+ private static class Matching<S> {
+ private final Collection<Matcher<? super S>> matchers;
+ private final Description mismatchDescription;
+
+ public Matching(Collection<Matcher<? super S>> matchers, Description mismatchDescription) {
+ this.matchers = new ArrayList<Matcher<? super S>>(matchers);
+ this.mismatchDescription = mismatchDescription;
+ }
+
+ public boolean matches(S item) {
+ if (matchers.isEmpty()) {
+ mismatchDescription.appendText("no match for: ").appendValue(item);
+ return false;
+ }
+ return isMatched(item);
+ }
+
+ public boolean isFinished(Iterable<? extends S> items) {
+ if (matchers.isEmpty()) {
+ return true;
+ }
+ mismatchDescription
+ .appendText("no item matches: ").appendList("", ", ", "", matchers)
+ .appendText(" in ").appendValueList("[", ", ", "]", items);
+ return false;
+ }
+
+ private boolean isMatched(S item) {
+ for (Matcher<? super S> matcher : matchers) {
+ if (matcher.matches(item)) {
+ matchers.remove(matcher);
+ return true;
+ }
+ }
+ mismatchDescription.appendText("not matched: ").appendValue(item);
+ return false;
+ }
+ }
+
+ /**
+ * <p>
+ * Creates an order agnostic matcher for {@link Iterable}s that matches when a single pass over
+ * the examined {@link Iterable} yields a series of items, each satisfying one matcher anywhere
+ * in the specified matchers. For a positive match, the examined iterable must be of the same
+ * length as the number of specified matchers.
+ * </p>
+ * <p>
+ * N.B. each of the specified matchers will only be used once during a given examination, so be
+ * careful when specifying matchers that may be satisfied by more than one entry in an examined
+ * iterable.
+ * </p>
+ * <p>
+ * For example:
+ * </p>
+ * <pre>assertThat(Arrays.asList("foo", "bar"), containsInAnyOrder(equalTo("bar"), equalTo("foo")))</pre>
+ *
+ * @param itemMatchers
+ * a list of matchers, each of which must be satisfied by an item provided by an examined {@link Iterable}
+ */
+ public static <T> Matcher<Iterable<? extends T>> containsInAnyOrder(Matcher<? super T>... itemMatchers) {
+ return containsInAnyOrder((List) Arrays.asList(itemMatchers));
+ }
+
+ /**
+ * <p>
+ * Creates an order agnostic matcher for {@link Iterable}s that matches when a single pass over
+ * the examined {@link Iterable} yields a series of items, each logically equal to one item
+ * anywhere in the specified items. For a positive match, the examined iterable
+ * must be of the same length as the number of specified items.
+ * </p>
+ * <p>
+ * N.B. each of the specified items will only be used once during a given examination, so be
+ * careful when specifying items that may be equal to more than one entry in an examined
+ * iterable.
+ * </p>
+ * <p>
+ * For example:
+ * </p>
+ * <pre>assertThat(Arrays.asList("foo", "bar"), containsInAnyOrder("bar", "foo"))</pre>
+ *
+ * @param items
+ * the items that must equal the items provided by an examined {@link Iterable} in any order
+ */
+ public static <T> Matcher<Iterable<? extends T>> containsInAnyOrder(T... items) {
+ List<Matcher<? super T>> matchers = new ArrayList<Matcher<? super T>>();
+ for (T item : items) {
+ matchers.add(equalTo(item));
+ }
+
+ return new IsIterableContainingInAnyOrder<T>(matchers);
+ }
+
+ /**
+ * <p>
+ * Creates an order agnostic matcher for {@link Iterable}s that matches when a single pass over
+ * the examined {@link Iterable} yields a series of items, each satisfying one matcher anywhere
+ * in the specified collection of matchers. For a positive match, the examined iterable
+ * must be of the same length as the specified collection of matchers.
+ * </p>
+ * <p>
+ * N.B. each matcher in the specified collection will only be used once during a given
+ * examination, so be careful when specifying matchers that may be satisfied by more than
+ * one entry in an examined iterable.
+ * </p>
+ * <p>For example:</p>
+ * <pre>assertThat(Arrays.asList("foo", "bar"), containsInAnyOrder(Arrays.asList(equalTo("bar"), equalTo("foo"))))</pre>
+ *
+ * @param itemMatchers
+ * a list of matchers, each of which must be satisfied by an item provided by an examined {@link Iterable}
+ */
+ public static <T> Matcher<Iterable<? extends T>> containsInAnyOrder(Collection<Matcher<? super T>> itemMatchers) {
+ return new IsIterableContainingInAnyOrder<T>(itemMatchers);
+ }
+}
+
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableContainingInOrder.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableContainingInOrder.java
new file mode 100644
index 0000000..6309566
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableContainingInOrder.java
@@ -0,0 +1,153 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.hamcrest.internal.NullSafety;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public class IsIterableContainingInOrder<E> extends TypeSafeDiagnosingMatcher<Iterable<? extends E>> {
+ private final List<Matcher<? super E>> matchers;
+
+ public IsIterableContainingInOrder(List<Matcher<? super E>> matchers) {
+ this.matchers = matchers;
+ }
+
+ @Override
+ protected boolean matchesSafely(Iterable<? extends E> iterable, Description mismatchDescription) {
+ final MatchSeries<E> matchSeries = new MatchSeries<E>(matchers, mismatchDescription);
+ for (E item : iterable) {
+ if (!matchSeries.matches(item)) {
+ return false;
+ }
+ }
+
+ return matchSeries.isFinished();
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("iterable containing ").appendList("[", ", ", "]", matchers);
+ }
+
+ private static class MatchSeries<F> {
+ private final List<Matcher<? super F>> matchers;
+ private final Description mismatchDescription;
+ private int nextMatchIx = 0;
+
+ public MatchSeries(List<Matcher<? super F>> matchers, Description mismatchDescription) {
+ this.mismatchDescription = mismatchDescription;
+ if (matchers.isEmpty()) {
+ throw new IllegalArgumentException("Should specify at least one expected element");
+ }
+ this.matchers = matchers;
+ }
+
+ public boolean matches(F item) {
+ if (matchers.size() <= nextMatchIx) {
+ mismatchDescription.appendText("not matched: ").appendValue(item);
+ return false;
+ }
+
+ return isMatched(item);
+ }
+
+ public boolean isFinished() {
+ if (nextMatchIx < matchers.size()) {
+ mismatchDescription.appendText("no item was ").appendDescriptionOf(matchers.get(nextMatchIx));
+ return false;
+ }
+ return true;
+ }
+
+ private boolean isMatched(F item) {
+ final Matcher<? super F> matcher = matchers.get(nextMatchIx);
+ if (!matcher.matches(item)) {
+ describeMismatch(matcher, item);
+ return false;
+ }
+ nextMatchIx++;
+ return true;
+ }
+
+ private void describeMismatch(Matcher<? super F> matcher, F item) {
+ mismatchDescription.appendText("item " + nextMatchIx + ": ");
+ matcher.describeMismatch(item, mismatchDescription);
+ }
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields a series of items, each logically equal to the
+ * corresponding item in the specified items. For a positive match, the examined iterable
+ * must be of the same length as the number of specified items.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), contains("foo", "bar"))</pre>
+ *
+ * @param items
+ * the items that must equal the items provided by an examined {@link Iterable}
+ */
+ public static <E> Matcher<Iterable<? extends E>> contains(E... items) {
+ List<Matcher<? super E>> matchers = new ArrayList<Matcher<? super E>>();
+ for (E item : items) {
+ matchers.add(equalTo(item));
+ }
+
+ return contains(matchers);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields a single item that satisfies the specified matcher.
+ * For a positive match, the examined iterable must only yield one item.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo"), contains(equalTo("foo")))</pre>
+ *
+ * @param itemMatcher
+ * the matcher that must be satisfied by the single item provided by an
+ * examined {@link Iterable}
+ */
+ @SuppressWarnings("unchecked")
+ public static <E> Matcher<Iterable<? extends E>> contains(final Matcher<? super E> itemMatcher) {
+ return contains(new ArrayList<Matcher<? super E>>(asList(itemMatcher)));
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields a series of items, each satisfying the corresponding
+ * matcher in the specified matchers. For a positive match, the examined iterable
+ * must be of the same length as the number of specified matchers.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), contains(equalTo("foo"), equalTo("bar")))</pre>
+ *
+ * @param itemMatchers
+ * the matchers that must be satisfied by the items provided by an examined {@link Iterable}
+ */
+ public static <E> Matcher<Iterable<? extends E>> contains(Matcher<? super E>... itemMatchers) {
+ // required for JDK 1.6
+ //noinspection RedundantTypeArguments
+ final List<Matcher<? super E>> nullSafeWithExplicitTypeMatchers = NullSafety.<E>nullSafe(itemMatchers);
+ return contains(nullSafeWithExplicitTypeMatchers);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields a series of items, each satisfying the corresponding
+ * matcher in the specified list of matchers. For a positive match, the examined iterable
+ * must be of the same length as the specified list of matchers.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), contains(Arrays.asList(equalTo("foo"), equalTo("bar"))))</pre>
+ *
+ * @param itemMatchers
+ * a list of matchers, each of which must be satisfied by the corresponding item provided by
+ * an examined {@link Iterable}
+ */
+ public static <E> Matcher<Iterable<? extends E>> contains(List<Matcher<? super E>> itemMatchers) {
+ return new IsIterableContainingInOrder<E>(itemMatchers);
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableContainingInRelativeOrder.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableContainingInRelativeOrder.java
new file mode 100644
index 0000000..f669835
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableContainingInRelativeOrder.java
@@ -0,0 +1,117 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public class IsIterableContainingInRelativeOrder<E> extends TypeSafeDiagnosingMatcher<Iterable<? extends E>> {
+ private final List<Matcher<? super E>> matchers;
+
+ public IsIterableContainingInRelativeOrder(List<Matcher<? super E>> matchers) {
+ this.matchers = matchers;
+ }
+
+ @Override
+ protected boolean matchesSafely(Iterable<? extends E> iterable, Description mismatchDescription) {
+ MatchSeriesInRelativeOrder<E> matchSeriesInRelativeOrder = new MatchSeriesInRelativeOrder<E>(matchers, mismatchDescription);
+ matchSeriesInRelativeOrder.processItems(iterable);
+ return matchSeriesInRelativeOrder.isFinished();
+ }
+
+ public void describeTo(Description description) {
+ description.appendText("iterable containing ").appendList("[", ", ", "]", matchers).appendText(" in relative order");
+ }
+
+ private static class MatchSeriesInRelativeOrder<F> {
+ public final List<Matcher<? super F>> matchers;
+ private final Description mismatchDescription;
+ private int nextMatchIx = 0;
+ private F lastMatchedItem = null;
+
+ public MatchSeriesInRelativeOrder(List<Matcher<? super F>> matchers, Description mismatchDescription) {
+ this.mismatchDescription = mismatchDescription;
+ if (matchers.isEmpty()) {
+ throw new IllegalArgumentException("Should specify at least one expected element");
+ }
+ this.matchers = matchers;
+ }
+
+ public void processItems(Iterable<? extends F> iterable) {
+ for (F item : iterable) {
+ if (nextMatchIx < matchers.size()) {
+ Matcher<? super F> matcher = matchers.get(nextMatchIx);
+ if (matcher.matches(item)) {
+ lastMatchedItem = item;
+ nextMatchIx++;
+ }
+ }
+ }
+ }
+
+ public boolean isFinished() {
+ if (nextMatchIx < matchers.size()) {
+ mismatchDescription.appendDescriptionOf(matchers.get(nextMatchIx)).appendText(" was not found");
+ if (lastMatchedItem != null) {
+ mismatchDescription.appendText(" after ").appendValue(lastMatchedItem);
+ }
+ return false;
+ }
+ return true;
+ }
+
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields a series of items, that contains items logically equal to the
+ * corresponding item in the specified items, in the same relative order
+ * For example:
+ * <pre>assertThat(Arrays.asList("a", "b", "c", "d", "e"), containsInRelativeOrder("b", "d"))</pre>
+ *
+ * @param items
+ * the items that must be contained within items provided by an examined {@link Iterable} in the same relative order
+ */
+ public static <E> Matcher<Iterable<? extends E>> containsInRelativeOrder(E... items) {
+ List<Matcher<? super E>> matchers = new ArrayList<Matcher<? super E>>();
+ for (E item : items) {
+ matchers.add(equalTo(item));
+ }
+
+ return containsInRelativeOrder(matchers);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields a series of items, that each satisfying the corresponding
+ * matcher in the specified matchers, in the same relative order.
+ * For example:
+ * <pre>assertThat(Arrays.asList("a", "b", "c", "d", "e"), containsInRelativeOrder(equalTo("b"), equalTo("d")))</pre>
+ *
+ * @param itemMatchers
+ * the matchers that must be satisfied by the items provided by an examined {@link Iterable} in the same relative order
+ */
+ public static <E> Matcher<Iterable<? extends E>> containsInRelativeOrder(Matcher<? super E>... itemMatchers) {
+ return containsInRelativeOrder((List) asList(itemMatchers));
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields a series of items, that contains items satisfying the corresponding
+ * matcher in the specified list of matchers, in the same relative order.
+ * For example:
+ * <pre>assertThat(Arrays.asList("a", "b", "c", "d", "e"), contains(Arrays.asList(equalTo("b"), equalTo("d"))))</pre>
+ *
+ * @param itemMatchers
+ * a list of matchers, each of which must be satisfied by the items provided by
+ * an examined {@link Iterable} in the same relative order
+ */
+ public static <E> Matcher<Iterable<? extends E>> containsInRelativeOrder(List<Matcher<? super E>> itemMatchers) {
+ return new IsIterableContainingInRelativeOrder<E>(itemMatchers);
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableWithSize.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableWithSize.java
new file mode 100644
index 0000000..0a1535f
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsIterableWithSize.java
@@ -0,0 +1,53 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.FeatureMatcher;
+import org.hamcrest.Matcher;
+
+import java.util.Iterator;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public class IsIterableWithSize<E> extends FeatureMatcher<Iterable<E>, Integer> {
+
+ public IsIterableWithSize(Matcher<? super Integer> sizeMatcher) {
+ super(sizeMatcher, "an iterable with size", "iterable size");
+ }
+
+
+ @Override
+ protected Integer featureValueOf(Iterable<E> actual) {
+ int size = 0;
+ for (Iterator<E> iterator = actual.iterator(); iterator.hasNext(); iterator.next()) {
+ size++;
+ }
+ return size;
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields an item count that satisfies the specified
+ * matcher.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), iterableWithSize(equalTo(2)))</pre>
+ *
+ * @param sizeMatcher
+ * a matcher for the number of items that should be yielded by an examined {@link Iterable}
+ */
+ public static <E> Matcher<Iterable<E>> iterableWithSize(Matcher<? super Integer> sizeMatcher) {
+ return new IsIterableWithSize<E>(sizeMatcher);
+ }
+
+ /**
+ * Creates a matcher for {@link Iterable}s that matches when a single pass over the
+ * examined {@link Iterable} yields an item count that is equal to the specified
+ * <code>size</code> argument.
+ * For example:
+ * <pre>assertThat(Arrays.asList("foo", "bar"), iterableWithSize(2))</pre>
+ *
+ * @param size
+ * the number of items that should be yielded by an examined {@link Iterable}
+ */
+ public static <E> Matcher<Iterable<E>> iterableWithSize(int size) {
+ return iterableWithSize(equalTo(size));
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsMapContaining.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsMapContaining.java
index 74572dd..c29801e 100644
--- a/hamcrest-library/src/main/java/org/hamcrest/collection/IsMapContaining.java
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsMapContaining.java
@@ -1,28 +1,27 @@
package org.hamcrest.collection;
import org.hamcrest.Description;
-import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
-import org.hamcrest.core.IsAnything;
-
-import static org.hamcrest.core.IsEqual.equalTo;
import java.util.Map;
import java.util.Map.Entry;
-public class IsMapContaining<K,V> extends TypeSafeMatcher<Map<K, V>> {
+import static org.hamcrest.core.IsAnything.anything;
+import static org.hamcrest.core.IsEqual.equalTo;
- private final Matcher<K> keyMatcher;
- private final Matcher<V> valueMatcher;
+public class IsMapContaining<K,V> extends TypeSafeMatcher<Map<? extends K, ? extends V>> {
+ private final Matcher<? super K> keyMatcher;
+ private final Matcher<? super V> valueMatcher;
- public IsMapContaining(Matcher<K> keyMatcher, Matcher<V> valueMatcher) {
+ public IsMapContaining(Matcher<? super K> keyMatcher, Matcher<? super V> valueMatcher) {
this.keyMatcher = keyMatcher;
this.valueMatcher = valueMatcher;
}
- public boolean matchesSafely(Map<K, V> map) {
- for (Entry<K, V> entry : map.entrySet()) {
+ @Override
+ public boolean matchesSafely(Map<? extends K, ? extends V> map) {
+ for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
if (keyMatcher.matches(entry.getKey()) && valueMatcher.matches(entry.getValue())) {
return true;
}
@@ -30,41 +29,101 @@ public class IsMapContaining<K,V> extends TypeSafeMatcher<Map<K, V>> {
return false;
}
+ @Override
+ public void describeMismatchSafely(Map<? extends K, ? extends V> map, Description mismatchDescription) {
+ mismatchDescription.appendText("map was ").appendValueList("[", ", ", "]", map.entrySet());
+ }
+
+ @Override
public void describeTo(Description description) {
description.appendText("map containing [")
.appendDescriptionOf(keyMatcher)
.appendText("->")
- .appendDescriptionOf(valueMatcher)
- .appendText("]");
+ .appendDescriptionOf(valueMatcher)
+ .appendText("]");
}
- @Factory
- public static <K,V> Matcher<Map<K,V>> hasEntry(Matcher<K> keyMatcher, Matcher<V> valueMatcher) {
+ /**
+ * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains
+ * at least one entry whose key satisfies the specified <code>keyMatcher</code> <b>and</b> whose
+ * value satisfies the specified <code>valueMatcher</code>.
+ * For example:
+ * <pre>assertThat(myMap, hasEntry(equalTo("bar"), equalTo("foo")))</pre>
+ *
+ * @param keyMatcher
+ * the key matcher that, in combination with the valueMatcher, must be satisfied by at least one entry
+ * @param valueMatcher
+ * the value matcher that, in combination with the keyMatcher, must be satisfied by at least one entry
+ */
+ public static <K,V> Matcher<Map<? extends K,? extends V>> hasEntry(Matcher<? super K> keyMatcher, Matcher<? super V> valueMatcher) {
return new IsMapContaining<K,V>(keyMatcher, valueMatcher);
}
- @Factory
- public static <K,V> Matcher<Map<K,V>> hasEntry(K key, V value) {
- return hasEntry(equalTo(key), equalTo(value));
+ /**
+ * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains
+ * at least one entry whose key equals the specified <code>key</code> <b>and</b> whose value equals the
+ * specified <code>value</code>.
+ * For example:
+ * <pre>assertThat(myMap, hasEntry("bar", "foo"))</pre>
+ *
+ * @param key
+ * the key that, in combination with the value, must be describe at least one entry
+ * @param value
+ * the value that, in combination with the key, must be describe at least one entry
+ */
+ public static <K,V> Matcher<Map<? extends K,? extends V>> hasEntry(K key, V value) {
+ return new IsMapContaining<K,V>(equalTo(key), equalTo(value));
}
-
- @Factory
- public static <K,V> Matcher<Map<K,V>> hasKey(Matcher<K> keyMatcher) {
- return hasEntry(keyMatcher, IsAnything.<V>anything());
+
+ /**
+ * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains
+ * at least one key that satisfies the specified matcher.
+ * For example:
+ * <pre>assertThat(myMap, hasKey(equalTo("bar")))</pre>
+ *
+ * @param keyMatcher
+ * the matcher that must be satisfied by at least one key
+ */
+ public static <K> Matcher<Map<? extends K, ?>> hasKey(Matcher<? super K> keyMatcher) {
+ return new IsMapContaining<K,Object>(keyMatcher, anything());
}
- @Factory
- public static <K,V> Matcher<Map<K,V>> hasKey(K key) {
- return hasKey(equalTo(key));
+ /**
+ * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains
+ * at least one key that is equal to the specified key.
+ * For example:
+ * <pre>assertThat(myMap, hasKey("bar"))</pre>
+ *
+ * @param key
+ * the key that satisfying maps must contain
+ */
+ public static <K> Matcher<Map<? extends K, ?>> hasKey(K key) {
+ return new IsMapContaining<K,Object>(equalTo(key), anything());
}
- @Factory
- public static <K,V> Matcher<Map<K,V>> hasValue(Matcher<V> valueMatcher) {
- return hasEntry(IsAnything.<K>anything(), valueMatcher);
+ /**
+ * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains
+ * at least one value that satisfies the specified valueMatcher.
+ * For example:
+ * <pre>assertThat(myMap, hasValue(equalTo("foo")))</pre>
+ *
+ * @param valueMatcher
+ * the matcher that must be satisfied by at least one value
+ */
+ public static <V> Matcher<Map<?, ? extends V>> hasValue(Matcher<? super V> valueMatcher) {
+ return new IsMapContaining<Object,V>(anything(), valueMatcher);
}
- @Factory
- public static <K,V> Matcher<Map<K,V>> hasValue(V value) {
- return hasValue(equalTo(value));
+ /**
+ * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains
+ * at least one value that is equal to the specified value.
+ * For example:
+ * <pre>assertThat(myMap, hasValue("foo"))</pre>
+ *
+ * @param value
+ * the value that satisfying maps must contain
+ */
+ public static <V> Matcher<Map<?, ? extends V>> hasValue(V value) {
+ return new IsMapContaining<Object,V>(anything(), equalTo(value));
}
}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/collection/IsMapWithSize.java b/hamcrest-library/src/main/java/org/hamcrest/collection/IsMapWithSize.java
new file mode 100644
index 0000000..0132390
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/collection/IsMapWithSize.java
@@ -0,0 +1,60 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.FeatureMatcher;
+import org.hamcrest.Matcher;
+
+import java.util.Map;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+
+/**
+ * Matches if map size satisfies a nested matcher.
+ */
+public final class IsMapWithSize<K, V> extends FeatureMatcher<Map<? extends K, ? extends V>, Integer> {
+ public IsMapWithSize(Matcher<? super Integer> sizeMatcher) {
+ super(sizeMatcher, "a map with size", "map size");
+ }
+
+ @Override
+ protected Integer featureValueOf(Map<? extends K, ? extends V> actual) {
+ return actual.size();
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Map}s that matches when the <code>size()</code> method returns
+ * a value that satisfies the specified matcher.
+ * For example:
+ * <pre>assertThat(myMap, is(aMapWithSize(equalTo(2))))</pre>
+ *
+ * @param sizeMatcher
+ * a matcher for the size of an examined {@link java.util.Map}
+ */
+ public static <K, V> Matcher<Map<? extends K, ? extends V>> aMapWithSize(Matcher<? super Integer> sizeMatcher) {
+ return new IsMapWithSize<K, V>(sizeMatcher);
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Map}s that matches when the <code>size()</code> method returns
+ * a value equal to the specified <code>size</code>.
+ * For example:
+ * <pre>assertThat(myMap, is(aMapWithSize(2)))</pre>
+ *
+ * @param size
+ * the expected size of an examined {@link java.util.Map}
+ */
+ public static <K, V> Matcher<Map<? extends K, ? extends V>> aMapWithSize(int size) {
+ Matcher<? super Integer> matcher = equalTo(size);
+ return IsMapWithSize.aMapWithSize(matcher);
+ }
+
+ /**
+ * Creates a matcher for {@link java.util.Map}s that matches when the <code>size()</code> method returns
+ * zero.
+ * For example:
+ * <pre>assertThat(myMap, is(anEmptyMap()))</pre>
+ *
+ */
+ public static <K, V> Matcher<Map<? extends K, ? extends V>> anEmptyMap() {
+ return IsMapWithSize.aMapWithSize(equalTo(0));
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/comparator/ComparatorMatcherBuilder.java b/hamcrest-library/src/main/java/org/hamcrest/comparator/ComparatorMatcherBuilder.java
new file mode 100644
index 0000000..cf52211
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/comparator/ComparatorMatcherBuilder.java
@@ -0,0 +1,178 @@
+package org.hamcrest.comparator;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+import java.util.Comparator;
+
+import static java.lang.Integer.signum;
+
+public final class ComparatorMatcherBuilder<T> {
+
+ private final Comparator<T> comparator;
+ private final boolean includeComparatorInDescription;
+
+ /**
+ * Creates a matcher factory for matchers of {@code Comparable}s.
+ * For example:
+ * <pre>assertThat(1, ComparatorMatcherBuilder.&lt;Integer&gt;usingNaturalOrdering().lessThanOrEqualTo(1))</pre>
+ */
+ public static <T extends Comparable<T>> ComparatorMatcherBuilder<T> usingNaturalOrdering() {
+ return new ComparatorMatcherBuilder<T>(new Comparator<T>() {
+ @Override
+ public int compare(T o1, T o2) {
+ return o1.compareTo(o2);
+ }
+ }, false);
+ }
+
+ /**
+ * Creates a matcher factory for matchers of {@code Comparators}s of {@code T}.
+ * For example:
+ * <pre>assertThat(5, comparedBy(new Comparator&lt;Integer&gt;() {
+ * public int compare(Integer o1, Integer o2) {
+ * return -o1.compareTo(o2);
+ * }
+ * }).lessThan(4))</pre>
+ */
+ public static <T> ComparatorMatcherBuilder<T> comparedBy(Comparator<T> comparator) {
+ return new ComparatorMatcherBuilder<T>(comparator, true);
+ }
+
+ private ComparatorMatcherBuilder(Comparator<T> comparator, boolean includeComparatorInDescription) {
+ this.comparator = comparator;
+ this.includeComparatorInDescription = includeComparatorInDescription;
+ }
+
+ private static final class ComparatorMatcher<T> extends TypeSafeMatcher<T> {
+ private static final int LESS_THAN = -1;
+ private static final int GREATER_THAN = 1;
+ private static final int EQUAL = 0;
+
+ private final Comparator<T> comparator;
+ private final T expected;
+ private final int minCompare;
+ private final int maxCompare;
+ private final boolean includeComparatorInDescription;
+
+ private static final String[] comparisonDescriptions = {
+ "less than",
+ "equal to",
+ "greater than"
+ };
+
+ private ComparatorMatcher(Comparator<T> comparator, T expected, int minCompare, int maxCompare, boolean includeComparatorInDescription) {
+ this.comparator = comparator;
+ this.expected = expected;
+ this.minCompare = minCompare;
+ this.maxCompare = maxCompare;
+ this.includeComparatorInDescription = includeComparatorInDescription;
+ }
+
+ @Override
+ public boolean matchesSafely(T actual) {
+ try {
+ int compare = signum(comparator.compare(actual, expected));
+ return minCompare <= compare && compare <= maxCompare;
+ } catch (ClassCastException e) {
+ return false; // type erasure means someone can shonk in a non-T :(
+ }
+ }
+
+ @Override
+ public void describeMismatchSafely(T actual, Description mismatchDescription) {
+ mismatchDescription.appendValue(actual).appendText(" was ")
+ .appendText(asText(comparator.compare(actual, expected)))
+ .appendText(" ").appendValue(expected);
+ if (includeComparatorInDescription) {
+ mismatchDescription.appendText(" when compared by ").appendValue(comparator);
+ }
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("a value ").appendText(asText(minCompare));
+ if (minCompare != maxCompare) {
+ description.appendText(" or ").appendText(asText(maxCompare));
+ }
+ description.appendText(" ").appendValue(expected);
+ if (includeComparatorInDescription) {
+ description.appendText(" when compared by ").appendValue(comparator);
+ }
+ }
+
+ private static String asText(int comparison) {
+ return comparisonDescriptions[signum(comparison) + 1];
+ }
+ }
+
+ /**
+ * Creates a matcher of {@code T} object that matches when the examined object is
+ * equal to the specified value, as reported by the {@code Comparator} used to
+ * create this builder.
+ * For example:
+ * <pre>assertThat(1, ComparatorMatcherBuilder.&lt;Integer&gt;usingNaturalOrdering().comparesEqualTo(1))</pre>
+ *
+ * @param value the value which, when passed to the Comparator supplied to this builder, should return zero
+ */
+ public Matcher<T> comparesEqualTo(T value) {
+ return new ComparatorMatcher<T>(comparator, value, ComparatorMatcher.EQUAL, ComparatorMatcher.EQUAL, includeComparatorInDescription);
+ }
+
+ /**
+ * Creates a matcher of {@code T} object that matches when the examined object is
+ * greater than the specified value, as reported by the {@code Comparator} used to
+ * create this builder.
+ * For example:
+ * <pre>assertThat(2, ComparatorMatcherBuilder.&lt;Integer&gt;usingNaturalOrdering().greaterThan(1))</pre>
+ *
+ * @param value the value which, when passed to the Comparator supplied to this builder, should return greater
+ * than zero
+ */
+ public Matcher<T> greaterThan(T value) {
+ return new ComparatorMatcher<T>(comparator, value, ComparatorMatcher.GREATER_THAN, ComparatorMatcher.GREATER_THAN, includeComparatorInDescription);
+ }
+
+ /**
+ * Creates a matcher of {@code T} object that matches when the examined object is
+ * greater than or equal to the specified value, as reported by the {@code Comparator} used to
+ * create this builder.
+ * For example:
+ * <pre>assertThat(1, ComparatorMatcherBuilder.&lt;Integer&gt;usingNaturalOrdering().greaterThanOrEqualTo(1))</pre>
+ *
+ * @param value the value which, when passed to the Comparator supplied to this builder, should return greater
+ * than or equal to zero
+ */
+ public Matcher<T> greaterThanOrEqualTo(T value) {
+ return new ComparatorMatcher<T>(comparator, value, ComparatorMatcher.EQUAL, ComparatorMatcher.GREATER_THAN, includeComparatorInDescription);
+ }
+
+ /**
+ * Creates a matcher of {@code T} object that matches when the examined object is
+ * less than the specified value, as reported by the {@code Comparator} used to
+ * create this builder.
+ * For example:
+ * <pre>assertThat(1, ComparatorMatcherBuilder.&lt;Integer&gt;usingNaturalOrdering().lessThan(2))</pre>
+ *
+ * @param value the value which, when passed to the Comparator supplied to this builder, should return less
+ * than zero
+ */
+ public Matcher<T> lessThan(T value) {
+ return new ComparatorMatcher<T>(comparator, value, ComparatorMatcher.LESS_THAN, ComparatorMatcher.LESS_THAN, includeComparatorInDescription);
+ }
+
+ /**
+ * Creates a matcher of {@code T} object that matches when the examined object is
+ * less than or equal to the specified value, as reported by the {@code Comparator} used to
+ * create this builder.
+ * For example:
+ * <pre>assertThat(1, ComparatorMatcherBuilder.&lt;Integer&gt;usingNaturalOrdering().lessThanOrEqualTo(1))</pre>
+ *
+ * @param value the value which, when passed to the Comparator supplied to this builder, should return less
+ * than or equal to zero
+ */
+ public Matcher<T> lessThanOrEqualTo(T value) {
+ return new ComparatorMatcher<T>(comparator, value, ComparatorMatcher.LESS_THAN, ComparatorMatcher.EQUAL, includeComparatorInDescription);
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/io/FileMatchers.java b/hamcrest-library/src/main/java/org/hamcrest/io/FileMatchers.java
new file mode 100644
index 0000000..88288b0
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/io/FileMatchers.java
@@ -0,0 +1,107 @@
+package org.hamcrest.io;
+
+import org.hamcrest.Description;
+import org.hamcrest.FeatureMatcher;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public final class FileMatchers {
+
+ public static Matcher<File> anExistingDirectory() {
+ return fileChecker(IS_DIRECTORY, "an existing directory", "is not a directory");
+ }
+
+ public static Matcher<File> anExistingFileOrDirectory() {
+ return fileChecker(EXISTS, "an existing file or directory", "does not exist");
+ }
+
+ public static Matcher<File> anExistingFile() {
+ return fileChecker(IS_FILE, "an existing File", "is not a file");
+ }
+
+ public static Matcher<File> aReadableFile() {
+ return fileChecker(CAN_READ, "a readable File", "cannot be read");
+ }
+
+ public static Matcher<File> aWritableFile() {
+ return fileChecker(CAN_WRITE, "a writable File", "cannot be written to");
+ }
+
+ public static Matcher<File> aFileWithSize(long size) {
+ return aFileWithSize(equalTo(size));
+ }
+
+ public static Matcher<File> aFileWithSize(final Matcher<Long> expected) {
+ return new FeatureMatcher<File, Long>(expected, "A file with size", "size") {
+ @Override protected Long featureValueOf(File actual) { return actual.length(); }
+ };
+ }
+
+ public static Matcher<File> aFileNamed(final Matcher<String> expected) {
+ return new FeatureMatcher<File, String>(expected, "A file with name", "name") {
+ @Override protected String featureValueOf(File actual) { return actual.getName(); }
+ };
+ }
+
+ public static Matcher<File> aFileWithCanonicalPath(final Matcher<String> expected) {
+ return new FeatureMatcher<File, String>(expected, "A file with canonical path", "path") {
+ @Override protected String featureValueOf(File actual) {
+ try {
+ return actual.getCanonicalPath();
+ } catch (IOException e) {
+ return "Exception: " + e.getMessage();
+ }
+ }
+ };
+ }
+
+ public static Matcher<File> aFileWithAbsolutePath(final Matcher<String> expected) {
+ return new FeatureMatcher<File, String>(expected, "A file with absolute path", "path") {
+ @Override protected String featureValueOf(File actual) { return actual.getAbsolutePath(); }
+ };
+ }
+
+ public static interface FileStatus {
+ boolean check(File actual);
+ }
+
+ public static final FileStatus CAN_WRITE = new FileStatus() {
+ @Override public boolean check(File actual) { return actual.canWrite(); }
+ };
+ public static final FileStatus CAN_READ = new FileStatus() {
+ @Override public boolean check(File actual) { return actual.canRead(); }
+ };
+
+ public static final FileStatus IS_FILE = new FileStatus() {
+ @Override public boolean check(File actual) { return actual.isFile(); }
+ };
+
+ public static final FileStatus IS_DIRECTORY = new FileStatus() {
+ @Override public boolean check(File actual) { return actual.isDirectory(); }
+ };
+
+ public static final FileStatus EXISTS = new FileStatus() {
+ @Override public boolean check(File actual) { return actual.exists(); }
+ };
+
+ private static Matcher<File> fileChecker(final FileStatus fileStatus, final String successDescription, final String failureDescription) {
+ return new TypeSafeDiagnosingMatcher<File>() {
+ public boolean matchesSafely(File actual, Description mismatchDescription) {
+ final boolean result = fileStatus.check(actual);
+ if (!result) {
+ mismatchDescription.appendText(failureDescription);
+ }
+ return result;
+ }
+
+ public void describeTo(Description description) {
+ description.appendText(successDescription);
+ }
+ };
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/number/BigDecimalCloseTo.java b/hamcrest-library/src/main/java/org/hamcrest/number/BigDecimalCloseTo.java
new file mode 100644
index 0000000..d9cb026
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/number/BigDecimalCloseTo.java
@@ -0,0 +1,63 @@
+package org.hamcrest.number;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+
+public class BigDecimalCloseTo extends TypeSafeMatcher<BigDecimal> {
+
+ private final BigDecimal delta;
+ private final BigDecimal value;
+
+ public BigDecimalCloseTo(BigDecimal value, BigDecimal error) {
+ this.delta = error;
+ this.value = value;
+ }
+
+ @Override
+ public boolean matchesSafely(BigDecimal item) {
+ return actualDelta(item).compareTo(BigDecimal.ZERO) <= 0;
+ }
+
+ @Override
+ public void describeMismatchSafely(BigDecimal item, Description mismatchDescription) {
+ mismatchDescription.appendValue(item)
+ .appendText(" differed by ")
+ .appendValue(actualDelta(item))
+ .appendText(" more than delta ")
+ .appendValue(delta);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("a numeric value within ")
+ .appendValue(delta)
+ .appendText(" of ")
+ .appendValue(value);
+ }
+
+ private BigDecimal actualDelta(BigDecimal item) {
+ return item.subtract(value, MathContext.DECIMAL128).abs().subtract(delta, MathContext.DECIMAL128).stripTrailingZeros();
+ }
+
+ /**
+ * Creates a matcher of {@link java.math.BigDecimal}s that matches when an examined BigDecimal is equal
+ * to the specified <code>operand</code>, within a range of +/- <code>error</code>. The comparison for equality
+ * is done by BigDecimals {@link java.math.BigDecimal#compareTo(java.math.BigDecimal)} method.
+ * For example:
+ * <pre>assertThat(new BigDecimal("1.03"), is(closeTo(new BigDecimal("1.0"), new BigDecimal("0.03"))))</pre>
+ *
+ * @param operand
+ * the expected value of matching BigDecimals
+ * @param error
+ * the delta (+/-) within which matches will be allowed
+ */
+ public static Matcher<BigDecimal> closeTo(BigDecimal operand, BigDecimal error) {
+ return new BigDecimalCloseTo(operand, error);
+ }
+
+}
+
diff --git a/hamcrest-library/src/main/java/org/hamcrest/number/IsCloseTo.java b/hamcrest-library/src/main/java/org/hamcrest/number/IsCloseTo.java
index dc183e8..3b6967d 100644
--- a/hamcrest-library/src/main/java/org/hamcrest/number/IsCloseTo.java
+++ b/hamcrest-library/src/main/java/org/hamcrest/number/IsCloseTo.java
@@ -1,40 +1,63 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
package org.hamcrest.number;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
import org.hamcrest.TypeSafeMatcher;
+import static java.lang.Math.abs;
+
/**
* Is the value a number equal to a value within some range of
* acceptable error?
*/
public class IsCloseTo extends TypeSafeMatcher<Double> {
- private final double error;
+ private final double delta;
private final double value;
public IsCloseTo(double value, double error) {
- this.error = error;
+ this.delta = error;
this.value = value;
}
+ @Override
public boolean matchesSafely(Double item) {
- return Math.abs((item - value)) <= error;
+ return actualDelta(item) <= 0.0;
+ }
+
+ @Override
+ public void describeMismatchSafely(Double item, Description mismatchDescription) {
+ mismatchDescription.appendValue(item)
+ .appendText(" differed by ")
+ .appendValue(actualDelta(item))
+ .appendText(" more than delta ")
+ .appendValue(delta);
}
+ @Override
public void describeTo(Description description) {
description.appendText("a numeric value within ")
- .appendValue(error)
+ .appendValue(delta)
.appendText(" of ")
.appendValue(value);
}
- @Factory
+ private double actualDelta(Double item) {
+ return abs(item - value) - delta;
+ }
+
+ /**
+ * Creates a matcher of {@link Double}s that matches when an examined double is equal
+ * to the specified <code>operand</code>, within a range of +/- <code>error</code>.
+ * For example:
+ * <pre>assertThat(1.03, is(closeTo(1.0, 0.03)))</pre>
+ *
+ * @param operand
+ * the expected value of matching doubles
+ * @param error
+ * the delta (+/-) within which matches will be allowed
+ */
public static Matcher<Double> closeTo(double operand, double error) {
return new IsCloseTo(operand, error);
}
-
}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/number/IsGreaterThan.java b/hamcrest-library/src/main/java/org/hamcrest/number/IsGreaterThan.java
deleted file mode 100644
index 34046b7..0000000
--- a/hamcrest-library/src/main/java/org/hamcrest/number/IsGreaterThan.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
-package org.hamcrest.number;
-
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeMatcher;
-
-/**
- * Is the value less than or greater than another {@link java.lang.Comparable} value?
- */
-public class IsGreaterThan<T extends Comparable<T>> extends TypeSafeMatcher<T> {
- private final Comparable<T> compareTo;
-
- public IsGreaterThan(Comparable<T> compareTo) {
- this.compareTo = compareTo;
- }
-
- public boolean matchesSafely(T item) {
- return compareTo.compareTo(item) < 0;
- }
-
- public void describeTo(Description description) {
- description.appendText("a value greater than ");
- description.appendValue(compareTo);
- }
-}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/number/IsNaN.java b/hamcrest-library/src/main/java/org/hamcrest/number/IsNaN.java
new file mode 100644
index 0000000..415a9a2
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/number/IsNaN.java
@@ -0,0 +1,38 @@
+package org.hamcrest.number;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+
+/**
+ * Is the value a number actually not a number (NaN)?
+ */
+public final class IsNaN extends TypeSafeMatcher<Double> {
+
+ private IsNaN() { }
+
+ @Override
+ public boolean matchesSafely(Double item) {
+ return Double.isNaN(item);
+ }
+
+ @Override
+ public void describeMismatchSafely(Double item, Description mismatchDescription) {
+ mismatchDescription.appendText("was ").appendValue(item);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("a double value of NaN");
+ }
+
+ /**
+ * Creates a matcher of {@link Double}s that matches when an examined double is not a number.
+ * For example:
+ * <pre>assertThat(Double.NaN, is(notANumber()))</pre>
+ */
+ public static Matcher<Double> notANumber() {
+ return new IsNaN();
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/number/OrderingComparison.java b/hamcrest-library/src/main/java/org/hamcrest/number/OrderingComparison.java
new file mode 100644
index 0000000..8a77713
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/number/OrderingComparison.java
@@ -0,0 +1,79 @@
+package org.hamcrest.number;
+
+import org.hamcrest.Matcher;
+import org.hamcrest.comparator.ComparatorMatcherBuilder;
+
+public class OrderingComparison {
+
+ private OrderingComparison() {
+ }
+
+ /**
+ * Creates a matcher of {@link Comparable} object that matches when the examined object is
+ * equal to the specified value, as reported by the <code>compareTo</code> method of the
+ * <b>examined</b> object.
+ * For example:
+ * <pre>assertThat(1, comparesEqualTo(1))</pre>
+ *
+ * @param value the value which, when passed to the compareTo method of the examined object, should return zero
+ */
+ public static <T extends Comparable<T>> Matcher<T> comparesEqualTo(T value) {
+ return ComparatorMatcherBuilder.<T>usingNaturalOrdering().comparesEqualTo(value);
+ }
+
+ /**
+ * Creates a matcher of {@link Comparable} object that matches when the examined object is
+ * greater than the specified value, as reported by the <code>compareTo</code> method of the
+ * <b>examined</b> object.
+ * For example:
+ * <pre>assertThat(2, greaterThan(1))</pre>
+ *
+ * @param value the value which, when passed to the compareTo method of the examined object, should return greater
+ * than zero
+ */
+ public static <T extends Comparable<T>> Matcher<T> greaterThan(T value) {
+ return ComparatorMatcherBuilder.<T>usingNaturalOrdering().greaterThan(value);
+ }
+
+ /**
+ * Creates a matcher of {@link Comparable} object that matches when the examined object is
+ * greater than or equal to the specified value, as reported by the <code>compareTo</code> method
+ * of the <b>examined</b> object.
+ * For example:
+ * <pre>assertThat(1, greaterThanOrEqualTo(1))</pre>
+ *
+ * @param value the value which, when passed to the compareTo method of the examined object, should return greater
+ * than or equal to zero
+ */
+ public static <T extends Comparable<T>> Matcher<T> greaterThanOrEqualTo(T value) {
+ return ComparatorMatcherBuilder.<T>usingNaturalOrdering().greaterThanOrEqualTo(value);
+ }
+
+ /**
+ * Creates a matcher of {@link Comparable} object that matches when the examined object is
+ * less than the specified value, as reported by the <code>compareTo</code> method of the
+ * <b>examined</b> object.
+ * For example:
+ * <pre>assertThat(1, lessThan(2))</pre>
+ *
+ * @param value the value which, when passed to the compareTo method of the examined object, should return less
+ * than zero
+ */
+ public static <T extends Comparable<T>> Matcher<T> lessThan(T value) {
+ return ComparatorMatcherBuilder.<T>usingNaturalOrdering().lessThan(value);
+ }
+
+ /**
+ * Creates a matcher of {@link Comparable} object that matches when the examined object is
+ * less than or equal to the specified value, as reported by the <code>compareTo</code> method
+ * of the <b>examined</b> object.
+ * For example:
+ * <pre>assertThat(1, lessThanOrEqualTo(1))</pre>
+ *
+ * @param value the value which, when passed to the compareTo method of the examined object, should return less
+ * than or equal to zero
+ */
+ public static <T extends Comparable<T>> Matcher<T> lessThanOrEqualTo(T value) {
+ return ComparatorMatcherBuilder.<T>usingNaturalOrdering().lessThanOrEqualTo(value);
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/number/OrderingComparisons.java b/hamcrest-library/src/main/java/org/hamcrest/number/OrderingComparisons.java
deleted file mode 100644
index 1791a40..0000000
--- a/hamcrest-library/src/main/java/org/hamcrest/number/OrderingComparisons.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.hamcrest.number;
-
-import static org.hamcrest.core.AnyOf.anyOf;
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.hamcrest.core.IsNot.not;
-import static org.hamcrest.core.DescribedAs.describedAs;
-
-import org.hamcrest.Factory;
-import org.hamcrest.Matcher;
-
-@SuppressWarnings("unchecked")
-public class OrderingComparisons {
- @Factory
- public static <T extends Comparable<T>> Matcher<T> greaterThan(T value) {
- return new IsGreaterThan<T>(value);
- }
-
- @Factory
- public static <T extends Comparable<T>> Matcher<T> greaterThanOrEqualTo(T value) {
- return describedAs("a value greater than or equal to %0",
- anyOf(greaterThan(value), equalTo(value)),
- value);
- }
-
- @Factory
- public static <T extends Comparable<T>> Matcher<T> lessThan(T value) {
- return describedAs("a value less than %0",
- not(greaterThanOrEqualTo(value)),
- value);
- }
-
- @Factory
- public static <T extends Comparable<T>> Matcher<T> lessThanOrEqualTo(T value) {
- return describedAs("a value less than or equal to %0",
- not(greaterThan(value)),
- value);
- }
-}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/object/HasToString.java b/hamcrest-library/src/main/java/org/hamcrest/object/HasToString.java
index 0f12ffd..2dab9de 100644
--- a/hamcrest-library/src/main/java/org/hamcrest/object/HasToString.java
+++ b/hamcrest-library/src/main/java/org/hamcrest/object/HasToString.java
@@ -1,31 +1,43 @@
package org.hamcrest.object;
-import org.hamcrest.Description;
+import org.hamcrest.FeatureMatcher;
import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
-import org.hamcrest.BaseMatcher;
-public class HasToString<T> extends BaseMatcher<T> {
+import static org.hamcrest.core.IsEqual.equalTo;
- private final Matcher<String> toStringMatcher;
-
- public HasToString(Matcher<String> toStringMatcher) {
- this.toStringMatcher = toStringMatcher;
+public class HasToString<T> extends FeatureMatcher<T, String> {
+ public HasToString(Matcher<? super String> toStringMatcher) {
+ super(toStringMatcher, "with toString()", "toString()");
}
-
- public boolean matches(Object item) {
- return item != null && toStringMatcher.matches(item.toString());
+
+ @Override
+ protected String featureValueOf(T actual) {
+ return String.valueOf(actual);
}
- public void describeTo(Description description) {
- description
- .appendText("asString(")
- .appendDescriptionOf(toStringMatcher)
- .appendText(")");
- }
-
- @Factory
- public static <T> Matcher<T> hasToString(Matcher<String> toStringMatcher) {
+ /**
+ * Creates a matcher that matches any examined object whose <code>toString</code> method
+ * returns a value that satisfies the specified matcher.
+ * For example:
+ * <pre>assertThat(true, hasToString(equalTo("TRUE")))</pre>
+ *
+ * @param toStringMatcher
+ * the matcher used to verify the toString result
+ */
+ public static <T> Matcher<T> hasToString(Matcher<? super String> toStringMatcher) {
return new HasToString<T>(toStringMatcher);
}
+
+ /**
+ * Creates a matcher that matches any examined object whose <code>toString</code> method
+ * returns a value equalTo the specified string.
+ * For example:
+ * <pre>assertThat(true, hasToString("TRUE"))</pre>
+ *
+ * @param expectedToString
+ * the expected toString result
+ */
+ public static <T> Matcher<T> hasToString(String expectedToString) {
+ return new HasToString<T>(equalTo(expectedToString));
+ }
}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/object/IsCompatibleType.java b/hamcrest-library/src/main/java/org/hamcrest/object/IsCompatibleType.java
index 3a2dc7a..e1410a4 100644
--- a/hamcrest-library/src/main/java/org/hamcrest/object/IsCompatibleType.java
+++ b/hamcrest-library/src/main/java/org/hamcrest/object/IsCompatibleType.java
@@ -2,7 +2,6 @@ package org.hamcrest.object;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
import org.hamcrest.TypeSafeMatcher;
public class IsCompatibleType<T> extends TypeSafeMatcher<Class<?>> {
@@ -12,15 +11,30 @@ public class IsCompatibleType<T> extends TypeSafeMatcher<Class<?>> {
this.type = type;
}
+ @Override
public boolean matchesSafely(Class<?> cls) {
return type.isAssignableFrom(cls);
}
+ @Override
+ public void describeMismatchSafely(Class<?> cls, Description mismatchDescription) {
+ mismatchDescription.appendValue(cls.getName());
+ }
+
+ @Override
public void describeTo(Description description) {
description.appendText("type < ").appendText(type.getName());
}
- @Factory
+ /**
+ * Creates a matcher of {@link Class} that matches when the specified baseType is
+ * assignable from the examined class.
+ * For example:
+ * <pre>assertThat(Integer.class, typeCompatibleWith(Number.class))</pre>
+ *
+ * @param baseType
+ * the base class to examine classes against
+ */
public static <T> Matcher<Class<?>> typeCompatibleWith(Class<T> baseType) {
return new IsCompatibleType<T>(baseType);
}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/object/IsEventFrom.java b/hamcrest-library/src/main/java/org/hamcrest/object/IsEventFrom.java
index 504a8f5..43b64d4 100644
--- a/hamcrest-library/src/main/java/org/hamcrest/object/IsEventFrom.java
+++ b/hamcrest-library/src/main/java/org/hamcrest/object/IsEventFrom.java
@@ -1,11 +1,8 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
package org.hamcrest.object;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
-import org.hamcrest.TypeSafeMatcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
import java.util.EventObject;
@@ -13,24 +10,35 @@ import java.util.EventObject;
/**
* Tests if the value is an event announced by a specific object.
*/
-public class IsEventFrom extends TypeSafeMatcher<EventObject> {
- private final Class eventClass;
+public class IsEventFrom extends TypeSafeDiagnosingMatcher<EventObject> {
+ private final Class<?> eventClass;
private final Object source;
- public IsEventFrom(Class eventClass, Object source) {
+ public IsEventFrom(Class<?> eventClass, Object source) {
this.eventClass = eventClass;
this.source = source;
}
- public boolean matchesSafely(EventObject item) {
- return eventClass.isInstance(item)
- && eventHasSameSource(item);
+ @Override
+ public boolean matchesSafely(EventObject item, Description mismatchDescription) {
+ if (!eventClass.isInstance(item)) {
+ mismatchDescription.appendText("item type was " + item.getClass().getName());
+ return false;
+ }
+
+ if (!eventHasSameSource(item)) {
+ mismatchDescription.appendText("source was ").appendValue(item.getSource());
+ return false;
+ }
+ return true;
}
+
private boolean eventHasSameSource(EventObject ev) {
return ev.getSource() == source;
}
+ @Override
public void describeTo(Description description) {
description.appendText("an event of type ")
.appendText(eventClass.getName())
@@ -39,20 +47,29 @@ public class IsEventFrom extends TypeSafeMatcher<EventObject> {
}
/**
- * Constructs an IsEventFrom Matcher that returns true for any object
+ * Creates a matcher of {@link java.util.EventObject} that matches any object
* derived from <var>eventClass</var> announced by <var>source</var>.
+ * For example:
+ * <pre>assertThat(myEvent, is(eventFrom(PropertyChangeEvent.class, myBean)))</pre>
+ *
+ * @param eventClass
+ * the class of the event to match on
+ * @param source
+ * the source of the event
*/
- @Factory
public static Matcher<EventObject> eventFrom(Class<? extends EventObject> eventClass, Object source) {
return new IsEventFrom(eventClass, source);
}
/**
- * Constructs an IsEventFrom Matcher that returns true for any object
- * derived from {@link java.util.EventObject} announced by <var>source
- * </var>.
+ * Creates a matcher of {@link java.util.EventObject} that matches any EventObject
+ * announced by <var>source</var>.
+ * For example:
+ * <pre>assertThat(myEvent, is(eventFrom(myBean)))</pre>
+ *
+ * @param source
+ * the source of the event
*/
- @Factory
public static Matcher<EventObject> eventFrom(Object source) {
return eventFrom(EventObject.class, source);
}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/text/IsBlankString.java b/hamcrest-library/src/main/java/org/hamcrest/text/IsBlankString.java
new file mode 100644
index 0000000..b168541
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/text/IsBlankString.java
@@ -0,0 +1,55 @@
+
+package org.hamcrest.text;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+import java.util.regex.Pattern;
+
+import static org.hamcrest.core.AnyOf.anyOf;
+import static org.hamcrest.core.IsNull.nullValue;
+
+/**
+ * Matches blank Strings (and null).
+ */
+public final class IsBlankString extends TypeSafeMatcher<String> {
+ private static final IsBlankString BLANK_INSTANCE = new IsBlankString();
+ @SuppressWarnings("unchecked")
+ private static final Matcher<String> NULL_OR_BLANK_INSTANCE = anyOf(nullValue(), BLANK_INSTANCE);
+
+ private static final Pattern REGEX_WHITESPACE = Pattern.compile("\\s*");
+
+ private IsBlankString() { }
+
+ @Override
+ public boolean matchesSafely(String item) {
+ return REGEX_WHITESPACE.matcher(item).matches();
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("a blank string");
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string contains
+ * zero or more whitespace characters and nothing else.
+ * For example:
+ * <pre>assertThat(" ", is(blankString()))</pre>
+ */
+ public static Matcher<String> blankString() {
+ return BLANK_INSTANCE;
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string is <code>null</code>, or
+ * contains zero or more whitespace characters and nothing else.
+ * For example:
+ * <pre>assertThat(((String)null), is(blankOrNullString()))</pre>
+ *
+ */
+ public static Matcher<String> blankOrNullString() {
+ return NULL_OR_BLANK_INSTANCE;
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/text/IsEmptyString.java b/hamcrest-library/src/main/java/org/hamcrest/text/IsEmptyString.java
new file mode 100644
index 0000000..bbe5681
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/text/IsEmptyString.java
@@ -0,0 +1,77 @@
+
+package org.hamcrest.text;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+import static org.hamcrest.core.AnyOf.anyOf;
+import static org.hamcrest.core.IsNull.nullValue;
+
+/**
+ * Matches empty Strings (and null).
+ */
+public final class IsEmptyString extends TypeSafeMatcher<String> {
+ private static final IsEmptyString INSTANCE = new IsEmptyString();
+ @SuppressWarnings("unchecked")
+ private static final Matcher<String> NULL_OR_EMPTY_INSTANCE = anyOf(nullValue(), INSTANCE);
+
+ private IsEmptyString() { }
+
+ @Override
+ public boolean matchesSafely(String item) {
+ return item.equals("");
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("an empty string");
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string has zero length.
+ * For example:
+ * <pre>assertThat("", isEmptyString())</pre>
+ *
+ * @deprecated use is(emptyString()) instead
+ */
+ @Deprecated
+ public static Matcher<String> isEmptyString() {
+ return emptyString();
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string has zero length.
+ * For example:
+ * <pre>assertThat("", is(emptyString()))</pre>
+ *
+ */
+ public static Matcher<String> emptyString() {
+ return INSTANCE;
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string is <code>null</code>, or
+ * has zero length.
+ * For example:
+ * <pre>assertThat(((String)null), isEmptyOrNullString())</pre>
+ *
+ * @deprecated use is(emptyOrNullString()) instead
+ *
+ */
+ @Deprecated
+ public static Matcher<String> isEmptyOrNullString() {
+ return emptyOrNullString();
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string is <code>null</code>, or
+ * has zero length.
+ * For example:
+ * <pre>assertThat(((String)null), is(emptyOrNullString()))</pre>
+ *
+ */
+ public static Matcher<String> emptyOrNullString() {
+ return NULL_OR_EMPTY_INSTANCE;
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/text/IsEqualIgnoringCase.java b/hamcrest-library/src/main/java/org/hamcrest/text/IsEqualIgnoringCase.java
index cc78c71..00586f6 100644
--- a/hamcrest-library/src/main/java/org/hamcrest/text/IsEqualIgnoringCase.java
+++ b/hamcrest-library/src/main/java/org/hamcrest/text/IsEqualIgnoringCase.java
@@ -1,42 +1,54 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
-package org.hamcrest.text;
-
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
-import org.hamcrest.TypeSafeMatcher;
-
-/**
- * Tests if a string is equal to another string, regardless of the case.
- */
-public class IsEqualIgnoringCase extends TypeSafeMatcher<String> {
-
- // TODO: Replace String with CharSequence to allow for easy interopability between
- // String, StringBuffer, StringBuilder, CharBuffer, etc (joe).
-
- private final String string;
-
- public IsEqualIgnoringCase(String string) {
- if (string == null) {
- throw new IllegalArgumentException("Non-null value required by IsEqualIgnoringCase()");
- }
- this.string = string;
- }
-
- public boolean matchesSafely(String item) {
- return string.equalsIgnoreCase(item);
- }
-
- public void describeTo(Description description) {
- description.appendText("eqIgnoringCase(")
- .appendValue(string)
- .appendText(")");
- }
-
- @Factory
- public static Matcher<String> equalToIgnoringCase(String string) {
- return new IsEqualIgnoringCase(string);
- }
-
-}
+package org.hamcrest.text;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * Tests if a string is equal to another string, regardless of the case.
+ */
+public class IsEqualIgnoringCase extends TypeSafeMatcher<String> {
+
+ // TODO: Replace String with CharSequence to allow for easy interoperability between
+ // String, StringBuffer, StringBuilder, CharBuffer, etc (joe).
+
+ private final String string;
+
+ public IsEqualIgnoringCase(String string) {
+ if (string == null) {
+ throw new IllegalArgumentException("Non-null value required by IsEqualIgnoringCase()");
+ }
+ this.string = string;
+ }
+
+ @Override
+ public boolean matchesSafely(String item) {
+ return string.equalsIgnoreCase(item);
+ }
+
+ @Override
+ public void describeMismatchSafely(String item, Description mismatchDescription) {
+ mismatchDescription.appendText("was ").appendValue(item);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("equalToIgnoringCase(")
+ .appendValue(string)
+ .appendText(")");
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string is equal to
+ * the specified expectedString, ignoring case.
+ * For example:
+ * <pre>assertThat("Foo", equalToIgnoringCase("FOO"))</pre>
+ *
+ * @param expectedString
+ * the expected value of matched strings
+ */
+ public static Matcher<String> equalToIgnoringCase(String expectedString) {
+ return new IsEqualIgnoringCase(expectedString);
+ }
+
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/text/IsEqualIgnoringWhiteSpace.java b/hamcrest-library/src/main/java/org/hamcrest/text/IsEqualIgnoringWhiteSpace.java
index dd390e8..f2b706c 100644
--- a/hamcrest-library/src/main/java/org/hamcrest/text/IsEqualIgnoringWhiteSpace.java
+++ b/hamcrest-library/src/main/java/org/hamcrest/text/IsEqualIgnoringWhiteSpace.java
@@ -1,60 +1,79 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
-package org.hamcrest.text;
-
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.Factory;
-import org.hamcrest.TypeSafeMatcher;
-
-/**
- * Tests if a string is equal to another string, ignoring any changes in whitespace.
- */
-public class IsEqualIgnoringWhiteSpace extends TypeSafeMatcher<String> {
-
- // TODO: Replace String with CharSequence to allow for easy interopability between
- // String, StringBuffer, StringBuilder, CharBuffer, etc (joe).
-
- private final String string;
-
- public IsEqualIgnoringWhiteSpace(String string) {
- if (string == null) {
- throw new IllegalArgumentException("Non-null value required by IsEqualIgnoringCase()");
- }
- this.string = string;
- }
-
- public boolean matchesSafely(String item) {
- return stripSpace(string).equalsIgnoreCase(stripSpace(item));
- }
-
- public void describeTo(Description description) {
- description.appendText("eqIgnoringWhiteSpace(")
- .appendValue(string)
- .appendText(")");
- }
-
- public String stripSpace(String string) {
- StringBuilder result = new StringBuilder();
- boolean lastWasSpace = true;
- for (int i = 0; i < string.length(); i++) {
- char c = string.charAt(i);
- if (Character.isWhitespace(c)) {
- if (!lastWasSpace) {
- result.append(' ');
- }
- lastWasSpace = true;
- } else {
- result.append(c);
- lastWasSpace = false;
- }
- }
- return result.toString().trim();
- }
-
- @Factory
- public static Matcher<String> equalToIgnoringWhiteSpace(String string) {
- return new IsEqualIgnoringWhiteSpace(string);
- }
-
-}
+package org.hamcrest.text;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+import static java.lang.Character.isWhitespace;
+
+/**
+ * Tests if a string is equal to another string, ignoring any changes in whitespace.
+ */
+public class IsEqualIgnoringWhiteSpace extends TypeSafeMatcher<String> {
+
+ // TODO: Replace String with CharSequence to allow for easy interoperability between
+ // String, StringBuffer, StringBuilder, CharBuffer, etc (joe).
+
+ private final String string;
+
+ public IsEqualIgnoringWhiteSpace(String string) {
+ if (string == null) {
+ throw new IllegalArgumentException("Non-null value required by IsEqualIgnoringCase()");
+ }
+ this.string = string;
+ }
+
+ @Override
+ public boolean matchesSafely(String item) {
+ return stripSpace(string).equalsIgnoreCase(stripSpace(item));
+ }
+
+ @Override
+ public void describeMismatchSafely(String item, Description mismatchDescription) {
+ mismatchDescription.appendText("was ").appendText(stripSpace(item));
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("equalToIgnoringWhiteSpace(")
+ .appendValue(string)
+ .appendText(")");
+ }
+
+ public String stripSpace(String toBeStripped) {
+ final StringBuilder result = new StringBuilder();
+ boolean lastWasSpace = true;
+ for (int i = 0; i < toBeStripped.length(); i++) {
+ char c = toBeStripped.charAt(i);
+ if (isWhitespace(c)) {
+ if (!lastWasSpace) {
+ result.append(' ');
+ }
+ lastWasSpace = true;
+ } else {
+ result.append(c);
+ lastWasSpace = false;
+ }
+ }
+ return result.toString().trim();
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string is equal to
+ * the specified expectedString, when whitespace differences are (mostly) ignored. To be
+ * exact, the following whitespace rules are applied:
+ * <ul>
+ * <li>all leading and trailing whitespace of both the expectedString and the examined string are ignored</li>
+ * <li>any remaining whitespace, appearing within either string, is collapsed to a single space before comparison</li>
+ * </ul>
+ * For example:
+ * <pre>assertThat(" my\tfoo bar ", equalToIgnoringWhiteSpace(" my foo bar"))</pre>
+ *
+ * @param expectedString
+ * the expected value of matched strings
+ */
+ public static Matcher<String> equalToIgnoringWhiteSpace(String expectedString) {
+ return new IsEqualIgnoringWhiteSpace(expectedString);
+ }
+
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/text/MatchesPattern.java b/hamcrest-library/src/main/java/org/hamcrest/text/MatchesPattern.java
new file mode 100644
index 0000000..e0eda0a
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/text/MatchesPattern.java
@@ -0,0 +1,41 @@
+package org.hamcrest.text;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+import java.util.regex.Pattern;
+
+public class MatchesPattern extends TypeSafeMatcher<String> {
+ private final Pattern pattern;
+
+ public MatchesPattern(Pattern pattern) {
+ this.pattern = pattern;
+ }
+
+ @Override
+ protected boolean matchesSafely(String item) {
+ return pattern.matcher(item).matches();
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("a string matching the pattern '" + pattern + "'");
+ }
+
+ /**
+ * Creates a matcher of {@link java.lang.String} that matches when the examined string
+ * exactly matches the given {@link java.util.regex.Pattern}.
+ */
+ public static Matcher<String> matchesPattern(Pattern pattern) {
+ return new MatchesPattern(pattern);
+ }
+
+ /**
+ * Creates a matcher of {@link java.lang.String} that matches when the examined string
+ * exactly matches the given regular expression, treated as a {@link java.util.regex.Pattern}.
+ */
+ public static Matcher<String> matchesPattern(String regex) {
+ return new MatchesPattern(Pattern.compile(regex));
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/text/StringContains.java b/hamcrest-library/src/main/java/org/hamcrest/text/StringContains.java
deleted file mode 100644
index 9e55560..0000000
--- a/hamcrest-library/src/main/java/org/hamcrest/text/StringContains.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
-package org.hamcrest.text;
-
-import org.hamcrest.Factory;
-import org.hamcrest.Matcher;
-
-/**
- * Tests if the argument is a string that contains a substring.
- */
-public class StringContains extends SubstringMatcher {
- public StringContains(String substring) {
- super(substring);
- }
-
- protected boolean evalSubstringOf(String s) {
- return s.indexOf(substring) >= 0;
- }
-
- protected String relationship() {
- return "containing";
- }
-
- @Factory
- public static Matcher<String> containsString(String substring) {
- return new StringContains(substring);
- }
-
-} \ No newline at end of file
diff --git a/hamcrest-library/src/main/java/org/hamcrest/text/StringContainsInOrder.java b/hamcrest-library/src/main/java/org/hamcrest/text/StringContainsInOrder.java
new file mode 100644
index 0000000..f5d24ff
--- /dev/null
+++ b/hamcrest-library/src/main/java/org/hamcrest/text/StringContainsInOrder.java
@@ -0,0 +1,69 @@
+package org.hamcrest.text;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+import java.util.Arrays;
+
+public class StringContainsInOrder extends TypeSafeMatcher<String> {
+ private final Iterable<String> substrings;
+
+ public StringContainsInOrder(Iterable<String> substrings) {
+ this.substrings = substrings;
+ }
+
+ @Override
+ public boolean matchesSafely(String s) {
+ int fromIndex = 0;
+
+ for (String substring : substrings) {
+ fromIndex = s.indexOf(substring, fromIndex);
+ if (fromIndex == -1) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public void describeMismatchSafely(String item, Description mismatchDescription) {
+ mismatchDescription.appendText("was \"").appendText(item).appendText("\"");
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("a string containing ")
+ .appendValueList("", ", ", "", substrings)
+ .appendText(" in order");
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string contains all of
+ * the specified substrings, considering the order of their appearance.
+ * For example:
+ * <pre>assertThat("myfoobarbaz", stringContainsInOrder(Arrays.asList("bar", "foo")))</pre>
+ * fails as "foo" occurs before "bar" in the string "myfoobarbaz"
+ *
+ * @param substrings
+ * the substrings that must be contained within matching strings
+ */
+ public static Matcher<String> stringContainsInOrder(Iterable<String> substrings) {
+ return new StringContainsInOrder(substrings);
+ }
+
+ /**
+ * Creates a matcher of {@link String} that matches when the examined string contains all of
+ * the specified substrings, considering the order of their appearance.
+ * For example:
+ * <pre>assertThat("myfoobarbaz", stringContainsInOrder("bar", "foo"))</pre>
+ * fails as "foo" occurs before "bar" in the string "myfoobarbaz"
+ *
+ * @param substrings
+ * the substrings that must be contained within matching strings
+ */
+ public static Matcher<String> stringContainsInOrder(String... substrings) {
+ return new StringContainsInOrder(Arrays.asList(substrings));
+ }
+}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/text/StringEndsWith.java b/hamcrest-library/src/main/java/org/hamcrest/text/StringEndsWith.java
deleted file mode 100644
index 10e4764..0000000
--- a/hamcrest-library/src/main/java/org/hamcrest/text/StringEndsWith.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
-package org.hamcrest.text;
-
-import org.hamcrest.Factory;
-import org.hamcrest.Matcher;
-
-/**
- * Tests if the argument is a string that contains a substring.
- */
-public class StringEndsWith extends SubstringMatcher {
- public StringEndsWith(String substring) {
- super(substring);
- }
-
- protected boolean evalSubstringOf(String s) {
- return s.endsWith(substring);
- }
-
- protected String relationship() {
- return "ending with";
- }
-
- @Factory
- public static Matcher<String> endsWith(String substring) {
- return new StringEndsWith(substring);
- }
-
-}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/text/StringStartsWith.java b/hamcrest-library/src/main/java/org/hamcrest/text/StringStartsWith.java
deleted file mode 100644
index 4613101..0000000
--- a/hamcrest-library/src/main/java/org/hamcrest/text/StringStartsWith.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (c) 2000-2006 hamcrest.org
- */
-package org.hamcrest.text;
-
-import org.hamcrest.Factory;
-import org.hamcrest.Matcher;
-
-/**
- * Tests if the argument is a string that contains a substring.
- */
-public class StringStartsWith extends SubstringMatcher {
- public StringStartsWith(String substring) {
- super(substring);
- }
-
- protected boolean evalSubstringOf(String s) {
- return s.startsWith(substring);
- }
-
- protected String relationship() {
- return "starting with";
- }
-
- @Factory
- public static Matcher<String> startsWith(String substring) {
- return new StringStartsWith(substring);
- }
-
-} \ No newline at end of file
diff --git a/hamcrest-library/src/main/java/org/hamcrest/text/SubstringMatcher.java b/hamcrest-library/src/main/java/org/hamcrest/text/SubstringMatcher.java
deleted file mode 100644
index 8ebe739..0000000
--- a/hamcrest-library/src/main/java/org/hamcrest/text/SubstringMatcher.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.hamcrest.text;
-
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeMatcher;
-
-public abstract class SubstringMatcher extends TypeSafeMatcher<String> {
-
- // TODO: Replace String with CharSequence to allow for easy interopability between
- // String, StringBuffer, StringBuilder, CharBuffer, etc (joe).
-
- protected final String substring;
-
- protected SubstringMatcher(final String substring) {
- this.substring = substring;
- }
-
- public boolean matchesSafely(String item) {
- return evalSubstringOf(item);
- }
-
- public void describeTo(Description description) {
- description.appendText("a string ")
- .appendText(relationship())
- .appendText(" ")
- .appendValue(substring);
- }
-
- protected abstract boolean evalSubstringOf(String string);
-
- protected abstract String relationship();
-} \ No newline at end of file
diff --git a/hamcrest-library/src/main/java/org/hamcrest/text/X.java b/hamcrest-library/src/main/java/org/hamcrest/text/X.java
deleted file mode 100644
index 7e85bd9..0000000
--- a/hamcrest-library/src/main/java/org/hamcrest/text/X.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.hamcrest.text;
-
-import org.hamcrest.Matcher;
-import org.hamcrest.CoreMatchers;
-
-public class X {
-
- public static void main(String[] args) {
-
- x(CoreMatchers.any(String.class));
-
-
- }
-
- private static void x(Matcher<String> s) {
-
- }
-}
diff --git a/hamcrest-library/src/main/java/org/hamcrest/xml/HasXPath.java b/hamcrest-library/src/main/java/org/hamcrest/xml/HasXPath.java
index 742935b..30ed081 100644
--- a/hamcrest-library/src/main/java/org/hamcrest/xml/HasXPath.java
+++ b/hamcrest-library/src/main/java/org/hamcrest/xml/HasXPath.java
@@ -1,27 +1,34 @@
package org.hamcrest.xml;
+import org.hamcrest.Condition;
import org.hamcrest.Description;
-import org.hamcrest.Factory;
import org.hamcrest.Matcher;
-import org.hamcrest.TypeSafeMatcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.hamcrest.core.IsAnything;
import org.w3c.dom.Node;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.xpath.*;
+
+import static javax.xml.xpath.XPathConstants.STRING;
+import static org.hamcrest.Condition.matched;
+import static org.hamcrest.Condition.notMatched;
/**
* Applies a Matcher to a given XML Node in an existing XML Node tree, specified by an XPath expression.
*
* @author Joe Walnes
+ * @author Steve Freeman
*/
-public class HasXPath extends TypeSafeMatcher<Node> {
-
+public class HasXPath extends TypeSafeDiagnosingMatcher<Node> {
+ public static final NamespaceContext NO_NAMESPACE_CONTEXT = null;
+ private static final IsAnything<String> WITH_ANY_CONTENT = new IsAnything<String>("");
+ private static final Condition.Step<Object,String> NODE_EXISTS = nodeExists();
private final Matcher<String> valueMatcher;
private final XPathExpression compiledXPath;
private final String xpathString;
+ private final QName evaluationMode;
/**
* @param xPathExpression XPath expression.
@@ -29,46 +36,134 @@ public class HasXPath extends TypeSafeMatcher<Node> {
* May be null to specify that the XPath must exist but the value is irrelevant.
*/
public HasXPath(String xPathExpression, Matcher<String> valueMatcher) {
+ this(xPathExpression, NO_NAMESPACE_CONTEXT, valueMatcher);
+ }
+
+ /**
+ * @param xPathExpression XPath expression.
+ * @param namespaceContext Resolves XML namespace prefixes in the XPath expression
+ * @param valueMatcher Matcher to use at given XPath.
+ * May be null to specify that the XPath must exist but the value is irrelevant.
+ */
+ public HasXPath(String xPathExpression, NamespaceContext namespaceContext, Matcher<String> valueMatcher) {
+ this(xPathExpression, namespaceContext, valueMatcher, STRING);
+ }
+
+ private HasXPath(String xPathExpression, NamespaceContext namespaceContext, Matcher<String> valueMatcher, QName mode) {
+ this.compiledXPath = compiledXPath(xPathExpression, namespaceContext);
+ this.xpathString = xPathExpression;
+ this.valueMatcher = valueMatcher;
+ this.evaluationMode = mode;
+ }
+
+ @Override
+ public boolean matchesSafely(Node item, Description mismatch) {
+ return evaluated(item, mismatch)
+ .and(NODE_EXISTS)
+ .matching(valueMatcher);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("an XML document with XPath ").appendText(xpathString);
+ if (valueMatcher != null) {
+ description.appendText(" ").appendDescriptionOf(valueMatcher);
+ }
+ }
+
+ private Condition<Object> evaluated(Node item, Description mismatch) {
try {
- XPath xPath = XPathFactory.newInstance().newXPath();
- compiledXPath = xPath.compile(xPathExpression);
- this.xpathString = xPathExpression;
- this.valueMatcher = valueMatcher;
+ return matched(compiledXPath.evaluate(item, evaluationMode), mismatch);
} catch (XPathExpressionException e) {
- throw new IllegalArgumentException("Invalid XPath : " + xPathExpression, e);
+ mismatch.appendText(e.getMessage());
}
+ return notMatched();
}
- public boolean matchesSafely(Node item) {
+ private static Condition.Step<Object, String> nodeExists() {
+ return new Condition.Step<Object, String>() {
+ @Override
+ public Condition<String> apply(Object value, Description mismatch) {
+ if (value == null) {
+ mismatch.appendText("xpath returned no results.");
+ return notMatched();
+ }
+ return matched(String.valueOf(value), mismatch);
+ }
+ };
+ }
+
+ private static XPathExpression compiledXPath(String xPathExpression, NamespaceContext namespaceContext) {
try {
- String result = (String) compiledXPath.evaluate(item, XPathConstants.STRING);
- if (result == null) {
- return false;
- } else if (valueMatcher == null) {
- return !result.equals("");
- } else {
- return valueMatcher.matches(result);
+ final XPath xPath = XPathFactory.newInstance().newXPath();
+ if (namespaceContext != null) {
+ xPath.setNamespaceContext(namespaceContext);
}
+ return xPath.compile(xPathExpression);
} catch (XPathExpressionException e) {
- return false;
+ throw new IllegalArgumentException("Invalid XPath : " + xPathExpression, e);
}
}
- public void describeTo(Description description) {
- description.appendText("an XML document with XPath ").appendText(xpathString);
- if (valueMatcher != null) {
- description.appendText(" ").appendDescriptionOf(valueMatcher);
- }
- }
-
- @Factory
+
+ /**
+ * Creates a matcher of {@link org.w3c.dom.Node}s that matches when the examined node has a value at the
+ * specified <code>xPath</code> that satisfies the specified <code>valueMatcher</code>.
+ * For example:
+ * <pre>assertThat(xml, hasXPath("/root/something[2]/cheese", equalTo("Cheddar")))</pre>
+ *
+ * @param xPath
+ * the target xpath
+ * @param valueMatcher
+ * matcher for the value at the specified xpath
+ */
public static Matcher<Node> hasXPath(String xPath, Matcher<String> valueMatcher) {
- return new HasXPath(xPath, valueMatcher);
+ return hasXPath(xPath, NO_NAMESPACE_CONTEXT, valueMatcher);
+ }
+
+ /**
+ * Creates a matcher of {@link org.w3c.dom.Node}s that matches when the examined node has a value at the
+ * specified <code>xPath</code>, within the specified <code>namespaceContext</code>, that satisfies
+ * the specified <code>valueMatcher</code>.
+ * For example:
+ * <pre>assertThat(xml, hasXPath("/root/something[2]/cheese", myNs, equalTo("Cheddar")))</pre>
+ *
+ * @param xPath
+ * the target xpath
+ * @param namespaceContext
+ * the namespace for matching nodes
+ * @param valueMatcher
+ * matcher for the value at the specified xpath
+ */
+ public static Matcher<Node> hasXPath(String xPath, NamespaceContext namespaceContext, Matcher<String> valueMatcher) {
+ return new HasXPath(xPath, namespaceContext, valueMatcher, STRING);
}
- @Factory
+ /**
+ * Creates a matcher of {@link org.w3c.dom.Node}s that matches when the examined node contains a node
+ * at the specified <code>xPath</code>, with any content.
+ * For example:
+ * <pre>assertThat(xml, hasXPath("/root/something[2]/cheese"))</pre>
+ *
+ * @param xPath
+ * the target xpath
+ */
public static Matcher<Node> hasXPath(String xPath) {
- return hasXPath(xPath, null);
+ return hasXPath(xPath, NO_NAMESPACE_CONTEXT);
}
+ /**
+ * Creates a matcher of {@link org.w3c.dom.Node}s that matches when the examined node contains a node
+ * at the specified <code>xPath</code> within the specified namespace context, with any content.
+ * For example:
+ * <pre>assertThat(xml, hasXPath("/root/something[2]/cheese", myNs))</pre>
+ *
+ * @param xPath
+ * the target xpath
+ * @param namespaceContext
+ * the namespace for matching nodes
+ */
+ public static Matcher<Node> hasXPath(String xPath, NamespaceContext namespaceContext) {
+ return new HasXPath(xPath, namespaceContext, WITH_ANY_CONTENT, XPathConstants.NODE);
+ }
}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/beans/HasPropertyTest.java b/hamcrest-library/src/test/java/org/hamcrest/beans/HasPropertyTest.java
new file mode 100644
index 0000000..314797f
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/beans/HasPropertyTest.java
@@ -0,0 +1,48 @@
+package org.hamcrest.beans;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.beans.HasProperty.hasProperty;
+
+/**
+ * @author Iain McGinniss
+ * @author Nat Pryce
+ * @author Steve Freeman
+ * @author Tom Denley
+ * @since 1.1.0
+ */
+public final class HasPropertyTest {
+
+ private final HasPropertyWithValueTest.BeanWithoutInfo bean = new HasPropertyWithValueTest.BeanWithoutInfo("a bean");
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<Object> matcher = hasProperty("irrelevant");
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ matchesWhenThePropertyExists() {
+ assertMatches(hasProperty("writeOnlyProperty"), bean);
+ }
+
+ @Test public void
+ doesNotMatchIfPropertyDoesNotExist() {
+ assertDoesNotMatch(hasProperty("aNonExistentProp"), bean);
+ }
+
+ @Test public void
+ describesItself() {
+ assertDescription("hasProperty(\"property\")", hasProperty("property"));
+ }
+
+ @Test public void
+ describesAMismatch() {
+ assertMismatchDescription("no \"aNonExistentProp\" in <[Person: a bean]>",
+ hasProperty("aNonExistentProp"), bean);
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/beans/HasPropertyWithValueTest.java b/hamcrest-library/src/test/java/org/hamcrest/beans/HasPropertyWithValueTest.java
new file mode 100644
index 0000000..eeaa113
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/beans/HasPropertyWithValueTest.java
@@ -0,0 +1,139 @@
+package org.hamcrest.beans;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.StringDescription;
+import org.hamcrest.core.IsEqual;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.beans.SimpleBeanInfo;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
+import static org.hamcrest.core.IsAnything.anything;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+/**
+ * @author Iain McGinniss
+ * @author Nat Pryce
+ * @author Steve Freeman
+ * @since 1.1.0
+ */
+@SuppressWarnings("UnusedDeclaration")
+public class HasPropertyWithValueTest extends AbstractMatcherTest {
+ private final BeanWithoutInfo shouldMatch = new BeanWithoutInfo("is expected");
+ private final BeanWithoutInfo shouldNotMatch = new BeanWithoutInfo("not expected");
+
+ private final BeanWithInfo beanWithInfo = new BeanWithInfo("with info");
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return hasProperty("irrelevant", anything());
+ }
+
+ public void testMatchesInfolessBeanWithMatchedNamedProperty() {
+ assertMatches("with property", hasProperty("property", equalTo("is expected")), shouldMatch);
+ assertMismatchDescription("property 'property' was \"not expected\"",
+ hasProperty("property", equalTo("is expected")), shouldNotMatch);
+ }
+
+ public void testMatchesBeanWithInfoWithMatchedNamedProperty() {
+ assertMatches("with bean info", hasProperty("property", equalTo("with info")), beanWithInfo);
+ assertMismatchDescription("property 'property' was \"with info\"",
+ hasProperty("property", equalTo("without info")), beanWithInfo);
+ }
+
+ public void testDoesNotMatchInfolessBeanWithoutMatchedNamedProperty() {
+ assertMismatchDescription("No property \"nonExistentProperty\"",
+ hasProperty("nonExistentProperty", anything()), shouldNotMatch);
+ }
+
+ public void testDoesNotMatchWriteOnlyProperty() {
+ assertMismatchDescription("property \"writeOnlyProperty\" is not readable",
+ hasProperty("writeOnlyProperty", anything()), shouldNotMatch);
+ }
+
+ public void testDescribeTo() {
+ assertDescription("hasProperty(\"property\", <true>)", hasProperty("property", equalTo(true)));
+ }
+
+ public void testMatchesPropertyAndValue() {
+ assertMatches("property with value", hasProperty( "property", anything()), beanWithInfo);
+ }
+
+ public void testDoesNotWriteMismatchIfPropertyMatches() {
+ Description description = new StringDescription();
+ hasProperty( "property", anything()).describeMismatch(beanWithInfo, description);
+ assertEquals("Expected mismatch description", "", description.toString());
+ }
+
+ public void testDescribesMissingPropertyMismatch() {
+ assertMismatchDescription("No property \"honk\"", hasProperty( "honk", anything()), shouldNotMatch);
+ }
+
+ public void testCanAccessAnAnonymousInnerClass() {
+ class X implements IX {
+ @Override
+ public int getTest() {
+ return 1;
+ }
+ }
+
+ assertThat(new X(), HasPropertyWithValue.hasProperty("test", IsEqual.equalTo(1)));
+ }
+
+ interface IX {
+ int getTest();
+ }
+
+ public static class BeanWithoutInfo {
+ private String property;
+
+ public BeanWithoutInfo(String property) {
+ this.property = property;
+ }
+
+ public String getProperty() {
+ return property;
+ }
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ public void setWriteOnlyProperty(@SuppressWarnings("unused") float property) {
+ }
+
+ @Override
+ public String toString() {
+ return "[Person: " + property + "]";
+ }
+ }
+
+ public static class BeanWithInfo {
+ private final String propertyValue;
+
+ public BeanWithInfo(String propertyValue) {
+ this.propertyValue = propertyValue;
+ }
+
+ public String property() {
+ return propertyValue;
+ }
+ }
+
+ public static class BeanWithInfoBeanInfo extends SimpleBeanInfo {
+ @Override
+ public PropertyDescriptor[] getPropertyDescriptors() {
+ try {
+ return new PropertyDescriptor[] {
+ new PropertyDescriptor("property", BeanWithInfo.class, "property", null)
+ };
+ } catch (IntrospectionException e) {
+ throw new RuntimeException("Introspection exception: " + e.getMessage());
+ }
+ }
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/beans/SamePropertyValuesAsTest.java b/hamcrest-library/src/test/java/org/hamcrest/beans/SamePropertyValuesAsTest.java
new file mode 100644
index 0000000..173457f
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/beans/SamePropertyValuesAsTest.java
@@ -0,0 +1,98 @@
+package org.hamcrest.beans;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.beans.SamePropertyValuesAs.samePropertyValuesAs;
+
+@SuppressWarnings("UnusedDeclaration")
+public class SamePropertyValuesAsTest extends AbstractMatcherTest {
+ private static final Value aValue = new Value("expected");
+ private static final ExampleBean expectedBean = new ExampleBean("same", 1, aValue);
+ private static final ExampleBean actualBean = new ExampleBean("same", 1, aValue);
+
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return samePropertyValuesAs(expectedBean);
+ }
+
+ public void testReportsMatchWhenAllPropertiesMatch() {
+ assertMatches("matched properties", samePropertyValuesAs(expectedBean), actualBean);
+ }
+
+ public void testReportsMismatchWhenActualTypeIsNotAssignableToExpectedType() {
+ assertMismatchDescription("is incompatible type: ExampleBean",
+ samePropertyValuesAs((Object)aValue), actualBean);
+ }
+
+ public void testReportsMismatchOnFirstPropertyDifference() {
+ assertMismatchDescription("string was \"different\"",
+ samePropertyValuesAs(expectedBean), new ExampleBean("different", 1, aValue));
+ assertMismatchDescription("int was <2>",
+ samePropertyValuesAs(expectedBean), new ExampleBean("same", 2, aValue));
+ assertMismatchDescription("value was <Value other>",
+ samePropertyValuesAs(expectedBean), new ExampleBean("same", 1, new Value("other")));
+ }
+
+ public void testMatchesBeansWithInheritanceButNoExtraProperties() {
+ assertMatches("sub type with same properties",
+ samePropertyValuesAs(expectedBean), new SubBeanWithNoExtraProperties("same", 1, aValue));
+ }
+
+ public void testRejectsSubTypeThatHasExtraProperties() {
+ assertMismatchDescription("has extra properties called [extra]",
+ samePropertyValuesAs(expectedBean), new SubBeanWithExtraProperty("same", 1, aValue));
+ }
+
+ public void testDescribesItself() {
+ assertDescription("same property values as ExampleBean [int: <1>, string: \"same\", value: <Value expected>]", samePropertyValuesAs(expectedBean));
+ }
+
+ public static class Value {
+ public Value(Object value) {
+ this.value = value;
+ }
+
+ public final Object value;
+ @Override
+ public String toString() {
+ return "Value " + value;
+ }
+ }
+
+ public static class ExampleBean {
+ private String stringProperty;
+ private int intProperty;
+ private Value valueProperty;
+
+ public ExampleBean(String stringProperty, int intProperty, Value valueProperty) {
+ this.stringProperty = stringProperty;
+ this.intProperty = intProperty;
+ this.valueProperty = valueProperty;
+ }
+
+ public String getString() {
+ return stringProperty;
+ }
+ public int getInt() {
+ return intProperty;
+ }
+ public Value getValue() {
+ return valueProperty;
+ }
+ }
+
+ public static class SubBeanWithNoExtraProperties extends ExampleBean {
+ public SubBeanWithNoExtraProperties(String stringProperty, int intProperty, Value valueProperty) {
+ super(stringProperty, intProperty, valueProperty);
+ }
+ }
+
+ public static class SubBeanWithExtraProperty extends ExampleBean {
+ public SubBeanWithExtraProperty(String stringProperty, int intProperty, Value valueProperty) {
+ super(stringProperty, intProperty, valueProperty);
+ }
+ public String getExtra() { return "extra"; }
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayContainingInAnyOrderTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayContainingInAnyOrderTest.java
new file mode 100644
index 0000000..d4dc270
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayContainingInAnyOrderTest.java
@@ -0,0 +1,43 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.collection.IsArrayContainingInAnyOrder.arrayContainingInAnyOrder;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public class IsArrayContainingInAnyOrderTest extends AbstractMatcherTest {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected Matcher<?> createMatcher() {
+ return arrayContainingInAnyOrder(equalTo(1), equalTo(2));
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testHasAReadableDescription() {
+ assertDescription("[<1>, <2>] in any order", arrayContainingInAnyOrder(equalTo(1), equalTo(2)));
+ assertDescription("[<1>, <2>] in any order", arrayContainingInAnyOrder(1, 2));
+ }
+
+ public void testMatchesItemsInAnyOrder() {
+ assertMatches("in order", arrayContainingInAnyOrder(1, 2, 3), new Integer[] {1, 2, 3});
+ assertMatches("out of order", arrayContainingInAnyOrder(1, 2, 3), new Integer[] {3, 2, 1});
+ assertMatches("single", arrayContainingInAnyOrder(1), new Integer[] {1});
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testAppliesMatchersInAnyOrder() {
+ assertMatches("in order", arrayContainingInAnyOrder(equalTo(1), equalTo(2), equalTo(3)), new Integer[] {1, 2, 3});
+ assertMatches("out of order", arrayContainingInAnyOrder(equalTo(1), equalTo(2), equalTo(3)), new Integer[] {3, 2, 1});
+ assertMatches("single", arrayContainingInAnyOrder(equalTo(1)), new Integer[] {1});
+ }
+
+ public void testMismatchesItemsInAnyOrder() {
+ Matcher<Integer[]> matcher = arrayContainingInAnyOrder(1, 2, 3);
+ assertMismatchDescription("was null", matcher, null);
+ assertMismatchDescription("no item matches: <1>, <2>, <3> in []", matcher, new Integer[] {});
+ assertMismatchDescription("no item matches: <2>, <3> in [<1>]", matcher, new Integer[] {1});
+ assertMismatchDescription("not matched: <4>", matcher, new Integer[] {4,3,2,1});
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayContainingInOrderTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayContainingInOrderTest.java
new file mode 100644
index 0000000..ab1d821
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayContainingInOrderTest.java
@@ -0,0 +1,45 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.collection.IsArrayContainingInOrder.arrayContaining;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public class IsArrayContainingInOrderTest extends AbstractMatcherTest {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected Matcher<?> createMatcher() {
+ return arrayContaining(equalTo(1), equalTo(2));
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testHasAReadableDescription() {
+ assertDescription("[<1>, <2>]", arrayContaining(equalTo(1), equalTo(2)));
+ }
+
+ public void testMatchesItemsInOrder() {
+ assertMatches("in order", arrayContaining(1, 2, 3), new Integer[] {1, 2, 3});
+ assertMatches("single", arrayContaining(1), new Integer[] {1});
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testAppliesMatchersInOrder() {
+ assertMatches("in order", arrayContaining(equalTo(1), equalTo(2), equalTo(3)), new Integer[] {1, 2, 3});
+ assertMatches("single", arrayContaining(equalTo(1)), new Integer[] {1});
+ }
+
+ public void testMismatchesItemsInOrder() {
+ Matcher<Integer[]> matcher = arrayContaining(1, 2, 3);
+ assertMismatchDescription("was null", matcher, null);
+ assertMismatchDescription("no item was <1>", matcher, new Integer[] {});
+ assertMismatchDescription("no item was <2>", matcher, new Integer[] {1});
+ assertMismatchDescription("item 0: was <4>", matcher, new Integer[] {4,3,2,1});
+ assertMismatchDescription("item 2: was <4>", matcher, new Integer[] {1,2, 4});
+ }
+
+ public void testCanHandleNullValuesInAnArray() {
+ assertMatches("with nulls", arrayContaining(null, null), new Object[]{null, null});
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayContainingTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayContainingTest.java
new file mode 100644
index 0000000..275984c
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayContainingTest.java
@@ -0,0 +1,72 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.collection.IsArrayContaining.hasItemInArray;
+
+public class IsArrayContainingTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return hasItemInArray("irrelevant");
+ }
+
+ public void testMatchesAnArrayThatContainsAnElementMatchingTheGivenMatcher() {
+ assertMatches("should matches array that contains 'a'",
+ hasItemInArray("a"), new String[]{"a", "b", "c"});
+ }
+
+ public void testDoesNotMatchAnArrayThatDoesntContainAnElementMatchingTheGivenMatcher() {
+ assertDoesNotMatch("should not matches array that doesn't contain 'a'",
+ hasItemInArray("a"), new String[]{"b", "c"});
+ assertDoesNotMatch("should not matches empty array",
+ hasItemInArray("a"), new String[0]);
+ }
+
+ public void testDoesNotMatchNull() {
+ assertDoesNotMatch("should not matches null",
+ hasItemInArray("a"), null);
+ }
+
+ public void testHasAReadableDescription() {
+ assertDescription("an array containing \"a\"", hasItemInArray("a"));
+ }
+
+ // Remaining code no longer compiles, thanks to generics. I think that's a good thing, but
+ // I still need to investigate how this behaves with code that doesn't use generics.
+ // I expect ClassCastExceptions will be thrown.
+ // -Joe.
+
+// public void testDoesNotMatchObjectThatIsNotAnArray() {
+// assertDoesNotMatch("should not matches empty list",
+// arrayContaining("a"), "not a collection");
+// }
+
+// public void testMatchesPrimitiveArrayElements() {
+// assertMatches("boolean", arrayContaining(true), new boolean[]{true, false});
+// assertDoesNotMatch("boolean", arrayContaining(false), new boolean[]{false});
+//
+// assertMatches("byte", arrayContaining((byte) 1), new byte[]{1, 2, 3});
+// assertDoesNotMatch("byte", arrayContaining((byte) 0), new byte[]{1, 2, 3});
+//
+// assertMatches("char", arrayContaining('a'), new char[]{'a', 'b', 'c'});
+// assertDoesNotMatch("char", arrayContaining('z'), new char[]{'a', 'b', 'c'});
+//
+// assertMatches("short", arrayContaining((short) 1), new short[]{1, 2, 3});
+// assertDoesNotMatch("short", arrayContaining((short) 0), new short[]{1, 2, 3});
+//
+// assertMatches("int", arrayContaining(1), new int[]{1, 2, 3});
+// assertDoesNotMatch("int", arrayContaining(0), new int[]{1, 2, 3});
+//
+// assertMatches("long", arrayContaining(1L), new long[]{1, 2, 3});
+// assertDoesNotMatch("long", arrayContaining(0L), new long[]{1, 2, 3});
+//
+// assertMatches("float", arrayContaining(1f), new float[]{1f, 2f, 3f});
+// assertDoesNotMatch("float", arrayContaining(0f), new float[]{1f, 2f, 3f});
+//
+// assertMatches("double", arrayContaining(1.0), new double[]{1.0, 2.0, 3.0});
+// assertDoesNotMatch("double", arrayContaining(0.0), new double[]{1.0, 2.0, 3.0});
+// }
+
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayTest.java
new file mode 100644
index 0000000..4135d9f
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayTest.java
@@ -0,0 +1,59 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.collection.IsArray.array;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+@SuppressWarnings("unchecked")
+public class IsArrayTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return array(equalTo("irrelevant"));
+ }
+
+ public void testMatchesAnArrayThatMatchesAllTheElementMatchers() {
+ assertMatches("should match array with matching elements",
+ array(equalTo("a"), equalTo("b"), equalTo("c")), new String[]{"a", "b", "c"});
+ }
+
+ public void testDoesNotMatchAnArrayWhenElementsDoNotMatch() {
+ assertDoesNotMatch("should not match array with different elements",
+ array(equalTo("a"), equalTo("b")), new String[]{"b", "c"});
+ }
+
+ public void testDoesNotMatchAnArrayOfDifferentSize() {
+ assertDoesNotMatch("should not match larger array",
+ array(equalTo("a"), equalTo("b")), new String[]{"a", "b", "c"});
+ assertDoesNotMatch("should not match smaller array",
+ array(equalTo("a"), equalTo("b")), new String[]{"a"});
+ }
+
+ public void testDoesNotMatchNull() {
+ assertDoesNotMatch("should not match null",
+ array(equalTo("a")), null);
+ }
+
+ public void testHasAReadableDescription() {
+ assertDescription("[\"a\", \"b\"]", array(equalTo("a"), equalTo("b")));
+ }
+
+ public void testHasAReadableMismatchDescriptionUsing() {
+ assertMismatchDescription("element <0> was \"c\"", array(equalTo("a"), equalTo("b")), new String[]{"c", "b"});
+ }
+
+ public void testHasAReadableMismatchDescriptionUsingCustomMatchers() {
+ final BaseMatcher<String> m = new BaseMatcher<String>() {
+ @Override public boolean matches(Object item) { return false; }
+ @Override public void describeTo(Description description) { description.appendText("c"); }
+ @Override public void describeMismatch(Object item, Description description) {
+ description.appendText("didn't match");
+ }
+ };
+ assertMismatchDescription("element <0> didn't match", array(m, equalTo("b")), new String[]{"c", "b"});
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayWithSizeTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayWithSizeTest.java
new file mode 100644
index 0000000..18f607e
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsArrayWithSizeTest.java
@@ -0,0 +1,36 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.collection.IsArrayWithSize.arrayWithSize;
+import static org.hamcrest.collection.IsArrayWithSize.emptyArray;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public class IsArrayWithSizeTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return arrayWithSize(equalTo(2));
+ }
+
+ public void testMatchesWhenSizeIsCorrect() {
+ assertMatches("correct size", arrayWithSize(equalTo(3)), new Object[] {1, 2, 3});
+ assertDoesNotMatch("incorrect size", arrayWithSize(equalTo(2)), new Object[] {1, 2, 3});
+ }
+
+ public void testProvidesConvenientShortcutForArrayWithSizeEqualTo() {
+ assertMatches("correct size", arrayWithSize(3), new Object[] {1, 2, 3});
+ assertDoesNotMatch("incorrect size", arrayWithSize(2), new Object[] {1, 2, 3});
+ }
+
+ public void testEmptyArray() {
+ assertMatches("correct size", emptyArray(), new Object[] {});
+ assertDoesNotMatch("incorrect size", emptyArray(), new Object[] {1});
+ }
+
+ public void testHasAReadableDescription() {
+ assertDescription("an array with size <3>", arrayWithSize(equalTo(3)));
+ assertDescription("an empty array", emptyArray());
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsCollectionWithSizeTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsCollectionWithSizeTest.java
new file mode 100644
index 0000000..b04a0c5
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsCollectionWithSizeTest.java
@@ -0,0 +1,77 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+import org.hamcrest.MatcherAssert;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public class IsCollectionWithSizeTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return hasSize(7);
+ }
+
+ public void testMatchesWhenSizeIsCorrect() {
+ assertMatches("correct size", hasSize(equalTo(2)), asList(null, null));
+ assertMismatchDescription("collection size was <3>", hasSize(equalTo(2)), asList(null, null, null));
+ }
+
+ public void testMatchesCollectionWhenSizeIsCorrectUsingObjectElementType() {
+ Collection<Object> list = asList(null, null);
+ assertMatches("correct size", hasSize(equalTo(2)), list);
+ assertMismatchDescription("collection size was <2>", hasSize(equalTo(3)), list);
+ }
+
+ public void testMatchesCollectionWhenSizeIsCorrectUsingStringElementType() {
+ Collection<String> list = asList("a", "b");
+ assertMatches("correct size", hasSize(equalTo(2)), list);
+ assertMismatchDescription("collection size was <2>", hasSize(equalTo(3)), list);
+ }
+
+ public void testMatchesCollectionWhenSizeIsCorrectUsingWildcardElementType() {
+ Collection<?> list = asList("a", "b");
+ assertMatches("correct size", hasSize(equalTo(2)), list);
+ assertMismatchDescription("collection size was <2>", hasSize(equalTo(3)), list);
+ }
+
+ public void testMatchesListWhenSizeIsCorrectUsingObjectElementType() {
+ List<Object> list = asList(null, null);
+ assertMatches("correct size", hasSize(equalTo(2)), list);
+ assertMismatchDescription("collection size was <2>", hasSize(equalTo(3)), list);
+ }
+
+ public void testMatchesListWhenSizeIsCorrectUsingStringElementType() {
+ List<String> list = asList("a", "b");
+ assertMatches("correct size", hasSize(equalTo(2)), list);
+ assertMismatchDescription("collection size was <2>", hasSize(equalTo(3)), list);
+ }
+
+ public void testMatchesListWhenSizeIsCorrectUsingWildcardElementType() {
+ List<?> list = asList("a", "b");
+ assertMatches("correct size", hasSize(equalTo(2)), list);
+ assertMismatchDescription("collection size was <2>", hasSize(equalTo(3)), list);
+ }
+
+ public void testProvidesConvenientShortcutForHasSizeEqualTo() {
+ assertMatches("correct size", hasSize(2), asList(null, null));
+ assertMismatchDescription("collection size was <3>", hasSize(2), asList(null, null, null));
+ }
+
+ public void testHasAReadableDescription() {
+ assertDescription("a collection with size <3>", hasSize(equalTo(3)));
+ }
+
+ public void testCompilesWithATypedCollection() {
+ // To prove Issue 43
+ ArrayList<String> arrayList = new ArrayList<String>();
+ MatcherAssert.assertThat(arrayList, hasSize(0));
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsEmptyCollectionTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsEmptyCollectionTest.java
new file mode 100644
index 0000000..ea875e8
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsEmptyCollectionTest.java
@@ -0,0 +1,45 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.collection.IsEmptyCollection.empty;
+import static org.hamcrest.core.Is.is;
+
+public class IsEmptyCollectionTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<Collection<?>> createMatcher() {
+ return empty();
+ }
+
+ public void testMatchesAnEmptyCollection() {
+ assertMatches("empty collection", createMatcher(), emptyCollection());
+ }
+
+ public void testDoesNotMatchACollectionWithAnItem() {
+ assertMismatchDescription("<[one, three]>", is(createMatcher()), collectionOfValues());
+ }
+
+ public void testHasAReadableDescription() {
+ assertDescription("an empty collection", createMatcher());
+ }
+
+ public void testCompiles() {
+ needs(IsEmptyCollection.emptyCollectionOf(String.class));
+ }
+
+ private void needs(@SuppressWarnings("unused") Matcher<Collection<String>> bar) { }
+
+ private static Collection<String> collectionOfValues() {
+ return new ArrayList<String>(asList("one", "three"));
+ }
+
+ private static Collection<Integer> emptyCollection() {
+ return new ArrayList<Integer>();
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsEmptyIterableTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsEmptyIterableTest.java
new file mode 100644
index 0000000..600b576
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsEmptyIterableTest.java
@@ -0,0 +1,44 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.collection.IsEmptyIterable.emptyIterable;
+
+public class IsEmptyIterableTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<Iterable<?>> createMatcher() {
+ return emptyIterable();
+ }
+
+ public void testMatchesAnEmptyIterable() {
+ assertMatches("empty iterable", createMatcher(), emptyCollection());
+ }
+
+ public void testDoesNotMatchAnIterableWithItems() {
+ assertDoesNotMatch("iterable with an item", createMatcher(), collectionOfValues());
+ }
+
+ public void testHasAReadableDescription() {
+ assertDescription("an empty iterable", createMatcher());
+ }
+
+ public void testCompiles() {
+ needs(IsEmptyIterable.emptyIterableOf(String.class));
+ }
+
+ private void needs(@SuppressWarnings("unused") Matcher<Iterable<String>> bar) { }
+
+ private static Collection<String> collectionOfValues() {
+ return new ArrayList<String>(asList("one", "three"));
+ }
+
+ private static Collection<Integer> emptyCollection() {
+ return new ArrayList<Integer>();
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsInTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsInTest.java
new file mode 100644
index 0000000..e9fcbdc
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsInTest.java
@@ -0,0 +1,44 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+import org.hamcrest.StringDescription;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+public class IsInTest extends AbstractMatcherTest {
+ String[] elements = {"a", "b", "c"};
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return new IsIn<String>(elements);
+ }
+
+ public void testReturnsTrueIfArgumentIsInCollection() {
+ Collection<String> collection = Arrays.asList(elements);
+ Matcher<String> isIn = new IsIn<String>(collection);
+
+ assertMatches("a", isIn, "a");
+ assertMatches("b", isIn, "b");
+ assertMatches("c", isIn, "c");
+ assertDoesNotMatch("d", isIn, "d");
+ }
+
+ public void testReturnsTrueIfArgumentIsInArray() {
+ Matcher<String> isIn = new IsIn<String>(elements);
+
+ assertMatches("a", isIn, "a");
+ assertMatches("b", isIn, "b");
+ assertMatches("c", isIn, "c");
+ assertDoesNotMatch("d", isIn, "d");
+ }
+
+ public void testHasReadableDescription() {
+ Matcher<String> isIn = new IsIn<String>(elements);
+
+ assertEquals("description",
+ "one of {\"a\", \"b\", \"c\"}",
+ StringDescription.toString(isIn));
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableContainingInAnyOrderTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableContainingInAnyOrderTest.java
new file mode 100644
index 0000000..091c347
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableContainingInAnyOrderTest.java
@@ -0,0 +1,54 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+import org.hamcrest.collection.IsIterableContainingInOrderTest.WithValue;
+
+import java.util.Collections;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
+import static org.hamcrest.collection.IsIterableContainingInOrderTest.make;
+import static org.hamcrest.collection.IsIterableContainingInOrderTest.value;
+
+public class IsIterableContainingInAnyOrderTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return containsInAnyOrder(1, 2);
+ }
+
+ public void testMatchesSingleItemIterable() {
+ assertMatches("single item", containsInAnyOrder(1), asList(1));
+ }
+
+ public void testDoesNotMatchEmpty() {
+ assertMismatchDescription("no item matches: <1>, <2> in []", containsInAnyOrder(1, 2), Collections.<Integer>emptyList());
+ }
+
+ public void testMatchesIterableOutOfOrder() {
+ assertMatches("Out of order", containsInAnyOrder(1, 2), asList(2, 1));
+ }
+
+ public void testMatchesIterableInOrder() {
+ assertMatches("In order", containsInAnyOrder(1, 2), asList(1, 2));
+ }
+
+ public void testDoesNotMatchIfOneOfMultipleElementsMismatches() {
+ assertMismatchDescription("not matched: <4>", containsInAnyOrder(1, 2, 3), asList(1, 2, 4));
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testDoesNotMatchIfThereAreMoreElementsThanMatchers() {
+ final Matcher<Iterable<? extends WithValue>> helpTheCompilerOut = containsInAnyOrder(value(1), value(3));
+ assertMismatchDescription("not matched: <WithValue 2>", helpTheCompilerOut, asList(make(1), make(2), make(3)));
+ }
+
+ public void testDoesNotMatchIfThereAreMoreMatchersThanElements() {
+ assertMismatchDescription("no item matches: <4> in [<1>, <2>, <3>]", containsInAnyOrder(1, 2, 3, 4), asList(1, 2, 3));
+ }
+
+ public void testHasAReadableDescription() {
+ assertDescription("iterable with items [<1>, <2>] in any order", containsInAnyOrder(1, 2));
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableContainingInOrderTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableContainingInOrderTest.java
new file mode 100644
index 0000000..8cb1bf8
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableContainingInOrderTest.java
@@ -0,0 +1,77 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.FeatureMatcher;
+import org.hamcrest.Matcher;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+@SuppressWarnings("unchecked")
+public class IsIterableContainingInOrderTest extends AbstractMatcherTest {
+ // temporary hack until the Java type system works
+ private final Matcher<Iterable<? extends WithValue>> contains123 = contains(value(1), value(2), value(3));
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return contains(1, 2);
+ }
+
+ public void testMatchingSingleItemIterable() throws Exception {
+ assertMatches("Single item iterable", contains(1), asList(1));
+ }
+
+ public void testMatchingMultipleItemIterable() throws Exception {
+ assertMatches("Multiple item iterable", contains(1, 2, 3), asList(1, 2, 3));
+ }
+
+ public void testDoesNotMatchWithMoreElementsThanExpected() throws Exception {
+ assertMismatchDescription("not matched: <4>", contains(1, 2, 3), asList(1, 2, 3, 4));
+ }
+
+ public void testDoesNotMatchWithFewerElementsThanExpected() throws Exception {
+ List<WithValue> valueList = asList(make(1), make(2));
+ assertMismatchDescription("no item was value with <3>", contains123, valueList);
+ }
+
+ public void testDoesNotMatchIfSingleItemMismatches() throws Exception {
+ assertMismatchDescription("item 0: value was <3>", contains(value(4)), asList(make(3)));
+ }
+
+ public void testDoesNotMatchIfOneOfMultipleItemsMismatch() throws Exception {
+ assertMismatchDescription("item 2: value was <4>", contains123, asList(make(1), make(2), make(4)));
+ }
+
+ public void testDoesNotMatchEmptyIterable() throws Exception {
+ assertMismatchDescription("no item was value with <4>", contains(value(4)), new ArrayList<WithValue>());
+ }
+
+ public void testHasAReadableDescription() {
+ assertDescription("iterable containing [<1>, <2>]", contains(1, 2));
+ }
+
+ public void testCanHandleNullMatchers() {
+ assertMatches(contains(null, null), asList(null, null));
+ }
+
+ public static class WithValue {
+ private final int value;
+ public WithValue(int value) { this.value = value; }
+ public int getValue() { return value; }
+ @Override public String toString() { return "WithValue " + value; }
+ }
+
+ public static WithValue make(int value) {
+ return new WithValue(value);
+ }
+
+ public static Matcher<WithValue> value(int value) {
+ return new FeatureMatcher<WithValue, Integer>(equalTo(value), "value with", "value") {
+ @Override protected Integer featureValueOf(WithValue actual) { return actual.getValue(); }
+ };
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableContainingInRelativeOrderTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableContainingInRelativeOrderTest.java
new file mode 100644
index 0000000..8192c8b
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableContainingInRelativeOrderTest.java
@@ -0,0 +1,93 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.FeatureMatcher;
+import org.hamcrest.Matcher;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.collection.IsIterableContainingInRelativeOrder.containsInRelativeOrder;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+@SuppressWarnings("unchecked")
+public class IsIterableContainingInRelativeOrderTest extends AbstractMatcherTest {
+ // temporary hack until the Java type system works
+ private final Matcher<Iterable<? extends WithValue>> contains123 = containsInRelativeOrder(value(1), value(2), value(3));
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return containsInRelativeOrder(1, 2);
+ }
+
+ public void testMatchingSingleItemIterable() throws Exception {
+ assertMatches("Single item iterable", containsInRelativeOrder(1), asList(1));
+ }
+
+ public void testMatchingMultipleItemIterable() throws Exception {
+ assertMatches("Multiple item iterable", containsInRelativeOrder(1, 2, 3), asList(1, 2, 3));
+ }
+
+ public void testMatchesWithMoreElementsThanExpectedAtBeginning() throws Exception {
+ assertMatches("More elements at beginning", containsInRelativeOrder(2, 3, 4), asList(1, 2, 3, 4));
+ }
+
+ public void testMatchesWithMoreElementsThanExpectedAtEnd() throws Exception {
+ assertMatches("More elements at end", containsInRelativeOrder(1, 2, 3), asList(1, 2, 3, 4));
+ }
+
+ public void testMatchesWithMoreElementsThanExpectedInBetween() throws Exception {
+ assertMatches("More elements in between", containsInRelativeOrder(1, 3), asList(1, 2, 3));
+ }
+
+ public void testMatchesSubSection() throws Exception {
+ assertMatches("Sub section of iterable", containsInRelativeOrder(2, 3), asList(1, 2, 3, 4));
+ }
+
+ public void testMatchesWithSingleGapAndNotFirstOrLast() throws Exception {
+ assertMatches("Sub section with single gaps without a first or last match", containsInRelativeOrder(2, 4), asList(1, 2, 3, 4, 5));
+ }
+
+ public void testMatchingSubSectionWithManyGaps() throws Exception {
+ assertMatches("Sub section with many gaps iterable", containsInRelativeOrder(2, 4, 6), asList(1, 2, 3, 4, 5, 6, 7));
+ }
+
+ public void testDoesNotMatchWithFewerElementsThanExpected() throws Exception {
+ List<WithValue> valueList = asList(make(1), make(2));
+ assertMismatchDescription("value with <3> was not found after <WithValue 2>", contains123, valueList);
+ }
+
+ public void testDoesNotMatchIfSingleItemNotFound() throws Exception {
+ assertMismatchDescription("value with <4> was not found", containsInRelativeOrder(value(4)), asList(make(3)));
+ }
+
+ public void testDoesNotMatchIfOneOfMultipleItemsNotFound() throws Exception {
+ assertMismatchDescription("value with <3> was not found after <WithValue 2>", contains123, asList(make(1), make(2), make(4)));
+ }
+
+ public void testDoesNotMatchEmptyIterable() throws Exception {
+ assertMismatchDescription("value with <4> was not found", containsInRelativeOrder(value(4)), new ArrayList<WithValue>());
+ }
+
+ public void testHasAReadableDescription() {
+ assertDescription("iterable containing [<1>, <2>] in relative order", containsInRelativeOrder(1, 2));
+ }
+
+ public static class WithValue {
+ private final int value;
+ public WithValue(int value) { this.value = value; }
+ public int getValue() { return value; }
+ @Override public String toString() { return "WithValue " + value; }
+ }
+
+ public static WithValue make(int value) {
+ return new WithValue(value);
+ }
+
+ public static Matcher<WithValue> value(int value) {
+ return new FeatureMatcher<WithValue, Integer>(equalTo(value), "value with", "value") {
+ @Override protected Integer featureValueOf(WithValue actual) { return actual.getValue(); }
+ };
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableWithSizeTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableWithSizeTest.java
new file mode 100644
index 0000000..8bf65d1
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsIterableWithSizeTest.java
@@ -0,0 +1,37 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.hamcrest.collection.IsIterableWithSize.iterableWithSize;
+
+public class IsIterableWithSizeTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return iterableWithSize(7);
+ }
+
+ public void testMatchesEmptyIterable() throws Exception {
+ assertMatches("Empty iterable", iterableWithSize(0), Collections.emptyList());
+ }
+
+ public void testMatchingSingleItemIterable() throws Exception {
+ assertMatches("Single item iterable", iterableWithSize(1), Arrays.<Object>asList(1));
+ }
+
+ public void testMatchingMultipleItemIterable() throws Exception {
+ assertMatches("Multiple item iterable", iterableWithSize(3), Arrays.<Object>asList(1, 2, 3));
+ }
+
+ public void testDoesNotMatchIncorrectSize() throws Exception {
+ assertDoesNotMatch("Incorrect size", iterableWithSize(3), Arrays.<Object>asList(1));
+ }
+
+ public void testHasAReadableDescription() {
+ assertDescription("an iterable with size <4>", iterableWithSize(4));
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsMapContainingKeyTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsMapContainingKeyTest.java
new file mode 100644
index 0000000..13f067c
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsMapContainingKeyTest.java
@@ -0,0 +1,84 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.collection.IsMapContaining.hasKey;
+
+public class IsMapContainingKeyTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return hasKey("foo");
+ }
+
+ public void testMatchesSingletonMapContainingKey() {
+ Map<String,Integer> map = new HashMap<String, Integer>();
+ map.put("a", 1);
+
+ assertMatches("Matches single key", hasKey("a"), map);
+ }
+
+ public void testMatchesMapContainingKey() {
+ Map<String,Integer> map = new HashMap<String, Integer>();
+ map.put("a", 1);
+ map.put("b", 2);
+ map.put("c", 3);
+
+ assertMatches("Matches a", hasKey("a"), map);
+ assertMatches("Matches c", hasKey("c"), map);
+ }
+
+
+// No longer compiles
+// public void testMatchesMapContainingKeyWithNoGenerics() {
+// Map map = new HashMap();
+// map.put("a", 1);
+// map.put("b", 2);
+// map.put("c", 3);
+//
+// assertMatches("Matches a", hasKey("a"), map);
+// assertMatches("Matches c", hasKey("c"), map);
+// }
+
+ public void testMatchesMapContainingKeyWithIntegerKeys() throws Exception {
+ Map<Integer, String> map = new HashMap<Integer, String>();
+ map.put(1, "A");
+ map.put(2, "B");
+
+ assertThat(map, hasKey(1));
+ }
+
+ public void testMatchesMapContainingKeyWithNumberKeys() throws Exception {
+ Map<Number, String> map = new HashMap<Number, String>();
+ map.put(1, "A");
+ map.put(2, "B");
+
+ assertThat(map, hasKey((Number)1));
+
+ // TODO: work out the correct sprinkling of wildcards to get this to work!
+// assertThat(map, hasKey(1));
+ }
+
+ public void testHasReadableDescription() {
+ assertDescription("map containing [\"a\"->ANYTHING]", hasKey("a"));
+ }
+
+ public void testDoesNotMatchEmptyMap() {
+ assertMismatchDescription("map was []", hasKey("Foo"), new HashMap<String,Integer>());
+ }
+
+ public void testDoesNotMatchMapMissingKey() {
+ Map<String,Integer> map = new TreeMap<String, Integer>();
+ map.put("a", 1);
+ map.put("b", 2);
+ map.put("c", 3);
+
+ assertMismatchDescription("map was [<a=1>, <b=2>, <c=3>]", hasKey("d"), map);
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsMapContainingTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsMapContainingTest.java
new file mode 100644
index 0000000..f472224
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsMapContainingTest.java
@@ -0,0 +1,58 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import static org.hamcrest.collection.IsMapContaining.hasEntry;
+import static org.hamcrest.core.IsAnything.anything;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public class IsMapContainingTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return IsMapContaining.hasEntry("irrelevant", "irrelevant");
+ }
+
+ public void testMatchesMapContainingMatchingKeyAndValue() {
+ Map<String,Integer> map = new TreeMap<String,Integer>();
+ map.put("a", 1);
+ map.put("b", 2);
+
+ assertMatches("matcherA", hasEntry(equalTo("a"), equalTo(1)), map);
+ assertMatches("matcherB", hasEntry(equalTo("b"), equalTo(2)), map);
+ assertMismatchDescription("map was [<a=1>, <b=2>]", hasEntry(equalTo("c"), equalTo(3)), map);
+ }
+
+// no longer compiles. SF
+// public void testMatchesMapContainingMatchingKeyAndValueWithoutGenerics() {
+// Map map = new HashMap();
+// map.put("a", 1);
+// map.put("b", 2);
+//
+// assertMatches("matcherA", hasEntry(equalTo("a"), equalTo(1)), map);
+// assertMatches("matcherB", hasEntry(equalTo("b"), equalTo(2)), map);
+// assertDoesNotMatch("matcherC", hasEntry(equalTo("c"), equalTo(3)), map);
+// }
+//
+ public void testDoesNotMatchNull() {
+ assertMismatchDescription("was null", hasEntry(anything(), anything()), null);
+ }
+
+ public void testHasReadableDescription() {
+ assertDescription("map containing [\"a\"-><2>]", hasEntry(equalTo("a"), (equalTo(2))));
+ }
+
+ // Remaining code no longer compiles, thanks to generics. I think that's a good thing, but
+ // I still need to investigate how this behaves with code that doesn't use generics.
+ // I expect ClassCastExceptions will be thrown.
+ // -Joe.
+
+// public void testDoesNotMatchAnObjectThatIsNotAMap() {
+// assertDoesNotMatch("should not matches a string",
+// mapContaining(ANYTHING, ANYTHING), "not a map");
+// }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsMapContainingValueTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsMapContainingValueTest.java
new file mode 100644
index 0000000..a2d7f90
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsMapContainingValueTest.java
@@ -0,0 +1,46 @@
+package org.hamcrest.collection;
+
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+import static org.hamcrest.collection.IsMapContaining.hasValue;
+
+public class IsMapContainingValueTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return hasValue("foo");
+ }
+
+ public void testHasReadableDescription() {
+ assertDescription("map containing [ANYTHING->\"a\"]", hasValue("a"));
+ }
+
+ public void testDoesNotMatchEmptyMap() {
+ Map<String,Integer> map = new HashMap<String,Integer>();
+ assertMismatchDescription("map was []", hasValue(1), map);
+ }
+
+ public void testMatchesSingletonMapContainingValue() {
+ Map<String,Integer> map = new HashMap<String,Integer>();
+ map.put("a", 1);
+
+ assertMatches("Singleton map", hasValue(1), map);
+ }
+
+ public void testMatchesMapContainingValue() {
+ Map<String,Integer> map = new TreeMap<String,Integer>();
+ map.put("a", 1);
+ map.put("b", 2);
+ map.put("c", 3);
+
+ assertMatches("hasValue 1", hasValue(1), map);
+ assertMatches("hasValue 3", hasValue(3), map);
+ assertMismatchDescription("map was [<a=1>, <b=2>, <c=3>]", hasValue(4), map);
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/collection/IsMapWithSizeTest.java b/hamcrest-library/src/test/java/org/hamcrest/collection/IsMapWithSizeTest.java
new file mode 100644
index 0000000..c050924
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/collection/IsMapWithSizeTest.java
@@ -0,0 +1,82 @@
+package org.hamcrest.collection;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+import org.hamcrest.MatcherAssert;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.collection.IsMapWithSize.aMapWithSize;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+public final class IsMapWithSizeTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return aMapWithSize(7);
+ }
+
+ public void testMatchesWhenSizeIsCorrect() {
+ assertMatches("correct size", aMapWithSize(equalTo(2)), mapWithKeys("a", "b"));
+ assertMismatchDescription("map size was <3>", aMapWithSize(equalTo(2)), mapWithKeys("a", "b", "c"));
+ }
+
+ public void testMatchesMapWhenSizeIsCorrectUsingObjectElementType() {
+ Map<Object, Object> map = mapWithKeys(new Object(), new Object());
+ assertMatches("correct size", aMapWithSize(equalTo(2)), map);
+ assertMismatchDescription("map size was <2>", aMapWithSize(equalTo(3)), map);
+ }
+
+ public void testMatchesMapWhenSizeIsCorrectUsingStringElementType() {
+ Map<String, Integer> map = mapWithKeys("a", "b");
+ assertMatches("correct size", aMapWithSize(equalTo(2)), map);
+ assertMismatchDescription("map size was <2>", aMapWithSize(equalTo(3)), map);
+ }
+
+ public void testMatchesMapWhenSizeIsCorrectUsingWildcardElementType() {
+ Map<?, ?> map = mapWithKeys("a", "b");
+ assertMatches("correct size", aMapWithSize(equalTo(2)), map);
+ assertMismatchDescription("map size was <2>", aMapWithSize(equalTo(3)), map);
+ }
+
+ public void testMatchesListWhenSizeIsCorrectUsingObjectElementType() {
+ Map<Object, Object> map = mapWithKeys(new Object(), new Object());
+ assertMatches("correct size", aMapWithSize(equalTo(2)), map);
+ assertMismatchDescription("map size was <2>", aMapWithSize(equalTo(3)), map);
+ }
+
+ public void testMatchesListWhenSizeIsCorrectUsingStringElementType() {
+ Map<String, Integer> list = mapWithKeys("a", "b");
+ assertMatches("correct size", aMapWithSize(equalTo(2)), list);
+ assertMismatchDescription("map size was <2>", aMapWithSize(equalTo(3)), list);
+ }
+
+ public void testMatchesListWhenSizeIsCorrectUsingWildcardElementType() {
+ Map<?, ?> list = mapWithKeys("a", "b");
+ assertMatches("correct size", aMapWithSize(equalTo(2)), list);
+ assertMismatchDescription("map size was <2>", aMapWithSize(equalTo(3)), list);
+ }
+
+ public void testProvidesConvenientShortcutForHasSizeEqualTo() {
+ assertMatches("correct size", aMapWithSize(2), mapWithKeys(new Object(), new Object()));
+ assertMismatchDescription("map size was <3>", aMapWithSize(2), mapWithKeys(new Object(), new Object(), new Object()));
+ }
+
+ public void testHasAReadableDescription() {
+ assertDescription("a map with size <3>", aMapWithSize(equalTo(3)));
+ }
+
+ public void testCompilesWithATypedMap() {
+ Map<String, Integer> arrayList = new HashMap<String, Integer>();
+ MatcherAssert.assertThat(arrayList, aMapWithSize(0));
+ }
+
+ private static <K, V> Map<K, V> mapWithKeys(K... keys) {
+ final Map<K, V> result = new HashMap<K, V>();
+ for (K key : keys) {
+ result.put(key, null);
+ }
+ return result;
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/comparator/ComparatorMatcherBuilderTest.java b/hamcrest-library/src/test/java/org/hamcrest/comparator/ComparatorMatcherBuilderTest.java
new file mode 100644
index 0000000..a5fdb4a
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/comparator/ComparatorMatcherBuilderTest.java
@@ -0,0 +1,128 @@
+package org.hamcrest.comparator;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import java.math.BigDecimal;
+import java.util.Comparator;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.comparator.ComparatorMatcherBuilder.comparedBy;
+import static org.hamcrest.core.IsNot.not;
+
+public class ComparatorMatcherBuilderTest extends AbstractMatcherTest {
+
+ private final ComparatorMatcherBuilder<Integer> integerComparatorMatcherBuilder = ComparatorMatcherBuilder.usingNaturalOrdering();
+ private final ComparatorMatcherBuilder<Double> doubleComparatorMatcherBuilder = ComparatorMatcherBuilder.usingNaturalOrdering();
+ private final ComparatorMatcherBuilder<String> stringComparatorMatcherBuilder = ComparatorMatcherBuilder.usingNaturalOrdering();
+ private final ComparatorMatcherBuilder<BigDecimal> bigDecimalComparatorMatcherBuilder = ComparatorMatcherBuilder.usingNaturalOrdering();
+ private final Comparator<Integer> backwardsIntegerComparator = new Comparator<Integer>() {
+ @Override
+ public int compare(Integer o1, Integer o2) {
+ return -o1.compareTo(o2);
+ }
+
+ @Override
+ public String toString() {
+ return "backwards integer comparator";
+ }
+ };
+
+ @Override
+ protected Matcher<Integer> createMatcher() {
+ return integerComparatorMatcherBuilder.greaterThan(1);
+ }
+
+ public void testDescription() {
+ assertDescription("a value greater than <1>", integerComparatorMatcherBuilder.greaterThan(1));
+ assertDescription("a value equal to or greater than <1>", integerComparatorMatcherBuilder.greaterThanOrEqualTo(1));
+ assertDescription("a value equal to <1>", integerComparatorMatcherBuilder.comparesEqualTo(1));
+ assertDescription("a value less than or equal to <1>", integerComparatorMatcherBuilder.lessThanOrEqualTo(1));
+ assertDescription("a value less than <1>", integerComparatorMatcherBuilder.lessThan(1));
+
+ assertDescription("a value greater than <1> when compared by <backwards integer comparator>", comparedBy(backwardsIntegerComparator).greaterThan(1));
+ assertDescription("a value equal to or greater than <1> when compared by <backwards integer comparator>", comparedBy(backwardsIntegerComparator).greaterThanOrEqualTo(1));
+ assertDescription("a value equal to <1> when compared by <backwards integer comparator>", comparedBy(backwardsIntegerComparator).comparesEqualTo(1));
+ assertDescription("a value less than or equal to <1> when compared by <backwards integer comparator>", comparedBy(backwardsIntegerComparator).lessThanOrEqualTo(1));
+ assertDescription("a value less than <1> when compared by <backwards integer comparator>", comparedBy(backwardsIntegerComparator).lessThan(1));
+ }
+
+ public void testMismatchDescriptions() {
+ assertMismatchDescription("<0> was less than <1>", integerComparatorMatcherBuilder.greaterThan(1), 0);
+ assertMismatchDescription("<1> was equal to <1>", integerComparatorMatcherBuilder.greaterThan(1), 1);
+ assertMismatchDescription("<1> was greater than <0>", integerComparatorMatcherBuilder.lessThan(0), 1);
+ assertMismatchDescription("<2> was equal to <2>", integerComparatorMatcherBuilder.lessThan(2), 2);
+
+ assertMismatchDescription("<1> was less than <0> when compared by <backwards integer comparator>", comparedBy(backwardsIntegerComparator).greaterThan(0), 1);
+ assertMismatchDescription("<1> was equal to <1> when compared by <backwards integer comparator>", comparedBy(backwardsIntegerComparator).greaterThan(1), 1);
+ assertMismatchDescription("<0> was greater than <1> when compared by <backwards integer comparator>", comparedBy(backwardsIntegerComparator).lessThan(1), 0);
+ assertMismatchDescription("<2> was equal to <2> when compared by <backwards integer comparator>", comparedBy(backwardsIntegerComparator).lessThan(2), 2);
+ }
+
+ public void testComparesObjectsForGreaterThan() {
+ assertThat(2, integerComparatorMatcherBuilder.greaterThan(1));
+ assertThat(0, not(integerComparatorMatcherBuilder.greaterThan(1)));
+ }
+
+ public void testComparesObjectsForLessThan() {
+ assertThat(2, integerComparatorMatcherBuilder.lessThan(3));
+ assertThat(0, integerComparatorMatcherBuilder.lessThan(1));
+ }
+
+
+ public void testComparesObjectsForEquality() {
+ assertThat(3, integerComparatorMatcherBuilder.comparesEqualTo(3));
+ assertThat("aa", stringComparatorMatcherBuilder.comparesEqualTo("aa"));
+ }
+
+ public void testAllowsForInclusiveComparisons() {
+ assertThat("less", 1, integerComparatorMatcherBuilder.lessThanOrEqualTo(1));
+ assertThat("greater", 1, integerComparatorMatcherBuilder.greaterThanOrEqualTo(1));
+ }
+
+ public void testSupportsDifferentTypesOfComparableObjects() {
+ assertThat(1.1, doubleComparatorMatcherBuilder.greaterThan(1.0));
+ assertThat("cc", stringComparatorMatcherBuilder.greaterThan("bb"));
+ }
+
+ public void testComparesBigDecimalsWithDifferentScalesCorrectlyForIssue20() {
+ assertThat(new BigDecimal("10.0"), bigDecimalComparatorMatcherBuilder.greaterThanOrEqualTo(new BigDecimal("10")));
+ assertThat(new BigDecimal(10), bigDecimalComparatorMatcherBuilder.greaterThanOrEqualTo(new BigDecimal("10.0")));
+ assertThat(new BigDecimal("2"), bigDecimalComparatorMatcherBuilder.comparesEqualTo(new BigDecimal("2.000")));
+ }
+
+ public void testComparesCustomTypesWhoseCompareToReturnsValuesGreaterThatOne() {
+ assertThat(new CustomInt(5), ComparatorMatcherBuilder.<CustomInt>usingNaturalOrdering().lessThan(new CustomInt(10)));
+ }
+
+ public void testComparesByCustomComparator() {
+ assertThat(5, comparedBy(backwardsIntegerComparator).lessThan(4));
+ }
+
+ public void testJavadocExamples() {
+ assertThat(1, ComparatorMatcherBuilder.<Integer>usingNaturalOrdering().comparesEqualTo(1));
+ assertThat(2, ComparatorMatcherBuilder.<Integer>usingNaturalOrdering().greaterThan(1));
+ assertThat(1, ComparatorMatcherBuilder.<Integer>usingNaturalOrdering().greaterThanOrEqualTo(1));
+ assertThat(1, ComparatorMatcherBuilder.<Integer>usingNaturalOrdering().lessThan(2));
+ assertThat(1, ComparatorMatcherBuilder.<Integer>usingNaturalOrdering().lessThanOrEqualTo(1));
+ assertThat(5, comparedBy(new Comparator<Integer>() {
+ @Override
+ public int compare(Integer o1, Integer o2) {
+ return -o1.compareTo(o2);
+ }
+ }).lessThan(4));
+ }
+
+ private static final class CustomInt implements Comparable<CustomInt> {
+ private final int value;
+
+ public CustomInt(int value) {
+ this.value = value;
+ }
+
+ @Override
+ public int compareTo(CustomInt other) {
+ return value - other.value;
+ }
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/comparator/ComparatorMatcherTest.java b/hamcrest-library/src/test/java/org/hamcrest/comparator/ComparatorMatcherTest.java
new file mode 100644
index 0000000..2bc53d4
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/comparator/ComparatorMatcherTest.java
@@ -0,0 +1,87 @@
+package org.hamcrest.comparator;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import java.math.BigDecimal;
+import java.util.Comparator;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.number.OrderingComparison.*;
+
+public class ComparatorMatcherTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<Integer> createMatcher() {
+ return ComparatorMatcherBuilder.comparedBy(new Comparator<Integer>() {
+ @Override
+ public int compare(Integer o1, Integer o2) {
+ return o1.compareTo(o2);
+ }
+ }).greaterThan(1);
+ }
+
+ public void testDescription() {
+ assertDescription("a value greater than <1>", greaterThan(1));
+ assertDescription("a value equal to or greater than <1>", greaterThanOrEqualTo(1));
+ assertDescription("a value equal to <1>", comparesEqualTo(1));
+ assertDescription("a value less than or equal to <1>", lessThanOrEqualTo(1));
+ assertDescription("a value less than <1>", lessThan(1));
+ }
+
+ public void testMismatchDescriptions() {
+ assertMismatchDescription("<0> was less than <1>", greaterThan(1), 0);
+ assertMismatchDescription("<1> was equal to <1>", greaterThan(1), 1);
+ assertMismatchDescription("<1> was greater than <0>", lessThan(0), 1);
+ assertMismatchDescription("<2> was equal to <2>", lessThan(2), 2);
+ }
+
+ public void testComparesObjectsForGreaterThan() {
+ assertThat(2, greaterThan(1));
+ assertThat(0, not(greaterThan(1)));
+ }
+
+ public void testComparesObjectsForLessThan() {
+ assertThat(2, lessThan(3));
+ assertThat(0, lessThan(1));
+ }
+
+
+ public void testComparesObjectsForEquality() {
+ assertThat(3, comparesEqualTo(3));
+ assertThat("aa", comparesEqualTo("aa"));
+ }
+
+ public void testAllowsForInclusiveComparisons() {
+ assertThat("less", 1, lessThanOrEqualTo(1));
+ assertThat("greater", 1, greaterThanOrEqualTo(1));
+ }
+
+ public void testSupportsDifferentTypesOfComparableObjects() {
+ assertThat(1.1, greaterThan(1.0));
+ assertThat("cc", greaterThan("bb"));
+ }
+
+ public void testComparesBigDecimalsWithDifferentScalesCorrectlyForIssue20() {
+ assertThat(new BigDecimal("10.0"), greaterThanOrEqualTo(new BigDecimal("10")));
+ assertThat(new BigDecimal(10), greaterThanOrEqualTo(new BigDecimal("10.0")));
+ assertThat(new BigDecimal("2"), comparesEqualTo(new BigDecimal("2.000")));
+ }
+
+ public void testComparesCustomTypesWhoseCompareToReturnsValuesGreaterThatOne() {
+ assertThat(new CustomInt(5), lessThan(new CustomInt(10)));
+ }
+
+ private static final class CustomInt implements Comparable<CustomInt> {
+ private final int value;
+
+ public CustomInt(int value) {
+ this.value = value;
+ }
+
+ public int compareTo(CustomInt other) {
+ return value - other.value;
+ }
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/io/FileMatchersTest.java b/hamcrest-library/src/test/java/org/hamcrest/io/FileMatchersTest.java
new file mode 100644
index 0000000..b186549
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/io/FileMatchersTest.java
@@ -0,0 +1,93 @@
+package org.hamcrest.io;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import java.io.File;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+
+@SuppressWarnings("ResultOfMethodCallIgnored")
+public class FileMatchersTest extends AbstractMatcherTest {
+
+ private File directory;
+ private File file;
+
+ @Override
+ protected void setUp() throws Exception {
+ directory = File.createTempFile("myDir", "");
+ directory.delete();
+ directory.mkdirs();
+
+ file = new File(directory, "myFile");
+ file.createNewFile();
+ }
+
+ public void testAnExistingDirectory() {
+ assertMatches("matches existing directory", FileMatchers.anExistingDirectory(), directory);
+ assertDoesNotMatch("doesn't match existing file", FileMatchers.anExistingDirectory(), file);
+ assertDoesNotMatch("doesn't match missing file", FileMatchers.anExistingDirectory(), new File("foo"));
+ }
+
+ public void testAnExistingFileOrDirectory() {
+ assertMatches("matches existing file", FileMatchers.anExistingFileOrDirectory(), file);
+ assertMatches("matches existing directory", FileMatchers.anExistingFileOrDirectory(), directory);
+ assertDoesNotMatch("doesn't match missing file", FileMatchers.anExistingFileOrDirectory(), new File("foo"));
+ }
+
+ public void testAnExistingFile() {
+ assertMatches("matches existing file", FileMatchers.anExistingFile(), file);
+ assertDoesNotMatch("doesn't match existing directory", FileMatchers.anExistingFile(), directory);
+ assertDoesNotMatch("doesn't match missing file", FileMatchers.anExistingFile(), new File("foo"));
+ }
+
+ public void testAReadableFile() {
+ file.setReadable(true);
+ assertMatches("matches readable file", FileMatchers.aReadableFile(), file);
+ if (file.setReadable(false)) {
+ assertDoesNotMatch("doesn't match unreadable file", FileMatchers.aReadableFile(), file);
+ }
+ }
+
+ public void testAWritableFile() {
+ assertMatches("matches writable file", FileMatchers.aWritableFile(), file);
+ file.setWritable(false);
+ assertDoesNotMatch("doesn't match unwritable file", FileMatchers.aWritableFile(), file);
+ }
+
+ public void testAFileWithSizeLong() {
+ assertMatches("matches file size", FileMatchers.aFileWithSize(0L), file);
+ file.setWritable(false);
+ assertDoesNotMatch("doesn't match incorrect file size", FileMatchers.aFileWithSize(34L), file);
+ }
+
+ public void testAFileWithSizeMatcherOfLong() {
+ assertMatches("matches file size", FileMatchers.aFileWithSize(equalTo(0L)), file);
+ file.setWritable(false);
+ assertDoesNotMatch("doesn't match incorrect file size", FileMatchers.aFileWithSize(equalTo(23L)), file);
+ }
+
+ public void testAFileNamed() {
+ assertMatches("matches file name", FileMatchers.aFileNamed(equalTo(file.getName())), file);
+ file.setWritable(false);
+ assertDoesNotMatch("doesn't match incorrect file name", FileMatchers.aFileNamed(equalTo("foo")), file);
+ }
+
+ public void testAFileWithCanonicalPath() throws Exception {
+ assertMatches("matches file canonical path", FileMatchers.aFileWithCanonicalPath(equalTo(file.getCanonicalPath())), file);
+ file.setWritable(false);
+ assertDoesNotMatch("doesn't match incorrect canonical path", FileMatchers.aFileWithCanonicalPath(equalTo("foo")), file);
+ }
+
+ public void testAFileWithAbsolutePath() {
+ assertMatches("matches file absolute path", FileMatchers.aFileWithAbsolutePath(equalTo(file.getAbsolutePath())), file);
+ file.setWritable(false);
+ assertDoesNotMatch("doesn't match incorrect absolute path", FileMatchers.aFileWithAbsolutePath(equalTo("foo")), file);
+ }
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return FileMatchers.aFileWithSize(1L);
+ }
+
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/number/BigDecimalCloseToTest.java b/hamcrest-library/src/test/java/org/hamcrest/number/BigDecimalCloseToTest.java
new file mode 100644
index 0000000..c82e6f4
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/number/BigDecimalCloseToTest.java
@@ -0,0 +1,45 @@
+package org.hamcrest.number;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import java.math.BigDecimal;
+
+import static org.hamcrest.number.BigDecimalCloseTo.closeTo;
+
+public class BigDecimalCloseToTest extends AbstractMatcherTest {
+ private final Matcher<BigDecimal> matcher = closeTo(new BigDecimal("1.0"), new BigDecimal("0.5"));
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ BigDecimal irrelevant = new BigDecimal("0.01");
+ return closeTo(irrelevant, irrelevant);
+ }
+
+ public void testEvaluatesToTrueIfArgumentIsEqualToABigDecimalWithinSomeError() {
+ assertTrue(matcher.matches(new BigDecimal("1.0")));
+ assertTrue(matcher.matches(new BigDecimal("0.5")));
+ assertTrue(matcher.matches(new BigDecimal("1.5")));
+
+ assertDoesNotMatch("too large", matcher, new BigDecimal("2.0"));
+ assertMismatchDescription("<2.0> differed by <0.5> more than delta <0.5>", matcher, new BigDecimal("2.0"));
+ assertDoesNotMatch("number too small", matcher, new BigDecimal("0.0"));
+ assertMismatchDescription("<0.0> differed by <0.5> more than delta <0.5>", matcher, new BigDecimal("0.0"));
+ }
+
+ public void testEvaluatesToTrueIfArgumentHasDifferentScale() {
+ assertTrue(matcher.matches(new BigDecimal("1.000000")));
+ assertTrue(matcher.matches(new BigDecimal("0.500000")));
+ assertTrue(matcher.matches(new BigDecimal("1.500000")));
+
+ assertDoesNotMatch("too large", matcher, new BigDecimal("2.000000"));
+ assertMismatchDescription("<2.000000> differed by <0.5> more than delta <0.5>", matcher, new BigDecimal("2.000000"));
+ assertDoesNotMatch("number too small", matcher, new BigDecimal("0.000000"));
+ assertMismatchDescription("<0.000000> differed by <0.5> more than delta <0.5>", matcher, new BigDecimal("0.000000"));
+ }
+
+ public void test_is_self_describing() {
+ assertDescription("a numeric value within <0.5> of <1.0>", matcher);
+ }
+
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/number/IsCloseToTest.java b/hamcrest-library/src/test/java/org/hamcrest/number/IsCloseToTest.java
new file mode 100644
index 0000000..8b0e244
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/number/IsCloseToTest.java
@@ -0,0 +1,32 @@
+package org.hamcrest.number;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.number.IsCloseTo.closeTo;
+
+public class IsCloseToTest extends AbstractMatcherTest {
+ private final Matcher<Double> matcher = closeTo(1.0d, 0.5d);
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ final double irrelevant = 0.1;
+ return closeTo(irrelevant, irrelevant);
+ }
+
+ public void test_matchesIfArgumentIsEqualToADoubleValueWithinSomeError() {
+ assertMatches("1.0", matcher, 1.0);
+ assertMatches("0.5d", matcher, 0.5d);
+ assertMatches("1.5d", matcher, 1.5d);
+
+ assertDoesNotMatch("too large", matcher, 2.0);
+ assertMismatchDescription("<3.0> differed by <1.5> more than delta <0.5>", matcher, 3.0d);
+ assertDoesNotMatch("number too small", matcher, 0.0);
+ assertMismatchDescription("<0.1> differed by <0.4> more than delta <0.5>", matcher, 0.1);
+ }
+
+ public void test_is_self_describing() {
+ assertDescription("a numeric value within <0.5> of <1.0>", matcher);
+ }
+
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/number/IsNanTest.java b/hamcrest-library/src/test/java/org/hamcrest/number/IsNanTest.java
new file mode 100644
index 0000000..c9b3956
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/number/IsNanTest.java
@@ -0,0 +1,43 @@
+package org.hamcrest.number;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.number.IsNaN.notANumber;
+
+public final class IsNanTest {
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<Double> matcher = notANumber();
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ matchesNaN() {
+ assertMatches(notANumber(), Double.NaN);
+ }
+
+ @Test public void
+ doesNotMatchDoubleValue() {
+ assertDoesNotMatch(notANumber(), 1.25);
+ }
+
+ @Test public void
+ doesNotMatchInfinity() {
+ assertDoesNotMatch(notANumber(), Double.POSITIVE_INFINITY);
+ }
+
+ @Test public void
+ describesItself() {
+ assertDescription("a double value of NaN", notANumber());
+ }
+
+ @Test public void
+ describesAMismatch() {
+ assertMismatchDescription("was <1.25>", notANumber(), 1.25);
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/number/OrderingComparisonTest.java b/hamcrest-library/src/test/java/org/hamcrest/number/OrderingComparisonTest.java
new file mode 100644
index 0000000..5953bd0
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/number/OrderingComparisonTest.java
@@ -0,0 +1,80 @@
+package org.hamcrest.number;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import java.math.BigDecimal;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.number.OrderingComparison.*;
+
+public class OrderingComparisonTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<Integer> createMatcher() {
+ return greaterThan(1);
+ }
+
+ public void testDescription() {
+ assertDescription("a value greater than <1>", greaterThan(1));
+ assertDescription("a value equal to or greater than <1>", greaterThanOrEqualTo(1));
+ assertDescription("a value equal to <1>", comparesEqualTo(1));
+ assertDescription("a value less than or equal to <1>", lessThanOrEqualTo(1));
+ assertDescription("a value less than <1>", lessThan(1));
+ }
+
+ public void testMismatchDescriptions() {
+ assertMismatchDescription("<0> was less than <1>", greaterThan(1), 0);
+ assertMismatchDescription("<1> was equal to <1>", greaterThan(1), 1);
+ assertMismatchDescription("<1> was greater than <0>", lessThan(0), 1);
+ assertMismatchDescription("<2> was equal to <2>", lessThan(2), 2);
+ }
+
+ public void testComparesObjectsForGreaterThan() {
+ assertThat(2, greaterThan(1));
+ assertThat(0, not(greaterThan(1)));
+ }
+
+ public void testComparesObjectsForLessThan() {
+ assertThat(2, lessThan(3));
+ assertThat(0, lessThan(1));
+ }
+
+
+ public void testComparesObjectsForEquality() {
+ assertThat(3, comparesEqualTo(3));
+ assertThat("aa", comparesEqualTo("aa"));
+ }
+
+ public void testAllowsForInclusiveComparisons() {
+ assertThat("less", 1, lessThanOrEqualTo(1));
+ assertThat("greater", 1, greaterThanOrEqualTo(1));
+ }
+
+ public void testSupportsDifferentTypesOfComparableObjects() {
+ assertThat(1.1, greaterThan(1.0));
+ assertThat("cc", greaterThan("bb"));
+ }
+
+ public void testComparesBigDecimalsWithDifferentScalesCorrectlyForIssue20() {
+ assertThat(new BigDecimal("10.0"), greaterThanOrEqualTo(new BigDecimal("10")));
+ assertThat(new BigDecimal(10), greaterThanOrEqualTo(new BigDecimal("10.0")));
+ assertThat(new BigDecimal("2"), comparesEqualTo(new BigDecimal("2.000")));
+ }
+
+ public void testComparesCustomTypesWhoseCompareToReturnsValuesGreaterThatOne() {
+ assertThat(new CustomInt(5), lessThan(new CustomInt(10)));
+ }
+
+ private static final class CustomInt implements Comparable<CustomInt> {
+ private final int value;
+ public CustomInt(int value) {
+ this.value = value;
+ }
+
+ public int compareTo(CustomInt other) {
+ return value - other.value;
+ }
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/object/HasToStringTest.java b/hamcrest-library/src/test/java/org/hamcrest/object/HasToStringTest.java
new file mode 100644
index 0000000..5c75ae7
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/object/HasToStringTest.java
@@ -0,0 +1,55 @@
+package org.hamcrest.object;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.object.HasToString.hasToString;
+
+public final class HasToStringTest {
+ private static final String TO_STRING_RESULT = "toString result";
+ private static final Object TEST_OBJECT = new Object() {
+ @Override
+ public String toString() {
+ return TO_STRING_RESULT;
+ }
+ };
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<Object> matcher = hasToString(equalTo("irrelevant"));
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ matchesWhenUtilisingANestedMatcher() {
+ final Matcher<Object> matcher = hasToString(equalTo(TO_STRING_RESULT));
+
+ assertMatches(matcher, TEST_OBJECT);
+ assertDoesNotMatch(matcher, new Object());
+ }
+
+ @Test public void
+ matchesWhenUsingShortcutForHasToStringEqualTo() {
+ final Matcher<Object> matcher = hasToString(TO_STRING_RESULT);
+
+ assertMatches(matcher, TEST_OBJECT);
+ assertDoesNotMatch(matcher, new Object());
+ }
+
+ @Test public void
+ describesItself() {
+ final Matcher<Object> matcher = hasToString(equalTo(TO_STRING_RESULT));
+ assertDescription("with toString() \"toString result\"", matcher);
+ }
+
+ @Test public void
+ describesAMismatch() {
+ final Matcher<Object> matcher = hasToString(equalTo(TO_STRING_RESULT));
+ String expectedMismatchString = "toString() was \"Cheese\"";
+ assertMismatchDescription(expectedMismatchString, matcher, "Cheese");
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/object/IsCompatibleTypeTest.java b/hamcrest-library/src/test/java/org/hamcrest/object/IsCompatibleTypeTest.java
new file mode 100644
index 0000000..8432fdb
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/object/IsCompatibleTypeTest.java
@@ -0,0 +1,58 @@
+package org.hamcrest.object;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.object.IsCompatibleType.typeCompatibleWith;
+
+public class IsCompatibleTypeTest extends AbstractMatcherTest {
+ public static class BaseClass {
+ }
+
+ public static class ExtendedClass extends BaseClass {
+ }
+
+ public interface BaseInterface {
+ }
+
+ public interface ExtendedInterface extends BaseInterface {
+ }
+
+ public static class ClassImplementingBaseInterface implements BaseInterface {
+ }
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return typeCompatibleWith(BaseClass.class);
+ }
+
+ public void testMatchesSameClass() {
+ assertThat(BaseClass.class, typeCompatibleWith(BaseClass.class));
+ }
+
+ public void testMatchesSameInterface() {
+ assertThat(BaseInterface.class, typeCompatibleWith(BaseInterface.class));
+ }
+
+ public void testMatchesExtendedClass() {
+ assertThat(ExtendedClass.class, typeCompatibleWith(BaseClass.class));
+ }
+
+ public void testMatchesClassImplementingInterface() {
+ assertThat(ClassImplementingBaseInterface.class, typeCompatibleWith(BaseInterface.class));
+ }
+
+ public void testMatchesExtendedInterface() {
+ assertThat(ExtendedInterface.class, typeCompatibleWith(BaseInterface.class));
+ }
+
+// public void testDoesNotMatchIncompatibleTypes() {
+// assertThat(BaseClass.class, not(compatibleType(ExtendedClass.class)));
+// assertThat(Integer.class, not(compatibleType(String.class)));
+// }
+
+ public void testHasReadableDescription() {
+ assertDescription("type < java.lang.Runnable", typeCompatibleWith(Runnable.class));
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/object/IsEventFromTest.java b/hamcrest-library/src/test/java/org/hamcrest/object/IsEventFromTest.java
new file mode 100644
index 0000000..b3c4a3a
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/object/IsEventFromTest.java
@@ -0,0 +1,52 @@
+package org.hamcrest.object;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import java.util.EventObject;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.object.IsEventFrom.eventFrom;
+
+
+public class IsEventFromTest extends AbstractMatcherTest {
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return eventFrom(null);
+ }
+
+ public void testEvaluatesToTrueIfArgumentIsAnEventObjectFiredByASpecifiedSource() {
+ Object o = "Source";
+ EventObject ev = new EventObject(o);
+ EventObject ev2 = new EventObject("source 2");
+
+ Matcher<EventObject> isEventMatcher = eventFrom(o);
+
+ assertThat(ev, isEventMatcher);
+ assertMismatchDescription("source was \"source 2\"", isEventMatcher, ev2);
+ }
+
+ private static class DerivedEvent extends EventObject {
+ private static final long serialVersionUID = 1L;
+
+ public DerivedEvent(Object source) {
+ super(source);
+ }
+ }
+
+ public void testCanTestForSpecificEventClasses() {
+ Object o = new Object();
+ DerivedEvent goodEv = new DerivedEvent(o);
+ DerivedEvent wrongSource = new DerivedEvent("wrong source");
+ EventObject wrongType = new EventObject(o);
+ EventObject wrongSourceAndType = new EventObject(new Object());
+
+ Matcher<EventObject> isEventMatcher = IsEventFrom.eventFrom(DerivedEvent.class, o);
+
+ assertThat(goodEv, isEventMatcher);
+ assertMismatchDescription("source was \"wrong source\"", isEventMatcher, wrongSource);
+ assertMismatchDescription("item type was java.util.EventObject", isEventMatcher, wrongType);
+ assertMismatchDescription("item type was java.util.EventObject", isEventMatcher, wrongSourceAndType);
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/object/MatchesPatternTest.java b/hamcrest-library/src/test/java/org/hamcrest/object/MatchesPatternTest.java
new file mode 100644
index 0000000..3e2d911
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/object/MatchesPatternTest.java
@@ -0,0 +1,59 @@
+package org.hamcrest.object;
+
+import org.hamcrest.Matcher;
+import org.hamcrest.text.MatchesPattern;
+import org.junit.Test;
+
+import java.util.regex.Pattern;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.junit.Assert.assertThat;
+
+public class MatchesPatternTest {
+ @Test
+ public void copesWithNullsAndUnknownTypes() {
+ Matcher<String> matcher = new MatchesPattern(Pattern.compile("."));
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test
+ public void matchesExactString() {
+ assertThat("a", new MatchesPattern(Pattern.compile("a")));
+ }
+
+ @Test
+ public void doesNotMatchADifferentString() {
+ assertDoesNotMatch("A different string does not match", new MatchesPattern(Pattern.compile("a")), "b");
+ }
+
+ @Test
+ public void doesNotMatchSubstring() {
+ assertDoesNotMatch("A substring does not match", new MatchesPattern(Pattern.compile("a")), "ab");
+ }
+
+ @Test
+ public void hasAReadableDescription() {
+ Matcher<?> m = new MatchesPattern(Pattern.compile("a[bc](d|e)"));
+ assertDescription("a string matching the pattern 'a[bc](d|e)'", m );
+ }
+
+ @Test
+ public void describesAMismatch() {
+ final Matcher<String> matcher = new MatchesPattern(Pattern.compile("a"));
+ assertMismatchDescription("was \"Cheese\"", matcher, "Cheese");
+ }
+
+ @Test
+ public void factoryMethodAllowsCreationWithPattern() {
+ Matcher<?> m = MatchesPattern.matchesPattern(Pattern.compile("a[bc](d|e)"));
+ assertDescription("a string matching the pattern 'a[bc](d|e)'", m );
+ }
+
+ @Test
+ public void factoryMethodAllowsCreationWithString() {
+ Matcher<?> m = MatchesPattern.matchesPattern("a[bc](d|e)");
+ assertDescription("a string matching the pattern 'a[bc](d|e)'", m );
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/text/IsBlankStringTest.java b/hamcrest-library/src/test/java/org/hamcrest/text/IsBlankStringTest.java
new file mode 100644
index 0000000..c5f35f1
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/text/IsBlankStringTest.java
@@ -0,0 +1,55 @@
+package org.hamcrest.text;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.text.IsBlankString.blankOrNullString;
+import static org.hamcrest.text.IsBlankString.blankString;
+
+public final class IsBlankStringTest {
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<String> matcher = blankString();
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ matchesEmptyString() {
+ assertMatches(blankOrNullString(), "");
+ assertMatches(blankString(), "");
+ }
+
+ @Test public void
+ matchesNullAppropriately() {
+ assertMatches(blankOrNullString(), null);
+ assertDoesNotMatch(blankString(), null);
+ }
+
+ @Test public void
+ matchesBlankStringAppropriately() {
+ assertMatches(blankString(), " \t");
+ assertMatches(blankOrNullString(), " \t");
+ }
+
+ @Test public void
+ doesNotMatchFilledString() {
+ assertDoesNotMatch(blankString(), "a");
+ assertDoesNotMatch(blankOrNullString(), "a");
+ }
+
+ @Test public void
+ describesItself() {
+ assertDescription("a blank string", blankString());
+ assertDescription("(null or a blank string)", blankOrNullString());
+ }
+
+ @Test public void
+ describesAMismatch() {
+ assertMismatchDescription("was \"a\"", blankString(), "a");
+ assertMismatchDescription("was \"a\"", blankOrNullString(), "a");
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/text/IsEmptyStringTest.java b/hamcrest-library/src/test/java/org/hamcrest/text/IsEmptyStringTest.java
new file mode 100644
index 0000000..62e3053
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/text/IsEmptyStringTest.java
@@ -0,0 +1,55 @@
+package org.hamcrest.text;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.text.IsEmptyString.emptyOrNullString;
+import static org.hamcrest.text.IsEmptyString.emptyString;
+
+public final class IsEmptyStringTest {
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<String> matcher = emptyString();
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ matchesEmptyString() {
+ assertMatches(emptyOrNullString(), "");
+ assertMatches(emptyString(), "");
+ }
+
+ @Test public void
+ matchesNullAppropriately() {
+ assertMatches(emptyOrNullString(), null);
+ assertDoesNotMatch(emptyString(), null);
+ }
+
+ @Test public void
+ matchesBlankStringAppropriately() {
+ assertDoesNotMatch(emptyString(), " ");
+ assertDoesNotMatch(emptyOrNullString(), " ");
+ }
+
+ @Test public void
+ doesNotMatchFilledString() {
+ assertDoesNotMatch(emptyString(), "a");
+ assertDoesNotMatch(emptyOrNullString(), "a");
+ }
+
+ @Test public void
+ describesItself() {
+ assertDescription("an empty string", emptyString());
+ assertDescription("(null or an empty string)", emptyOrNullString());
+ }
+
+ @Test public void
+ describesAMismatch() {
+ assertMismatchDescription("was \"a\"", emptyString(), "a");
+ assertMismatchDescription("was \"a\"", emptyOrNullString(), "a");
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/text/IsEqualIgnoringCaseTest.java b/hamcrest-library/src/test/java/org/hamcrest/text/IsEqualIgnoringCaseTest.java
new file mode 100644
index 0000000..4800f43
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/text/IsEqualIgnoringCaseTest.java
@@ -0,0 +1,62 @@
+package org.hamcrest.text;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.text.IsEqualIgnoringCase.equalToIgnoringCase;
+
+public final class IsEqualIgnoringCaseTest {
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<String> matcher = equalToIgnoringCase("irrelevant");
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ ignoresCaseOfCharsInString() {
+ final Matcher<String> matcher = equalToIgnoringCase("heLLo");
+
+ assertMatches(matcher, "HELLO");
+ assertMatches(matcher, "hello");
+ assertMatches(matcher, "HelLo");
+ assertDoesNotMatch(matcher, "bye");
+ }
+
+ @Test public void
+ mismatchesIfAdditionalWhitespaceIsPresent() {
+ final Matcher<String> matcher = equalToIgnoringCase("heLLo");
+
+ assertDoesNotMatch(matcher, "hello ");
+ assertDoesNotMatch(matcher, " hello");
+ }
+
+ @Test public void
+ mismatchesNull() {
+ final Matcher<String> matcher = equalToIgnoringCase("heLLo");
+
+ assertDoesNotMatch(matcher, null);
+ }
+
+ @Test(expected=IllegalArgumentException.class) public void
+ canOnlyBeConstructedAboutANonNullString() {
+ equalToIgnoringCase(null);
+ }
+
+
+ @Test public void
+ describesItself() {
+ final Matcher<String> matcher = equalToIgnoringCase("heLLo");
+ assertDescription("equalToIgnoringCase(\"heLLo\")", matcher);
+ }
+
+ @Test public void
+ describesAMismatch() {
+ final Matcher<String> matcher = equalToIgnoringCase("heLLo");
+ String expectedMismatchString = "was \"Cheese\"";
+ assertMismatchDescription(expectedMismatchString, matcher, "Cheese");
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/text/IsEqualIgnoringWhiteSpaceTest.java b/hamcrest-library/src/test/java/org/hamcrest/text/IsEqualIgnoringWhiteSpaceTest.java
new file mode 100644
index 0000000..d5c7576
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/text/IsEqualIgnoringWhiteSpaceTest.java
@@ -0,0 +1,51 @@
+package org.hamcrest.text;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.text.IsEqualIgnoringWhiteSpace.equalToIgnoringWhiteSpace;
+
+public class IsEqualIgnoringWhiteSpaceTest extends AbstractMatcherTest {
+
+ private final Matcher<String> matcher = equalToIgnoringWhiteSpace("Hello World how\n are we? ");
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return matcher;
+ }
+
+ public void testPassesIfWordsAreSameButWhitespaceDiffers() {
+ assertThat("Hello World how are we?", matcher);
+ assertThat(" Hello World how are \n\n\twe?", matcher);
+ }
+
+ public void testFailsIfTextOtherThanWhitespaceDiffers() {
+ assertThat("Hello PLANET how are we?", not(matcher));
+ assertThat("Hello World how are we", not(matcher));
+ }
+
+ public void testFailsIfWhitespaceIsAddedOrRemovedInMidWord() {
+ assertThat("HelloWorld how are we?", not(matcher));
+ assertThat("Hello Wo rld how are we?", not(matcher));
+ }
+
+ public void testFailsIfMatchingAgainstNull() {
+ assertThat(null, not(matcher));
+ }
+
+ public void testRequiresNonNullStringToBeConstructed() {
+ try {
+ new IsEqualIgnoringWhiteSpace(null);
+ fail("Expected exception");
+ } catch (IllegalArgumentException goodException) {
+ // expected!
+ }
+ }
+
+ public void testHasAReadableDescription() {
+ assertDescription("equalToIgnoringWhiteSpace(\"Hello World how\\n are we? \")",
+ matcher);
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/text/StringContainsInOrderTest.java b/hamcrest-library/src/test/java/org/hamcrest/text/StringContainsInOrderTest.java
new file mode 100644
index 0000000..8ffbc67
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/text/StringContainsInOrderTest.java
@@ -0,0 +1,30 @@
+package org.hamcrest.text;
+
+import org.hamcrest.AbstractMatcherTest;
+import org.hamcrest.Matcher;
+
+import static java.util.Arrays.asList;
+
+
+public class StringContainsInOrderTest extends AbstractMatcherTest {
+ StringContainsInOrder m = new StringContainsInOrder(asList("a", "b", "c"));
+
+ @Override
+ protected Matcher<?> createMatcher() {
+ return m;
+ }
+
+ public void testMatchesOnlyIfStringContainsGivenSubstringsInTheSameOrder() {
+ assertMatches("substrings in order", m, "abc");
+ assertMatches("substrings separated", m, "1a2b3c4");
+
+ assertDoesNotMatch("substrings out of order", m, "cab");
+ assertDoesNotMatch("no substrings in string", m, "xyz");
+ assertDoesNotMatch("substring missing", m, "ac");
+ assertDoesNotMatch("empty string", m, "");
+ }
+
+ public void testHasAReadableDescription() {
+ assertDescription("a string containing \"a\", \"b\", \"c\" in order", m);
+ }
+}
diff --git a/hamcrest-library/src/test/java/org/hamcrest/xml/HasXPathTest.java b/hamcrest-library/src/test/java/org/hamcrest/xml/HasXPathTest.java
new file mode 100644
index 0000000..a66689d
--- /dev/null
+++ b/hamcrest-library/src/test/java/org/hamcrest/xml/HasXPathTest.java
@@ -0,0 +1,147 @@
+package org.hamcrest.xml;
+
+import org.hamcrest.Matcher;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.ByteArrayInputStream;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import static org.hamcrest.AbstractMatcherTest.*;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.core.StringContains.containsString;
+import static org.hamcrest.xml.HasXPath.hasXPath;
+import static org.junit.Assert.fail;
+
+/**
+ * @author Joe Walnes
+ * @author Tom Denley
+ */
+public final class HasXPathTest {
+
+ private final Document xml = parse(""
+ + "<root type='food'>\n"
+ + " <something id='a'><cheese>Edam</cheese></something>\n"
+ + " <something id='b'><cheese>Cheddar</cheese></something>\n"
+ + " <f:foreignSomething xmlns:f=\"http://cheese.com\" milk=\"camel\">Caravane</f:foreignSomething>\n"
+ + " <emptySomething />\n"
+ + " <f:emptySomething xmlns:f=\"http://cheese.com\" />"
+ + "</root>\n"
+ );
+
+ private final NamespaceContext ns = new NamespaceContext() {
+ @Override
+ public String getNamespaceURI(String prefix) {
+ return ("cheese".equals(prefix) ? "http://cheese.com" : null);
+ }
+
+ @Override
+ public String getPrefix(String namespaceURI) {
+ return ("http://cheese.com".equals(namespaceURI) ? "cheese" : null);
+ }
+
+ @Override
+ public Iterator<String> getPrefixes(String namespaceURI) {
+ HashSet<String> prefixes = new HashSet<String>();
+ String prefix = getPrefix(namespaceURI);
+ if (prefix != null) {
+ prefixes.add(prefix);
+ }
+ return prefixes.iterator();
+ }
+ };
+
+ @Test public void
+ copesWithNullsAndUnknownTypes() {
+ Matcher<Node> matcher = hasXPath("//irrelevant");
+
+ assertNullSafe(matcher);
+ assertUnknownTypeSafe(matcher);
+ }
+
+ @Test public void
+ appliesMatcherToXPathInDocument() {
+ assertMatches(hasXPath("/root/something[2]/cheese", equalTo("Cheddar")), xml);
+ assertMatches(hasXPath("//something[1]/cheese", containsString("dam")), xml);
+ assertMatches(hasXPath("//something[2]/cheese", not(containsString("dam"))), xml);
+ assertMatches(hasXPath("/root/@type", equalTo("food")), xml);
+ assertMatches(hasXPath("//something[@id='b']/cheese", equalTo("Cheddar")), xml);
+ assertMatches(hasXPath("//something[@id='b']/cheese"), xml);
+ }
+
+ @Test public void
+ matchesEmptyElement() {
+ assertMatches(hasXPath("//emptySomething"), xml);
+ }
+
+ @Test public void
+ matchesEmptyElementInNamespace() {
+ assertMatches(hasXPath("//cheese:emptySomething", ns), xml);
+ }
+
+ @Test public void
+ failsIfNodeIsMissing() {
+ assertDoesNotMatch(hasXPath("/root/something[3]/cheese", ns, equalTo("Cheddar")), xml);
+ assertDoesNotMatch(hasXPath("//something[@id='c']/cheese", ns), xml);
+ }
+
+ @Test public void
+ failsIfNodeIsMissingInNamespace() {
+ assertDoesNotMatch(hasXPath("//cheese:foreignSomething", equalTo("Badger")), xml);
+ assertDoesNotMatch(hasXPath("//cheese:foreignSomething"), xml);
+ }
+
+ @Test public void
+ matchesWithNamespace() {
+ assertMatches(hasXPath("//cheese:foreignSomething", ns), xml);
+ assertMatches(hasXPath("//cheese:foreignSomething/@milk", ns, equalTo("camel")), xml);
+ assertMatches(hasXPath("//cheese:foreignSomething/text()", ns, equalTo("Caravane")), xml);
+ }
+
+ @Test public void
+ throwsIllegalArgumentExceptionIfGivenIllegalExpression() {
+ try {
+ hasXPath("\\g:dfgd::DSgf/root/something[2]/cheese", equalTo("blah"));
+ fail("Expected exception");
+ } catch (IllegalArgumentException expectedException) {
+ // expected exception
+ }
+ }
+
+ @Test public void
+ describesItself() {
+ assertDescription("an XML document with XPath /some/path \"Cheddar\"",
+ hasXPath("/some/path", equalTo("Cheddar")));
+
+ assertDescription("an XML document with XPath /some/path",
+ hasXPath("/some/path"));
+ }
+
+ @Test public void
+ describesMissingNodeMismatch() {
+ assertMismatchDescription("xpath returned no results.", hasXPath("//honky"), xml);
+ }
+
+ @Test public void
+ describesIncorrectNodeValueMismatch() {
+ assertMismatchDescription("was \"Edam\"", hasXPath("//something[1]/cheese", equalTo("parmesan")), xml);
+ }
+
+ private static Document parse(String xml) {
+ try {
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+ return documentBuilder.parse(new ByteArrayInputStream(xml.getBytes()));
+ }
+ catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+}