diff options
author | Brett Chabot <brettchabot@google.com> | 2014-06-16 17:52:29 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-06-12 17:09:07 +0000 |
commit | cbb799a6e05bbb82d66619a551283621cbe2f3a7 (patch) | |
tree | b18d557dc268c8f3d02642115009b90c64b49b88 | |
parent | 19fa6b81908cfe9556d71f4149eb55d77bbc5e91 (diff) | |
parent | f5e9a2415ec42c425c2bb17db46f2a9649992d80 (diff) | |
download | hamcrest-cbb799a6e05bbb82d66619a551283621cbe2f3a7.tar.gz |
Merge "Add hamcrest 1.1 library and integration source"
34 files changed, 1368 insertions, 0 deletions
@@ -48,3 +48,5 @@ LOCAL_SDK_VERSION := 4 LOCAL_MODULE_TAGS := optional include $(BUILD_STATIC_JAVA_LIBRARY) + +include $(call all-makefiles-under, $(LOCAL_PATH)) diff --git a/integration/Android.mk b/integration/Android.mk new file mode 100644 index 0000000..8126b30 --- /dev/null +++ b/integration/Android.mk @@ -0,0 +1,33 @@ +# Copyright (C) 2014 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +LOCAL_PATH := $(call my-dir) + +# TODO: add host and hostdex jars + +#------------------------------- +# build a target jar + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_MODULE := hamcrest-integration +LOCAL_JAVA_LIBRARIES := hamcrest +LOCAL_SDK_VERSION := 4 +LOCAL_MODULE_TAGS := optional + +include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/integration/LICENSE.txt b/integration/LICENSE.txt new file mode 100644 index 0000000..5ebe92c --- /dev/null +++ b/integration/LICENSE.txt @@ -0,0 +1,27 @@ +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/integration/README.android b/integration/README.android new file mode 100644 index 0000000..a86659e --- /dev/null +++ b/integration/README.android @@ -0,0 +1 @@ +Source obtained from https://hamcrest.googlecode.com/files/hamcrest-integration-1.1.jar, with the easymock and jmock dependent classes removed diff --git a/integration/src/org/hamcrest/MatcherAssert.java b/integration/src/org/hamcrest/MatcherAssert.java new file mode 100644 index 0000000..3eb234a --- /dev/null +++ b/integration/src/org/hamcrest/MatcherAssert.java @@ -0,0 +1,24 @@ +/* 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());
+ }
+ }
+}
diff --git a/library/Android.mk b/library/Android.mk new file mode 100644 index 0000000..bdb4c58 --- /dev/null +++ b/library/Android.mk @@ -0,0 +1,33 @@ +# Copyright (C) 2014 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +LOCAL_PATH := $(call my-dir) + +# TODO: add host and hostdex jars + +#------------------------------- +# build a target jar + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_MODULE := hamcrest-library +LOCAL_JAVA_LIBRARIES := hamcrest +LOCAL_SDK_VERSION := 8 +LOCAL_MODULE_TAGS := optional + +include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/library/LICENSE.txt b/library/LICENSE.txt new file mode 100644 index 0000000..5ebe92c --- /dev/null +++ b/library/LICENSE.txt @@ -0,0 +1,27 @@ +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/library/README.android b/library/README.android new file mode 100644 index 0000000..dd099ed --- /dev/null +++ b/library/README.android @@ -0,0 +1 @@ +Ssource obtained from https://hamcrest.googlecode.com/files/hamcrest-library-1.1.jar, with org.hamcrest.beans removed diff --git a/library/src/org/hamcrest/Matchers.java b/library/src/org/hamcrest/Matchers.java new file mode 100644 index 0000000..b78864a --- /dev/null +++ b/library/src/org/hamcrest/Matchers.java @@ -0,0 +1,308 @@ +// 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); + } + + /** + * 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)) + */ + public static org.hamcrest.Matcher<java.lang.Object> is(java.lang.Class<?> type) { + return org.hamcrest.core.Is.is(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.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.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.hasItem(elementMatcher); + } + + public static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems(org.hamcrest.Matcher<? extends T>... elementMatchers) { + return org.hamcrest.collection.IsCollectionContaining.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); + } + + public static <T> org.hamcrest.Matcher<T> hasToString(org.hamcrest.Matcher<java.lang.String> toStringMatcher) { + return org.hamcrest.object.HasToString.hasToString(toStringMatcher); + } + + public static <T> org.hamcrest.Matcher<java.lang.Class<?>> typeCompatibleWith(java.lang.Class<T> baseType) { + return org.hamcrest.object.IsCompatibleType.typeCompatibleWith(baseType); + } + + /** + * 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); + } + + /** + * 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); + } + +} diff --git a/library/src/org/hamcrest/TypeSafeMatcher.java b/library/src/org/hamcrest/TypeSafeMatcher.java new file mode 100644 index 0000000..7f18fd3 --- /dev/null +++ b/library/src/org/hamcrest/TypeSafeMatcher.java @@ -0,0 +1,58 @@ +package org.hamcrest; + +import java.lang.reflect.Method; + +/** + * 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 + */ +public abstract class TypeSafeMatcher<T> extends BaseMatcher<T> { + + private Class expectedType; + + /** + * Subclasses should implement this. The item will already have been checked for + * the specific type and will never be null. + */ + public abstract boolean matchesSafely(T item); + + protected TypeSafeMatcher() { + expectedType = findExpectedType(getClass()); + } + + 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."); + } + + private static boolean isMatchesSafelyMethod(Method method) { + return method.getName().equals("matchesSafely") + && method.getParameterTypes().length == 1 + && !method.isSynthetic(); + } + + protected TypeSafeMatcher(Class<T> expectedType) { + this.expectedType = expectedType; + } + + /** + * Method made final to prevent accidental override. + * If you need to override this, there's no point on extending TypeSafeMatcher. + * Instead, extend the {@link BaseMatcher}. + */ + @SuppressWarnings({"unchecked"}) + public final boolean matches(Object item) { + return item != null + && expectedType.isInstance(item) + && matchesSafely((T) item); + } +} diff --git a/library/src/org/hamcrest/collection/IsArray.java b/library/src/org/hamcrest/collection/IsArray.java new file mode 100644 index 0000000..6a26ef1 --- /dev/null +++ b/library/src/org/hamcrest/collection/IsArray.java @@ -0,0 +1,64 @@ +package org.hamcrest.collection; + +import java.util.Arrays; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; + +public class IsArray<T> extends TypeSafeMatcher<T[]> { + private final Matcher<T>[] elementMatchers; + + public IsArray(Matcher<T>[] elementMatchers) { + this.elementMatchers = elementMatchers.clone(); + } + + public boolean matchesSafely(T[] array) { + if (array.length != elementMatchers.length) return false; + + for (int i = 0; i < array.length; i++) { + if (!elementMatchers[i].matches(array[i])) return false; + } + + return true; + } + + public void describeTo(Description description) { + description.appendList(descriptionStart(), descriptionSeparator(), descriptionEnd(), + Arrays.asList(elementMatchers)); + } + + /** + * Returns the string that starts the description. + * + * Can be overridden in subclasses to customise how the matcher is + * described. + */ + protected String descriptionStart() { + return "["; + } + + /** + * Returns the string that separates the elements in the description. + * + * Can be overridden in subclasses to customise how the matcher is + * described. + */ + protected String descriptionSeparator() { + return ", "; + } + + /** + * Returns the string that ends the description. + * + * Can be overridden in subclasses to customise how the matcher is + * described. + */ + protected String descriptionEnd() { + return "]"; + } + + public static <T> IsArray<T> array(Matcher<T>... elementMatchers) { + return new IsArray<T>(elementMatchers); + } +} diff --git a/library/src/org/hamcrest/collection/IsArrayContaining.java b/library/src/org/hamcrest/collection/IsArrayContaining.java new file mode 100644 index 0000000..76ddf9d --- /dev/null +++ b/library/src/org/hamcrest/collection/IsArrayContaining.java @@ -0,0 +1,42 @@ +package org.hamcrest.collection; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.Factory; +import org.hamcrest.TypeSafeMatcher; +import static org.hamcrest.core.IsEqual.equalTo; + +public class IsArrayContaining<T> extends TypeSafeMatcher<T[]> { + + private final Matcher<T> elementMatcher; + + public IsArrayContaining(Matcher<T> elementMatcher) { + this.elementMatcher = elementMatcher; + } + + public boolean matchesSafely(T[] array) { + for (T item : array) { + if (elementMatcher.matches(item)) { + return true; + } + } + return false; + } + + public void describeTo(Description description) { + description + .appendText("an array containing ") + .appendDescriptionOf(elementMatcher); + } + + @Factory + public static <T> Matcher<T[]> hasItemInArray(Matcher<T> elementMatcher) { + return new IsArrayContaining<T>(elementMatcher); + } + + @Factory + public static <T> Matcher<T[]> hasItemInArray(T element) { + return hasItemInArray(equalTo(element)); + } + +} diff --git a/library/src/org/hamcrest/collection/IsCollectionContaining.java b/library/src/org/hamcrest/collection/IsCollectionContaining.java new file mode 100644 index 0000000..ba98630 --- /dev/null +++ b/library/src/org/hamcrest/collection/IsCollectionContaining.java @@ -0,0 +1,65 @@ +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/library/src/org/hamcrest/collection/IsIn.java b/library/src/org/hamcrest/collection/IsIn.java new file mode 100644 index 0000000..0a7bbb5 --- /dev/null +++ b/library/src/org/hamcrest/collection/IsIn.java @@ -0,0 +1,45 @@ +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; + +public class IsIn<T> extends BaseMatcher<T> { + private final Collection<T> collection; + + public IsIn(Collection<T> collection) { + this.collection = collection; + } + + public IsIn(T[] elements) { + collection = Arrays.asList(elements); + } + + public boolean matches(Object o) { + return collection.contains(o); + } + + public void describeTo(Description buffer) { + buffer.appendText("one of "); + buffer.appendValueList("{", ", ", "}", collection); + } + + @Factory + public static <T> Matcher<T> isIn(Collection<T> collection) { + return new IsIn<T>(collection); + } + + @Factory + public static <T> Matcher<T> isIn(T[] elements) { + return new IsIn<T>(elements); + } + + @Factory + public static <T> Matcher<T> isOneOf(T... elements) { + return isIn(elements); + } +} diff --git a/library/src/org/hamcrest/collection/IsMapContaining.java b/library/src/org/hamcrest/collection/IsMapContaining.java new file mode 100644 index 0000000..74572dd --- /dev/null +++ b/library/src/org/hamcrest/collection/IsMapContaining.java @@ -0,0 +1,70 @@ +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>> { + + private final Matcher<K> keyMatcher; + private final Matcher<V> valueMatcher; + + public IsMapContaining(Matcher<K> keyMatcher, Matcher<V> valueMatcher) { + this.keyMatcher = keyMatcher; + this.valueMatcher = valueMatcher; + } + + public boolean matchesSafely(Map<K, V> map) { + for (Entry<K, V> entry : map.entrySet()) { + if (keyMatcher.matches(entry.getKey()) && valueMatcher.matches(entry.getValue())) { + return true; + } + } + return false; + } + + public void describeTo(Description description) { + description.appendText("map containing [") + .appendDescriptionOf(keyMatcher) + .appendText("->") + .appendDescriptionOf(valueMatcher) + .appendText("]"); + } + + @Factory + public static <K,V> Matcher<Map<K,V>> hasEntry(Matcher<K> keyMatcher, Matcher<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)); + } + + @Factory + public static <K,V> Matcher<Map<K,V>> hasKey(Matcher<K> keyMatcher) { + return hasEntry(keyMatcher, IsAnything.<V>anything()); + } + + @Factory + public static <K,V> Matcher<Map<K,V>> hasKey(K key) { + return hasKey(equalTo(key)); + } + + @Factory + public static <K,V> Matcher<Map<K,V>> hasValue(Matcher<V> valueMatcher) { + return hasEntry(IsAnything.<K>anything(), valueMatcher); + } + + @Factory + public static <K,V> Matcher<Map<K,V>> hasValue(V value) { + return hasValue(equalTo(value)); + } +} diff --git a/library/src/org/hamcrest/collection/package.html b/library/src/org/hamcrest/collection/package.html new file mode 100644 index 0000000..6248d8d --- /dev/null +++ b/library/src/org/hamcrest/collection/package.html @@ -0,0 +1,7 @@ +<html> +<head> +</head> +<body> + <p>Matchers of arrays and collections.</p> +</body> +</html> diff --git a/library/src/org/hamcrest/number/IsCloseTo.java b/library/src/org/hamcrest/number/IsCloseTo.java new file mode 100644 index 0000000..dc183e8 --- /dev/null +++ b/library/src/org/hamcrest/number/IsCloseTo.java @@ -0,0 +1,40 @@ +/* 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; + + +/** + * 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 value; + + public IsCloseTo(double value, double error) { + this.error = error; + this.value = value; + } + + public boolean matchesSafely(Double item) { + return Math.abs((item - value)) <= error; + } + + public void describeTo(Description description) { + description.appendText("a numeric value within ") + .appendValue(error) + .appendText(" of ") + .appendValue(value); + } + + @Factory + public static Matcher<Double> closeTo(double operand, double error) { + return new IsCloseTo(operand, error); + } + +} diff --git a/library/src/org/hamcrest/number/IsGreaterThan.java b/library/src/org/hamcrest/number/IsGreaterThan.java new file mode 100644 index 0000000..34046b7 --- /dev/null +++ b/library/src/org/hamcrest/number/IsGreaterThan.java @@ -0,0 +1,26 @@ +/* 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/library/src/org/hamcrest/number/OrderingComparisons.java b/library/src/org/hamcrest/number/OrderingComparisons.java new file mode 100644 index 0000000..1791a40 --- /dev/null +++ b/library/src/org/hamcrest/number/OrderingComparisons.java @@ -0,0 +1,38 @@ +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/library/src/org/hamcrest/number/package.html b/library/src/org/hamcrest/number/package.html new file mode 100644 index 0000000..2fbb07f --- /dev/null +++ b/library/src/org/hamcrest/number/package.html @@ -0,0 +1,7 @@ +<html> +<head> +</head> +<body> + <p>Matchers that perform numeric comparisons.</p> +</body> +</html> diff --git a/library/src/org/hamcrest/object/HasToString.java b/library/src/org/hamcrest/object/HasToString.java new file mode 100644 index 0000000..0f12ffd --- /dev/null +++ b/library/src/org/hamcrest/object/HasToString.java @@ -0,0 +1,31 @@ +package org.hamcrest.object; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.Factory; +import org.hamcrest.BaseMatcher; + +public class HasToString<T> extends BaseMatcher<T> { + + private final Matcher<String> toStringMatcher; + + public HasToString(Matcher<String> toStringMatcher) { + this.toStringMatcher = toStringMatcher; + } + + public boolean matches(Object item) { + return item != null && toStringMatcher.matches(item.toString()); + } + + public void describeTo(Description description) { + description + .appendText("asString(") + .appendDescriptionOf(toStringMatcher) + .appendText(")"); + } + + @Factory + public static <T> Matcher<T> hasToString(Matcher<String> toStringMatcher) { + return new HasToString<T>(toStringMatcher); + } +} diff --git a/library/src/org/hamcrest/object/IsCompatibleType.java b/library/src/org/hamcrest/object/IsCompatibleType.java new file mode 100644 index 0000000..3a2dc7a --- /dev/null +++ b/library/src/org/hamcrest/object/IsCompatibleType.java @@ -0,0 +1,27 @@ +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<?>> { + private final Class<T> type; + + public IsCompatibleType(Class<T> type) { + this.type = type; + } + + public boolean matchesSafely(Class<?> cls) { + return type.isAssignableFrom(cls); + } + + public void describeTo(Description description) { + description.appendText("type < ").appendText(type.getName()); + } + + @Factory + public static <T> Matcher<Class<?>> typeCompatibleWith(Class<T> baseType) { + return new IsCompatibleType<T>(baseType); + } +} diff --git a/library/src/org/hamcrest/object/IsEventFrom.java b/library/src/org/hamcrest/object/IsEventFrom.java new file mode 100644 index 0000000..504a8f5 --- /dev/null +++ b/library/src/org/hamcrest/object/IsEventFrom.java @@ -0,0 +1,59 @@ +/* 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 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; + private final 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); + } + + private boolean eventHasSameSource(EventObject ev) { + return ev.getSource() == source; + } + + public void describeTo(Description description) { + description.appendText("an event of type ") + .appendText(eventClass.getName()) + .appendText(" from ") + .appendValue(source); + } + + /** + * Constructs an IsEventFrom Matcher that returns true for any object + * derived from <var>eventClass</var> announced by <var>source</var>. + */ + @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>. + */ + @Factory + public static Matcher<EventObject> eventFrom(Object source) { + return eventFrom(EventObject.class, source); + } +} diff --git a/library/src/org/hamcrest/object/package.html b/library/src/org/hamcrest/object/package.html new file mode 100644 index 0000000..2fde62c --- /dev/null +++ b/library/src/org/hamcrest/object/package.html @@ -0,0 +1,7 @@ +<html> +<head> +</head> +<body> + <p>Matchers that inspect objects and classes.</p> +</body> +</html> diff --git a/library/src/org/hamcrest/text/IsEqualIgnoringCase.java b/library/src/org/hamcrest/text/IsEqualIgnoringCase.java new file mode 100644 index 0000000..cc78c71 --- /dev/null +++ b/library/src/org/hamcrest/text/IsEqualIgnoringCase.java @@ -0,0 +1,42 @@ +/* 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);
+ }
+
+}
diff --git a/library/src/org/hamcrest/text/IsEqualIgnoringWhiteSpace.java b/library/src/org/hamcrest/text/IsEqualIgnoringWhiteSpace.java new file mode 100644 index 0000000..dd390e8 --- /dev/null +++ b/library/src/org/hamcrest/text/IsEqualIgnoringWhiteSpace.java @@ -0,0 +1,60 @@ +/* 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);
+ }
+
+}
diff --git a/library/src/org/hamcrest/text/StringContains.java b/library/src/org/hamcrest/text/StringContains.java new file mode 100644 index 0000000..9e55560 --- /dev/null +++ b/library/src/org/hamcrest/text/StringContains.java @@ -0,0 +1,29 @@ +/* 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/library/src/org/hamcrest/text/StringEndsWith.java b/library/src/org/hamcrest/text/StringEndsWith.java new file mode 100644 index 0000000..10e4764 --- /dev/null +++ b/library/src/org/hamcrest/text/StringEndsWith.java @@ -0,0 +1,29 @@ +/* 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/library/src/org/hamcrest/text/StringStartsWith.java b/library/src/org/hamcrest/text/StringStartsWith.java new file mode 100644 index 0000000..4613101 --- /dev/null +++ b/library/src/org/hamcrest/text/StringStartsWith.java @@ -0,0 +1,29 @@ +/* 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/library/src/org/hamcrest/text/SubstringMatcher.java b/library/src/org/hamcrest/text/SubstringMatcher.java new file mode 100644 index 0000000..8ebe739 --- /dev/null +++ b/library/src/org/hamcrest/text/SubstringMatcher.java @@ -0,0 +1,31 @@ +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/library/src/org/hamcrest/text/X.java b/library/src/org/hamcrest/text/X.java new file mode 100644 index 0000000..7e85bd9 --- /dev/null +++ b/library/src/org/hamcrest/text/X.java @@ -0,0 +1,18 @@ +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/library/src/org/hamcrest/text/package.html b/library/src/org/hamcrest/text/package.html new file mode 100644 index 0000000..8cf576f --- /dev/null +++ b/library/src/org/hamcrest/text/package.html @@ -0,0 +1,7 @@ +<html> +<head> +</head> +<body> + <p>Matchers that perform text comparisons.</p> +</body> +</html> diff --git a/library/src/org/hamcrest/xml/HasXPath.java b/library/src/org/hamcrest/xml/HasXPath.java new file mode 100644 index 0000000..742935b --- /dev/null +++ b/library/src/org/hamcrest/xml/HasXPath.java @@ -0,0 +1,74 @@ +package org.hamcrest.xml; + +import org.hamcrest.Description; +import org.hamcrest.Factory; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; +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; + +/** + * Applies a Matcher to a given XML Node in an existing XML Node tree, specified by an XPath expression. + * + * @author Joe Walnes + */ +public class HasXPath extends TypeSafeMatcher<Node> { + + private final Matcher<String> valueMatcher; + private final XPathExpression compiledXPath; + private final String xpathString; + + /** + * @param xPathExpression 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, Matcher<String> valueMatcher) { + try { + XPath xPath = XPathFactory.newInstance().newXPath(); + compiledXPath = xPath.compile(xPathExpression); + this.xpathString = xPathExpression; + this.valueMatcher = valueMatcher; + } catch (XPathExpressionException e) { + throw new IllegalArgumentException("Invalid XPath : " + xPathExpression, e); + } + } + + public boolean matchesSafely(Node item) { + 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); + } + } catch (XPathExpressionException e) { + return false; + } + } + + public void describeTo(Description description) { + description.appendText("an XML document with XPath ").appendText(xpathString); + if (valueMatcher != null) { + description.appendText(" ").appendDescriptionOf(valueMatcher); + } + } + + @Factory + public static Matcher<Node> hasXPath(String xPath, Matcher<String> valueMatcher) { + return new HasXPath(xPath, valueMatcher); + } + + @Factory + public static Matcher<Node> hasXPath(String xPath) { + return hasXPath(xPath, null); + } + +} diff --git a/library/src/org/hamcrest/xml/package.html b/library/src/org/hamcrest/xml/package.html new file mode 100644 index 0000000..d9c5f97 --- /dev/null +++ b/library/src/org/hamcrest/xml/package.html @@ -0,0 +1,7 @@ +<html> +<head> +</head> +<body> + <p>Matchers of XML documents.</p> +</body> +</html> |