8889841cArray/IsArrayContainingKeyValuePairTest.php000064400000002112150524651050015040 0ustar001, 'b'=>2); $this->assertMatches(hasKeyValuePair(equalTo('a'), equalTo(1)), $array, 'matcherA'); $this->assertMatches(hasKeyValuePair(equalTo('b'), equalTo(2)), $array, 'matcherB'); $this->assertMismatchDescription( 'array was ["a" => <1>, "b" => <2>]', hasKeyValuePair(equalTo('c'), equalTo(3)), $array ); } public function testDoesNotMatchNull() { $this->assertMismatchDescription('was null', hasKeyValuePair(anything(), anything()), null); } public function testHasReadableDescription() { $this->assertDescription('array containing ["a" => <2>]', hasKeyValuePair(equalTo('a'), equalTo(2))); } } Array/IsArrayContainingTest.php000064400000002355150524651050012567 0ustar00assertMatches( hasItemInArray('a'), array('a', 'b', 'c'), "should matches array that contains 'a'" ); } public function testDoesNotMatchAnArrayThatDoesntContainAnElementMatchingTheGivenMatcher() { $this->assertDoesNotMatch( hasItemInArray('a'), array('b', 'c'), "should not matches array that doesn't contain 'a'" ); $this->assertDoesNotMatch( hasItemInArray('a'), array(), 'should not match empty array' ); } public function testDoesNotMatchNull() { $this->assertDoesNotMatch( hasItemInArray('a'), null, 'should not match null' ); } public function testHasAReadableDescription() { $this->assertDescription('an array containing "a"', hasItemInArray('a')); } } Array/IsArrayTest.php000064400000004676150524651050010565 0ustar00assertMatches( anArray(array(equalTo('a'), equalTo('b'), equalTo('c'))), array('a', 'b', 'c'), 'should match array with matching elements' ); } public function testDoesNotMatchAnArrayWhenElementsDoNotMatch() { $this->assertDoesNotMatch( anArray(array(equalTo('a'), equalTo('b'))), array('b', 'c'), 'should not match array with different elements' ); } public function testDoesNotMatchAnArrayOfDifferentSize() { $this->assertDoesNotMatch( anArray(array(equalTo('a'), equalTo('b'))), array('a', 'b', 'c'), 'should not match larger array' ); $this->assertDoesNotMatch( anArray(array(equalTo('a'), equalTo('b'))), array('a'), 'should not match smaller array' ); } public function testDoesNotMatchNull() { $this->assertDoesNotMatch( anArray(array(equalTo('a'))), null, 'should not match null' ); } public function testHasAReadableDescription() { $this->assertDescription( '["a", "b"]', anArray(array(equalTo('a'), equalTo('b'))) ); } public function testHasAReadableMismatchDescriptionWhenKeysDontMatch() { $this->assertMismatchDescription( 'array keys were [<1>, <2>]', anArray(array(equalTo('a'), equalTo('b'))), array(1 => 'a', 2 => 'b') ); } public function testSupportsMatchesAssociativeArrays() { $this->assertMatches( anArray(array('x'=>equalTo('a'), 'y'=>equalTo('b'), 'z'=>equalTo('c'))), array('x'=>'a', 'y'=>'b', 'z'=>'c'), 'should match associative array with matching elements' ); } public function testDoesNotMatchAnAssociativeArrayWhenKeysDoNotMatch() { $this->assertDoesNotMatch( anArray(array('x'=>equalTo('a'), 'y'=>equalTo('b'))), array('x'=>'b', 'z'=>'c'), 'should not match array with different keys' ); } } Array/IsArrayContainingInAnyOrderTest.php000064400000003274150524651050014523 0ustar00assertDescription('[<1>, <2>] in any order', containsInAnyOrder(array(1, 2))); } public function testMatchesItemsInAnyOrder() { $this->assertMatches(containsInAnyOrder(array(1, 2, 3)), array(1, 2, 3), 'in order'); $this->assertMatches(containsInAnyOrder(array(1, 2, 3)), array(3, 2, 1), 'out of order'); $this->assertMatches(containsInAnyOrder(array(1)), array(1), 'single'); } public function testAppliesMatchersInAnyOrder() { $this->assertMatches( containsInAnyOrder(array(1, 2, 3)), array(1, 2, 3), 'in order' ); $this->assertMatches( containsInAnyOrder(array(1, 2, 3)), array(3, 2, 1), 'out of order' ); $this->assertMatches( containsInAnyOrder(array(1)), array(1), 'single' ); } public function testMismatchesItemsInAnyOrder() { $matcher = containsInAnyOrder(array(1, 2, 3)); $this->assertMismatchDescription('was null', $matcher, null); $this->assertMismatchDescription('No item matches: <1>, <2>, <3> in []', $matcher, array()); $this->assertMismatchDescription('No item matches: <2>, <3> in [<1>]', $matcher, array(1)); $this->assertMismatchDescription('Not matched: <4>', $matcher, array(4, 3, 2, 1)); } } Array/IsArrayContainingInOrderTest.php000064400000003031150524651050014042 0ustar00assertDescription('[<1>, <2>]', arrayContaining(array(1, 2))); } public function testMatchesItemsInOrder() { $this->assertMatches(arrayContaining(array(1, 2, 3)), array(1, 2, 3), 'in order'); $this->assertMatches(arrayContaining(array(1)), array(1), 'single'); } public function testAppliesMatchersInOrder() { $this->assertMatches( arrayContaining(array(1, 2, 3)), array(1, 2, 3), 'in order' ); $this->assertMatches(arrayContaining(array(1)), array(1), 'single'); } public function testMismatchesItemsInAnyOrder() { if (defined('HHVM_VERSION')) { $this->markTestSkipped('Broken on HHVM.'); } $matcher = arrayContaining(array(1, 2, 3)); $this->assertMismatchDescription('was null', $matcher, null); $this->assertMismatchDescription('No item matched: <1>', $matcher, array()); $this->assertMismatchDescription('No item matched: <2>', $matcher, array(1)); $this->assertMismatchDescription('item with key 0: was <4>', $matcher, array(4, 3, 2, 1)); $this->assertMismatchDescription('item with key 2: was <4>', $matcher, array(1, 2, 4)); } } Array/IsArrayContainingKeyTest.php000064400000003076150524651050013241 0ustar001); $this->assertMatches(hasKey('a'), $array, 'Matches single key'); } public function testMatchesArrayContainingKey() { $array = array('a'=>1, 'b'=>2, 'c'=>3); $this->assertMatches(hasKey('a'), $array, 'Matches a'); $this->assertMatches(hasKey('c'), $array, 'Matches c'); } public function testMatchesArrayContainingKeyWithIntegerKeys() { $array = array(1=>'A', 2=>'B'); assertThat($array, hasKey(1)); } public function testMatchesArrayContainingKeyWithNumberKeys() { $array = array(1=>'A', 2=>'B'); assertThat($array, hasKey(1)); // very ugly version! assertThat($array, IsArrayContainingKey::hasKeyInArray(2)); } public function testHasReadableDescription() { $this->assertDescription('array with key "a"', hasKey('a')); } public function testDoesNotMatchEmptyArray() { $this->assertMismatchDescription('array was []', hasKey('Foo'), array()); } public function testDoesNotMatchArrayMissingKey() { $array = array('a'=>1, 'b'=>2, 'c'=>3); $this->assertMismatchDescription('array was ["a" => <1>, "b" => <2>, "c" => <3>]', hasKey('d'), $array); } } Array/IsArrayWithSizeTest.php000064400000002203150524651050012234 0ustar00assertMatches(arrayWithSize(equalTo(3)), array(1, 2, 3), 'correct size'); $this->assertDoesNotMatch(arrayWithSize(equalTo(2)), array(1, 2, 3), 'incorrect size'); } public function testProvidesConvenientShortcutForArrayWithSizeEqualTo() { $this->assertMatches(arrayWithSize(3), array(1, 2, 3), 'correct size'); $this->assertDoesNotMatch(arrayWithSize(2), array(1, 2, 3), 'incorrect size'); } public function testEmptyArray() { $this->assertMatches(emptyArray(), array(), 'correct size'); $this->assertDoesNotMatch(emptyArray(), array(1), 'incorrect size'); } public function testHasAReadableDescription() { $this->assertDescription('an array with size <3>', arrayWithSize(equalTo(3))); $this->assertDescription('an empty array', emptyArray()); } } Type/IsStringTest.php000064400000001657150524651050010614 0ustar00assertDescription('a string', stringValue()); } public function testDecribesActualTypeInMismatchMessage() { $this->assertMismatchDescription('was null', stringValue(), null); $this->assertMismatchDescription('was a double <5.2F>', stringValue(), 5.2); } } Type/IsResourceTest.php000064400000001632150524651050011126 0ustar00assertDescription('a resource', resourceValue()); } public function testDecribesActualTypeInMismatchMessage() { $this->assertMismatchDescription('was null', resourceValue(), null); $this->assertMismatchDescription('was a string "foo"', resourceValue(), 'foo'); } } Type/IsBooleanTest.php000064400000001667150524651050010726 0ustar00assertDescription('a boolean', booleanValue()); } public function testDecribesActualTypeInMismatchMessage() { $this->assertMismatchDescription('was null', booleanValue(), null); $this->assertMismatchDescription('was a string "foo"', booleanValue(), 'foo'); } } Type/IsIntegerTest.php000064400000001731150524651050010734 0ustar00assertDescription('an integer', integerValue()); } public function testDecribesActualTypeInMismatchMessage() { $this->assertMismatchDescription('was null', integerValue(), null); $this->assertMismatchDescription('was a string "foo"', integerValue(), 'foo'); } } Type/IsArrayTest.php000064400000001651150524651050010416 0ustar00assertDescription('an array', arrayValue()); } public function testDecribesActualTypeInMismatchMessage() { $this->assertMismatchDescription('was null', arrayValue(), null); $this->assertMismatchDescription('was a string "foo"', arrayValue(), 'foo'); } } Type/IsDoubleTest.php000064400000001666150524651050010560 0ustar00assertDescription('a double', doubleValue()); } public function testDecribesActualTypeInMismatchMessage() { $this->assertMismatchDescription('was null', doubleValue(), null); $this->assertMismatchDescription('was a string "foo"', doubleValue(), 'foo'); } } Type/IsObjectTest.php000064400000001611150524651050010542 0ustar00assertDescription('an object', objectValue()); } public function testDecribesActualTypeInMismatchMessage() { $this->assertMismatchDescription('was null', objectValue(), null); $this->assertMismatchDescription('was a string "foo"', objectValue(), 'foo'); } } Type/IsScalarTest.php000064400000002162150524651050010543 0ustar00assertDescription('a scalar', scalarValue()); } public function testDecribesActualTypeInMismatchMessage() { $this->assertMismatchDescription('was null', scalarValue(), null); $this->assertMismatchDescription('was an array ["foo"]', scalarValue(), array('foo')); } } Type/IsCallableTest.php000064400000005377150524651050011050 0ustar00=')) { $this->markTestSkipped('Closures require php 5.3'); } eval('assertThat(function () {}, callableValue());'); } public function testEvaluatesToTrueIfArgumentImplementsInvoke() { if (!version_compare(PHP_VERSION, '5.3', '>=')) { $this->markTestSkipped('Magic method __invoke() requires php 5.3'); } assertThat($this, callableValue()); } public function testEvaluatesToFalseIfArgumentIsInvalidFunctionName() { if (function_exists('not_a_Hamcrest_function')) { $this->markTestSkipped('Function "not_a_Hamcrest_function" must not exist'); } assertThat('not_a_Hamcrest_function', not(callableValue())); } public function testEvaluatesToFalseIfArgumentIsInvalidStaticMethodCallback() { assertThat( array('Hamcrest\Type\IsCallableTest', 'noMethod'), not(callableValue()) ); } public function testEvaluatesToFalseIfArgumentIsInvalidInstanceMethodCallback() { assertThat(array($this, 'noMethod'), not(callableValue())); } public function testEvaluatesToFalseIfArgumentDoesntImplementInvoke() { assertThat(new \stdClass(), not(callableValue())); } public function testEvaluatesToFalseIfArgumentDoesntMatchType() { assertThat(false, not(callableValue())); assertThat(5.2, not(callableValue())); } public function testHasAReadableDescription() { $this->assertDescription('a callable', callableValue()); } public function testDecribesActualTypeInMismatchMessage() { $this->assertMismatchDescription( 'was a string "invalid-function"', callableValue(), 'invalid-function' ); } } Type/IsNumericTest.php000064400000003470150524651050010743 0ustar00assertDescription('a number', numericValue()); } public function testDecribesActualTypeInMismatchMessage() { $this->assertMismatchDescription('was null', numericValue(), null); $this->assertMismatchDescription('was a string "foo"', numericValue(), 'foo'); } } Text/StringContainsInOrderTest.php000064400000002347150524651050013302 0ustar00_m = \Hamcrest\Text\StringContainsInOrder::stringContainsInOrder(array('a', 'b', 'c')); } protected function createMatcher() { return $this->_m; } public function testMatchesOnlyIfStringContainsGivenSubstringsInTheSameOrder() { $this->assertMatches($this->_m, 'abc', 'substrings in order'); $this->assertMatches($this->_m, '1a2b3c4', 'substrings separated'); $this->assertDoesNotMatch($this->_m, 'cab', 'substrings out of order'); $this->assertDoesNotMatch($this->_m, 'xyz', 'no substrings in string'); $this->assertDoesNotMatch($this->_m, 'ac', 'substring missing'); $this->assertDoesNotMatch($this->_m, '', 'empty string'); } public function testAcceptsVariableArguments() { $this->assertMatches(stringContainsInOrder('a', 'b', 'c'), 'abc', 'substrings as variable arguments'); } public function testHasAReadableDescription() { $this->assertDescription( 'a string containing "a", "b", "c" in order', $this->_m ); } } Text/MatchesPatternTest.php000064400000001533150524651050011770 0ustar00assertDescription('a string matching "pattern"', matchesPattern('pattern')); } } Text/StringEndsWithTest.php000064400000003552150524651050011765 0ustar00_stringEndsWith = \Hamcrest\Text\StringEndsWith::endsWith(self::EXCERPT); } protected function createMatcher() { return $this->_stringEndsWith; } public function testEvaluatesToTrueIfArgumentContainsSpecifiedSubstring() { $this->assertFalse( $this->_stringEndsWith->matches(self::EXCERPT . 'END'), 'should be false if excerpt at beginning' ); $this->assertTrue( $this->_stringEndsWith->matches('START' . self::EXCERPT), 'should be true if excerpt at end' ); $this->assertFalse( $this->_stringEndsWith->matches('START' . self::EXCERPT . 'END'), 'should be false if excerpt in middle' ); $this->assertTrue( $this->_stringEndsWith->matches(self::EXCERPT . self::EXCERPT), 'should be true if excerpt is at end and repeated' ); $this->assertFalse( $this->_stringEndsWith->matches('Something else'), 'should be false if excerpt is not in string' ); $this->assertFalse( $this->_stringEndsWith->matches(substr(self::EXCERPT, 0, strlen(self::EXCERPT) - 2)), 'should be false if part of excerpt is at end of string' ); } public function testEvaluatesToTrueIfArgumentIsEqualToSubstring() { $this->assertTrue( $this->_stringEndsWith->matches(self::EXCERPT), 'should be true if excerpt is entire string' ); } public function testHasAReadableDescription() { $this->assertDescription('a string ending with "EXCERPT"', $this->_stringEndsWith); } } Text/StringStartsWithTest.php000064400000003565150524651050012360 0ustar00_stringStartsWith = \Hamcrest\Text\StringStartsWith::startsWith(self::EXCERPT); } protected function createMatcher() { return $this->_stringStartsWith; } public function testEvaluatesToTrueIfArgumentContainsSpecifiedSubstring() { $this->assertTrue( $this->_stringStartsWith->matches(self::EXCERPT . 'END'), 'should be true if excerpt at beginning' ); $this->assertFalse( $this->_stringStartsWith->matches('START' . self::EXCERPT), 'should be false if excerpt at end' ); $this->assertFalse( $this->_stringStartsWith->matches('START' . self::EXCERPT . 'END'), 'should be false if excerpt in middle' ); $this->assertTrue( $this->_stringStartsWith->matches(self::EXCERPT . self::EXCERPT), 'should be true if excerpt is at beginning and repeated' ); $this->assertFalse( $this->_stringStartsWith->matches('Something else'), 'should be false if excerpt is not in string' ); $this->assertFalse( $this->_stringStartsWith->matches(substr(self::EXCERPT, 1)), 'should be false if part of excerpt is at start of string' ); } public function testEvaluatesToTrueIfArgumentIsEqualToSubstring() { $this->assertTrue( $this->_stringStartsWith->matches(self::EXCERPT), 'should be true if excerpt is entire string' ); } public function testHasAReadableDescription() { $this->assertDescription('a string starting with "EXCERPT"', $this->_stringStartsWith); } } Text/StringContainsTest.php000064400000005132150524651050012012 0ustar00_stringContains = \Hamcrest\Text\StringContains::containsString(self::EXCERPT); } protected function createMatcher() { return $this->_stringContains; } public function testEvaluatesToTrueIfArgumentContainsSubstring() { $this->assertTrue( $this->_stringContains->matches(self::EXCERPT . 'END'), 'should be true if excerpt at beginning' ); $this->assertTrue( $this->_stringContains->matches('START' . self::EXCERPT), 'should be true if excerpt at end' ); $this->assertTrue( $this->_stringContains->matches('START' . self::EXCERPT . 'END'), 'should be true if excerpt in middle' ); $this->assertTrue( $this->_stringContains->matches(self::EXCERPT . self::EXCERPT), 'should be true if excerpt is repeated' ); $this->assertFalse( $this->_stringContains->matches('Something else'), 'should not be true if excerpt is not in string' ); $this->assertFalse( $this->_stringContains->matches(substr(self::EXCERPT, 1)), 'should not be true if part of excerpt is in string' ); } public function testEvaluatesToTrueIfArgumentIsEqualToSubstring() { $this->assertTrue( $this->_stringContains->matches(self::EXCERPT), 'should be true if excerpt is entire string' ); } public function testEvaluatesToFalseIfArgumentContainsSubstringIgnoringCase() { $this->assertFalse( $this->_stringContains->matches(strtolower(self::EXCERPT)), 'should be false if excerpt is entire string ignoring case' ); $this->assertFalse( $this->_stringContains->matches('START' . strtolower(self::EXCERPT) . 'END'), 'should be false if excerpt is contained in string ignoring case' ); } public function testIgnoringCaseReturnsCorrectMatcher() { $this->assertTrue( $this->_stringContains->ignoringCase()->matches('EXceRpT'), 'should be true if excerpt is entire string ignoring case' ); } public function testHasAReadableDescription() { $this->assertDescription( 'a string containing "' . self::EXCERPT . '"', $this->_stringContains ); } } Text/StringContainsIgnoringCaseTest.php000064400000004671150524651050014312 0ustar00_stringContains = \Hamcrest\Text\StringContainsIgnoringCase::containsStringIgnoringCase( strtolower(self::EXCERPT) ); } protected function createMatcher() { return $this->_stringContains; } public function testEvaluatesToTrueIfArgumentContainsSpecifiedSubstring() { $this->assertTrue( $this->_stringContains->matches(self::EXCERPT . 'END'), 'should be true if excerpt at beginning' ); $this->assertTrue( $this->_stringContains->matches('START' . self::EXCERPT), 'should be true if excerpt at end' ); $this->assertTrue( $this->_stringContains->matches('START' . self::EXCERPT . 'END'), 'should be true if excerpt in middle' ); $this->assertTrue( $this->_stringContains->matches(self::EXCERPT . self::EXCERPT), 'should be true if excerpt is repeated' ); $this->assertFalse( $this->_stringContains->matches('Something else'), 'should not be true if excerpt is not in string' ); $this->assertFalse( $this->_stringContains->matches(substr(self::EXCERPT, 1)), 'should not be true if part of excerpt is in string' ); } public function testEvaluatesToTrueIfArgumentIsEqualToSubstring() { $this->assertTrue( $this->_stringContains->matches(self::EXCERPT), 'should be true if excerpt is entire string' ); } public function testEvaluatesToTrueIfArgumentContainsExactSubstring() { $this->assertTrue( $this->_stringContains->matches(strtolower(self::EXCERPT)), 'should be false if excerpt is entire string ignoring case' ); $this->assertTrue( $this->_stringContains->matches('START' . strtolower(self::EXCERPT) . 'END'), 'should be false if excerpt is contained in string ignoring case' ); } public function testHasAReadableDescription() { $this->assertDescription( 'a string containing in any case "' . strtolower(self::EXCERPT) . '"', $this->_stringContains ); } } Text/IsEqualIgnoringWhiteSpaceTest.php000064400000002556150524651050014071 0ustar00_matcher = \Hamcrest\Text\IsEqualIgnoringWhiteSpace::equalToIgnoringWhiteSpace( "Hello World how\n are we? " ); } protected function createMatcher() { return $this->_matcher; } public function testPassesIfWordsAreSameButWhitespaceDiffers() { assertThat('Hello World how are we?', $this->_matcher); assertThat(" Hello \rWorld \t how are\nwe?", $this->_matcher); } public function testFailsIfTextOtherThanWhitespaceDiffers() { assertThat('Hello PLANET how are we?', not($this->_matcher)); assertThat('Hello World how are we', not($this->_matcher)); } public function testFailsIfWhitespaceIsAddedOrRemovedInMidWord() { assertThat('HelloWorld how are we?', not($this->_matcher)); assertThat('Hello Wo rld how are we?', not($this->_matcher)); } public function testFailsIfMatchingAgainstNull() { assertThat(null, not($this->_matcher)); } public function testHasAReadableDescription() { $this->assertDescription( "equalToIgnoringWhiteSpace(\"Hello World how\\n are we? \")", $this->_matcher ); } } Text/IsEmptyStringTest.php000064400000004367150524651050011637 0ustar00assertDoesNotMatch(emptyString(), null, 'null'); } public function testEmptyDoesNotMatchZero() { $this->assertDoesNotMatch(emptyString(), 0, 'zero'); } public function testEmptyDoesNotMatchFalse() { $this->assertDoesNotMatch(emptyString(), false, 'false'); } public function testEmptyDoesNotMatchEmptyArray() { $this->assertDoesNotMatch(emptyString(), array(), 'empty array'); } public function testEmptyMatchesEmptyString() { $this->assertMatches(emptyString(), '', 'empty string'); } public function testEmptyDoesNotMatchNonEmptyString() { $this->assertDoesNotMatch(emptyString(), 'foo', 'non-empty string'); } public function testEmptyHasAReadableDescription() { $this->assertDescription('an empty string', emptyString()); } public function testEmptyOrNullMatchesNull() { $this->assertMatches(nullOrEmptyString(), null, 'null'); } public function testEmptyOrNullMatchesEmptyString() { $this->assertMatches(nullOrEmptyString(), '', 'empty string'); } public function testEmptyOrNullDoesNotMatchNonEmptyString() { $this->assertDoesNotMatch(nullOrEmptyString(), 'foo', 'non-empty string'); } public function testEmptyOrNullHasAReadableDescription() { $this->assertDescription('(null or an empty string)', nullOrEmptyString()); } public function testNonEmptyDoesNotMatchNull() { $this->assertDoesNotMatch(nonEmptyString(), null, 'null'); } public function testNonEmptyDoesNotMatchEmptyString() { $this->assertDoesNotMatch(nonEmptyString(), '', 'empty string'); } public function testNonEmptyMatchesNonEmptyString() { $this->assertMatches(nonEmptyString(), 'foo', 'non-empty string'); } public function testNonEmptyHasAReadableDescription() { $this->assertDescription('a non-empty string', nonEmptyString()); } } Text/IsEqualIgnoringCaseTest.php000064400000002174150524651050012704 0ustar00assertDescription( 'equalToIgnoringCase("heLLo")', equalToIgnoringCase('heLLo') ); } } Xml/HasXPathTest.php000064400000011750150524651050010344 0ustar00 alice Alice Frankel admin bob Bob Frankel user charlie Charlie Chan user XML; self::$doc = new \DOMDocument(); self::$doc->loadXML(self::$xml); self::$html = << Home Page

Heading

Some text

HTML; } protected function createMatcher() { return \Hamcrest\Xml\HasXPath::hasXPath('/users/user'); } public function testMatchesWhenXPathIsFound() { assertThat('one match', self::$doc, hasXPath('user[id = "bob"]')); assertThat('two matches', self::$doc, hasXPath('user[role = "user"]')); } public function testDoesNotMatchWhenXPathIsNotFound() { assertThat( 'no match', self::$doc, not(hasXPath('user[contains(id, "frank")]')) ); } public function testMatchesWhenExpressionWithoutMatcherEvaluatesToTrue() { assertThat( 'one match', self::$doc, hasXPath('count(user[id = "bob"])') ); } public function testDoesNotMatchWhenExpressionWithoutMatcherEvaluatesToFalse() { assertThat( 'no matches', self::$doc, not(hasXPath('count(user[id = "frank"])')) ); } public function testMatchesWhenExpressionIsEqual() { assertThat( 'one match', self::$doc, hasXPath('count(user[id = "bob"])', 1) ); assertThat( 'two matches', self::$doc, hasXPath('count(user[role = "user"])', 2) ); } public function testDoesNotMatchWhenExpressionIsNotEqual() { assertThat( 'no match', self::$doc, not(hasXPath('count(user[id = "frank"])', 2)) ); assertThat( 'one match', self::$doc, not(hasXPath('count(user[role = "admin"])', 2)) ); } public function testMatchesWhenContentMatches() { assertThat( 'one match', self::$doc, hasXPath('user/name', containsString('ice')) ); assertThat( 'two matches', self::$doc, hasXPath('user/role', equalTo('user')) ); } public function testDoesNotMatchWhenContentDoesNotMatch() { assertThat( 'no match', self::$doc, not(hasXPath('user/name', containsString('Bobby'))) ); assertThat( 'no matches', self::$doc, not(hasXPath('user/role', equalTo('owner'))) ); } public function testProvidesConvenientShortcutForHasXPathEqualTo() { assertThat('matches', self::$doc, hasXPath('count(user)', 3)); assertThat('matches', self::$doc, hasXPath('user[2]/id', 'bob')); } public function testProvidesConvenientShortcutForHasXPathCountEqualTo() { assertThat('matches', self::$doc, hasXPath('user[id = "charlie"]', 1)); } public function testMatchesAcceptsXmlString() { assertThat('accepts XML string', self::$xml, hasXPath('user')); } public function testMatchesAcceptsHtmlString() { assertThat('accepts HTML string', self::$html, hasXPath('body/h1', 'Heading')); } public function testHasAReadableDescription() { $this->assertDescription( 'XML or HTML document with XPath "/users/user"', hasXPath('/users/user') ); $this->assertDescription( 'XML or HTML document with XPath "count(/users/user)" <2>', hasXPath('/users/user', 2) ); $this->assertDescription( 'XML or HTML document with XPath "/users/user/name"' . ' a string starting with "Alice"', hasXPath('/users/user/name', startsWith('Alice')) ); } public function testHasAReadableMismatchDescription() { $this->assertMismatchDescription( 'XPath returned no results', hasXPath('/users/name'), self::$doc ); $this->assertMismatchDescription( 'XPath expression result was <3F>', hasXPath('/users/user', 2), self::$doc ); $this->assertMismatchDescription( 'XPath returned ["alice", "bob", "charlie"]', hasXPath('/users/user/id', 'Frank'), self::$doc ); } } MatcherAssertTest.php000064400000016275150524651050010700 0ustar00getMessage()); } try { \Hamcrest\MatcherAssert::assertThat(null); self::fail('expected assertion failure'); } catch (\Hamcrest\AssertionError $ex) { self::assertEquals('', $ex->getMessage()); } try { \Hamcrest\MatcherAssert::assertThat(''); self::fail('expected assertion failure'); } catch (\Hamcrest\AssertionError $ex) { self::assertEquals('', $ex->getMessage()); } try { \Hamcrest\MatcherAssert::assertThat(0); self::fail('expected assertion failure'); } catch (\Hamcrest\AssertionError $ex) { self::assertEquals('', $ex->getMessage()); } try { \Hamcrest\MatcherAssert::assertThat(0.0); self::fail('expected assertion failure'); } catch (\Hamcrest\AssertionError $ex) { self::assertEquals('', $ex->getMessage()); } try { \Hamcrest\MatcherAssert::assertThat(array()); self::fail('expected assertion failure'); } catch (\Hamcrest\AssertionError $ex) { self::assertEquals('', $ex->getMessage()); } self::assertEquals(6, \Hamcrest\MatcherAssert::getCount(), 'assertion count'); } public function testAssertThatWithIdentifierAndTrueArgPasses() { \Hamcrest\MatcherAssert::assertThat('identifier', true); \Hamcrest\MatcherAssert::assertThat('identifier', 'non-empty'); \Hamcrest\MatcherAssert::assertThat('identifier', 1); \Hamcrest\MatcherAssert::assertThat('identifier', 3.14159); \Hamcrest\MatcherAssert::assertThat('identifier', array(true)); self::assertEquals(5, \Hamcrest\MatcherAssert::getCount(), 'assertion count'); } public function testAssertThatWithIdentifierAndFalseArgFails() { try { \Hamcrest\MatcherAssert::assertThat('identifier', false); self::fail('expected assertion failure'); } catch (\Hamcrest\AssertionError $ex) { self::assertEquals('identifier', $ex->getMessage()); } try { \Hamcrest\MatcherAssert::assertThat('identifier', null); self::fail('expected assertion failure'); } catch (\Hamcrest\AssertionError $ex) { self::assertEquals('identifier', $ex->getMessage()); } try { \Hamcrest\MatcherAssert::assertThat('identifier', ''); self::fail('expected assertion failure'); } catch (\Hamcrest\AssertionError $ex) { self::assertEquals('identifier', $ex->getMessage()); } try { \Hamcrest\MatcherAssert::assertThat('identifier', 0); self::fail('expected assertion failure'); } catch (\Hamcrest\AssertionError $ex) { self::assertEquals('identifier', $ex->getMessage()); } try { \Hamcrest\MatcherAssert::assertThat('identifier', 0.0); self::fail('expected assertion failure'); } catch (\Hamcrest\AssertionError $ex) { self::assertEquals('identifier', $ex->getMessage()); } try { \Hamcrest\MatcherAssert::assertThat('identifier', array()); self::fail('expected assertion failure'); } catch (\Hamcrest\AssertionError $ex) { self::assertEquals('identifier', $ex->getMessage()); } self::assertEquals(6, \Hamcrest\MatcherAssert::getCount(), 'assertion count'); } public function testAssertThatWithActualValueAndMatcherArgsThatMatchPasses() { \Hamcrest\MatcherAssert::assertThat(true, is(true)); self::assertEquals(1, \Hamcrest\MatcherAssert::getCount(), 'assertion count'); } public function testAssertThatWithActualValueAndMatcherArgsThatDontMatchFails() { $expected = 'expected'; $actual = 'actual'; $expectedMessage = 'Expected: "expected"' . PHP_EOL . ' but: was "actual"'; try { \Hamcrest\MatcherAssert::assertThat($actual, equalTo($expected)); self::fail('expected assertion failure'); } catch (\Hamcrest\AssertionError $ex) { self::assertEquals($expectedMessage, $ex->getMessage()); self::assertEquals(1, \Hamcrest\MatcherAssert::getCount(), 'assertion count'); } } public function testAssertThatWithIdentifierAndActualValueAndMatcherArgsThatMatchPasses() { \Hamcrest\MatcherAssert::assertThat('identifier', true, is(true)); self::assertEquals(1, \Hamcrest\MatcherAssert::getCount(), 'assertion count'); } public function testAssertThatWithIdentifierAndActualValueAndMatcherArgsThatDontMatchFails() { $expected = 'expected'; $actual = 'actual'; $expectedMessage = 'identifier' . PHP_EOL . 'Expected: "expected"' . PHP_EOL . ' but: was "actual"'; try { \Hamcrest\MatcherAssert::assertThat('identifier', $actual, equalTo($expected)); self::fail('expected assertion failure'); } catch (\Hamcrest\AssertionError $ex) { self::assertEquals($expectedMessage, $ex->getMessage()); self::assertEquals(1, \Hamcrest\MatcherAssert::getCount(), 'assertion count'); } } public function testAssertThatWithNoArgsThrowsErrorAndDoesntIncrementCount() { try { \Hamcrest\MatcherAssert::assertThat(); self::fail('expected invalid argument exception'); } catch (\InvalidArgumentException $ex) { self::assertEquals(0, \Hamcrest\MatcherAssert::getCount(), 'assertion count'); } } public function testAssertThatWithFourArgsThrowsErrorAndDoesntIncrementCount() { try { \Hamcrest\MatcherAssert::assertThat(1, 2, 3, 4); self::fail('expected invalid argument exception'); } catch (\InvalidArgumentException $ex) { self::assertEquals(0, \Hamcrest\MatcherAssert::getCount(), 'assertion count'); } } } InvokedMatcherTest.php000064400000001143150524651050011022 0ustar00matchAgainst = $matchAgainst; } public function matches($item) { return $item == $this->matchAgainst; } } class InvokedMatcherTest extends TestCase { public function testInvokedMatchersCallMatches() { $sampleMatcher = new SampleInvokeMatcher('foo'); $this->assertTrue($sampleMatcher('foo')); $this->assertFalse($sampleMatcher('bar')); } } BaseMatcherTest.php000064400000001027150524651050010276 0ustar00appendText('SOME DESCRIPTION'); } public function testDescribesItselfWithToStringMethod() { $someMatcher = new \Hamcrest\SomeMatcher(); $this->assertEquals('SOME DESCRIPTION', (string) $someMatcher); } } StringDescriptionTest.php000064400000012526150524651050011600 0ustar00_text = $text; } public function describeTo(\Hamcrest\Description $description) { $description->appendText($this->_text); } } class StringDescriptionTest extends TestCase { private $_description; protected function setUp() { $this->_description = new \Hamcrest\StringDescription(); } public function testAppendTextAppendsTextInformation() { $this->_description->appendText('foo')->appendText('bar'); $this->assertEquals('foobar', (string) $this->_description); } public function testAppendValueCanAppendTextTypes() { $this->_description->appendValue('foo'); $this->assertEquals('"foo"', (string) $this->_description); } public function testSpecialCharactersAreEscapedForStringTypes() { $this->_description->appendValue("foo\\bar\"zip\r\n"); $this->assertEquals('"foo\\bar\\"zip\r\n"', (string) $this->_description); } public function testIntegerValuesCanBeAppended() { $this->_description->appendValue(42); $this->assertEquals('<42>', (string) $this->_description); } public function testFloatValuesCanBeAppended() { $this->_description->appendValue(42.78); $this->assertEquals('<42.78F>', (string) $this->_description); } public function testNullValuesCanBeAppended() { $this->_description->appendValue(null); $this->assertEquals('null', (string) $this->_description); } public function testArraysCanBeAppended() { $this->_description->appendValue(array('foo', 42.78)); $this->assertEquals('["foo", <42.78F>]', (string) $this->_description); } public function testObjectsCanBeAppended() { $this->_description->appendValue(new \stdClass()); $this->assertEquals('', (string) $this->_description); } public function testBooleanValuesCanBeAppended() { $this->_description->appendValue(false); $this->assertEquals('', (string) $this->_description); } public function testListsOfvaluesCanBeAppended() { $this->_description->appendValue(array('foo', 42.78)); $this->assertEquals('["foo", <42.78F>]', (string) $this->_description); } public function testIterableOfvaluesCanBeAppended() { $items = new \ArrayObject(array('foo', 42.78)); $this->_description->appendValue($items); $this->assertEquals('["foo", <42.78F>]', (string) $this->_description); } public function testIteratorOfvaluesCanBeAppended() { $items = new \ArrayObject(array('foo', 42.78)); $this->_description->appendValue($items->getIterator()); $this->assertEquals('["foo", <42.78F>]', (string) $this->_description); } public function testListsOfvaluesCanBeAppendedManually() { $this->_description->appendValueList('@start@', '@sep@ ', '@end@', array('foo', 42.78)); $this->assertEquals('@start@"foo"@sep@ <42.78F>@end@', (string) $this->_description); } public function testIterableOfvaluesCanBeAppendedManually() { $items = new \ArrayObject(array('foo', 42.78)); $this->_description->appendValueList('@start@', '@sep@ ', '@end@', $items); $this->assertEquals('@start@"foo"@sep@ <42.78F>@end@', (string) $this->_description); } public function testIteratorOfvaluesCanBeAppendedManually() { $items = new \ArrayObject(array('foo', 42.78)); $this->_description->appendValueList('@start@', '@sep@ ', '@end@', $items->getIterator()); $this->assertEquals('@start@"foo"@sep@ <42.78F>@end@', (string) $this->_description); } public function testSelfDescribingObjectsCanBeAppended() { $this->_description ->appendDescriptionOf(new \Hamcrest\SampleSelfDescriber('foo')) ->appendDescriptionOf(new \Hamcrest\SampleSelfDescriber('bar')) ; $this->assertEquals('foobar', (string) $this->_description); } public function testSelfDescribingObjectsCanBeAppendedAsLists() { $this->_description->appendList('@start@', '@sep@ ', '@end@', array( new \Hamcrest\SampleSelfDescriber('foo'), new \Hamcrest\SampleSelfDescriber('bar') )); $this->assertEquals('@start@foo@sep@ bar@end@', (string) $this->_description); } public function testSelfDescribingObjectsCanBeAppendedAsIteratedLists() { $items = new \ArrayObject(array( new \Hamcrest\SampleSelfDescriber('foo'), new \Hamcrest\SampleSelfDescriber('bar') )); $this->_description->appendList('@start@', '@sep@ ', '@end@', $items); $this->assertEquals('@start@foo@sep@ bar@end@', (string) $this->_description); } public function testSelfDescribingObjectsCanBeAppendedAsIterators() { $items = new \ArrayObject(array( new \Hamcrest\SampleSelfDescriber('foo'), new \Hamcrest\SampleSelfDescriber('bar') )); $this->_description->appendList('@start@', '@sep@ ', '@end@', $items->getIterator()); $this->assertEquals('@start@foo@sep@ bar@end@', (string) $this->_description); } } Collection/IsTraversableWithSizeTest.php000064400000002532150524651050014452 0ustar00assertMatches( traversableWithSize(equalTo(3)), new \ArrayObject(array(1, 2, 3)), 'correct size' ); } public function testDoesNotMatchWhenSizeIsIncorrect() { $this->assertDoesNotMatch( traversableWithSize(equalTo(2)), new \ArrayObject(array(1, 2, 3)), 'incorrect size' ); } public function testDoesNotMatchNull() { $this->assertDoesNotMatch( traversableWithSize(3), null, 'should not match null' ); } public function testProvidesConvenientShortcutForTraversableWithSizeEqualTo() { $this->assertMatches( traversableWithSize(3), new \ArrayObject(array(1, 2, 3)), 'correct size' ); } public function testHasAReadableDescription() { $this->assertDescription( 'a traversable with size <3>', traversableWithSize(equalTo(3)) ); } } Collection/IsEmptyTraversableTest.php000064400000003513150524651050014002 0ustar00assertMatches( emptyTraversable(), new \ArrayObject(array()), 'an empty traversable' ); } public function testEmptyMatcherDoesNotMatchWhenNotEmpty() { $this->assertDoesNotMatch( emptyTraversable(), new \ArrayObject(array(1, 2, 3)), 'a non-empty traversable' ); } public function testEmptyMatcherDoesNotMatchNull() { $this->assertDoesNotMatch( emptyTraversable(), null, 'should not match null' ); } public function testEmptyMatcherHasAReadableDescription() { $this->assertDescription('an empty traversable', emptyTraversable()); } public function testNonEmptyDoesNotMatchNull() { $this->assertDoesNotMatch( nonEmptyTraversable(), null, 'should not match null' ); } public function testNonEmptyDoesNotMatchWhenEmpty() { $this->assertDoesNotMatch( nonEmptyTraversable(), new \ArrayObject(array()), 'an empty traversable' ); } public function testNonEmptyMatchesWhenNotEmpty() { $this->assertMatches( nonEmptyTraversable(), new \ArrayObject(array(1, 2, 3)), 'a non-empty traversable' ); } public function testNonEmptyNonEmptyMatcherHasAReadableDescription() { $this->assertDescription('a non-empty traversable', nonEmptyTraversable()); } } Core/IsEqualTest.php000064400000005316150524651050010360 0ustar00_arg = $arg; } public function __toString() { return $this->_arg; } } class IsEqualTest extends \Hamcrest\AbstractMatcherTest { protected function createMatcher() { return \Hamcrest\Core\IsEqual::equalTo('irrelevant'); } public function testComparesObjectsUsingEqualityOperator() { assertThat("hi", equalTo("hi")); assertThat("bye", not(equalTo("hi"))); assertThat(1, equalTo(1)); assertThat(1, not(equalTo(2))); assertThat("2", equalTo(2)); } public function testCanCompareNullValues() { assertThat(null, equalTo(null)); assertThat(null, not(equalTo('hi'))); assertThat('hi', not(equalTo(null))); } public function testComparesTheElementsOfAnArray() { $s1 = array('a', 'b'); $s2 = array('a', 'b'); $s3 = array('c', 'd'); $s4 = array('a', 'b', 'c', 'd'); assertThat($s1, equalTo($s1)); assertThat($s2, equalTo($s1)); assertThat($s3, not(equalTo($s1))); assertThat($s4, not(equalTo($s1))); } public function testComparesTheElementsOfAnArrayOfPrimitiveTypes() { $i1 = array(1, 2); $i2 = array(1, 2); $i3 = array(3, 4); $i4 = array(1, 2, 3, 4); assertThat($i1, equalTo($i1)); assertThat($i2, equalTo($i1)); assertThat($i3, not(equalTo($i1))); assertThat($i4, not(equalTo($i1))); } public function testRecursivelyTestsElementsOfArrays() { $i1 = array(array(1, 2), array(3, 4)); $i2 = array(array(1, 2), array(3, 4)); $i3 = array(array(5, 6), array(7, 8)); $i4 = array(array(1, 2, 3, 4), array(3, 4)); assertThat($i1, equalTo($i1)); assertThat($i2, equalTo($i1)); assertThat($i3, not(equalTo($i1))); assertThat($i4, not(equalTo($i1))); } public function testIncludesTheResultOfCallingToStringOnItsArgumentInTheDescription() { $argumentDescription = 'ARGUMENT DESCRIPTION'; $argument = new \Hamcrest\Core\DummyToStringClass($argumentDescription); $this->assertDescription('<' . $argumentDescription . '>', equalTo($argument)); } public function testReturnsAnObviousDescriptionIfCreatedWithANestedMatcherByMistake() { $innerMatcher = equalTo('NestedMatcher'); $this->assertDescription('<' . (string) $innerMatcher . '>', equalTo($innerMatcher)); } public function testReturnsGoodDescriptionIfCreatedWithNullReference() { $this->assertDescription('null', equalTo(null)); } } Core/IsAnythingTest.php000064400000001254150524651050011067 0ustar00assertDescription('ANYTHING', anything()); } public function testCanOverrideDescription() { $description = 'description'; $this->assertDescription($description, anything($description)); } } Core/HasToStringTest.php000064400000004476150524651050011230 0ustar00assertMatches( hasToString(equalTo('php')), new \Hamcrest\Core\PhpForm(), 'correct __toString' ); $this->assertMatches( hasToString(equalTo('java')), new \Hamcrest\Core\JavaForm(), 'correct toString' ); } public function testPicksJavaOverPhpToString() { $this->assertMatches( hasToString(equalTo('java')), new \Hamcrest\Core\BothForms(), 'correct toString' ); } public function testDoesNotMatchWhenToStringDoesNotMatch() { $this->assertDoesNotMatch( hasToString(equalTo('mismatch')), new \Hamcrest\Core\PhpForm(), 'incorrect __toString' ); $this->assertDoesNotMatch( hasToString(equalTo('mismatch')), new \Hamcrest\Core\JavaForm(), 'incorrect toString' ); $this->assertDoesNotMatch( hasToString(equalTo('mismatch')), new \Hamcrest\Core\BothForms(), 'incorrect __toString' ); } public function testDoesNotMatchNull() { $this->assertDoesNotMatch( hasToString(equalTo('a')), null, 'should not match null' ); } public function testProvidesConvenientShortcutForTraversableWithSizeEqualTo() { $this->assertMatches( hasToString(equalTo('php')), new \Hamcrest\Core\PhpForm(), 'correct __toString' ); } public function testHasAReadableDescription() { $this->assertDescription( 'an object with toString() "php"', hasToString(equalTo('php')) ); } } Core/IsIdenticalTest.php000064400000001401150524651050011174 0ustar00assertDescription('"ARG"', identicalTo('ARG')); } public function testReturnsReadableDescriptionFromToStringWhenInitialisedWithNull() { $this->assertDescription('null', identicalTo(null)); } } Core/AllOfTest.php000064400000003033150524651050010004 0ustar00assertDescription( '("good" and "bad" and "ugly")', allOf('good', 'bad', 'ugly') ); } public function testMismatchDescriptionDescribesFirstFailingMatch() { $this->assertMismatchDescription( '"good" was "bad"', allOf('bad', 'good'), 'bad' ); } } Core/AnyOfTest.php000064400000004637150524651050010036 0ustar00assertDescription( '("good" or "bad" or "ugly")', anyOf('good', 'bad', 'ugly') ); } public function testNoneOfEvaluatesToTheLogicalDisjunctionOfTwoOtherMatchers() { assertThat('good', not(noneOf('bad', 'good'))); assertThat('good', not(noneOf('good', 'good'))); assertThat('good', not(noneOf('good', 'bad'))); assertThat('good', noneOf('bad', startsWith('b'))); } public function testNoneOfEvaluatesToTheLogicalDisjunctionOfManyOtherMatchers() { assertThat('good', not(noneOf('bad', 'good', 'bad', 'bad', 'bad'))); assertThat('good', noneOf('bad', 'bad', 'bad', 'bad', 'bad')); } public function testNoneOfSupportsMixedTypes() { $combined = noneOf( equalTo(new \Hamcrest\Core\SampleBaseClass('good')), equalTo(new \Hamcrest\Core\SampleBaseClass('ugly')), equalTo(new \Hamcrest\Core\SampleSubClass('good')) ); assertThat(new \Hamcrest\Core\SampleSubClass('bad'), $combined); } public function testNoneOfHasAReadableDescription() { $this->assertDescription( 'not ("good" or "bad" or "ugly")', noneOf('good', 'bad', 'ugly') ); } } Core/CombinableMatcherTest.php000064400000003355150524651050012355 0ustar00_either_3_or_4 = \Hamcrest\Core\CombinableMatcher::either(equalTo(3))->orElse(equalTo(4)); $this->_not_3_and_not_4 = \Hamcrest\Core\CombinableMatcher::both(not(equalTo(3)))->andAlso(not(equalTo(4))); } protected function createMatcher() { return \Hamcrest\Core\CombinableMatcher::either(equalTo('irrelevant'))->orElse(equalTo('ignored')); } public function testBothAcceptsAndRejects() { assertThat(2, $this->_not_3_and_not_4); assertThat(3, not($this->_not_3_and_not_4)); } public function testAcceptsAndRejectsThreeAnds() { $tripleAnd = $this->_not_3_and_not_4->andAlso(equalTo(2)); assertThat(2, $tripleAnd); assertThat(3, not($tripleAnd)); } public function testBothDescribesItself() { $this->assertEquals('(not <3> and not <4>)', (string) $this->_not_3_and_not_4); $this->assertMismatchDescription('was <3>', $this->_not_3_and_not_4, 3); } public function testEitherAcceptsAndRejects() { assertThat(3, $this->_either_3_or_4); assertThat(6, not($this->_either_3_or_4)); } public function testAcceptsAndRejectsThreeOrs() { $orTriple = $this->_either_3_or_4->orElse(greaterThan(10)); assertThat(11, $orTriple); assertThat(9, not($orTriple)); } public function testEitherDescribesItself() { $this->assertEquals('(<3> or <4>)', (string) $this->_either_3_or_4); $this->assertMismatchDescription('was <6>', $this->_either_3_or_4, 6); } } Core/DescribedAsTest.php000064400000002057150524651050011164 0ustar00assertDescription('m1 description', $m1); $this->assertDescription('m2 description', $m2); } public function testAppendsValuesToDescription() { $m = describedAs('value 1 = %0, value 2 = %1', anything(), 33, 97); $this->assertDescription('value 1 = <33>, value 2 = <97>', $m); } public function testDelegatesMatchingToAnotherMatcher() { $m1 = describedAs('irrelevant', anything()); $m2 = describedAs('irrelevant', not(anything())); $this->assertTrue($m1->matches(new \stdClass())); $this->assertFalse($m2->matches('hi')); } } Core/EveryTest.php000064400000001502150524651050010100 0ustar00assertEquals('every item is a string containing "a"', (string) $each); $this->assertMismatchDescription('an item was "BbB"', $each, array('BbB')); } } Core/IsCollectionContainingTest.php000064400000005106150524651050013413 0ustar00assertMatches( $itemMatcher, array('a', 'b', 'c'), "should match list that contains 'a'" ); } public function testDoesNotMatchCollectionThatDoesntContainAnElementMatchingTheGivenMatcher() { $matcher1 = hasItem(equalTo('a')); $this->assertDoesNotMatch( $matcher1, array('b', 'c'), "should not match list that doesn't contain 'a'" ); $matcher2 = hasItem(equalTo('a')); $this->assertDoesNotMatch( $matcher2, array(), 'should not match the empty list' ); } public function testDoesNotMatchNull() { $this->assertDoesNotMatch( hasItem(equalTo('a')), null, 'should not match null' ); } public function testHasAReadableDescription() { $this->assertDescription('a collection containing "a"', hasItem(equalTo('a'))); } public function testMatchesAllItemsInCollection() { $matcher1 = hasItems(equalTo('a'), equalTo('b'), equalTo('c')); $this->assertMatches( $matcher1, array('a', 'b', 'c'), 'should match list containing all items' ); $matcher2 = hasItems('a', 'b', 'c'); $this->assertMatches( $matcher2, array('a', 'b', 'c'), 'should match list containing all items (without matchers)' ); $matcher3 = hasItems(equalTo('a'), equalTo('b'), equalTo('c')); $this->assertMatches( $matcher3, array('c', 'b', 'a'), 'should match list containing all items in any order' ); $matcher4 = hasItems(equalTo('a'), equalTo('b'), equalTo('c')); $this->assertMatches( $matcher4, array('e', 'c', 'b', 'a', 'd'), 'should match list containing all items plus others' ); $matcher5 = hasItems(equalTo('a'), equalTo('b'), equalTo('c')); $this->assertDoesNotMatch( $matcher5, array('e', 'c', 'b', 'd'), // 'a' missing 'should not match list unless it contains all items' ); } } Core/IsTypeOfTest.php000064400000002711150524651050010513 0ustar00assertDescription('a double', typeOf('double')); $this->assertDescription('an integer', typeOf('integer')); } public function testDecribesActualTypeInMismatchMessage() { $this->assertMismatchDescription('was null', typeOf('boolean'), null); $this->assertMismatchDescription('was an integer <5>', typeOf('float'), 5); } } Core/IsNotTest.php000064400000001746150524651050010054 0ustar00assertMatches(not(equalTo('A')), 'B', 'should match'); $this->assertDoesNotMatch(not(equalTo('B')), 'B', 'should not match'); } public function testProvidesConvenientShortcutForNotEqualTo() { $this->assertMatches(not('A'), 'B', 'should match'); $this->assertMatches(not('B'), 'A', 'should match'); $this->assertDoesNotMatch(not('A'), 'A', 'should not match'); $this->assertDoesNotMatch(not('B'), 'B', 'should not match'); } public function testUsesDescriptionOfNegatedMatcherWithPrefix() { $this->assertDescription('not a value greater than <2>', not(greaterThan(2))); $this->assertDescription('not "A"', not('A')); } } Core/SampleSubClass.php000064400000000140150524651050011024 0ustar00assertMatches(is(equalTo(true)), true, 'should match'); $this->assertMatches(is(equalTo(false)), false, 'should match'); $this->assertDoesNotMatch(is(equalTo(true)), false, 'should not match'); $this->assertDoesNotMatch(is(equalTo(false)), true, 'should not match'); } public function testGeneratesIsPrefixInDescription() { $this->assertDescription('is ', is(equalTo(true))); } public function testProvidesConvenientShortcutForIsEqualTo() { $this->assertMatches(is('A'), 'A', 'should match'); $this->assertMatches(is('B'), 'B', 'should match'); $this->assertDoesNotMatch(is('A'), 'B', 'should not match'); $this->assertDoesNotMatch(is('B'), 'A', 'should not match'); $this->assertDescription('is "A"', is('A')); } } Core/IsInstanceOfTest.php000064400000003456150524651050011345 0ustar00_baseClassInstance = new \Hamcrest\Core\SampleBaseClass('good'); $this->_subClassInstance = new \Hamcrest\Core\SampleSubClass('good'); } protected function createMatcher() { return \Hamcrest\Core\IsInstanceOf::anInstanceOf('stdClass'); } public function testEvaluatesToTrueIfArgumentIsInstanceOfASpecificClass() { assertThat($this->_baseClassInstance, anInstanceOf('Hamcrest\Core\SampleBaseClass')); assertThat($this->_subClassInstance, anInstanceOf('Hamcrest\Core\SampleSubClass')); assertThat(null, not(anInstanceOf('Hamcrest\Core\SampleBaseClass'))); assertThat(new \stdClass(), not(anInstanceOf('Hamcrest\Core\SampleBaseClass'))); } public function testEvaluatesToFalseIfArgumentIsNotAnObject() { assertThat(null, not(anInstanceOf('Hamcrest\Core\SampleBaseClass'))); assertThat(false, not(anInstanceOf('Hamcrest\Core\SampleBaseClass'))); assertThat(5, not(anInstanceOf('Hamcrest\Core\SampleBaseClass'))); assertThat('foo', not(anInstanceOf('Hamcrest\Core\SampleBaseClass'))); assertThat(array(1, 2, 3), not(anInstanceOf('Hamcrest\Core\SampleBaseClass'))); } public function testHasAReadableDescription() { $this->assertDescription('an instance of stdClass', anInstanceOf('stdClass')); } public function testDecribesActualClassInMismatchMessage() { $this->assertMismatchDescription( '[Hamcrest\Core\SampleBaseClass] ', anInstanceOf('Hamcrest\Core\SampleSubClass'), $this->_baseClassInstance ); } } Core/IsSameTest.php000064400000001433150524651050010172 0ustar00assertDescription('sameInstance("ARG")', sameInstance('ARG')); } public function testReturnsReadableDescriptionFromToStringWhenInitialisedWithNull() { $this->assertDescription('sameInstance(null)', sameInstance(null)); } } Core/SetTest.php000064400000006176150524651050007555 0ustar00_instanceProperty); } protected function createMatcher() { return \Hamcrest\Core\Set::set('property_name'); } public function testEvaluatesToTrueIfArrayPropertyIsSet() { assertThat(array('foo' => 'bar'), set('foo')); } public function testNegatedEvaluatesToFalseIfArrayPropertyIsSet() { assertThat(array('foo' => 'bar'), not(notSet('foo'))); } public function testEvaluatesToTrueIfClassPropertyIsSet() { self::$_classProperty = 'bar'; assertThat('Hamcrest\Core\SetTest', set('_classProperty')); } public function testNegatedEvaluatesToFalseIfClassPropertyIsSet() { self::$_classProperty = 'bar'; assertThat('Hamcrest\Core\SetTest', not(notSet('_classProperty'))); } public function testEvaluatesToTrueIfObjectPropertyIsSet() { $this->_instanceProperty = 'bar'; assertThat($this, set('_instanceProperty')); } public function testNegatedEvaluatesToFalseIfObjectPropertyIsSet() { $this->_instanceProperty = 'bar'; assertThat($this, not(notSet('_instanceProperty'))); } public function testEvaluatesToFalseIfArrayPropertyIsNotSet() { assertThat(array('foo' => 'bar'), not(set('baz'))); } public function testNegatedEvaluatesToTrueIfArrayPropertyIsNotSet() { assertThat(array('foo' => 'bar'), notSet('baz')); } public function testEvaluatesToFalseIfClassPropertyIsNotSet() { assertThat('Hamcrest\Core\SetTest', not(set('_classProperty'))); } public function testNegatedEvaluatesToTrueIfClassPropertyIsNotSet() { assertThat('Hamcrest\Core\SetTest', notSet('_classProperty')); } public function testEvaluatesToFalseIfObjectPropertyIsNotSet() { assertThat($this, not(set('_instanceProperty'))); } public function testNegatedEvaluatesToTrueIfObjectPropertyIsNotSet() { assertThat($this, notSet('_instanceProperty')); } public function testHasAReadableDescription() { $this->assertDescription('set property foo', set('foo')); $this->assertDescription('unset property bar', notSet('bar')); } public function testDecribesPropertySettingInMismatchMessage() { $this->assertMismatchDescription( 'was not set', set('bar'), array('foo' => 'bar') ); $this->assertMismatchDescription( 'was "bar"', notSet('foo'), array('foo' => 'bar') ); self::$_classProperty = 'bar'; $this->assertMismatchDescription( 'was "bar"', notSet('_classProperty'), 'Hamcrest\Core\SetTest' ); $this->_instanceProperty = 'bar'; $this->assertMismatchDescription( 'was "bar"', notSet('_instanceProperty'), $this ); } } Core/SampleBaseClass.php000064400000000347150524651050011156 0ustar00_arg = $arg; } public function __toString() { return $this->_arg; } } Number/IsCloseToTest.php000064400000001441150524651050011214 0ustar00assertTrue($p->matches(1.0)); $this->assertTrue($p->matches(0.5)); $this->assertTrue($p->matches(1.5)); $this->assertDoesNotMatch($p, 2.0, 'too large'); $this->assertMismatchDescription('<2F> differed by <0.5F>', $p, 2.0); $this->assertDoesNotMatch($p, 0.0, 'number too small'); $this->assertMismatchDescription('<0F> differed by <0.5F>', $p, 0.0); } } Number/OrderingComparisonTest.php000064400000001750150524651050013157 0ustar00assertSame($matcher, $newMatcher); } public function testWrapValueWithIsEqualWrapsPrimitive() { $matcher = \Hamcrest\Util::wrapValueWithIsEqual('foo'); $this->assertInstanceOf('Hamcrest\Core\IsEqual', $matcher); $this->assertTrue($matcher->matches('foo')); } public function testCheckAllAreMatchersAcceptsMatchers() { \Hamcrest\Util::checkAllAreMatchers(array( new \Hamcrest\Text\MatchesPattern('/fo+/'), new \Hamcrest\Core\IsEqual('foo'), )); } /** * @expectedException InvalidArgumentException */ public function testCheckAllAreMatchersFailsForPrimitive() { \Hamcrest\Util::checkAllAreMatchers(array( new \Hamcrest\Text\MatchesPattern('/fo+/'), 'foo', )); } private function callAndAssertCreateMatcherArray($items) { $matchers = \Hamcrest\Util::createMatcherArray($items); $this->assertInternalType('array', $matchers); $this->assertSameSize($items, $matchers); foreach ($matchers as $matcher) { $this->assertInstanceOf('\Hamcrest\Matcher', $matcher); } return $matchers; } public function testCreateMatcherArrayLeavesMatchersUntouched() { $matcher = new \Hamcrest\Text\MatchesPattern('/fo+/'); $items = array($matcher); $matchers = $this->callAndAssertCreateMatcherArray($items); $this->assertSame($matcher, $matchers[0]); } public function testCreateMatcherArrayWrapsPrimitiveWithIsEqualMatcher() { $matchers = $this->callAndAssertCreateMatcherArray(array('foo')); $this->assertInstanceOf('Hamcrest\Core\IsEqual', $matchers[0]); $this->assertTrue($matchers[0]->matches('foo')); } public function testCreateMatcherArrayDoesntModifyOriginalArray() { $items = array('foo'); $this->callAndAssertCreateMatcherArray($items); $this->assertSame('foo', $items[0]); } public function testCreateMatcherArrayUnwrapsSingleArrayElement() { $matchers = $this->callAndAssertCreateMatcherArray(array(array('foo'))); $this->assertInstanceOf('Hamcrest\Core\IsEqual', $matchers[0]); $this->assertTrue($matchers[0]->matches('foo')); } } FeatureMatcherTest.php000064400000003175150524651050011025 0ustar00_result = $result; } public function getResult() { return $this->_result; } } /* Test-specific subclass only */ class ResultMatcher extends \Hamcrest\FeatureMatcher { public function __construct() { parent::__construct(self::TYPE_ANY, null, equalTo('bar'), 'Thingy with result', 'result'); } public function featureValueOf($actual) { if ($actual instanceof \Hamcrest\Thingy) { return $actual->getResult(); } } } class FeatureMatcherTest extends \Hamcrest\AbstractMatcherTest { private $_resultMatcher; protected function setUp() { $this->_resultMatcher = $this->_resultMatcher(); } protected function createMatcher() { return $this->_resultMatcher(); } public function testMatchesPartOfAnObject() { $this->assertMatches($this->_resultMatcher, new \Hamcrest\Thingy('bar'), 'feature'); $this->assertDescription('Thingy with result "bar"', $this->_resultMatcher); } public function testMismatchesPartOfAnObject() { $this->assertMismatchDescription( 'result was "foo"', $this->_resultMatcher, new \Hamcrest\Thingy('foo') ); } public function testDoesNotGenerateNoticesForNull() { $this->assertMismatchDescription('result was null', $this->_resultMatcher, null); } // -- Creation Methods private function _resultMatcher() { return new \Hamcrest\ResultMatcher(); } } AbstractMatcherTest.php000064400000003577150524651050011203 0ustar00assertTrue($matcher->matches($arg), $message); } public function assertDoesNotMatch(\Hamcrest\Matcher $matcher, $arg, $message) { $this->assertFalse($matcher->matches($arg), $message); } public function assertDescription($expected, \Hamcrest\Matcher $matcher) { $description = new \Hamcrest\StringDescription(); $description->appendDescriptionOf($matcher); $this->assertEquals($expected, (string) $description, 'Expected description'); } public function assertMismatchDescription($expected, \Hamcrest\Matcher $matcher, $arg) { $description = new \Hamcrest\StringDescription(); $this->assertFalse( $matcher->matches($arg), 'Precondtion: Matcher should not match item' ); $matcher->describeMismatch($arg, $description); $this->assertEquals( $expected, (string) $description, 'Expected mismatch description' ); } public function testIsNullSafe() { //Should not generate any notices $this->createMatcher()->matches(null); $this->createMatcher()->describeMismatch( null, new \Hamcrest\NullDescription() ); } public function testCopesWithUnknownTypes() { //Should not generate any notices $this->createMatcher()->matches(new UnknownType()); $this->createMatcher()->describeMismatch( new UnknownType(), new NullDescription() ); } } AssertionError.php000064400000000167150524651160010247 0ustar00featureValueOf() in a subclass to pull out the feature to be * matched against. */ abstract class FeatureMatcher extends TypeSafeDiagnosingMatcher { private $_subMatcher; private $_featureDescription; private $_featureName; /** * Constructor. * * @param string $type * @param string $subtype * @param \Hamcrest\Matcher $subMatcher The matcher to apply to the feature * @param string $featureDescription Descriptive text to use in describeTo * @param string $featureName Identifying text for mismatch message */ public function __construct($type, $subtype, Matcher $subMatcher, $featureDescription, $featureName) { parent::__construct($type, $subtype); $this->_subMatcher = $subMatcher; $this->_featureDescription = $featureDescription; $this->_featureName = $featureName; } /** * Implement this to extract the interesting feature. * * @param mixed $actual the target object * * @return mixed the feature to be matched */ abstract protected function featureValueOf($actual); public function matchesSafelyWithDiagnosticDescription($actual, Description $mismatchDescription) { $featureValue = $this->featureValueOf($actual); if (!$this->_subMatcher->matches($featureValue)) { $mismatchDescription->appendText($this->_featureName) ->appendText(' was ')->appendValue($featureValue); return false; } return true; } final public function describeTo(Description $description) { $description->appendText($this->_featureDescription)->appendText(' ') ->appendDescriptionOf($this->_subMatcher) ; } } Type/IsObject.php000064400000000750150524651160007707 0ustar00isHexadecimal($item)) { return true; } return is_numeric($item); } /** * Return if the string passed is a valid hexadecimal number. * This check is necessary because PHP 7 doesn't recognize hexadecimal string as numeric anymore. * * @param mixed $item * @return boolean */ private function isHexadecimal($item) { if (is_string($item) && preg_match('/^0x(.*)$/', $item, $matches)) { return ctype_xdigit($matches[1]); } return false; } /** * Is the value a numeric? * * @factory */ public static function numericValue() { return new self; } } Type/IsDouble.php000064400000001053150524651160007710 0ustar00 * Matcher implementations should NOT directly implement this interface. * Instead, extend the {@link Hamcrest\BaseMatcher} abstract class, * which will ensure that the Matcher API can grow to support * new features and remain compatible with all Matcher implementations. *

* For easy access to common Matcher implementations, use the static factory * methods in {@link Hamcrest\CoreMatchers}. * * @see Hamcrest\CoreMatchers * @see Hamcrest\BaseMatcher */ interface Matcher extends SelfDescribing { /** * Evaluates the matcher for argument $item. * * @param mixed $item the object against which the matcher is evaluated. * * @return boolean true if $item matches, * otherwise false. * * @see Hamcrest\BaseMatcher */ public function matches($item); /** * Generate a description of why the matcher has not accepted the item. * The description will be part of a larger description of why a matching * failed, so it should be concise. * This method assumes that matches($item) is false, but * will not check this. * * @param mixed $item The item that the Matcher has rejected. * @param Description $description * @return */ public function describeMismatch($item, Description $description); } Text/MatchesPattern.php000064400000001353150524651160011132 0ustar00_substring, (string) $item) >= 1; } protected function relationship() { return 'matching'; } } Text/StringContainsIgnoringCase.php000064400000001452150524651160013446 0ustar00_substring)); } protected function relationship() { return 'containing in any case'; } } Text/StringContains.php000064400000001522150524651160011153 0ustar00_substring); } /** * Matches if value is a string that contains $substring. * * @factory */ public static function containsString($substring) { return new self($substring); } // -- Protected Methods protected function evalSubstringOf($item) { return (false !== strpos((string) $item, $this->_substring)); } protected function relationship() { return 'containing'; } } Text/IsEqualIgnoringWhiteSpace.php000064400000003071150524651160013224 0ustar00_string = $string; } protected function matchesSafely($item) { return (strtolower($this->_stripSpace($item)) === strtolower($this->_stripSpace($this->_string))); } protected function describeMismatchSafely($item, Description $mismatchDescription) { $mismatchDescription->appendText('was ')->appendText($item); } public function describeTo(Description $description) { $description->appendText('equalToIgnoringWhiteSpace(') ->appendValue($this->_string) ->appendText(')') ; } /** * Matches if value is a string equal to $string, regardless of whitespace. * * @factory */ public static function equalToIgnoringWhiteSpace($string) { return new self($string); } // -- Private Methods private function _stripSpace($string) { $parts = preg_split("/[\r\n\t ]+/", $string); foreach ($parts as $i => $part) { $parts[$i] = trim($part, " \r\n\t"); } return trim(implode(' ', $parts), " \r\n\t"); } } Text/SubstringMatcher.php000064400000002107150524651160011472 0ustar00_substring = $substring; } protected function matchesSafely($item) { return $this->evalSubstringOf($item); } protected function describeMismatchSafely($item, Description $mismatchDescription) { $mismatchDescription->appendText('was "')->appendText($item)->appendText('"'); } public function describeTo(Description $description) { $description->appendText('a string ') ->appendText($this->relationship()) ->appendText(' ') ->appendValue($this->_substring) ; } abstract protected function evalSubstringOf($string); abstract protected function relationship(); } Text/IsEqualIgnoringCase.php000064400000002270150524651160012043 0ustar00_string = $string; } protected function matchesSafely($item) { return strtolower($this->_string) === strtolower($item); } protected function describeMismatchSafely($item, Description $mismatchDescription) { $mismatchDescription->appendText('was ')->appendText($item); } public function describeTo(Description $description) { $description->appendText('equalToIgnoringCase(') ->appendValue($this->_string) ->appendText(')') ; } /** * Matches if value is a string equal to $string, regardless of the case. * * @factory */ public static function equalToIgnoringCase($string) { return new self($string); } } Text/StringEndsWith.php000064400000001363150524651160011125 0ustar00_substring))) === $this->_substring); } protected function relationship() { return 'ending with'; } } Text/IsEmptyString.php000064400000003434150524651160010773 0ustar00_empty = $empty; } public function matches($item) { return $this->_empty ? ($item === '') : is_string($item) && $item !== ''; } public function describeTo(Description $description) { $description->appendText($this->_empty ? 'an empty string' : 'a non-empty string'); } /** * Matches if value is a zero-length string. * * @factory emptyString */ public static function isEmptyString() { if (!self::$_INSTANCE) { self::$_INSTANCE = new self(true); } return self::$_INSTANCE; } /** * Matches if value is null or a zero-length string. * * @factory nullOrEmptyString */ public static function isEmptyOrNullString() { if (!self::$_NULL_OR_EMPTY_INSTANCE) { self::$_NULL_OR_EMPTY_INSTANCE = AnyOf::anyOf( IsNull::nullvalue(), self::isEmptyString() ); } return self::$_NULL_OR_EMPTY_INSTANCE; } /** * Matches if value is a non-zero-length string. * * @factory nonEmptyString */ public static function isNonEmptyString() { if (!self::$_NOT_INSTANCE) { self::$_NOT_INSTANCE = new self(false); } return self::$_NOT_INSTANCE; } } Text/StringStartsWith.php000064400000001366150524651160011517 0ustar00_substring)) === $this->_substring); } protected function relationship() { return 'starting with'; } } Text/StringContainsInOrder.php000064400000003035150524651160012437 0ustar00_substrings = $substrings; } protected function matchesSafely($item) { $fromIndex = 0; foreach ($this->_substrings as $substring) { if (false === $fromIndex = strpos($item, $substring, $fromIndex)) { return false; } } return true; } protected function describeMismatchSafely($item, Description $mismatchDescription) { $mismatchDescription->appendText('was ')->appendText($item); } public function describeTo(Description $description) { $description->appendText('a string containing ') ->appendValueList('', ', ', '', $this->_substrings) ->appendText(' in order') ; } /** * Matches if value contains $substrings in a constrained order. * * @factory ... */ public static function stringContainsInOrder(/* args... */) { $args = func_get_args(); if (isset($args[0]) && is_array($args[0])) { $args = $args[0]; } return new self($args); } } NullDescription.php000064400000001273150524651160010403 0ustar00 all items are */ public static function createMatcherArray(array $items) { //Extract single array item if (count($items) == 1 && is_array($items[0])) { $items = $items[0]; } //Replace non-matchers foreach ($items as &$item) { if (!($item instanceof Matcher)) { $item = Core\IsEqual::equalTo($item); } } return $items; } } StringDescription.php000064400000002143150524651160010734 0ustar00_out = (string) $out; } public function __toString() { return $this->_out; } /** * Return the description of a {@link Hamcrest\SelfDescribing} object as a * String. * * @param \Hamcrest\SelfDescribing $selfDescribing * The object to be described. * * @return string * The description of the object. */ public static function toString(SelfDescribing $selfDescribing) { $self = new self(); return (string) $self->appendDescriptionOf($selfDescribing); } /** * Alias for {@link toString()}. */ public static function asString(SelfDescribing $selfDescribing) { return self::toString($selfDescribing); } // -- Protected Methods protected function append($str) { $this->_out .= $str; } } Xml/HasXPath.php000064400000013747150524651160007516 0ustar00_xpath = $xpath; $this->_matcher = $matcher; } /** * Matches if the XPath matches against the DOM node and the matcher. * * @param string|\DOMNode $actual * @param Description $mismatchDescription * @return bool */ protected function matchesWithDiagnosticDescription($actual, Description $mismatchDescription) { if (is_string($actual)) { $actual = $this->createDocument($actual); } elseif (!$actual instanceof \DOMNode) { $mismatchDescription->appendText('was ')->appendValue($actual); return false; } $result = $this->evaluate($actual); if ($result instanceof \DOMNodeList) { return $this->matchesContent($result, $mismatchDescription); } else { return $this->matchesExpression($result, $mismatchDescription); } } /** * Creates and returns a DOMDocument from the given * XML or HTML string. * * @param string $text * @return \DOMDocument built from $text * @throws \InvalidArgumentException if the document is not valid */ protected function createDocument($text) { $document = new \DOMDocument(); if (preg_match('/^\s*<\?xml/', $text)) { if (!@$document->loadXML($text)) { throw new \InvalidArgumentException('Must pass a valid XML document'); } } else { if (!@$document->loadHTML($text)) { throw new \InvalidArgumentException('Must pass a valid HTML or XHTML document'); } } return $document; } /** * Applies the configured XPath to the DOM node and returns either * the result if it's an expression or the node list if it's a query. * * @param \DOMNode $node context from which to issue query * @return mixed result of expression or DOMNodeList from query */ protected function evaluate(\DOMNode $node) { if ($node instanceof \DOMDocument) { $xpathDocument = new \DOMXPath($node); return $xpathDocument->evaluate($this->_xpath); } else { $xpathDocument = new \DOMXPath($node->ownerDocument); return $xpathDocument->evaluate($this->_xpath, $node); } } /** * Matches if the list of nodes is not empty and the content of at least * one node matches the configured matcher, if supplied. * * @param \DOMNodeList $nodes selected by the XPath query * @param Description $mismatchDescription * @return bool */ protected function matchesContent(\DOMNodeList $nodes, Description $mismatchDescription) { if ($nodes->length == 0) { $mismatchDescription->appendText('XPath returned no results'); } elseif ($this->_matcher === null) { return true; } else { foreach ($nodes as $node) { if ($this->_matcher->matches($node->textContent)) { return true; } } $content = array(); foreach ($nodes as $node) { $content[] = $node->textContent; } $mismatchDescription->appendText('XPath returned ') ->appendValue($content); } return false; } /** * Matches if the result of the XPath expression matches the configured * matcher or evaluates to true if there is none. * * @param mixed $result result of the XPath expression * @param Description $mismatchDescription * @return bool */ protected function matchesExpression($result, Description $mismatchDescription) { if ($this->_matcher === null) { if ($result) { return true; } $mismatchDescription->appendText('XPath expression result was ') ->appendValue($result); } else { if ($this->_matcher->matches($result)) { return true; } $mismatchDescription->appendText('XPath expression result '); $this->_matcher->describeMismatch($result, $mismatchDescription); } return false; } public function describeTo(Description $description) { $description->appendText('XML or HTML document with XPath "') ->appendText($this->_xpath) ->appendText('"'); if ($this->_matcher !== null) { $description->appendText(' '); $this->_matcher->describeTo($description); } } /** * Wraps $matcher with {@link Hamcrest\Core\IsEqual) * if it's not a matcher and the XPath in count() * if it's an integer. * * @factory */ public static function hasXPath($xpath, $matcher = null) { if ($matcher === null || $matcher instanceof Matcher) { return new self($xpath, $matcher); } elseif (is_int($matcher) && strpos($xpath, 'count(') !== 0) { $xpath = 'count(' . $xpath . ')'; } return new self($xpath, IsEqual::equalTo($matcher)); } } BaseMatcher.php000064400000001065150524651160007442 0ustar00appendText('was ')->appendValue($item); } public function __toString() { return StringDescription::toString($this); } public function __invoke() { return call_user_func_array(array($this, 'matches'), func_get_args()); } } TypeSafeDiagnosingMatcher.php000064400000001511150524651160012307 0ustar00matchesSafelyWithDiagnosticDescription($item, new NullDescription()); } final public function describeMismatchSafely($item, Description $mismatchDescription) { $this->matchesSafelyWithDiagnosticDescription($item, $mismatchDescription); } // -- Protected Methods /** * Subclasses should implement these. The item will already have been checked for * the specific type. */ abstract protected function matchesSafelyWithDiagnosticDescription($item, Description $mismatchDescription); } Arrays/IsArrayContainingKeyValuePair.php000064400000004323150524651160014373 0ustar00_keyMatcher = $keyMatcher; $this->_valueMatcher = $valueMatcher; } protected function matchesSafely($array) { foreach ($array as $key => $value) { if ($this->_keyMatcher->matches($key) && $this->_valueMatcher->matches($value)) { return true; } } return false; } protected function describeMismatchSafely($array, Description $mismatchDescription) { //Not using appendValueList() so that keys can be shown $mismatchDescription->appendText('array was ') ->appendText('[') ; $loop = false; foreach ($array as $key => $value) { if ($loop) { $mismatchDescription->appendText(', '); } $mismatchDescription->appendValue($key)->appendText(' => ')->appendValue($value); $loop = true; } $mismatchDescription->appendText(']'); } public function describeTo(Description $description) { $description->appendText('array containing [') ->appendDescriptionOf($this->_keyMatcher) ->appendText(' => ') ->appendDescriptionOf($this->_valueMatcher) ->appendText(']') ; } /** * Test if an array has both an key and value in parity with each other. * * @factory hasEntry */ public static function hasKeyValuePair($key, $value) { return new self( Util::wrapValueWithIsEqual($key), Util::wrapValueWithIsEqual($value) ); } } Arrays/MatchingOnce.php000064400000003126150524651160011064 0ustar00_elementMatchers = $elementMatchers; $this->_mismatchDescription = $mismatchDescription; } public function matches($item) { return $this->_isNotSurplus($item) && $this->_isMatched($item); } public function isFinished($items) { if (empty($this->_elementMatchers)) { return true; } $this->_mismatchDescription ->appendText('No item matches: ')->appendList('', ', ', '', $this->_elementMatchers) ->appendText(' in ')->appendValueList('[', ', ', ']', $items) ; return false; } // -- Private Methods private function _isNotSurplus($item) { if (empty($this->_elementMatchers)) { $this->_mismatchDescription->appendText('Not matched: ')->appendValue($item); return false; } return true; } private function _isMatched($item) { /** @var $matcher \Hamcrest\Matcher */ foreach ($this->_elementMatchers as $i => $matcher) { if ($matcher->matches($item)) { unset($this->_elementMatchers[$i]); return true; } } $this->_mismatchDescription->appendText('Not matched: ')->appendValue($item); return false; } } Arrays/IsArrayWithSize.php000064400000002715150524651160011571 0ustar00_elementMatchers = $elementMatchers; } protected function matchesSafely($array) { if (array_keys($array) != array_keys($this->_elementMatchers)) { return false; } /** @var $matcher \Hamcrest\Matcher */ foreach ($this->_elementMatchers as $k => $matcher) { if (!$matcher->matches($array[$k])) { return false; } } return true; } protected function describeMismatchSafely($actual, Description $mismatchDescription) { if (count($actual) != count($this->_elementMatchers)) { $mismatchDescription->appendText('array length was ' . count($actual)); return; } elseif (array_keys($actual) != array_keys($this->_elementMatchers)) { $mismatchDescription->appendText('array keys were ') ->appendValueList( $this->descriptionStart(), $this->descriptionSeparator(), $this->descriptionEnd(), array_keys($actual) ) ; return; } /** @var $matcher \Hamcrest\Matcher */ foreach ($this->_elementMatchers as $k => $matcher) { if (!$matcher->matches($actual[$k])) { $mismatchDescription->appendText('element ')->appendValue($k) ->appendText(' was ')->appendValue($actual[$k]); return; } } } public function describeTo(Description $description) { $description->appendList( $this->descriptionStart(), $this->descriptionSeparator(), $this->descriptionEnd(), $this->_elementMatchers ); } /** * Evaluates to true only if each $matcher[$i] is satisfied by $array[$i]. * * @factory ... */ public static function anArray(/* args... */) { $args = func_get_args(); return new self(Util::createMatcherArray($args)); } // -- Protected Methods protected function descriptionStart() { return '['; } protected function descriptionSeparator() { return ', '; } protected function descriptionEnd() { return ']'; } } Arrays/IsArrayContaining.php000064400000002731150524651160012112 0ustar00_elementMatcher = $elementMatcher; } protected function matchesSafely($array) { foreach ($array as $element) { if ($this->_elementMatcher->matches($element)) { return true; } } return false; } protected function describeMismatchSafely($array, Description $mismatchDescription) { $mismatchDescription->appendText('was ')->appendValue($array); } public function describeTo(Description $description) { $description ->appendText('an array containing ') ->appendDescriptionOf($this->_elementMatcher) ; } /** * Evaluates to true if any item in an array satisfies the given matcher. * * @param mixed $item as a {@link Hamcrest\Matcher} or a value. * * @return \Hamcrest\Arrays\IsArrayContaining * @factory hasValue */ public static function hasItemInArray($item) { return new self(Util::wrapValueWithIsEqual($item)); } } Arrays/SeriesMatchingOnce.php000064400000003454150524651160012243 0ustar00_elementMatchers = $elementMatchers; $this->_keys = array_keys($elementMatchers); $this->_mismatchDescription = $mismatchDescription; } public function matches($item) { return $this->_isNotSurplus($item) && $this->_isMatched($item); } public function isFinished() { if (!empty($this->_elementMatchers)) { $nextMatcher = current($this->_elementMatchers); $this->_mismatchDescription->appendText('No item matched: ')->appendDescriptionOf($nextMatcher); return false; } return true; } // -- Private Methods private function _isNotSurplus($item) { if (empty($this->_elementMatchers)) { $this->_mismatchDescription->appendText('Not matched: ')->appendValue($item); return false; } return true; } private function _isMatched($item) { $this->_nextMatchKey = array_shift($this->_keys); $nextMatcher = array_shift($this->_elementMatchers); if (!$nextMatcher->matches($item)) { $this->_describeMismatch($nextMatcher, $item); return false; } return true; } private function _describeMismatch(Matcher $matcher, $item) { $this->_mismatchDescription->appendText('item with key ' . $this->_nextMatchKey . ': '); $matcher->describeMismatch($item, $this->_mismatchDescription); } } Arrays/IsArrayContainingInAnyOrder.php000064400000002732150524651160014046 0ustar00_elementMatchers = $elementMatchers; } protected function matchesSafelyWithDiagnosticDescription($array, Description $mismatchDescription) { $matching = new MatchingOnce($this->_elementMatchers, $mismatchDescription); foreach ($array as $element) { if (!$matching->matches($element)) { return false; } } return $matching->isFinished($array); } public function describeTo(Description $description) { $description->appendList('[', ', ', ']', $this->_elementMatchers) ->appendText(' in any order') ; } /** * An array with elements that match the given matchers. * * @factory containsInAnyOrder ... */ public static function arrayContainingInAnyOrder(/* args... */) { $args = func_get_args(); return new self(Util::createMatcherArray($args)); } } Arrays/IsArrayContainingKey.php000064400000003654150524651160012570 0ustar00_keyMatcher = $keyMatcher; } protected function matchesSafely($array) { foreach ($array as $key => $element) { if ($this->_keyMatcher->matches($key)) { return true; } } return false; } protected function describeMismatchSafely($array, Description $mismatchDescription) { //Not using appendValueList() so that keys can be shown $mismatchDescription->appendText('array was ') ->appendText('[') ; $loop = false; foreach ($array as $key => $value) { if ($loop) { $mismatchDescription->appendText(', '); } $mismatchDescription->appendValue($key)->appendText(' => ')->appendValue($value); $loop = true; } $mismatchDescription->appendText(']'); } public function describeTo(Description $description) { $description ->appendText('array with key ') ->appendDescriptionOf($this->_keyMatcher) ; } /** * Evaluates to true if any key in an array matches the given matcher. * * @param mixed $key as a {@link Hamcrest\Matcher} or a value. * * @return \Hamcrest\Arrays\IsArrayContainingKey * @factory hasKey */ public static function hasKeyInArray($key) { return new self(Util::wrapValueWithIsEqual($key)); } } Arrays/IsArrayContainingInOrder.php000064400000002560150524651160013375 0ustar00_elementMatchers = $elementMatchers; } protected function matchesSafelyWithDiagnosticDescription($array, Description $mismatchDescription) { $series = new SeriesMatchingOnce($this->_elementMatchers, $mismatchDescription); foreach ($array as $element) { if (!$series->matches($element)) { return false; } } return $series->isFinished(); } public function describeTo(Description $description) { $description->appendList('[', ', ', ']', $this->_elementMatchers); } /** * An array with elements that match the given matchers in the same order. * * @factory contains ... */ public static function arrayContaining(/* args... */) { $args = func_get_args(); return new self(Util::createMatcherArray($args)); } } BaseDescription.php000064400000006153150524651160010345 0ustar00append($text); return $this; } public function appendDescriptionOf(SelfDescribing $value) { $value->describeTo($this); return $this; } public function appendValue($value) { if (is_null($value)) { $this->append('null'); } elseif (is_string($value)) { $this->_toPhpSyntax($value); } elseif (is_float($value)) { $this->append('<'); $this->append($value); $this->append('F>'); } elseif (is_bool($value)) { $this->append('<'); $this->append($value ? 'true' : 'false'); $this->append('>'); } elseif (is_array($value) || $value instanceof \Iterator || $value instanceof \IteratorAggregate) { $this->appendValueList('[', ', ', ']', $value); } elseif (is_object($value) && !method_exists($value, '__toString')) { $this->append('<'); $this->append(get_class($value)); $this->append('>'); } else { $this->append('<'); $this->append($value); $this->append('>'); } return $this; } public function appendValueList($start, $separator, $end, $values) { $list = array(); foreach ($values as $v) { $list[] = new SelfDescribingValue($v); } $this->appendList($start, $separator, $end, $list); return $this; } public function appendList($start, $separator, $end, $values) { $this->append($start); $separate = false; foreach ($values as $value) { /*if (!($value instanceof Hamcrest\SelfDescribing)) { $value = new Hamcrest\Internal\SelfDescribingValue($value); }*/ if ($separate) { $this->append($separator); } $this->appendDescriptionOf($value); $separate = true; } $this->append($end); return $this; } // -- Protected Methods /** * Append the String $str to the description. */ abstract protected function append($str); // -- Private Methods private function _toPhpSyntax($value) { $str = '"'; for ($i = 0, $len = strlen($value); $i < $len; ++$i) { switch ($value[$i]) { case '"': $str .= '\\"'; break; case "\t": $str .= '\\t'; break; case "\r": $str .= '\\r'; break; case "\n": $str .= '\\n'; break; default: $str .= $value[$i]; } } $str .= '"'; $this->append($str); } } Collection/IsTraversableWithSize.php000064400000001633150524651160013615 0ustar00_empty = $empty; } public function matches($item) { if (!$item instanceof \Traversable) { return false; } foreach ($item as $value) { return !$this->_empty; } return $this->_empty; } public function describeTo(Description $description) { $description->appendText($this->_empty ? 'an empty traversable' : 'a non-empty traversable'); } /** * Returns true if traversable is empty. * * @factory */ public static function emptyTraversable() { if (!self::$_INSTANCE) { self::$_INSTANCE = new self; } return self::$_INSTANCE; } /** * Returns true if traversable is not empty. * * @factory */ public static function nonEmptyTraversable() { if (!self::$_NOT_INSTANCE) { self::$_NOT_INSTANCE = new self(false); } return self::$_NOT_INSTANCE; } } Core/IsNot.php000064400000001472150524651160007212 0ustar00_matcher = $matcher; } public function matches($arg) { return !$this->_matcher->matches($arg); } public function describeTo(Description $description) { $description->appendText('not ')->appendDescriptionOf($this->_matcher); } /** * Matches if value does not match $value. * * @factory */ public static function not($value) { return new self(Util::wrapValueWithIsEqual($value)); } } Core/Every.php000064400000002472150524651160007251 0ustar00_matcher = $matcher; } protected function matchesSafelyWithDiagnosticDescription($items, Description $mismatchDescription) { foreach ($items as $item) { if (!$this->_matcher->matches($item)) { $mismatchDescription->appendText('an item '); $this->_matcher->describeMismatch($item, $mismatchDescription); return false; } } return true; } public function describeTo(Description $description) { $description->appendText('every item is ')->appendDescriptionOf($this->_matcher); } /** * @param Matcher $itemMatcher * A matcher to apply to every element in an array. * * @return \Hamcrest\Core\Every * Evaluates to TRUE for a collection in which every item matches $itemMatcher * * @factory */ public static function everyItem(Matcher $itemMatcher) { return new self($itemMatcher); } } Core/IsTypeOf.php000064400000003221150524651160007652 0ustar00_theType = strtolower($theType); } public function matches($item) { return strtolower(gettype($item)) == $this->_theType; } public function describeTo(Description $description) { $description->appendText(self::getTypeDescription($this->_theType)); } public function describeMismatch($item, Description $description) { if ($item === null) { $description->appendText('was null'); } else { $description->appendText('was ') ->appendText(self::getTypeDescription(strtolower(gettype($item)))) ->appendText(' ') ->appendValue($item) ; } } public static function getTypeDescription($type) { if ($type == 'null') { return 'null'; } return (strpos('aeiou', substr($type, 0, 1)) === false ? 'a ' : 'an ') . $type; } /** * Is the value a particular built-in type? * * @factory */ public static function typeOf($theType) { return new self($theType); } } Core/AnyOf.php000064400000002356150524651160007174 0ustar00true. */ class AnyOf extends ShortcutCombination { public function __construct(array $matchers) { parent::__construct($matchers); } public function matches($item) { return $this->matchesWithShortcut($item, true); } public function describeTo(Description $description) { $this->describeToWithOperator($description, 'or'); } /** * Evaluates to true if ANY of the passed in matchers evaluate to true. * * @factory ... */ public static function anyOf(/* args... */) { $args = func_get_args(); return new self(Util::createMatcherArray($args)); } /** * Evaluates to false if ANY of the passed in matchers evaluate to true. * * @factory ... */ public static function noneOf(/* args... */) { $args = func_get_args(); return IsNot::not( new self(Util::createMatcherArray($args)) ); } } Core/CombinableMatcher.php000064400000003365150524651160011520 0ustar00_matcher = $matcher; } public function matches($item) { return $this->_matcher->matches($item); } public function describeTo(Description $description) { $description->appendDescriptionOf($this->_matcher); } /** Diversion from Hamcrest-Java... Logical "and" not permitted */ public function andAlso(Matcher $other) { return new self(new AllOf($this->_templatedListWith($other))); } /** Diversion from Hamcrest-Java... Logical "or" not permitted */ public function orElse(Matcher $other) { return new self(new AnyOf($this->_templatedListWith($other))); } /** * This is useful for fluently combining matchers that must both pass. * For example: *

     *   assertThat($string, both(containsString("a"))->andAlso(containsString("b")));
     * 
