From f5e9a2415ec42c425c2bb17db46f2a9649992d80 Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Wed, 11 Jun 2014 16:08:22 -0700 Subject: Add hamcrest 1.1 library and integration source Change-Id: I98691c987d5845c1d6e05325971517eec7e6f8b5 --- Android.mk | 2 + integration/Android.mk | 33 +++ integration/LICENSE.txt | 27 ++ integration/README.android | 1 + integration/src/org/hamcrest/MatcherAssert.java | 24 ++ library/Android.mk | 33 +++ library/LICENSE.txt | 27 ++ library/README.android | 1 + library/src/org/hamcrest/Matchers.java | 308 +++++++++++++++++++++ library/src/org/hamcrest/TypeSafeMatcher.java | 58 ++++ library/src/org/hamcrest/collection/IsArray.java | 64 +++++ .../org/hamcrest/collection/IsArrayContaining.java | 42 +++ .../collection/IsCollectionContaining.java | 65 +++++ library/src/org/hamcrest/collection/IsIn.java | 45 +++ .../org/hamcrest/collection/IsMapContaining.java | 70 +++++ library/src/org/hamcrest/collection/package.html | 7 + library/src/org/hamcrest/number/IsCloseTo.java | 40 +++ library/src/org/hamcrest/number/IsGreaterThan.java | 26 ++ .../org/hamcrest/number/OrderingComparisons.java | 38 +++ library/src/org/hamcrest/number/package.html | 7 + library/src/org/hamcrest/object/HasToString.java | 31 +++ .../src/org/hamcrest/object/IsCompatibleType.java | 27 ++ library/src/org/hamcrest/object/IsEventFrom.java | 59 ++++ library/src/org/hamcrest/object/package.html | 7 + .../src/org/hamcrest/text/IsEqualIgnoringCase.java | 42 +++ .../hamcrest/text/IsEqualIgnoringWhiteSpace.java | 60 ++++ library/src/org/hamcrest/text/StringContains.java | 29 ++ library/src/org/hamcrest/text/StringEndsWith.java | 29 ++ .../src/org/hamcrest/text/StringStartsWith.java | 29 ++ .../src/org/hamcrest/text/SubstringMatcher.java | 31 +++ library/src/org/hamcrest/text/X.java | 18 ++ library/src/org/hamcrest/text/package.html | 7 + library/src/org/hamcrest/xml/HasXPath.java | 74 +++++ library/src/org/hamcrest/xml/package.html | 7 + 34 files changed, 1368 insertions(+) create mode 100644 integration/Android.mk create mode 100644 integration/LICENSE.txt create mode 100644 integration/README.android create mode 100644 integration/src/org/hamcrest/MatcherAssert.java create mode 100644 library/Android.mk create mode 100644 library/LICENSE.txt create mode 100644 library/README.android create mode 100644 library/src/org/hamcrest/Matchers.java create mode 100644 library/src/org/hamcrest/TypeSafeMatcher.java create mode 100644 library/src/org/hamcrest/collection/IsArray.java create mode 100644 library/src/org/hamcrest/collection/IsArrayContaining.java create mode 100644 library/src/org/hamcrest/collection/IsCollectionContaining.java create mode 100644 library/src/org/hamcrest/collection/IsIn.java create mode 100644 library/src/org/hamcrest/collection/IsMapContaining.java create mode 100644 library/src/org/hamcrest/collection/package.html create mode 100644 library/src/org/hamcrest/number/IsCloseTo.java create mode 100644 library/src/org/hamcrest/number/IsGreaterThan.java create mode 100644 library/src/org/hamcrest/number/OrderingComparisons.java create mode 100644 library/src/org/hamcrest/number/package.html create mode 100644 library/src/org/hamcrest/object/HasToString.java create mode 100644 library/src/org/hamcrest/object/IsCompatibleType.java create mode 100644 library/src/org/hamcrest/object/IsEventFrom.java create mode 100644 library/src/org/hamcrest/object/package.html create mode 100644 library/src/org/hamcrest/text/IsEqualIgnoringCase.java create mode 100644 library/src/org/hamcrest/text/IsEqualIgnoringWhiteSpace.java create mode 100644 library/src/org/hamcrest/text/StringContains.java create mode 100644 library/src/org/hamcrest/text/StringEndsWith.java create mode 100644 library/src/org/hamcrest/text/StringStartsWith.java create mode 100644 library/src/org/hamcrest/text/SubstringMatcher.java create mode 100644 library/src/org/hamcrest/text/X.java create mode 100644 library/src/org/hamcrest/text/package.html create mode 100644 library/src/org/hamcrest/xml/HasXPath.java create mode 100644 library/src/org/hamcrest/xml/package.html diff --git a/Android.mk b/Android.mk index bd2ea37..e4fa21f 100644 --- a/Android.mk +++ b/Android.mk @@ -50,3 +50,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 void assertThat(T actual, Matcher matcher) { + assertThat("", actual, matcher); + } + + public static void assertThat(String reason, T actual, Matcher 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 org.hamcrest.Matcher is(org.hamcrest.Matcher 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 org.hamcrest.Matcher 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 is(java.lang.Class type) { + return org.hamcrest.core.Is.is(type); + } + + /** + * Inverts the rule. + */ + public static org.hamcrest.Matcher not(org.hamcrest.Matcher 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 org.hamcrest.Matcher 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 org.hamcrest.Matcher equalTo(T operand) { + return org.hamcrest.core.IsEqual.equalTo(operand); + } + + /** + * Is the value an instance of a particular type? + */ + public static org.hamcrest.Matcher 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 org.hamcrest.Matcher allOf(org.hamcrest.Matcher... matchers) { + return org.hamcrest.core.AllOf.allOf(matchers); + } + + /** + * Evaluates to true only if ALL of the passed in matchers evaluate to true. + */ + public static org.hamcrest.Matcher allOf(java.lang.Iterable> matchers) { + return org.hamcrest.core.AllOf.allOf(matchers); + } + + /** + * Evaluates to true if ANY of the passed in matchers evaluate to true. + */ + public static org.hamcrest.Matcher anyOf(org.hamcrest.Matcher... matchers) { + return org.hamcrest.core.AnyOf.anyOf(matchers); + } + + /** + * Evaluates to true if ANY of the passed in matchers evaluate to true. + */ + public static org.hamcrest.Matcher anyOf(java.lang.Iterable> 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 org.hamcrest.Matcher sameInstance(T object) { + return org.hamcrest.core.IsSame.sameInstance(object); + } + + /** + * This matcher always evaluates to true. + */ + public static org.hamcrest.Matcher anything() { + return org.hamcrest.core.IsAnything.anything(); + } + + /** + * This matcher always evaluates to true. + * + * @param description A meaningful string used when describing itself. + */ + public static org.hamcrest.Matcher anything(java.lang.String description) { + return org.hamcrest.core.IsAnything.anything(description); + } + + /** + * This matcher always evaluates to true. With type inference. + */ + public static org.hamcrest.Matcher any(java.lang.Class type) { + return org.hamcrest.core.IsAnything.any(type); + } + + /** + * Matches if value is null. + */ + public static org.hamcrest.Matcher nullValue() { + return org.hamcrest.core.IsNull.nullValue(); + } + + /** + * Matches if value is null. With type inference. + */ + public static org.hamcrest.Matcher nullValue(java.lang.Class type) { + return org.hamcrest.core.IsNull.nullValue(type); + } + + /** + * Matches if value is not null. + */ + public static org.hamcrest.Matcher notNullValue() { + return org.hamcrest.core.IsNull.notNullValue(); + } + + /** + * Matches if value is not null. With type inference. + */ + public static org.hamcrest.Matcher notNullValue(java.lang.Class type) { + return org.hamcrest.core.IsNull.notNullValue(type); + } + + /** + * Wraps an existing matcher and overrides the description when it fails. + */ + public static org.hamcrest.Matcher describedAs(java.lang.String description, org.hamcrest.Matcher matcher, java.lang.Object... values) { + return org.hamcrest.core.DescribedAs.describedAs(description, matcher, values); + } + + public static org.hamcrest.Matcher hasItemInArray(org.hamcrest.Matcher elementMatcher) { + return org.hamcrest.collection.IsArrayContaining.hasItemInArray(elementMatcher); + } + + public static org.hamcrest.Matcher hasItemInArray(T element) { + return org.hamcrest.collection.IsArrayContaining.hasItemInArray(element); + } + + public static org.hamcrest.Matcher> hasItem(T element) { + return org.hamcrest.collection.IsCollectionContaining.hasItem(element); + } + + public static org.hamcrest.Matcher> hasItem(org.hamcrest.Matcher elementMatcher) { + return org.hamcrest.collection.IsCollectionContaining.hasItem(elementMatcher); + } + + public static org.hamcrest.Matcher> hasItems(org.hamcrest.Matcher... elementMatchers) { + return org.hamcrest.collection.IsCollectionContaining.hasItems(elementMatchers); + } + + public static org.hamcrest.Matcher> hasItems(T... elements) { + return org.hamcrest.collection.IsCollectionContaining.hasItems(elements); + } + + public static org.hamcrest.Matcher> hasEntry(org.hamcrest.Matcher keyMatcher, org.hamcrest.Matcher valueMatcher) { + return org.hamcrest.collection.IsMapContaining.hasEntry(keyMatcher, valueMatcher); + } + + public static org.hamcrest.Matcher> hasEntry(K key, V value) { + return org.hamcrest.collection.IsMapContaining.hasEntry(key, value); + } + + public static org.hamcrest.Matcher> hasKey(org.hamcrest.Matcher keyMatcher) { + return org.hamcrest.collection.IsMapContaining.hasKey(keyMatcher); + } + + public static org.hamcrest.Matcher> hasKey(K key) { + return org.hamcrest.collection.IsMapContaining.hasKey(key); + } + + public static org.hamcrest.Matcher> hasValue(org.hamcrest.Matcher valueMatcher) { + return org.hamcrest.collection.IsMapContaining.hasValue(valueMatcher); + } + + public static org.hamcrest.Matcher> hasValue(V value) { + return org.hamcrest.collection.IsMapContaining.hasValue(value); + } + + public static org.hamcrest.Matcher isIn(java.util.Collection collection) { + return org.hamcrest.collection.IsIn.isIn(collection); + } + + public static org.hamcrest.Matcher isIn(T[] param1) { + return org.hamcrest.collection.IsIn.isIn(param1); + } + + public static org.hamcrest.Matcher isOneOf(T... elements) { + return org.hamcrest.collection.IsIn.isOneOf(elements); + } + + public static org.hamcrest.Matcher closeTo(double operand, double error) { + return org.hamcrest.number.IsCloseTo.closeTo(operand, error); + } + + public static > org.hamcrest.Matcher greaterThan(T value) { + return org.hamcrest.number.OrderingComparisons.greaterThan(value); + } + + public static > org.hamcrest.Matcher greaterThanOrEqualTo(T value) { + return org.hamcrest.number.OrderingComparisons.greaterThanOrEqualTo(value); + } + + public static > org.hamcrest.Matcher lessThan(T value) { + return org.hamcrest.number.OrderingComparisons.lessThan(value); + } + + public static > org.hamcrest.Matcher lessThanOrEqualTo(T value) { + return org.hamcrest.number.OrderingComparisons.lessThanOrEqualTo(value); + } + + public static org.hamcrest.Matcher equalToIgnoringCase(java.lang.String string) { + return org.hamcrest.text.IsEqualIgnoringCase.equalToIgnoringCase(string); + } + + public static org.hamcrest.Matcher equalToIgnoringWhiteSpace(java.lang.String string) { + return org.hamcrest.text.IsEqualIgnoringWhiteSpace.equalToIgnoringWhiteSpace(string); + } + + public static org.hamcrest.Matcher containsString(java.lang.String substring) { + return org.hamcrest.text.StringContains.containsString(substring); + } + + public static org.hamcrest.Matcher endsWith(java.lang.String substring) { + return org.hamcrest.text.StringEndsWith.endsWith(substring); + } + + public static org.hamcrest.Matcher startsWith(java.lang.String substring) { + return org.hamcrest.text.StringStartsWith.startsWith(substring); + } + + public static org.hamcrest.Matcher hasToString(org.hamcrest.Matcher toStringMatcher) { + return org.hamcrest.object.HasToString.hasToString(toStringMatcher); + } + + public static org.hamcrest.Matcher> typeCompatibleWith(java.lang.Class baseType) { + return org.hamcrest.object.IsCompatibleType.typeCompatibleWith(baseType); + } + + /** + * Constructs an IsEventFrom Matcher that returns true for any object + * derived from eventClass announced by source. + */ + public static org.hamcrest.Matcher eventFrom(java.lang.Class 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 source + * . + */ + public static org.hamcrest.Matcher eventFrom(java.lang.Object source) { + return org.hamcrest.object.IsEventFrom.eventFrom(source); + } + + /* android-changed REMOVE + public static org.hamcrest.Matcher hasProperty(java.lang.String propertyName) { + return org.hamcrest.beans.HasProperty.hasProperty(propertyName); + } + + public static org.hamcrest.Matcher hasProperty(java.lang.String propertyName, org.hamcrest.Matcher value) { + return org.hamcrest.beans.HasPropertyWithValue.hasProperty(propertyName, value); + } + */ + + public static org.hamcrest.Matcher hasXPath(java.lang.String xPath, org.hamcrest.Matcher valueMatcher) { + return org.hamcrest.xml.HasXPath.hasXPath(xPath, valueMatcher); + } + + public static org.hamcrest.Matcher 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 extends BaseMatcher { + + 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 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 extends TypeSafeMatcher { + private final Matcher[] elementMatchers; + + public IsArray(Matcher[] 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 IsArray array(Matcher... elementMatchers) { + return new IsArray(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 extends TypeSafeMatcher { + + private final Matcher elementMatcher; + + public IsArrayContaining(Matcher 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 Matcher hasItemInArray(Matcher elementMatcher) { + return new IsArrayContaining(elementMatcher); + } + + @Factory + public static Matcher 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 extends TypeSafeMatcher> { + private final Matcher elementMatcher; + + public IsCollectionContaining(Matcher elementMatcher) { + this.elementMatcher = elementMatcher; + } + + public boolean matchesSafely(Iterable 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 Matcher> hasItem(Matcher elementMatcher) { + return new IsCollectionContaining(elementMatcher); + } + + @Factory + public static Matcher> hasItem(T element) { + return hasItem(equalTo(element)); + } + + @Factory + public static Matcher> hasItems(Matcher... elementMatchers) { + Collection>> all + = new ArrayList>>(elementMatchers.length); + for (Matcher elementMatcher : elementMatchers) { + all.add(hasItem(elementMatcher)); + } + return allOf(all); + } + + @Factory + public static Matcher> hasItems(T... elements) { + Collection>> all + = new ArrayList>>(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 extends BaseMatcher { + private final Collection collection; + + public IsIn(Collection 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 Matcher isIn(Collection collection) { + return new IsIn(collection); + } + + @Factory + public static Matcher isIn(T[] elements) { + return new IsIn(elements); + } + + @Factory + public static Matcher 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 extends TypeSafeMatcher> { + + private final Matcher keyMatcher; + private final Matcher valueMatcher; + + public IsMapContaining(Matcher keyMatcher, Matcher valueMatcher) { + this.keyMatcher = keyMatcher; + this.valueMatcher = valueMatcher; + } + + public boolean matchesSafely(Map map) { + for (Entry 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 Matcher> hasEntry(Matcher keyMatcher, Matcher valueMatcher) { + return new IsMapContaining(keyMatcher, valueMatcher); + } + + @Factory + public static Matcher> hasEntry(K key, V value) { + return hasEntry(equalTo(key), equalTo(value)); + } + + @Factory + public static Matcher> hasKey(Matcher keyMatcher) { + return hasEntry(keyMatcher, IsAnything.anything()); + } + + @Factory + public static Matcher> hasKey(K key) { + return hasKey(equalTo(key)); + } + + @Factory + public static Matcher> hasValue(Matcher valueMatcher) { + return hasEntry(IsAnything.anything(), valueMatcher); + } + + @Factory + public static Matcher> 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 @@ + + + + +

Matchers of arrays and collections.

+ + 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 { + 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 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> extends TypeSafeMatcher { + private final Comparable compareTo; + + public IsGreaterThan(Comparable 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 > Matcher greaterThan(T value) { + return new IsGreaterThan(value); + } + + @Factory + public static > Matcher greaterThanOrEqualTo(T value) { + return describedAs("a value greater than or equal to %0", + anyOf(greaterThan(value), equalTo(value)), + value); + } + + @Factory + public static > Matcher lessThan(T value) { + return describedAs("a value less than %0", + not(greaterThanOrEqualTo(value)), + value); + } + + @Factory + public static > Matcher 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 @@ + + + + +

Matchers that perform numeric comparisons.

+ + 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 extends BaseMatcher { + + private final Matcher toStringMatcher; + + public HasToString(Matcher 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 Matcher hasToString(Matcher toStringMatcher) { + return new HasToString(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 extends TypeSafeMatcher> { + private final Class type; + + public IsCompatibleType(Class 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 Matcher> typeCompatibleWith(Class baseType) { + return new IsCompatibleType(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 { + 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 eventClass announced by source. + */ + @Factory + public static Matcher eventFrom(Class 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 source + * . + */ + @Factory + public static Matcher 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 @@ + + + + +

Matchers that inspect objects and classes.

+ + 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 { + + // 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 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 { + + // 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 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 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 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 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 { + + // 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 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 @@ + + + + +

Matchers that perform text comparisons.

+ + 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 { + + private final Matcher 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 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 hasXPath(String xPath, Matcher valueMatcher) { + return new HasXPath(xPath, valueMatcher); + } + + @Factory + public static Matcher 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 @@ + + + + +

Matchers of XML documents.

+ + -- cgit v1.2.3