* * @factory */ public static function both(Matcher $matcher) { return new self($matcher); } /** * This is useful for fluently combining matchers where either may pass, * for example: *
     *   assertThat($string, either(containsString("a"))->orElse(containsString("b")));
     * 
* * @factory */ public static function either(Matcher $matcher) { return new self($matcher); } // -- Private Methods private function _templatedListWith(Matcher $other) { return array($this->_matcher, $other); } } Core/IsEqual.php000064400000001503150524651160007514 0ustar00_item = $item; } public function matches($arg) { return (($arg == $this->_item) && ($this->_item == $arg)); } public function describeTo(Description $description) { $description->appendValue($this->_item); } /** * Is the value equal to another value, as tested by the use of the "==" * comparison operator? * * @factory */ public static function equalTo($item) { return new self($item); } } Core/IsCollectionContaining.php000064400000004154150524651160012557 0ustar00_elementMatcher = $elementMatcher; } protected function matchesSafely($items) { foreach ($items as $item) { if ($this->_elementMatcher->matches($item)) { return true; } } return false; } protected function describeMismatchSafely($items, Description $mismatchDescription) { $mismatchDescription->appendText('was ')->appendValue($items); } public function describeTo(Description $description) { $description ->appendText('a collection containing ') ->appendDescriptionOf($this->_elementMatcher) ; } /** * Test if the value is an array containing this matcher. * * Example: *
     * assertThat(array('a', 'b'), hasItem(equalTo('b')));
     * //Convenience defaults to equalTo()
     * assertThat(array('a', 'b'), hasItem('b'));
     * 
* * @factory ... */ public static function hasItem() { $args = func_get_args(); $firstArg = array_shift($args); return new self(Util::wrapValueWithIsEqual($firstArg)); } /** * Test if the value is an array containing elements that match all of these * matchers. * * Example: *
     * assertThat(array('a', 'b', 'c'), hasItems(equalTo('a'), equalTo('b')));
     * 
* * @factory ... */ public static function hasItems(/* args... */) { $args = func_get_args(); $matchers = array(); foreach ($args as $arg) { $matchers[] = self::hasItem($arg); } return AllOf::allOf($matchers); } } Core/HasToString.php000064400000002371150524651160010362 0ustar00toString(); } return (string) $actual; } /** * Does array size satisfy a given matcher? * * @factory */ public static function hasToString($matcher) { return new self(Util::wrapValueWithIsEqual($matcher)); } } Core/ShortcutCombination.php000064400000001630150524651160012150 0ustar00 */ private $_matchers; public function __construct(array $matchers) { Util::checkAllAreMatchers($matchers); $this->_matchers = $matchers; } protected function matchesWithShortcut($item, $shortcut) { /** @var $matcher \Hamcrest\Matcher */ foreach ($this->_matchers as $matcher) { if ($matcher->matches($item) == $shortcut) { return $shortcut; } } return !$shortcut; } public function describeToWithOperator(Description $description, $operator) { $description->appendList('(', ' ' . $operator . ' ', ')', $this->_matchers); } } Core/IsInstanceOf.php000064400000003250150524651160010477 0ustar00_theClass = $theClass; } protected function matchesWithDiagnosticDescription($item, Description $mismatchDescription) { if (!is_object($item)) { $mismatchDescription->appendText('was ')->appendValue($item); return false; } if (!($item instanceof $this->_theClass)) { $mismatchDescription->appendText('[' . get_class($item) . '] ') ->appendValue($item); return false; } return true; } public function describeTo(Description $description) { $description->appendText('an instance of ') ->appendText($this->_theClass) ; } /** * Is the value an instance of a particular type? * This version assumes no relationship between the required type and * the signature of the method that sets it up, for example in * assertThat($anObject, anInstanceOf('Thing')); * * @factory any */ public static function anInstanceOf($theClass) { return new self($theClass); } } Core/AllOf.php000064400000002654150524651160007156 0ustar00false. */ class AllOf extends DiagnosingMatcher { private $_matchers; public function __construct(array $matchers) { Util::checkAllAreMatchers($matchers); $this->_matchers = $matchers; } public function matchesWithDiagnosticDescription($item, Description $mismatchDescription) { /** @var $matcher \Hamcrest\Matcher */ foreach ($this->_matchers as $matcher) { if (!$matcher->matches($item)) { $mismatchDescription->appendDescriptionOf($matcher)->appendText(' '); $matcher->describeMismatch($item, $mismatchDescription); return false; } } return true; } public function describeTo(Description $description) { $description->appendList('(', ' and ', ')', $this->_matchers); } /** * Evaluates to true only if ALL of the passed in matchers evaluate to true. * * @factory ... */ public static function allOf(/* args... */) { $args = func_get_args(); return new self(Util::createMatcherArray($args)); } } Core/IsIdentical.php000064400000001304150524651160010340 0ustar00_value = $value; } public function describeTo(Description $description) { $description->appendValue($this->_value); } /** * Tests of the value is identical to $value as tested by the "===" operator. * * @factory */ public static function identicalTo($value) { return new self($value); } } Core/Is.php000064400000002513150524651160006526 0ustar00_matcher = $matcher; } public function matches($arg) { return $this->_matcher->matches($arg); } public function describeTo(Description $description) { $description->appendText('is ')->appendDescriptionOf($this->_matcher); } public function describeMismatch($item, Description $mismatchDescription) { $this->_matcher->describeMismatch($item, $mismatchDescription); } /** * Decorates another Matcher, retaining the behavior but allowing tests * to be slightly more expressive. * * For example: assertThat($cheese, equalTo($smelly)) * vs. assertThat($cheese, is(equalTo($smelly))) * * @factory */ public static function is($value) { return new self(Util::wrapValueWithIsEqual($value)); } } Core/Set.php000064400000004550150524651160006711 0ustar00 * assertThat(array('a', 'b'), set('b')); * assertThat($foo, set('bar')); * assertThat('Server', notSet('defaultPort')); * * * @todo Replace $property with a matcher and iterate all property names. */ class Set extends BaseMatcher { private $_property; private $_not; public function __construct($property, $not = false) { $this->_property = $property; $this->_not = $not; } public function matches($item) { if ($item === null) { return false; } $property = $this->_property; if (is_array($item)) { $result = isset($item[$property]); } elseif (is_object($item)) { $result = isset($item->$property); } elseif (is_string($item)) { $result = isset($item::$$property); } else { throw new \InvalidArgumentException('Must pass an object, array, or class name'); } return $this->_not ? !$result : $result; } public function describeTo(Description $description) { $description->appendText($this->_not ? 'unset property ' : 'set property ')->appendText($this->_property); } public function describeMismatch($item, Description $description) { $value = ''; if (!$this->_not) { $description->appendText('was not set'); } else { $property = $this->_property; if (is_array($item)) { $value = $item[$property]; } elseif (is_object($item)) { $value = $item->$property; } elseif (is_string($item)) { $value = $item::$$property; } parent::describeMismatch($value, $description); } } /** * Matches if value (class, object, or array) has named $property. * * @factory */ public static function set($property) { return new self($property); } /** * Matches if value (class, object, or array) does not have named $property. * * @factory */ public static function notSet($property) { return new self($property, true); } } Core/IsAnything.php000064400000001553150524651160010233 0ustar00true. */ class IsAnything extends BaseMatcher { private $_message; public function __construct($message = 'ANYTHING') { $this->_message = $message; } public function matches($item) { return true; } public function describeTo(Description $description) { $description->appendText($this->_message); } /** * This matcher always evaluates to true. * * @param string $description A meaningful string used when describing itself. * * @return \Hamcrest\Core\IsAnything * @factory */ public static function anything($description = 'ANYTHING') { return new self($description); } } Core/IsNull.php000064400000001720150524651160007360 0ustar00appendText('null'); } /** * Matches if value is null. * * @factory */ public static function nullValue() { if (!self::$_INSTANCE) { self::$_INSTANCE = new self(); } return self::$_INSTANCE; } /** * Matches if value is not null. * * @factory */ public static function notNullValue() { if (!self::$_NOT_INSTANCE) { self::$_NOT_INSTANCE = IsNot::not(self::nullValue()); } return self::$_NOT_INSTANCE; } } Core/IsSame.php000064400000002106150524651160007332 0ustar00_object = $object; } public function matches($object) { return ($object === $this->_object) && ($this->_object === $object); } public function describeTo(Description $description) { $description->appendText('sameInstance(') ->appendValue($this->_object) ->appendText(')') ; } /** * Creates a new instance of IsSame. * * @param mixed $object * The predicate evaluates to true only when the argument is * this object. * * @return \Hamcrest\Core\IsSame * @factory */ public static function sameInstance($object) { return new self($object); } } Core/DescribedAs.php000064400000003471150524651160010327 0ustar00_descriptionTemplate = $descriptionTemplate; $this->_matcher = $matcher; $this->_values = $values; } public function matches($item) { return $this->_matcher->matches($item); } public function describeTo(Description $description) { $textStart = 0; while (preg_match(self::ARG_PATTERN, $this->_descriptionTemplate, $matches, PREG_OFFSET_CAPTURE, $textStart)) { $text = $matches[0][0]; $index = $matches[1][0]; $offset = $matches[0][1]; $description->appendText(substr($this->_descriptionTemplate, $textStart, $offset - $textStart)); $description->appendValue($this->_values[$index]); $textStart = $offset + strlen($text); } if ($textStart < strlen($this->_descriptionTemplate)) { $description->appendText(substr($this->_descriptionTemplate, $textStart)); } } /** * Wraps an existing matcher and overrides the description when it fails. * * @factory ... */ public static function describedAs(/* $description, Hamcrest\Matcher $matcher, $values... */) { $args = func_get_args(); $description = array_shift($args); $matcher = array_shift($args); $values = $args; return new self($description, $matcher, $values); } } Number/OrderingComparison.php000064400000005545150524651160012327 0ustar00_value = $value; $this->_minCompare = $minCompare; $this->_maxCompare = $maxCompare; } protected function matchesSafely($other) { $compare = $this->_compare($this->_value, $other); return ($this->_minCompare <= $compare) && ($compare <= $this->_maxCompare); } protected function describeMismatchSafely($item, Description $mismatchDescription) { $mismatchDescription ->appendValue($item)->appendText(' was ') ->appendText($this->_comparison($this->_compare($this->_value, $item))) ->appendText(' ')->appendValue($this->_value) ; } public function describeTo(Description $description) { $description->appendText('a value ') ->appendText($this->_comparison($this->_minCompare)) ; if ($this->_minCompare != $this->_maxCompare) { $description->appendText(' or ') ->appendText($this->_comparison($this->_maxCompare)) ; } $description->appendText(' ')->appendValue($this->_value); } /** * The value is not > $value, nor < $value. * * @factory */ public static function comparesEqualTo($value) { return new self($value, 0, 0); } /** * The value is > $value. * * @factory */ public static function greaterThan($value) { return new self($value, -1, -1); } /** * The value is >= $value. * * @factory atLeast */ public static function greaterThanOrEqualTo($value) { return new self($value, -1, 0); } /** * The value is < $value. * * @factory */ public static function lessThan($value) { return new self($value, 1, 1); } /** * The value is <= $value. * * @factory atMost */ public static function lessThanOrEqualTo($value) { return new self($value, 0, 1); } // -- Private Methods private function _compare($left, $right) { $a = $left; $b = $right; if ($a < $b) { return -1; } elseif ($a == $b) { return 0; } else { return 1; } } private function _comparison($compare) { if ($compare > 0) { return 'less than'; } elseif ($compare == 0) { return 'equal to'; } else { return 'greater than'; } } } Number/IsCloseTo.php000064400000003233150524651160010357 0ustar00_value = $value; $this->_delta = $delta; } protected function matchesSafely($item) { return $this->_actualDelta($item) <= 0.0; } protected function describeMismatchSafely($item, Description $mismatchDescription) { $mismatchDescription->appendValue($item) ->appendText(' differed by ') ->appendValue($this->_actualDelta($item)) ; } public function describeTo(Description $description) { $description->appendText('a numeric value within ') ->appendValue($this->_delta) ->appendText(' of ') ->appendValue($this->_value) ; } /** * Matches if value is a number equal to $value within some range of * acceptable error $delta. * * @factory */ public static function closeTo($value, $delta) { return new self($value, $delta); } // -- Private Methods private function _actualDelta($item) { return (abs(($item - $this->_value)) - $this->_delta); } } TypeSafeMatcher.php000064400000005546150524651160010320 0ustar00_expectedType = $expectedType; $this->_expectedSubtype = $expectedSubtype; } final public function matches($item) { return $this->_isSafeType($item) && $this->matchesSafely($item); } final public function describeMismatch($item, Description $mismatchDescription) { if (!$this->_isSafeType($item)) { parent::describeMismatch($item, $mismatchDescription); } else { $this->describeMismatchSafely($item, $mismatchDescription); } } // -- Protected Methods /** * The item will already have been checked for the specific type and subtype. */ abstract protected function matchesSafely($item); /** * The item will already have been checked for the specific type and subtype. */ abstract protected function describeMismatchSafely($item, Description $mismatchDescription); // -- Private Methods private function _isSafeType($value) { switch ($this->_expectedType) { case self::TYPE_ANY: return true; case self::TYPE_STRING: return is_string($value) || is_numeric($value); case self::TYPE_NUMERIC: return is_numeric($value) || is_string($value); case self::TYPE_ARRAY: return is_array($value); case self::TYPE_OBJECT: return is_object($value) && ($this->_expectedSubtype === null || $value instanceof $this->_expectedSubtype); case self::TYPE_RESOURCE: return is_resource($value) && ($this->_expectedSubtype === null || get_resource_type($value) == $this->_expectedSubtype); case self::TYPE_BOOLEAN: return true; default: return true; } } } Internal/SelfDescribingValue.php000064400000000742150524651160012721 0ustar00_value = $value; } public function describeTo(Description $description) { $description->appendValue($this->_value); } } SelfDescribing.php000064400000001027150524651160010145 0ustar00matchesWithDiagnosticDescription($item, new NullDescription()); } public function describeMismatch($item, Description $mismatchDescription) { $this->matchesWithDiagnosticDescription($item, $mismatchDescription); } abstract protected function matchesWithDiagnosticDescription($item, Description $mismatchDescription); } MatcherAssert.php000064400000006473150524651160010041 0ustar00 * // With an identifier * assertThat("apple flavour", $apple->flavour(), equalTo("tasty")); * // Without an identifier * assertThat($apple->flavour(), equalTo("tasty")); * // Evaluating a boolean expression * assertThat("some error", $a > $b); * assertThat($a > $b); * */ public static function assertThat(/* $args ... */) { $args = func_get_args(); switch (count($args)) { case 1: self::$_count++; if (!$args[0]) { throw new AssertionError(); } break; case 2: self::$_count++; if ($args[1] instanceof Matcher) { self::doAssert('', $args[0], $args[1]); } elseif (!$args[1]) { throw new AssertionError($args[0]); } break; case 3: self::$_count++; self::doAssert( $args[0], $args[1], Util::wrapValueWithIsEqual($args[2]) ); break; default: throw new \InvalidArgumentException('assertThat() requires one to three arguments'); } } /** * Returns the number of assertions performed. * * @return int */ public static function getCount() { return self::$_count; } /** * Resets the number of assertions performed to zero. */ public static function resetCount() { self::$_count = 0; } /** * Performs the actual assertion logic. * * If $matcher doesn't match $actual, * throws a {@link Hamcrest\AssertionError} with a description * of the failure along with the optional $identifier. * * @param string $identifier added to the message upon failure * @param mixed $actual value to compare against $matcher * @param \Hamcrest\Matcher $matcher applied to $actual * @throws AssertionError */ private static function doAssert($identifier, $actual, Matcher $matcher) { if (!$matcher->matches($actual)) { $description = new StringDescription(); if (!empty($identifier)) { $description->appendText($identifier . PHP_EOL); } $description->appendText('Expected: ') ->appendDescriptionOf($matcher) ->appendText(PHP_EOL . ' but: '); $matcher->describeMismatch($actual, $description); throw new AssertionError((string) $description); } } } Matchers.php000064400000045021150524651160007032 0ustar00 * assertThat($string, both(containsString("a"))->andAlso(containsString("b"))); * */ public static function both(\Hamcrest\Matcher $matcher) { return \Hamcrest\Core\CombinableMatcher::both($matcher); } /** * This is useful for fluently combining matchers where either may pass, * for example: *
     *   assertThat($string, either(containsString("a"))->orElse(containsString("b")));
     * 
*/ public static function either(\Hamcrest\Matcher $matcher) { return \Hamcrest\Core\CombinableMatcher::either($matcher); } /** * Wraps an existing matcher and overrides the description when it fails. */ public static function describedAs(/* args... */) { $args = func_get_args(); return call_user_func_array(array('\Hamcrest\Core\DescribedAs', 'describedAs'), $args); } /** * @param Matcher $itemMatcher * A matcher to apply to every element in an array. * * @return \Hamcrest\Core\Every * Evaluates to TRUE for a collection in which every item matches $itemMatcher */ public static function everyItem(\Hamcrest\Matcher $itemMatcher) { return \Hamcrest\Core\Every::everyItem($itemMatcher); } /** * Does array size satisfy a given matcher? */ public static function hasToString($matcher) { return \Hamcrest\Core\HasToString::hasToString($matcher); } /** * Decorates another Matcher, retaining the behavior but allowing tests * to be slightly more expressive. * * For example: assertThat($cheese, equalTo($smelly)) * vs. assertThat($cheese, is(equalTo($smelly))) */ public static function is($value) { return \Hamcrest\Core\Is::is($value); } /** * This matcher always evaluates to true. * * @param string $description A meaningful string used when describing itself. * * @return \Hamcrest\Core\IsAnything */ public static function anything($description = 'ANYTHING') { return \Hamcrest\Core\IsAnything::anything($description); } /** * Test if the value is an array containing this matcher. * * Example: *
     * assertThat(array('a', 'b'), hasItem(equalTo('b')));
     * //Convenience defaults to equalTo()
     * assertThat(array('a', 'b'), hasItem('b'));
     * 
*/ public static function hasItem(/* args... */) { $args = func_get_args(); return call_user_func_array(array('\Hamcrest\Core\IsCollectionContaining', 'hasItem'), $args); } /** * Test if the value is an array containing elements that match all of these * matchers. * * Example: *
     * assertThat(array('a', 'b', 'c'), hasItems(equalTo('a'), equalTo('b')));
     * 
*/ public static function hasItems(/* args... */) { $args = func_get_args(); return call_user_func_array(array('\Hamcrest\Core\IsCollectionContaining', 'hasItems'), $args); } /** * Is the value equal to another value, as tested by the use of the "==" * comparison operator? */ public static function equalTo($item) { return \Hamcrest\Core\IsEqual::equalTo($item); } /** * Tests of the value is identical to $value as tested by the "===" operator. */ public static function identicalTo($value) { return \Hamcrest\Core\IsIdentical::identicalTo($value); } /** * Is the value an instance of a particular type? * This version assumes no relationship between the required type and * the signature of the method that sets it up, for example in * assertThat($anObject, anInstanceOf('Thing')); */ public static function anInstanceOf($theClass) { return \Hamcrest\Core\IsInstanceOf::anInstanceOf($theClass); } /** * Is the value an instance of a particular type? * This version assumes no relationship between the required type and * the signature of the method that sets it up, for example in * assertThat($anObject, anInstanceOf('Thing')); */ public static function any($theClass) { return \Hamcrest\Core\IsInstanceOf::anInstanceOf($theClass); } /** * Matches if value does not match $value. */ public static function not($value) { return \Hamcrest\Core\IsNot::not($value); } /** * Matches if value is null. */ public static function nullValue() { return \Hamcrest\Core\IsNull::nullValue(); } /** * Matches if value is not null. */ public static function notNullValue() { return \Hamcrest\Core\IsNull::notNullValue(); } /** * Creates a new instance of IsSame. * * @param mixed $object * The predicate evaluates to true only when the argument is * this object. * * @return \Hamcrest\Core\IsSame */ public static function sameInstance($object) { return \Hamcrest\Core\IsSame::sameInstance($object); } /** * Is the value a particular built-in type? */ public static function typeOf($theType) { return \Hamcrest\Core\IsTypeOf::typeOf($theType); } /** * Matches if value (class, object, or array) has named $property. */ public static function set($property) { return \Hamcrest\Core\Set::set($property); } /** * Matches if value (class, object, or array) does not have named $property. */ public static function notSet($property) { return \Hamcrest\Core\Set::notSet($property); } /** * Matches if value is a number equal to $value within some range of * acceptable error $delta. */ public static function closeTo($value, $delta) { return \Hamcrest\Number\IsCloseTo::closeTo($value, $delta); } /** * The value is not > $value, nor < $value. */ public static function comparesEqualTo($value) { return \Hamcrest\Number\OrderingComparison::comparesEqualTo($value); } /** * The value is > $value. */ public static function greaterThan($value) { return \Hamcrest\Number\OrderingComparison::greaterThan($value); } /** * The value is >= $value. */ public static function greaterThanOrEqualTo($value) { return \Hamcrest\Number\OrderingComparison::greaterThanOrEqualTo($value); } /** * The value is >= $value. */ public static function atLeast($value) { return \Hamcrest\Number\OrderingComparison::greaterThanOrEqualTo($value); } /** * The value is < $value. */ public static function lessThan($value) { return \Hamcrest\Number\OrderingComparison::lessThan($value); } /** * The value is <= $value. */ public static function lessThanOrEqualTo($value) { return \Hamcrest\Number\OrderingComparison::lessThanOrEqualTo($value); } /** * The value is <= $value. */ public static function atMost($value) { return \Hamcrest\Number\OrderingComparison::lessThanOrEqualTo($value); } /** * Matches if value is a zero-length string. */ public static function isEmptyString() { return \Hamcrest\Text\IsEmptyString::isEmptyString(); } /** * Matches if value is a zero-length string. */ public static function emptyString() { return \Hamcrest\Text\IsEmptyString::isEmptyString(); } /** * Matches if value is null or a zero-length string. */ public static function isEmptyOrNullString() { return \Hamcrest\Text\IsEmptyString::isEmptyOrNullString(); } /** * Matches if value is null or a zero-length string. */ public static function nullOrEmptyString() { return \Hamcrest\Text\IsEmptyString::isEmptyOrNullString(); } /** * Matches if value is a non-zero-length string. */ public static function isNonEmptyString() { return \Hamcrest\Text\IsEmptyString::isNonEmptyString(); } /** * Matches if value is a non-zero-length string. */ public static function nonEmptyString() { return \Hamcrest\Text\IsEmptyString::isNonEmptyString(); } /** * Matches if value is a string equal to $string, regardless of the case. */ public static function equalToIgnoringCase($string) { return \Hamcrest\Text\IsEqualIgnoringCase::equalToIgnoringCase($string); } /** * Matches if value is a string equal to $string, regardless of whitespace. */ public static function equalToIgnoringWhiteSpace($string) { return \Hamcrest\Text\IsEqualIgnoringWhiteSpace::equalToIgnoringWhiteSpace($string); } /** * Matches if value is a string that matches regular expression $pattern. */ public static function matchesPattern($pattern) { return \Hamcrest\Text\MatchesPattern::matchesPattern($pattern); } /** * Matches if value is a string that contains $substring. */ public static function containsString($substring) { return \Hamcrest\Text\StringContains::containsString($substring); } /** * Matches if value is a string that contains $substring regardless of the case. */ public static function containsStringIgnoringCase($substring) { return \Hamcrest\Text\StringContainsIgnoringCase::containsStringIgnoringCase($substring); } /** * Matches if value contains $substrings in a constrained order. */ public static function stringContainsInOrder(/* args... */) { $args = func_get_args(); return call_user_func_array(array('\Hamcrest\Text\StringContainsInOrder', 'stringContainsInOrder'), $args); } /** * Matches if value is a string that ends with $substring. */ public static function endsWith($substring) { return \Hamcrest\Text\StringEndsWith::endsWith($substring); } /** * Matches if value is a string that starts with $substring. */ public static function startsWith($substring) { return \Hamcrest\Text\StringStartsWith::startsWith($substring); } /** * Is the value an array? */ public static function arrayValue() { return \Hamcrest\Type\IsArray::arrayValue(); } /** * Is the value a boolean? */ public static function booleanValue() { return \Hamcrest\Type\IsBoolean::booleanValue(); } /** * Is the value a boolean? */ public static function boolValue() { return \Hamcrest\Type\IsBoolean::booleanValue(); } /** * Is the value callable? */ public static function callableValue() { return \Hamcrest\Type\IsCallable::callableValue(); } /** * Is the value a float/double? */ public static function doubleValue() { return \Hamcrest\Type\IsDouble::doubleValue(); } /** * Is the value a float/double? */ public static function floatValue() { return \Hamcrest\Type\IsDouble::doubleValue(); } /** * Is the value an integer? */ public static function integerValue() { return \Hamcrest\Type\IsInteger::integerValue(); } /** * Is the value an integer? */ public static function intValue() { return \Hamcrest\Type\IsInteger::integerValue(); } /** * Is the value a numeric? */ public static function numericValue() { return \Hamcrest\Type\IsNumeric::numericValue(); } /** * Is the value an object? */ public static function objectValue() { return \Hamcrest\Type\IsObject::objectValue(); } /** * Is the value an object? */ public static function anObject() { return \Hamcrest\Type\IsObject::objectValue(); } /** * Is the value a resource? */ public static function resourceValue() { return \Hamcrest\Type\IsResource::resourceValue(); } /** * Is the value a scalar (boolean, integer, double, or string)? */ public static function scalarValue() { return \Hamcrest\Type\IsScalar::scalarValue(); } /** * Is the value a string? */ public static function stringValue() { return \Hamcrest\Type\IsString::stringValue(); } /** * Wraps $matcher with {@link Hamcrest\Core\IsEqual) * if it's not a matcher and the XPath in count() * if it's an integer. */ public static function hasXPath($xpath, $matcher = null) { return \Hamcrest\Xml\HasXPath::hasXPath($xpath, $matcher); } }