[
  {
    "path": ".coveralls.yml",
    "content": "src_dir: hamcrest\n"
  },
  {
    "path": ".gitattributes",
    "content": "/.coveralls.yml export-ignore\r\n/.gush.yml export-ignore\r\n/.travis.yml export-ignore\r\n/.github export-ignore\r\n/tests export-ignore\r\n\r\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: ci\n\non:\n  push:\n  pull_request:\n\njobs:\n  static_analysis:\n    name: Static analysis\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: '8.0'\n          extensions: curl\n          tools: composer:v2\n          coverage: none\n\n      - name: Install PHP dependencies\n        run: composer update --prefer-dist --no-interaction --no-progress\n\n      - name: Run PHPStan\n        run: vendor/bin/phpstan analyze\n\n  tests:\n    name: Tests ${{ matrix.php }}\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        php:\n          - '7.4'\n          - '8.0'\n          - '8.1'\n          - '8.2'\n          - '8.3'\n          - '8.4'\n          - '8.5'\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: ${{ matrix.php }}\n          extensions: curl\n          tools: composer:v2\n          coverage: none\n\n      - name: Install PHP dependencies\n        run: composer update --prefer-dist --no-interaction --no-progress\n\n      - name: Execute tests\n        run: vendor/bin/phpunit -c tests/phpunit.xml.dist\n"
  },
  {
    "path": ".gitignore",
    "content": "composer.lock\ntests/.phpunit.result.cache\ntests/phpunit.xml\nvendor\n"
  },
  {
    "path": ".gush.yml",
    "content": "adapter: github\nissue_tracker: github\nmeta-header: \"Copyright (c) 2009-2015 hamcrest.org\"\ntable-pr:\n    fixed_tickets: ['Fixed Tickets', '']\n    license: ['License', MIT]\nbase: master\n"
  },
  {
    "path": "CHANGES.txt",
    "content": "== Version 2.1.1: Released Apr 30 2025 ==\n\n* Fix implicitly nullable via default value null for PHP 8.4 (#85)\n\n== Version 2.1.0: Released Apr 29 2025 ==\n\n* Dropped support for PHP <=7.3\n\n== Version 2.0.1: Released Jul 09 2020 ==\n\n* Added support for PHP 8\n\n\n== Version 2.0: Released Feb 26 2016 ==\n\n* Removed automatic loading of global functions\n\n\n== Version 1.1.0: Released Feb 2 2012 ==\n\nIssues Fixed: 121, 138, 147\n\n* Added non-empty matchers to complement the emptiness-matching forms.\n\n  - nonEmptyString()\n  - nonEmptyArray()\n  - nonEmptyTraversable()\n\n* Added ability to pass variable arguments to several array-based matcher\n  factory methods so they work like allOf() et al.\n\n  - anArray()\n  - arrayContainingInAnyOrder(), containsInAnyOrder()\n  - arrayContaining(), contains()\n  - stringContainsInOrder()\n\n* Matchers that accept an array of matchers now also accept variable arguments.\n  Any non-matcher arguments are wrapped by IsEqual.\n\n* Added noneOf() as a shortcut for not(anyOf()).\n\n\n== Version 1.0.0: Released Jan 20 2012 ==\n\nIssues Fixed: 119, 136, 139, 141, 148, 149, 172\n\n* Moved hamcrest.php into Hamcrest folder and renamed to Hamcrest.php.\n  This is more in line with PEAR packaging standards.\n\n* Renamed callable() to callableValue() for compatibility with PHP 5.4.\n\n* Added Hamcrest_Text_StringContainsIgnoringCase to assert using stripos().\n\n    assertThat('fOObAr', containsStringIgnoringCase('oba'));\n    assertThat('fOObAr', containsString('oba')->ignoringCase());\n\n* Fixed Hamcrest_Core_IsInstanceOf to return false for native types.\n\n* Moved string-based matchers to Hamcrest_Text package.\n  StringContains, StringEndsWith, StringStartsWith, and SubstringMatcher\n\n* Hamcrest.php and Hamcrest_Matchers.php are now built from @factory doctags.\n  Added @factory doctag to every static factory method.\n\n* Hamcrest_Matchers and Hamcrest.php now import each matcher as-needed\n  and Hamcrest.php calls the matchers directly instead of Hamcrest_Matchers.\n\n\n== Version 0.3.0: Released Jul 26 2010 ==\n\n* Added running count to Hamcrest_MatcherAssert with methods to get and reset it.\n  This can be used by unit testing frameworks for reporting.\n\n* Added Hamcrest_Core_HasToString to assert return value of toString() or __toString().\n\n    assertThat($anObject, hasToString('foo'));\n\n* Added Hamcrest_Type_IsScalar to assert is_scalar().\n  Matches values of type bool, int, float, double, and string.\n\n    assertThat($count, scalarValue());\n    assertThat('foo', scalarValue());\n\n* Added Hamcrest_Collection package.\n\n  - IsEmptyTraversable\n  - IsTraversableWithSize\n\n    assertThat($iterator, emptyTraversable());\n    assertThat($iterator, traversableWithSize(5));\n\n* Added Hamcrest_Xml_HasXPath to assert XPath expressions or the content of nodes in an XML/HTML DOM.\n\n    assertThat($dom, hasXPath('books/book/title'));\n    assertThat($dom, hasXPath('books/book[contains(title, \"Alice\")]', 3));\n    assertThat($dom, hasXPath('books/book/title', 'Alice in Wonderland'));\n    assertThat($dom, hasXPath('count(books/book)', greaterThan(10)));\n\n* Added aliases to match the Java API.\n\n    hasEntry() -> hasKeyValuePair()\n    hasValue() -> hasItemInArray()\n    contains() -> arrayContaining()\n    containsInAnyOrder() -> arrayContainingInAnyOrder()\n\n* Added optional subtype to Hamcrest_TypeSafeMatcher to enforce object class or resource type.\n\n* Hamcrest_TypeSafeDiagnosingMatcher now extends Hamcrest_TypeSafeMatcher.\n\n\n== Version 0.2.0: Released Jul 14 2010 ==\n\nIssues Fixed: 109, 111, 114, 115\n\n* Description::appendValues() and appendValueList() accept Iterator and IteratorAggregate. [111]\n  BaseDescription::appendValue() handles IteratorAggregate.\n\n* assertThat() accepts a single boolean parameter and\n  wraps any non-Matcher third parameter with equalTo().\n\n* Removed null return value from assertThat(). [114]\n\n* Fixed wrong variable name in contains(). [109]\n\n* Added Hamcrest_Core_IsSet to assert isset().\n\n    assertThat(array('foo' => 'bar'), set('foo'));\n    assertThat(array('foo' => 'bar'), notSet('bar'));\n\n* Added Hamcrest_Core_IsTypeOf to assert built-in types with gettype(). [115]\n  Types: array, boolean, double, integer, null, object, resource, and string.\n  Note that gettype() returns \"double\" for float values.\n\n    assertThat($count, typeOf('integer'));\n    assertThat(3.14159, typeOf('double'));\n    assertThat(array('foo', 'bar'), typeOf('array'));\n    assertThat(new stdClass(), typeOf('object'));\n\n* Added type-specific matchers in new Hamcrest_Type package.\n\n  - IsArray\n  - IsBoolean\n  - IsDouble (includes float values)\n  - IsInteger\n  - IsObject\n  - IsResource\n  - IsString\n\n    assertThat($count, integerValue());\n    assertThat(3.14159, floatValue());\n    assertThat('foo', stringValue());\n\n* Added Hamcrest_Type_IsNumeric to assert is_numeric().\n  Matches values of type int and float/double or strings that are formatted as numbers.\n\n    assertThat(5, numericValue());\n    assertThat('-5e+3', numericValue());\n\n* Added Hamcrest_Type_IsCallable to assert is_callable().\n\n    assertThat('preg_match', callable());\n    assertThat(array('SomeClass', 'SomeMethod'), callable());\n    assertThat(array($object, 'SomeMethod'), callable());\n    assertThat($object, callable());\n    assertThat(function ($x, $y) { return $x + $y; }, callable());\n\n* Added Hamcrest_Text_MatchesPattern for regex matching with preg_match().\n\n    assertThat('foobar', matchesPattern('/o+b/'));\n\n* Added aliases:\n  - atLeast() for greaterThanOrEqualTo()\n  - atMost() for lessThanOrEqualTo()\n\n\n== Version 0.1.0: Released Jul 7 2010 ==\n\n* Created PEAR package\n\n* Core matchers\n\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\nhamcrest-php is an open source, community-driven project. If you'd like to contribute, feel free to do this, but remember to follow these few simple rules:\n\n## Asking Questions\nFeel free to ask any questions and share your experiences in the [Issue tracking system](https://github.com/hamcrest/hamcrest-php/issues/) and help to improve the documentation.\n\n## Submitting an issues\n- A reproducible example is required for every bug report, otherwise it will most probably be __closed without warning__.\n- If you are going to make a big, substantial change, let's discuss it first.\n\n## Working with Pull Requests\n1. Create your feature addition or a bug fix branch based on __`master`__ branch in your repository's fork.\n2. Make necessary changes, but __don't mix__ code reformatting with code changes on topic.\n3. Add tests for those changes (please look into `tests/` folder for some examples). This is important so we don't break it in a future version unintentionally.\n4. Check your code using \"Coding Standard\" (see below).\n5. Commit your code.\n6. Squash your commits by topic to preserve a clean and readable log.\n7. Create Pull Request.\n\n## Running the Tests\n\n### Installation/Configuration\n\n1. Using `git clone https://github.com/hamcrest/hamcrest-php` to clone this repository.\n2. Using the `composer update` to update the dependencies to support your development environment.\n3. Using `vendor/bin/phpunit -c tests/phpunit.xml.dist` command to do unit test works.\n\n## Contributor Code of Conduct\n\nPlease note that this project is released with a [Contributor Code of\nConduct](http://contributor-covenant.org/). By participating in this project\nyou agree to abide by its terms. See [CODE_OF_CONDUCT](CODE_OF_CONDUCT.md) file.\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "BSD License\n\nCopyright (c) 2000-2025, www.hamcrest.org\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\nRedistributions of source code must retain the above copyright notice, this list of\nconditions and the following disclaimer. Redistributions in binary form must reproduce\nthe above copyright notice, this list of conditions and the following disclaimer in\nthe documentation and/or other materials provided with the distribution.\n\nNeither the name of Hamcrest nor the names of its contributors may be used to endorse\nor promote products derived from this software without specific prior written\npermission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\nSHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\nBUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY\nWAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGE.\n"
  },
  {
    "path": "README.md",
    "content": "This is the PHP port of Hamcrest Matchers\n=========================================\n\n[![tests](https://github.com/hamcrest/hamcrest-php/actions/workflows/ci.yml/badge.svg)](https://github.com/hamcrest/hamcrest-php/actions/workflows/ci.yml)\n\nHamcrest is a matching library originally written for Java, but\nsubsequently ported to many other languages.  hamcrest-php is the\nofficial PHP port of Hamcrest and essentially follows a literal\ntranslation of the original Java API for Hamcrest, with a few\nExceptions, mostly down to PHP language barriers:\n\n  1. `instanceOf($theClass)` is actually `anInstanceOf($theClass)`\n\n  2. `both(containsString('a'))->and(containsString('b'))`\n     is actually `both(containsString('a'))->andAlso(containsString('b'))`\n\n  3. `either(containsString('a'))->or(containsString('b'))`\n     is actually `either(containsString('a'))->orElse(containsString('b'))`\n\n  4. Unless it would be non-semantic for a matcher to do so, hamcrest-php\n     allows dynamic typing for it's input, in \"the PHP way\". Exception are\n     where semantics surrounding the type itself would suggest otherwise,\n     such as stringContains() and greaterThan().\n\n  5. Several official matchers have not been ported because they don't\n     make sense or don't apply in PHP:\n\n       - `typeCompatibleWith($theClass)`\n       - `eventFrom($source)`\n       - `hasProperty($name)` **\n       - `samePropertyValuesAs($obj)` **\n\n  6. When most of the collections matchers are finally ported, PHP-specific\n     aliases will probably be created due to a difference in naming\n     conventions between Java's Arrays, Collections, Sets and Maps compared\n     with PHP's Arrays.\n\n---\n** [Unless we consider POPO's (Plain Old PHP Objects) akin to JavaBeans]\n     - The POPO thing is a joke.  Java devs coin the term POJO's (Plain Old\n       Java Objects).\n\n\nUsage\n-----\n\nHamcrest matchers are easy to use as:\n\n```php\n\\Hamcrest\\MatcherAssert::assertThat('a', \\Hamcrest\\Matchers::equalToIgnoringCase('A'));\n```\n\nAlternatively, you can use the global proxy-functions:\n\n```php\n$result = true;\n// with an identifier\nassertThat(\"result should be true\", $result, equalTo(true));\n\n// without an identifier\nassertThat($result, equalTo(true));\n\n// evaluate a boolean expression\nassertThat($result === true);\n\n// with syntactic sugar is()\nassertThat(true, is(true));\n```\n\n> [!NOTE]\n> To prevent tests from being marked as Risky (the `This test did not perform any assertions` message)\n> add this code to your test case `tearDown` method:\n>\n> ```php\n> $this->addToAssertionCount(\\Hamcrest\\MatcherAssert::getCount());\n> \\Hamcrest\\MatcherAssert::resetCount();\n> ```\n\n> [!WARNING]\n> the global proxy-functions aren't autoloaded by default, so you will need to load them first:\n>\n> ```php\n> \\Hamcrest\\Util::registerGlobalFunctions();\n> ```\n\nFor brevity, all of the examples below use the proxy-functions.\n\n\nDocumentation\n-------------\nA tutorial can be found on the [Hamcrest site](https://code.google.com/archive/p/hamcrest/wikis/TutorialPHP.wiki).\n\n\nAvailable Matchers\n------------------\n* [Array](../master/README.md#array)\n* [Collection](../master/README.md#collection)\n* [Object](../master/README.md#object)\n* [Numbers](../master/README.md#numbers)\n* [Type checking](../master/README.md#type-checking)\n* [XML](../master/README.md#xml)\n\n\n### Array\n\n* `anArray` - evaluates an array\n```php\nassertThat([], anArray());\n```\n\n* `hasItemInArray` - check if item exists in array\n```php\n$list = range(2, 7, 2);\n$item = 4;\nassertThat($list, hasItemInArray($item));\n```\n\n* `hasValue` - alias of hasItemInArray\n\n* `arrayContainingInAnyOrder` - check if array contains elements in any order\n```php\nassertThat([2, 4, 6], arrayContainingInAnyOrder([6, 4, 2]));\nassertThat([2, 4, 6], arrayContainingInAnyOrder([4, 2, 6]));\n```\n\n* `containsInAnyOrder` - alias of arrayContainingInAnyOrder\n\n* `arrayContaining` - An array with elements that match the given matchers in the same order.\n```php\nassertThat([2, 4, 6], arrayContaining([2, 4, 6]));\nassertthat([2, 4, 6], not(arrayContaining([6, 4, 2])));\n```\n\n* `contains` - check array in same order\n```php\nassertThat([2, 4, 6], contains([2, 4, 6]));\n```\n\n* `hasKeyInArray` - check if array has given key\n```php\nassertThat(['name'=> 'foobar'], hasKeyInArray('name'));\n```\n\n* `hasKey` - alias of hasKeyInArray\n\n* `hasKeyValuePair` - check if array has given key, value pair\n```php\nassertThat(['name'=> 'foobar'], hasKeyValuePair('name', 'foobar'));\n```\n* `hasEntry` - same as hasKeyValuePair\n\n* `arrayWithSize` - check array has given size\n```php\nassertthat([2, 4, 6], arrayWithSize(3));\n```\n* `emptyArray` - check if array is empty\n```php\nassertThat([], emptyArray());\n```\n\n* `nonEmptyArray`\n```php\nassertThat([1], nonEmptyArray());\n```\n\n### Collection\n\n* `emptyTraversable` - check if traversable is empty\n```php\n$empty_it = new EmptyIterator;\nassertThat($empty_it, emptyTraversable());\n```\n\n* `nonEmptyTraversable` - check if traversable isn't empty\n```php\n$non_empty_it = new ArrayIterator(range(1, 10));\nassertThat($non_empty_it, nonEmptyTraversable());\na\n```\n\n* `traversableWithSize`\n```php\n$non_empty_it = new ArrayIterator(range(1, 10));\nassertThat($non_empty_it, traversableWithSize(count(range(1, 10))));\n`\n```\n\n### Core\n\n* `allOf` - Evaluates to true only if ALL of the passed in matchers evaluate to true.\n```php\nassertThat([2,4,6], allOf(hasValue(2), arrayWithSize(3)));\n```\n\n* `anyOf` - Evaluates to true if ANY of the passed in matchers evaluate to true.\n```php\nassertThat([2, 4, 6], anyOf(hasValue(8), hasValue(2)));\n```\n\n* `noneOf` - Evaluates to false if ANY of the passed in matchers evaluate to true.\n```php\nassertThat([2, 4, 6], noneOf(hasValue(1), hasValue(3)));\n```\n\n* `both` + `andAlso` - This is useful for fluently combining matchers that must both pass.\n```php\nassertThat([2, 4, 6], both(hasValue(2))->andAlso(hasValue(4)));\n```\n\n* `either` + `orElse` - This is useful for fluently combining matchers where either may pass,\n```php\nassertThat([2, 4, 6], either(hasValue(2))->orElse(hasValue(4)));\n```\n\n* `describedAs` - Wraps an existing matcher and overrides the description when it fails.\n```php \n$expected = \"Dog\";\n$found = null;\n// this assertion would result error message as Expected: is not null but: was null\n//assertThat(\"Expected {$expected}, got {$found}\", $found, is(notNullValue()));\n// and this assertion would result error message as Expected: Dog but: was null\n//assertThat($found, describedAs($expected, notNullValue()));\n```\n\n* `everyItem` - A matcher to apply to every element in an array.\n```php\nassertThat([2, 4, 6], everyItem(notNullValue()));\n```\n\n* `hasItem` - check array has given item, it can take a matcher argument\n```php\nassertThat([2, 4, 6], hasItem(equalTo(2)));\n```\n\n* `hasItems` - check array has given items, it can take multiple matcher as arguments\n```php\nassertThat([1, 3, 5], hasItems(equalTo(1), equalTo(3)));\n```\n\n### Object\n\n* `hasToString` - check `__toString` or `toString` method\n```php\nclass Foo {\n    public $name = null;\n\n    public function __toString() {\n        return \"[Foo]Instance\";\n    }\n}\n$foo = new Foo;\nassertThat($foo, hasToString(equalTo(\"[Foo]Instance\")));\n```\n\n* `equalTo` - compares two instances using comparison operator '=='\n```php\n$foo = new Foo;\n$foo2 = new Foo;\nassertThat($foo, equalTo($foo2));\n```\n\n* `identicalTo` - compares two instances using identity operator '==='\n```php\nassertThat($foo, is(not(identicalTo($foo2))));\n```\n\n* `anInstanceOf` - check instance is an instance|sub-class of given class\n```php\nassertThat($foo, anInstanceOf(Foo::class));\n```\n\n* `any` - alias of `anInstanceOf`\n\n* `nullValue` check null\n```php\nassertThat(null, is(nullValue()));\n```\n\n* `notNullValue` check not null\n```php\nassertThat(\"\", notNullValue());\n```\n\n* `sameInstance` - check for same instance\n```php\nassertThat($foo, is(not(sameInstance($foo2))));\nassertThat($foo, is(sameInstance($foo)));\n```\n\n* `typeOf`- check type\n```php \nassertThat(1, typeOf(\"integer\"));\n```\n\n* `notSet` - check if instance property is not set\n```php\nassertThat($foo, notSet(\"name\"));\n```\n\n* `set` - check if instance property is set\n```php\n$foo->name = \"bar\";\nassertThat($foo, set(\"name\"));\n```\n\n### Numbers\n\n* `closeTo` - check value close to a range\n```php\nassertThat(3, closeTo(3, 0.5));\n```\n\n* `comparesEqualTo` - check with '=='\n```php\nassertThat(2, comparesEqualTo(2));\n```\n\n* `greaterThan` - check '>'\n```\nassertThat(2, greaterThan(1));\n```\n\n* `greaterThanOrEqualTo`\n```php\nassertThat(2, greaterThanOrEqualTo(2));\n```\n\n* `atLeast` - The value is >= given value\n```php\nassertThat(3, atLeast(2));\n```\n* `lessThan`\n```php\nassertThat(2, lessThan(3));\n```\n\n* `lessThanOrEqualTo`\n```php\nassertThat(2, lessThanOrEqualTo(3));\n```\n\n* `atMost` - The value is <= given value\n```php\nassertThat(2, atMost(3));\n```\n\n### String\n\n* `emptyString` - check for empty string\n```php\nassertThat(\"\", emptyString());\n```\n\n* `isEmptyOrNullString`\n```php\nassertThat(null, isEmptyOrNullString());\n```\n\n* `nullOrEmptyString`\n```php\nassertThat(\"\", nullOrEmptyString());\n```\n\n* `isNonEmptyString`\n```php\nassertThat(\"foo\", isNonEmptyString());\n```\n\n* `nonEmptyString`\n```php\nassertThat(\"foo\", nonEmptyString());\n```\n\n* `equalToIgnoringCase`\n```php\nassertThat(\"Foo\", equalToIgnoringCase(\"foo\"));\n```\n* `equalToIgnoringWhiteSpace`\n```php\nassertThat(\" Foo \", equalToIgnoringWhiteSpace(\"Foo\"));\n```\n\n* `matchesPattern` - matches with regex pattern\n```php\nassertThat(\"foobarbaz\", matchesPattern('/(foo)(bar)(baz)/'));\n```\n\n* `containsString` - check for substring\n```php\nassertThat(\"foobar\", containsString(\"foo\"));\n```\n\n* `containsStringIgnoringCase`\n```php\nassertThat(\"fooBar\", containsStringIgnoringCase(\"bar\"));\n```\n\n* `stringContainsInOrder`\n```php\nassertThat(\"foo\", stringContainsInOrder(\"foo\"));\n```\n\n* `endsWith` - check string that ends with given value\n```php\nassertThat(\"foo\", endsWith(\"oo\"));\n```\n\n* `startsWith` - check string that starts with given value\n```php\nassertThat(\"bar\", startsWith(\"ba\"));\n```\n\n### Type-checking\n\n* `arrayValue` - check array type\n```php\nassertThat([], arrayValue());\n```\n\n* `booleanValue`\n```php\nassertThat(true, booleanValue());\n```\n* `boolValue` - alias of booleanValue\n\n* `callableValue` - check if value is callable\n```php\n$func = function () {};\nassertThat($func, callableValue());\n```\n* `doubleValue`\n```php\nassertThat(3.14, doubleValue());\n```\n\n* `floatValue`\n```php\nassertThat(3.14, floatValue());\n```\n\n* `integerValue`\n```php\nassertThat(1, integerValue());\n```\n\n* `intValue` - alias of `integerValue`\n\n* `numericValue` - check if value is numeric\n```php\nassertThat(\"123\", numericValue());\n```\n\n* `objectValue` - check for object\n```php\n$obj = new stdClass;\nassertThat($obj, objectValue());\n```\n* `anObject`\n```php\nassertThat($obj, anObject());\n```\n\n* `resourceValue` - check resource type\n```php\n$fp = fopen(\"/tmp/foo\", \"w+\");\nassertThat($fp, resourceValue());\n```\n\n* `scalarValue` - check for scalar value\n```php\nassertThat(1, scalarValue());\n```\n\n* `stringValue`\n```php\nassertThat(\"\", stringValue());\n```\n\n### XML\n\n* `hasXPath` - check xml with a xpath\n```php\n$xml = <<<XML\n<books>\n  <book>\n    <isbn>1</isbn>   \n  </book>\n  <book>\n    <isbn>2</isbn>   \n  </book>\n</books>\nXML;\n\n$doc = new DOMDocument;\n$doc->loadXML($xml);\nassertThat($doc, hasXPath(\"book\", 2));\n```\n\n"
  },
  {
    "path": "composer.json",
    "content": "{\n\t\"name\": \"hamcrest/hamcrest-php\",\n\t\"type\": \"library\",\n\t\"description\": \"This is the PHP port of Hamcrest Matchers\",\n\t\"keywords\": [\"test\"],\n\t\"license\": \"BSD-3-Clause\",\n\t\"authors\": [\n\t],\n\n\t\"autoload\": {\n\t\t\"classmap\": [\"hamcrest\"]\n\t},\n\t\"autoload-dev\": {\n\t\t\"classmap\": [\"tests\", \"generator\"]\n\t},\n\n\t\"require\": {\n\t\t\"php\": \"^7.4|^8.0\",\n\t\t\"ext-ctype\": \"*\",\n\t\t\"ext-dom\": \"*\"\n\t},\n\n\t\"require-dev\": {\n\t\t\"phpunit/php-file-iterator\": \"^1.4 || ^2.0 || ^3.0\",\n\t\t\"phpunit/phpunit\": \"^4.8.36 || ^5.7 || ^6.5 || ^7.0 || ^8.0 || ^9.0\",\n\t\t\"phpstan/phpstan\": \"^2.1\",\n\t\t\"phpstan/phpstan-phpunit\": \"^2.0\"\n\t},\n\n\t\"replace\": {\n\t\t\"kodova/hamcrest-php\": \"*\",\n\t\t\"davedevelopment/hamcrest-php\": \"*\",\n\t\t\"cordoval/hamcrest-php\": \"*\"\n\t},\n\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"3.0-dev\"\n        }\n    }\n}\n"
  },
  {
    "path": "generator/FactoryCall.php",
    "content": "<?php\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\nclass FactoryCall\n{\n    /**\n     * Hamcrest standard is two spaces for each level of indentation.\n     *\n     * @var string\n     */\n    const INDENT = '    ';\n\n    /**\n     * @var FactoryMethod\n     */\n    private $method;\n\n    /**\n     * @var string\n     */\n    private $name;\n\n    public function __construct(FactoryMethod $method, $name)\n    {\n        $this->method = $method;\n        $this->name = $name;\n    }\n\n    public function getMethod()\n    {\n        return $this->method;\n    }\n\n    public function getName()\n    {\n        return $this->name;\n    }\n}\n"
  },
  {
    "path": "generator/FactoryClass.php",
    "content": "<?php\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\nclass FactoryClass\n{\n    /**\n     * @var string\n     */\n    private $file;\n\n    /**\n     * @var ReflectionClass\n     */\n    private $reflector;\n\n    /**\n     * @var array\n     */\n    private $methods;\n\n    public function __construct($file, ReflectionClass $class)\n    {\n        $this->file = $file;\n        $this->reflector = $class;\n        $this->extractFactoryMethods();\n    }\n\n    public function extractFactoryMethods()\n    {\n        $this->methods = array();\n        foreach ($this->getPublicStaticMethods() as $method) {\n            if ($method->isFactory()) {\n                $this->methods[] = $method;\n            }\n        }\n    }\n\n    public function getPublicStaticMethods()\n    {\n        $methods = array();\n        foreach ($this->reflector->getMethods(ReflectionMethod::IS_STATIC) as $method) {\n            if ($method->isPublic() && $method->getDeclaringClass() == $this->reflector) {\n                $methods[] = new FactoryMethod($this, $method);\n            }\n        }\n        return $methods;\n    }\n\n    public function getFile()\n    {\n        return $this->file;\n    }\n\n    public function getName()\n    {\n        return $this->reflector->name;\n    }\n\n    public function isFactory()\n    {\n        return !empty($this->methods);\n    }\n\n    public function getMethods()\n    {\n        return $this->methods;\n    }\n}\n"
  },
  {
    "path": "generator/FactoryFile.php",
    "content": "<?php\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\nabstract class FactoryFile\n{\n    /**\n     * Hamcrest standard is two spaces for each level of indentation.\n     *\n     * @var string\n     */\n    const INDENT = '    ';\n\n    private $indent;\n\n    private $file;\n\n    private $code;\n\n    public function __construct($file, $indent)\n    {\n        $this->file = $file;\n        $this->indent = $indent;\n    }\n\n    abstract public function addCall(FactoryCall $call);\n\n    abstract public function build();\n\n    public function addFileHeader()\n    {\n        $this->code = '';\n        $this->addPart('file_header');\n    }\n\n    public function addPart($name)\n    {\n        $this->addCode($this->readPart($name));\n    }\n\n    public function addCode($code)\n    {\n        $this->code .= $code;\n    }\n\n    public function readPart($name)\n    {\n        return file_get_contents(__DIR__ . \"/parts/$name.txt\");\n    }\n\n    public function generateFactoryCall(FactoryCall $call)\n    {\n        $method = $call->getMethod();\n        $code = $method->getComment($this->indent) . \"\\n\";\n        $code .= $this->generateDeclaration($call->getName(), $method);\n        $code .= $this->generateCall($method);\n        $code .= $this->generateClosing();\n        return $code;\n    }\n\n    public function generateDeclaration($name, FactoryMethod $method)\n    {\n        $code = $this->indent . $this->getDeclarationModifiers()\n            . 'function ' . $name . '('\n            . $this->generateDeclarationArguments($method)\n            . '): ' . $this->generateReturnType($method) . \"\\n\" . $this->indent . '{' . \"\\n\";\n        return $code;\n    }\n\n    public function getDeclarationModifiers()\n    {\n        return '';\n    }\n\n    public function generateDeclarationArguments(FactoryMethod $method)\n    {\n        if ($method->acceptsVariableArguments()) {\n            return '/* args... */';\n        } else {\n            return $method->getParameterDeclarations();\n        }\n    }\n\n    public function generateReturnType(FactoryMethod $method): string\n    {\n        $call = $method->getCalls()[0];\n        if (!$call instanceof FactoryCall) {\n            throw new Exception('The first call in the FactoryMethod cannot be used to determine the return type. Method: '.$method->getName());\n        }\n\n        $returnType = $call->getMethod()->getReturnType();\n\n        if (!$returnType) {\n            throw new \\Exception('The first calls FactoryMethod cannot be used to determine the return type. Method: '.$method->getName());\n        }\n\n        return sprintf('\\\\%s', $returnType);\n    }\n\n    public function generateImport(FactoryMethod $method)\n    {\n        return $this->indent . self::INDENT . \"require_once '\" . $method->getClass()->getFile() . \"';\" . \"\\n\";\n    }\n\n    public function generateCall(FactoryMethod $method)\n    {\n        $code = '';\n        if ($method->acceptsVariableArguments()) {\n            $code .= $this->indent . self::INDENT . '$args = func_get_args();' . \"\\n\";\n        }\n\n        $code .= $this->indent . self::INDENT . 'return ';\n        if ($method->acceptsVariableArguments()) {\n            $code .= 'call_user_func_array(array(\\''\n                . '\\\\' . $method->getClassName() . '\\', \\''\n                . $method->getName() . '\\'), $args);' . \"\\n\";\n        } else {\n            $code .= '\\\\' . $method->getClassName() . '::'\n                . $method->getName() . '('\n                . $method->getParameterInvocations() . ');' . \"\\n\";\n        }\n\n        return $code;\n    }\n\n    public function generateClosing()\n    {\n        return $this->indent . '}' . \"\\n\";\n    }\n\n    public function write()\n    {\n        file_put_contents($this->file, $this->code);\n    }\n}\n"
  },
  {
    "path": "generator/FactoryGenerator.php",
    "content": "<?php\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\n/**\n * Controls the process of extracting @factory doctags\n * and generating factory method files.\n *\n * Uses File_Iterator to scan for PHP files.\n */\nclass FactoryGenerator\n{\n    /**\n     * Path to the Hamcrest PHP files to process.\n     *\n     * @var string\n     */\n    private $path;\n\n    /**\n     * @var array of FactoryFile\n     */\n    private $factoryFiles;\n\n    public function __construct($path)\n    {\n        $this->path = $path;\n        $this->factoryFiles = array();\n    }\n\n    public function addFactoryFile(FactoryFile $factoryFile)\n    {\n        $this->factoryFiles[] = $factoryFile;\n    }\n\n    public function generate()\n    {\n        $classes = $this->getClassesWithFactoryMethods();\n        foreach ($classes as $class) {\n            foreach ($class->getMethods() as $method) {\n                foreach ($method->getCalls() as $call) {\n                    foreach ($this->factoryFiles as $file) {\n                        $file->addCall($call);\n                    }\n                }\n            }\n        }\n    }\n\n    public function write()\n    {\n        foreach ($this->factoryFiles as $file) {\n            $file->build();\n            $file->write();\n        }\n    }\n\n    public function getClassesWithFactoryMethods()\n    {\n        $classes = array();\n        $files = $this->getSortedFiles();\n        foreach ($files as $file) {\n            $class = $this->getFactoryClass($file);\n            if ($class !== null) {\n                $classes[] = $class;\n            }\n        }\n\n        return $classes;\n    }\n\n    public function getSortedFiles()\n    {\n        $iter = $this->getFileIterator();\n        $files = array();\n        foreach ($iter as $file) {\n            $files[] = $file;\n        }\n        sort($files, SORT_STRING);\n\n        return $files;\n    }\n\n    private function getFileIterator()\n    {\n        $factoryClass = class_exists('File_Iterator_Factory') ? 'File_Iterator_Factory' : 'SebastianBergmann\\FileIterator\\Factory';\n\n        $factory = new $factoryClass();\n\n        return $factory->getFileIterator($this->path, '.php');\n    }\n\n    public function getFactoryClass($file)\n    {\n        $name = $this->getFactoryClassName($file);\n        if ($name !== null) {\n            require_once $file;\n\n            if (class_exists($name)) {\n                $class = new FactoryClass(substr($file, strpos($file, 'Hamcrest/')), new ReflectionClass($name));\n                if ($class->isFactory()) {\n                    return $class;\n                }\n            }\n        }\n\n        return null;\n    }\n\n    public function getFactoryClassName($file)\n    {\n        $content = file_get_contents($file);\n        if (preg_match('/namespace\\s+(.+);/', $content, $namespace)\n            && preg_match('/\\n\\s*class\\s+(\\w+)\\s+extends\\b/', $content, $className)\n            && preg_match('/@factory\\b/', $content)\n        ) {\n            return $namespace[1] . '\\\\' . $className[1];\n        }\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "generator/FactoryMethod.php",
    "content": "<?php\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\n/**\n * Represents a single static factory method from a {@link Matcher} class.\n *\n * @todo Search method in file contents for func_get_args() to replace factoryVarArgs.\n */\nclass FactoryMethod\n{\n    /**\n     * @var FactoryClass\n     */\n    private $class;\n\n    /**\n     * @var ReflectionMethod\n     */\n    private $reflector;\n\n    /**\n     * @var array of string\n     */\n    private $comment;\n\n    /**\n     * @var bool\n     */\n    private $isVarArgs;\n\n    /**\n     * @var array of FactoryCall\n     */\n    private $calls;\n\n    /**\n     * @var array FactoryParameter\n     */\n    private $parameters;\n\n    public function __construct(FactoryClass $class, ReflectionMethod $reflector)\n    {\n        $this->class = $class;\n        $this->reflector = $reflector;\n        $this->extractCommentWithoutLeadingShashesAndStars();\n        $this->extractFactoryNamesFromComment();\n        $this->extractParameters();\n    }\n\n    public function extractCommentWithoutLeadingShashesAndStars()\n    {\n        $this->comment = explode(\"\\n\", $this->reflector->getDocComment());\n        foreach ($this->comment as &$line) {\n            $line = preg_replace('#^\\s*(/\\\\*+|\\\\*+/|\\\\*)\\s?#', '', $line);\n        }\n        $this->trimLeadingBlankLinesFromComment();\n        $this->trimTrailingBlankLinesFromComment();\n    }\n\n    public function trimLeadingBlankLinesFromComment()\n    {\n        while (count($this->comment) > 0) {\n            $line = array_shift($this->comment);\n            if (trim($line) != '') {\n                array_unshift($this->comment, $line);\n                break;\n            }\n        }\n    }\n\n    public function trimTrailingBlankLinesFromComment()\n    {\n        while (count($this->comment) > 0) {\n            $line = array_pop($this->comment);\n            if (trim($line) != '') {\n                array_push($this->comment, $line);\n                break;\n            }\n        }\n    }\n\n    public function extractFactoryNamesFromComment()\n    {\n        $this->calls = array();\n        for ($i = 0; $i < count($this->comment); $i++) {\n            if ($this->extractFactoryNamesFromLine($this->comment[$i])) {\n                unset($this->comment[$i]);\n            }\n        }\n        $this->trimTrailingBlankLinesFromComment();\n    }\n\n    public function extractFactoryNamesFromLine($line)\n    {\n        if (preg_match('/^\\s*@factory(\\s+(.+))?$/', $line, $match)) {\n            $this->createCalls(\n                $this->extractFactoryNamesFromAnnotation(\n                    isset($match[2]) ? trim($match[2]) : null\n                )\n            );\n            return true;\n        }\n        return false;\n    }\n\n    public function extractFactoryNamesFromAnnotation($value)\n    {\n        $primaryName = $this->reflector->getName();\n        if (empty($value)) {\n            return array($primaryName);\n        }\n        preg_match_all('/(\\.{3}|-|[a-zA-Z_][a-zA-Z_0-9]*)/', $value, $match);\n        $names = $match[0];\n        if (in_array('...', $names)) {\n            $this->isVarArgs = true;\n        }\n        if (!in_array('-', $names) && !in_array($primaryName, $names)) {\n            array_unshift($names, $primaryName);\n        }\n        return $names;\n    }\n\n    public function createCalls(array $names)\n    {\n        $names = array_unique($names);\n        foreach ($names as $name) {\n            if ($name != '-' && $name != '...') {\n                $this->calls[] = new FactoryCall($this, $name);\n            }\n        }\n    }\n\n    public function extractParameters()\n    {\n        $this->parameters = array();\n        if (!$this->isVarArgs) {\n            foreach ($this->reflector->getParameters() as $parameter) {\n                $this->parameters[] = new FactoryParameter($this, $parameter);\n            }\n        }\n    }\n\n    public function getParameterDeclarations()\n    {\n        if ($this->isVarArgs || !$this->hasParameters()) {\n            return '';\n        }\n        $params = array();\n        foreach ($this->parameters as /** @var $parameter FactoryParameter */\n                 $parameter) {\n            $params[] = $parameter->getDeclaration();\n        }\n        return implode(', ', $params);\n    }\n\n    public function getParameterInvocations()\n    {\n        if ($this->isVarArgs) {\n            return '';\n        }\n        $params = array();\n        foreach ($this->parameters as $parameter) {\n            $params[] = $parameter->getInvocation();\n        }\n        return implode(', ', $params);\n    }\n\n\n    public function getClass()\n    {\n        return $this->class;\n    }\n\n    public function getClassName()\n    {\n        return $this->class->getName();\n    }\n\n    public function getName()\n    {\n        return $this->reflector->name;\n    }\n\n    public function isFactory()\n    {\n        return count($this->calls) > 0;\n    }\n\n    public function getCalls()\n    {\n        return $this->calls;\n    }\n\n    public function acceptsVariableArguments()\n    {\n        return $this->isVarArgs;\n    }\n\n    public function hasParameters()\n    {\n        return !empty($this->parameters);\n    }\n\n    public function getParameters()\n    {\n        return $this->parameters;\n    }\n\n    public function getFullName()\n    {\n        return $this->getClassName() . '::' . $this->getName();\n    }\n\n    public function getReturnType(): ?string\n    {\n        if (!$this->reflector->hasReturnType()) {\n            return null;\n        }\n\n        $returnType = $this->reflector->getReturnType()->getName();\n\n        if ($returnType === 'self') {\n            return $this->reflector->getDeclaringClass()->getName();\n        }\n\n        return $returnType;\n    }\n\n    public function getCommentText()\n    {\n        return implode(\"\\n\", $this->comment);\n    }\n\n    public function getComment($indent = '')\n    {\n        $comment = $indent . '/**';\n        foreach ($this->comment as $line) {\n            $comment .= \"\\n\" . rtrim($indent . ' * ' . $line);\n        }\n        $comment .= \"\\n\" . $indent . ' */';\n        return $comment;\n    }\n}\n"
  },
  {
    "path": "generator/FactoryParameter.php",
    "content": "<?php\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\nclass FactoryParameter\n{\n    /**\n     * @var FactoryMethod\n     */\n    private $method;\n\n    /**\n     * @var ReflectionParameter\n     */\n    private $reflector;\n\n    public function __construct(FactoryMethod $method, ReflectionParameter $reflector)\n    {\n        $this->method = $method;\n        $this->reflector = $reflector;\n    }\n\n    /**\n     * Compute the declaration code.\n     *\n     * @return string\n     */\n    public function getDeclaration()\n    {\n        $code = $this->getTypeCode() . $this->getInvocation();\n\n        if ($this->reflector->isOptional()) {\n            $default = $this->reflector->getDefaultValue();\n            if (is_null($default)) {\n                $default = 'null';\n            } elseif (is_bool($default)) {\n                $default = $default ? 'true' : 'false';\n            } elseif (is_string($default)) {\n                $default = \"'\" . $default . \"'\";\n            } elseif (is_numeric($default)) {\n                $default = strval($default);\n            } elseif (is_array($default)) {\n                $default = 'array()';\n            } else {\n                echo 'Warning: unknown default type for ' . $this->getMethod()->getFullName() . \"\\n\";\n                var_dump($default);\n                $default = 'null';\n            }\n            $code .= ' = ' . $default;\n        }\n        return $code;\n    }\n\n    /**\n     * Compute the type code for the parameter.\n     *\n     * @return string\n     */\n    private function getTypeCode()\n    {\n        // Handle PHP 5 separately\n        if (PHP_VERSION_ID < 70000) {\n            if ($this->reflector->isArray()) {\n                return 'array';\n            }\n\n            $class = $this->reflector->getClass();\n\n            return $class ? sprintf('\\\\%s ', $class->getName()) : '';\n        }\n\n        if (!$this->reflector->hasType()) {\n            return '';\n        }\n\n        $type = $this->reflector->getType();\n        $name = self::getQualifiedName($type);\n\n        // PHP 7.1+ supports nullable types via a leading question mark\n        return (PHP_VERSION_ID >= 70100 && $type->allowsNull()) ? sprintf('?%s ', $name) : sprintf('%s ', $name);\n    }\n\n    /**\n     * Compute qualified name for the given type.\n     *\n     * This function knows how to prefix class names with a leading slash and\n     * also how to handle PHP 8's union types.\n     *\n     * @param ReflectionType $type\n     *\n     * @return string\n     */\n    private static function getQualifiedName(ReflectionType $type)\n    {\n        // PHP 8 union types can be recursively processed\n        if ($type instanceof ReflectionUnionType) {\n            return implode('|', array_map(function (ReflectionType $type) {\n                // The \"self::\" call within a Closure is fine here because this\n                // code will only ever be executed on PHP 7.0+\n                return self::getQualifiedName($type);\n            }, $type->getTypes()));\n        }\n\n        // PHP 7.0 doesn't have named types, but 7.1+ does\n        $name = $type instanceof ReflectionNamedType ? $type->getName() : (string) $type;\n\n        return $type->isBuiltin() ? $name : sprintf('\\\\%s', $name);\n    }\n\n    /**\n     * Compute the invocation code.\n     *\n     * @return string\n     */\n    public function getInvocation()\n    {\n        return sprintf('$%s', $this->reflector->getName());\n    }\n\n    /**\n     * Compute the method name.\n     *\n     * @return string\n     */\n    public function getMethod()\n    {\n        return $this->method;\n    }\n}\n"
  },
  {
    "path": "generator/GlobalFunctionFile.php",
    "content": "<?php\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\nclass GlobalFunctionFile extends FactoryFile\n{\n    /**\n     * @var string containing function definitions\n     */\n    private $functions;\n\n    public function __construct($file)\n    {\n        parent::__construct($file, '    ');\n        $this->functions = '';\n    }\n\n    public function addCall(FactoryCall $call)\n    {\n        $this->functions .= \"\\n\" . $this->generateFactoryCall($call);\n    }\n\n    public function build()\n    {\n        $this->addFileHeader();\n        $this->addPart('functions_imports');\n        $this->addPart('functions_header');\n        $this->addCode($this->functions);\n        $this->addPart('functions_footer');\n    }\n\n    public function generateFactoryCall(FactoryCall $call)\n    {\n        $code = \"if (!function_exists('{$call->getName()}')) {\\n\";\n        $code.= parent::generateFactoryCall($call);\n        $code.= \"}\\n\";\n\n        return $code;\n    }\n}\n"
  },
  {
    "path": "generator/StaticMethodFile.php",
    "content": "<?php\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\nclass StaticMethodFile extends FactoryFile\n{\n    /**\n     * @var string containing method definitions\n     */\n    private $methods;\n\n    public function __construct($file)\n    {\n        parent::__construct($file, '    ');\n        $this->methods = '';\n    }\n\n    public function addCall(FactoryCall $call)\n    {\n        $this->methods .= PHP_EOL . $this->generateFactoryCall($call);\n    }\n\n    public function getDeclarationModifiers()\n    {\n        return 'public static ';\n    }\n\n    public function build()\n    {\n        $this->addFileHeader();\n        $this->addPart('matchers_imports');\n        $this->addPart('matchers_header');\n        $this->addCode($this->methods);\n        $this->addPart('matchers_footer');\n    }\n}\n"
  },
  {
    "path": "generator/parts/file_header.txt",
    "content": "<?php\n\n/*\n Copyright (c) 2009-2010 hamcrest.org\n */\n\n// This file is generated from the static method @factory doctags.\n"
  },
  {
    "path": "generator/parts/functions_footer.txt",
    "content": ""
  },
  {
    "path": "generator/parts/functions_header.txt",
    "content": "\nif (!function_exists('assertThat')) {\n    /**\n     * Make an assertion and throw {@link Hamcrest_AssertionError} if it fails.\n     *\n     * Example:\n     * <pre>\n     * //With an identifier\n     * assertThat(\"assertion identifier\", $apple->flavour(), equalTo(\"tasty\"));\n     * //Without an identifier\n     * assertThat($apple->flavour(), equalTo(\"tasty\"));\n     * //Evaluating a boolean expression\n     * assertThat(\"some error\", $a > $b);\n     * </pre>\n     */\n    function assertThat(): void\n    {\n        $args = func_get_args();\n        call_user_func_array(\n            array('Hamcrest\\MatcherAssert', 'assertThat'),\n            $args\n        );\n    }\n}\n"
  },
  {
    "path": "generator/parts/functions_imports.txt",
    "content": ""
  },
  {
    "path": "generator/parts/matchers_footer.txt",
    "content": "}\n"
  },
  {
    "path": "generator/parts/matchers_header.txt",
    "content": "\n\n/**\n * A series of static factories for all hamcrest matchers.\n */\nclass Matchers\n{\n"
  },
  {
    "path": "generator/parts/matchers_imports.txt",
    "content": "\nnamespace Hamcrest;"
  },
  {
    "path": "generator/run.php",
    "content": "<?php\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nrequire __DIR__ . '/../vendor/autoload.php';\n\n/*\n * Generates the Hamcrest\\Matchers factory class and factory functions\n * from the @factory doctags in the various matchers.\n */\n\ndefine('GENERATOR_BASE', __DIR__);\ndefine('HAMCREST_BASE', realpath(dirname(GENERATOR_BASE) . DIRECTORY_SEPARATOR . 'hamcrest'));\n\ndefine('GLOBAL_FUNCTIONS_FILE', HAMCREST_BASE . DIRECTORY_SEPARATOR . 'Hamcrest.php');\ndefine('STATIC_MATCHERS_FILE', HAMCREST_BASE . DIRECTORY_SEPARATOR . 'Hamcrest' . DIRECTORY_SEPARATOR . 'Matchers.php');\n\nset_include_path(\n    implode(\n        PATH_SEPARATOR,\n        array(\n            GENERATOR_BASE,\n            HAMCREST_BASE,\n            get_include_path()\n        )\n    )\n);\n\n@unlink(GLOBAL_FUNCTIONS_FILE);\n@unlink(STATIC_MATCHERS_FILE);\n\n$generator = new FactoryGenerator(HAMCREST_BASE . DIRECTORY_SEPARATOR . 'Hamcrest');\n$generator->addFactoryFile(new StaticMethodFile(STATIC_MATCHERS_FILE));\n$generator->addFactoryFile(new GlobalFunctionFile(GLOBAL_FUNCTIONS_FILE));\n$generator->generate();\n$generator->write();\n"
  },
  {
    "path": "hamcrest/Hamcrest/Arrays/IsArray.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\n// NOTE: This class is not exactly a direct port of Java's since Java handles\n//       arrays quite differently than PHP\n\n// TODO: Allow this to take matchers or values within the array\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\TypeSafeMatcher;\nuse Hamcrest\\Util;\n\n/**\n * Matcher for array whose elements satisfy a sequence of matchers.\n * The array size must equal the number of element matchers.\n */\nclass IsArray extends TypeSafeMatcher\n{\n\n    /**\n     * @var array<Matcher>\n     */\n    private array $_elementMatchers;\n\n    /**\n     * @param array<Matcher> $elementMatchers\n     */\n    public function __construct(array $elementMatchers)\n    {\n        parent::__construct(self::TYPE_ARRAY);\n\n        Util::checkAllAreMatchers($elementMatchers);\n\n        $this->_elementMatchers = $elementMatchers;\n    }\n\n    protected function matchesSafely($array): bool\n    {\n        if (array_keys($array) != array_keys($this->_elementMatchers)) {\n            return false;\n        }\n\n        foreach ($this->_elementMatchers as $k => $matcher) {\n            if (!$matcher->matches($array[$k])) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    protected function describeMismatchSafely($actual, Description $mismatchDescription): void\n    {\n        if (count($actual) != count($this->_elementMatchers)) {\n            $mismatchDescription->appendText('array length was ' . count($actual));\n\n            return;\n        } elseif (array_keys($actual) != array_keys($this->_elementMatchers)) {\n            $mismatchDescription->appendText('array keys were ')\n                                                    ->appendValueList(\n                                                        $this->descriptionStart(),\n                                                        $this->descriptionSeparator(),\n                                                        $this->descriptionEnd(),\n                                                        array_keys($actual)\n                                                    )\n                                                    ;\n\n            return;\n        }\n\n        foreach ($this->_elementMatchers as $k => $matcher) {\n            if (!$matcher->matches($actual[$k])) {\n                $mismatchDescription->appendText('element ')->appendValue($k)\n                    ->appendText(' was ')->appendValue($actual[$k]);\n\n                return;\n            }\n        }\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendList(\n            $this->descriptionStart(),\n            $this->descriptionSeparator(),\n            $this->descriptionEnd(),\n            $this->_elementMatchers\n        );\n    }\n\n    /**\n     * Evaluates to true only if each $matcher[$i] is satisfied by $array[$i].\n     *\n     * @factory ...\n     */\n    public static function anArray(/* args... */): self\n    {\n        $args = func_get_args();\n\n        return new self(Util::createMatcherArray($args));\n    }\n\n    // -- Protected Methods\n\n    protected function descriptionStart(): string\n    {\n        return '[';\n    }\n\n    protected function descriptionSeparator(): string\n    {\n        return ', ';\n    }\n\n    protected function descriptionEnd(): string\n    {\n        return ']';\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Arrays/IsArrayContaining.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\TypeSafeMatcher;\nuse Hamcrest\\Util;\n\n/**\n * Matches if an array contains an item satisfying a nested matcher.\n */\nclass IsArrayContaining extends TypeSafeMatcher\n{\n\n    private Matcher $_elementMatcher;\n\n    public function __construct(Matcher $elementMatcher)\n    {\n        parent::__construct(self::TYPE_ARRAY);\n\n        $this->_elementMatcher = $elementMatcher;\n    }\n\n    protected function matchesSafely($array): bool\n    {\n        foreach ($array as $element) {\n            if ($this->_elementMatcher->matches($element)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    protected function describeMismatchSafely($array, Description $mismatchDescription): void\n    {\n        $mismatchDescription->appendText('was ')->appendValue($array);\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description\n                 ->appendText('an array containing ')\n                 ->appendDescriptionOf($this->_elementMatcher)\n        ;\n    }\n\n    /**\n     * Evaluates to true if any item in an array satisfies the given matcher.\n     *\n     * @param mixed $item as a {@link Hamcrest\\Matcher} or a value.\n     *\n     * @return \\Hamcrest\\Arrays\\IsArrayContaining\n     * @factory hasValue\n     */\n    public static function hasItemInArray($item): self\n    {\n        return new self(Util::wrapValueWithIsEqual($item));\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Arrays/IsArrayContainingInAnyOrder.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\TypeSafeDiagnosingMatcher;\nuse Hamcrest\\Util;\n\n/**\n * Matches if an array contains a set of items satisfying nested matchers.\n */\nclass IsArrayContainingInAnyOrder extends TypeSafeDiagnosingMatcher\n{\n\n    /**\n     * @var array<Matcher>\n     */\n    private array $_elementMatchers;\n\n    /**\n     * @param array<Matcher> $elementMatchers\n     */\n    public function __construct(array $elementMatchers)\n    {\n        parent::__construct(self::TYPE_ARRAY);\n\n        Util::checkAllAreMatchers($elementMatchers);\n\n        $this->_elementMatchers = $elementMatchers;\n    }\n\n    protected function matchesSafelyWithDiagnosticDescription($array, Description $mismatchDescription): bool\n    {\n        $matching = new MatchingOnce($this->_elementMatchers, $mismatchDescription);\n\n        foreach ($array as $element) {\n            if (!$matching->matches($element)) {\n                return false;\n            }\n        }\n\n        return $matching->isFinished($array);\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendList('[', ', ', ']', $this->_elementMatchers)\n                                ->appendText(' in any order')\n                                ;\n    }\n\n    /**\n     * An array with elements that match the given matchers.\n     *\n     * @factory containsInAnyOrder ...\n     */\n    public static function arrayContainingInAnyOrder(/* args... */): self\n    {\n        $args = func_get_args();\n\n        return new self(Util::createMatcherArray($args));\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Arrays/IsArrayContainingInOrder.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\TypeSafeDiagnosingMatcher;\nuse Hamcrest\\Util;\n\n/**\n * Matches if an array contains a set of items satisfying nested matchers.\n */\nclass IsArrayContainingInOrder extends TypeSafeDiagnosingMatcher\n{\n\n    /**\n     * @var array<Matcher>\n     */\n    private array $_elementMatchers;\n\n    /**\n     * @param array<Matcher> $elementMatchers\n     */\n    public function __construct(array $elementMatchers)\n    {\n        parent::__construct(self::TYPE_ARRAY);\n\n        Util::checkAllAreMatchers($elementMatchers);\n\n        $this->_elementMatchers = $elementMatchers;\n    }\n\n    protected function matchesSafelyWithDiagnosticDescription($array, Description $mismatchDescription): bool\n    {\n        $series = new SeriesMatchingOnce($this->_elementMatchers, $mismatchDescription);\n\n        foreach ($array as $element) {\n            if (!$series->matches($element)) {\n                return false;\n            }\n        }\n\n        return $series->isFinished();\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendList('[', ', ', ']', $this->_elementMatchers);\n    }\n\n    /**\n     * An array with elements that match the given matchers in the same order.\n     *\n     * @factory contains ...\n     */\n    public static function arrayContaining(/* args... */): self\n    {\n        $args = func_get_args();\n\n        return new self(Util::createMatcherArray($args));\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Arrays/IsArrayContainingKey.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\TypeSafeMatcher;\nuse Hamcrest\\Util;\n\n/**\n * Matches if an array contains the specified key.\n */\nclass IsArrayContainingKey extends TypeSafeMatcher\n{\n\n    private Matcher $_keyMatcher;\n\n    public function __construct(Matcher $keyMatcher)\n    {\n        parent::__construct(self::TYPE_ARRAY);\n\n        $this->_keyMatcher = $keyMatcher;\n    }\n\n    protected function matchesSafely($array): bool\n    {\n        foreach ($array as $key => $element) {\n            if ($this->_keyMatcher->matches($key)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    protected function describeMismatchSafely($array, Description $mismatchDescription): void\n    {\n        //Not using appendValueList() so that keys can be shown\n        $mismatchDescription->appendText('array was ')\n                                                ->appendText('[')\n                                                ;\n        $loop = false;\n        foreach ($array as $key => $value) {\n            if ($loop) {\n                $mismatchDescription->appendText(', ');\n            }\n            $mismatchDescription->appendValue($key)->appendText(' => ')->appendValue($value);\n            $loop = true;\n        }\n        $mismatchDescription->appendText(']');\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description\n                 ->appendText('array with key ')\n                 ->appendDescriptionOf($this->_keyMatcher)\n                 ;\n    }\n\n    /**\n     * Evaluates to true if any key in an array matches the given matcher.\n     *\n     * @param mixed $key as a {@link Hamcrest\\Matcher} or a value.\n     *\n     * @return \\Hamcrest\\Arrays\\IsArrayContainingKey\n     * @factory hasKey\n     */\n    public static function hasKeyInArray($key): self\n    {\n        return new self(Util::wrapValueWithIsEqual($key));\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Arrays/IsArrayContainingKeyValuePair.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\n/**\n * Tests for the presence of both a key and value inside an array.\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\TypeSafeMatcher;\nuse Hamcrest\\Util;\n\n/**\n * @namespace\n */\n\nclass IsArrayContainingKeyValuePair extends TypeSafeMatcher\n{\n    private Matcher $_keyMatcher;\n    private Matcher $_valueMatcher;\n\n    public function __construct(Matcher $keyMatcher, Matcher $valueMatcher)\n    {\n        parent::__construct(self::TYPE_ARRAY);\n\n        $this->_keyMatcher = $keyMatcher;\n        $this->_valueMatcher = $valueMatcher;\n    }\n\n    protected function matchesSafely($array): bool\n    {\n        foreach ($array as $key => $value) {\n            if ($this->_keyMatcher->matches($key) && $this->_valueMatcher->matches($value)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    protected function describeMismatchSafely($array, Description $mismatchDescription): void\n    {\n        //Not using appendValueList() so that keys can be shown\n        $mismatchDescription->appendText('array was ')\n                                                ->appendText('[')\n                                                ;\n        $loop = false;\n        foreach ($array as $key => $value) {\n            if ($loop) {\n                $mismatchDescription->appendText(', ');\n            }\n            $mismatchDescription->appendValue($key)->appendText(' => ')->appendValue($value);\n            $loop = true;\n        }\n        $mismatchDescription->appendText(']');\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText('array containing [')\n                                ->appendDescriptionOf($this->_keyMatcher)\n                                ->appendText(' => ')\n                                ->appendDescriptionOf($this->_valueMatcher)\n                                ->appendText(']')\n                                ;\n    }\n\n    /**\n     * Test if an array has both an key and value in parity with each other.\n     *\n     * @factory hasEntry\n     * @param mixed $key\n     * @param mixed $value\n     */\n    public static function hasKeyValuePair($key, $value): self\n    {\n        return new self(\n            Util::wrapValueWithIsEqual($key),\n            Util::wrapValueWithIsEqual($value)\n        );\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Arrays/IsArrayWithSize.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Core\\DescribedAs;\nuse Hamcrest\\Core\\IsNot;\nuse Hamcrest\\FeatureMatcher;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\Util;\n\n/**\n * Matches if array size satisfies a nested matcher.\n */\nclass IsArrayWithSize extends FeatureMatcher\n{\n\n    public function __construct(Matcher $sizeMatcher)\n    {\n        parent::__construct(\n            self::TYPE_ARRAY,\n            null,\n            $sizeMatcher,\n            'an array with size',\n            'array size'\n        );\n    }\n\n    protected function featureValueOf($array)\n    {\n        return count($array);\n    }\n\n    /**\n     * Does array size satisfy a given matcher?\n     *\n     * @param \\Hamcrest\\Matcher|int $size as a {@link Hamcrest\\Matcher} or a value.\n     *\n     * @return \\Hamcrest\\Arrays\\IsArrayWithSize\n     * @factory\n     */\n    public static function arrayWithSize($size): self\n    {\n        return new self(Util::wrapValueWithIsEqual($size));\n    }\n\n    /**\n     * Matches an empty array.\n     *\n     * @factory\n     */\n    public static function emptyArray(): DescribedAs\n    {\n        return DescribedAs::describedAs(\n            'an empty array',\n            self::arrayWithSize(0)\n        );\n    }\n\n    /**\n     * Matches an empty array.\n     *\n     * @factory\n     */\n    public static function nonEmptyArray(): DescribedAs\n    {\n        return DescribedAs::describedAs(\n            'a non-empty array',\n            self::arrayWithSize(IsNot::not(0))\n        );\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Arrays/MatchingOnce.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\n\nclass MatchingOnce\n{\n\n    /**\n     * @var array<Matcher>\n     */\n    private array $_elementMatchers;\n    private Description $_mismatchDescription;\n\n    /**\n     * @param array<Matcher> $elementMatchers\n     */\n    public function __construct(array $elementMatchers, Description $mismatchDescription)\n    {\n        $this->_elementMatchers = $elementMatchers;\n        $this->_mismatchDescription = $mismatchDescription;\n    }\n\n    /**\n     * @param mixed $item\n     */\n    public function matches($item): bool\n    {\n        return $this->_isNotSurplus($item) && $this->_isMatched($item);\n    }\n\n    /**\n     * @param mixed $items\n     */\n    public function isFinished($items): bool\n    {\n        if (empty($this->_elementMatchers)) {\n            return true;\n        }\n\n        $this->_mismatchDescription\n                 ->appendText('No item matches: ')->appendList('', ', ', '', $this->_elementMatchers)\n                 ->appendText(' in ')->appendValueList('[', ', ', ']', $items)\n                 ;\n\n        return false;\n    }\n\n    // -- Private Methods\n\n    /**\n     * @param mixed $item\n     */\n    private function _isNotSurplus($item): bool\n    {\n        if (empty($this->_elementMatchers)) {\n            $this->_mismatchDescription->appendText('Not matched: ')->appendValue($item);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * @param mixed $item\n     */\n    private function _isMatched($item): bool\n    {\n        foreach ($this->_elementMatchers as $i => $matcher) {\n            if ($matcher->matches($item)) {\n                unset($this->_elementMatchers[$i]);\n\n                return true;\n            }\n        }\n\n        $this->_mismatchDescription->appendText('Not matched: ')->appendValue($item);\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Arrays/SeriesMatchingOnce.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\n\nclass SeriesMatchingOnce\n{\n\n    /**\n     * @var array<Matcher>\n     */\n    private array $_elementMatchers;\n    /**\n     * @var list<int|string>\n     */\n    private array $_keys;\n    private Description $_mismatchDescription;\n    /**\n     * @var int|string|null\n     */\n    private $_nextMatchKey;\n\n    /**\n     * @param array<Matcher> $elementMatchers\n     */\n    public function __construct(array $elementMatchers, Description $mismatchDescription)\n    {\n        $this->_elementMatchers = $elementMatchers;\n        $this->_keys = array_keys($elementMatchers);\n        $this->_mismatchDescription = $mismatchDescription;\n    }\n\n    /**\n     * @param mixed $item\n     */\n    public function matches($item): bool\n    {\n        return $this->_isNotSurplus($item) && $this->_isMatched($item);\n    }\n\n    public function isFinished(): bool\n    {\n        if (!empty($this->_elementMatchers)) {\n            $nextMatcher = current($this->_elementMatchers);\n            $this->_mismatchDescription->appendText('No item matched: ')->appendDescriptionOf($nextMatcher);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    // -- Private Methods\n\n    /**\n     * @param mixed $item\n     */\n    private function _isNotSurplus($item): bool\n    {\n        if (empty($this->_elementMatchers)) {\n            $this->_mismatchDescription->appendText('Not matched: ')->appendValue($item);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * @param mixed $item\n     */\n    private function _isMatched($item): bool\n    {\n        $this->_nextMatchKey = array_shift($this->_keys);\n        $nextMatcher = array_shift($this->_elementMatchers);\n\n        if (!$nextMatcher->matches($item)) {\n            $this->_describeMismatch($nextMatcher, $item);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * @param mixed $item\n     */\n    private function _describeMismatch(Matcher $matcher, $item): void\n    {\n        $this->_mismatchDescription->appendText('item with key ' . $this->_nextMatchKey . ': ');\n        $matcher->describeMismatch($item, $this->_mismatchDescription);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/AssertionError.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\nclass AssertionError extends \\RuntimeException\n{\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/BaseDescription.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Internal\\SelfDescribingValue;\n\n/**\n * A {@link Hamcrest\\Description} that is stored as a string.\n */\nabstract class BaseDescription implements Description\n{\n\n    public function appendText(string $text): self\n    {\n        $this->append($text);\n\n        return $this;\n    }\n\n    public function appendDescriptionOf(SelfDescribing $value)\n    {\n        $value->describeTo($this);\n\n        return $this;\n    }\n\n    public function appendValue($value): self\n    {\n        if (is_null($value)) {\n            $this->append('null');\n        } elseif (is_string($value)) {\n            $this->_toPhpSyntax($value);\n        } elseif (is_float($value)) {\n            $this->append('<');\n            $this->append($value);\n            $this->append('F>');\n        } elseif (is_bool($value)) {\n            $this->append('<');\n            $this->append($value ? 'true' : 'false');\n            $this->append('>');\n        } elseif (is_array($value) || $value instanceof \\Iterator || $value instanceof \\IteratorAggregate) {\n            $this->appendValueList('[', ', ', ']', $value);\n        } elseif (is_object($value) && !method_exists($value, '__toString')) {\n            $this->append('<');\n            $this->append(get_class($value));\n            $this->append('>');\n        } else {\n            $this->append('<');\n            $this->append($value);\n            $this->append('>');\n        }\n\n        return $this;\n    }\n\n    public function appendValueList(string $start, string $separator, string $end, iterable $values): self\n    {\n        $list = array();\n        foreach ($values as $v) {\n            $list[] = new SelfDescribingValue($v);\n        }\n\n        $this->appendList($start, $separator, $end, $list);\n\n        return $this;\n    }\n\n    public function appendList(string $start, string $separator, string $end, iterable $values): self\n    {\n        $this->append($start);\n\n        $separate = false;\n\n        foreach ($values as $value) {\n            /*if (!($value instanceof Hamcrest\\SelfDescribing)) {\n                $value = new Hamcrest\\Internal\\SelfDescribingValue($value);\n            }*/\n\n            if ($separate) {\n                $this->append($separator);\n            }\n\n            $this->appendDescriptionOf($value);\n\n            $separate = true;\n        }\n\n        $this->append($end);\n\n        return $this;\n    }\n\n    // -- Protected Methods\n\n    /**\n     * Append the String <var>$str</var> to the description.\n     * @param mixed $str\n     */\n    abstract protected function append($str): void;\n\n    // -- Private Methods\n\n    private function _toPhpSyntax(string $value): void\n    {\n        $str = '\"';\n        for ($i = 0, $len = strlen($value); $i < $len; ++$i) {\n            switch ($value[$i]) {\n                case '\"':\n                    $str .= '\\\\\"';\n                    break;\n\n                case \"\\t\":\n                    $str .= '\\\\t';\n                    break;\n\n                case \"\\r\":\n                    $str .= '\\\\r';\n                    break;\n\n                case \"\\n\":\n                    $str .= '\\\\n';\n                    break;\n\n                default:\n                    $str .= $value[$i];\n            }\n        }\n        $str .= '\"';\n        $this->append($str);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/BaseMatcher.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\n/**\n * BaseClass for all Matcher implementations.\n *\n * @see Hamcrest\\Matcher\n */\nabstract class BaseMatcher implements Matcher\n{\n    /**\n     * @param mixed $item\n     */\n    public function describeMismatch($item, Description $description): void\n    {\n        $description->appendText('was ')->appendValue($item);\n    }\n\n    public function __toString(): string\n    {\n        return StringDescription::toString($this);\n    }\n\n    public function __invoke(): bool\n    {\n        return call_user_func_array(array($this, 'matches'), func_get_args());\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Collection/IsEmptyTraversable.php",
    "content": "<?php\nnamespace Hamcrest\\Collection;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\BaseMatcher;\nuse Hamcrest\\Description;\n\n/**\n * Matches if traversable is empty or non-empty.\n */\nclass IsEmptyTraversable extends BaseMatcher\n{\n\n    private static ?self $_INSTANCE = null;\n    private static ?self $_NOT_INSTANCE = null;\n\n    private bool $_empty;\n\n    public function __construct(bool $empty = true)\n    {\n        $this->_empty = $empty;\n    }\n\n    public function matches($item): bool\n    {\n        if (!$item instanceof \\Traversable) {\n            return false;\n        }\n\n        foreach ($item as $value) {\n            return !$this->_empty;\n        }\n\n        return $this->_empty;\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText($this->_empty ? 'an empty traversable' : 'a non-empty traversable');\n    }\n\n    /**\n     * Returns true if traversable is empty.\n     *\n     * @factory\n     */\n    public static function emptyTraversable(): self\n    {\n        if (!self::$_INSTANCE) {\n            self::$_INSTANCE = new self;\n        }\n\n        return self::$_INSTANCE;\n    }\n\n    /**\n     * Returns true if traversable is not empty.\n     *\n     * @factory\n     */\n    public static function nonEmptyTraversable(): self\n    {\n        if (!self::$_NOT_INSTANCE) {\n            self::$_NOT_INSTANCE = new self(false);\n        }\n\n        return self::$_NOT_INSTANCE;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Collection/IsTraversableWithSize.php",
    "content": "<?php\nnamespace Hamcrest\\Collection;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\FeatureMatcher;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\Util;\n\n/**\n * Matches if traversable size satisfies a nested matcher.\n */\nclass IsTraversableWithSize extends FeatureMatcher\n{\n\n    public function __construct(Matcher $sizeMatcher)\n    {\n        parent::__construct(\n            self::TYPE_OBJECT,\n            'Traversable',\n            $sizeMatcher,\n            'a traversable with size',\n            'traversable size'\n        );\n    }\n\n    protected function featureValueOf($actual)\n    {\n        $size = 0;\n        foreach ($actual as $value) {\n            $size++;\n        }\n\n        return $size;\n    }\n\n    /**\n     * Does traversable size satisfy a given matcher?\n     *\n     * @factory\n     * @param mixed $size\n     */\n    public static function traversableWithSize($size): self\n    {\n        return new self(Util::wrapValueWithIsEqual($size));\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/AllOf.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\DiagnosingMatcher;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\Util;\n\n/**\n * Calculates the logical conjunction of multiple matchers. Evaluation is\n * shortcut, so subsequent matchers are not called if an earlier matcher\n * returns <code>false</code>.\n */\nclass AllOf extends DiagnosingMatcher\n{\n\n    /**\n     * @var array<Matcher>\n     */\n    private array $_matchers;\n\n    /**\n     * @param array<Matcher> $matchers\n     */\n    public function __construct(array $matchers)\n    {\n        Util::checkAllAreMatchers($matchers);\n\n        $this->_matchers = $matchers;\n    }\n\n    public function matchesWithDiagnosticDescription($item, Description $mismatchDescription): bool\n    {\n        foreach ($this->_matchers as $matcher) {\n            if (!$matcher->matches($item)) {\n                $mismatchDescription->appendDescriptionOf($matcher)->appendText(' ');\n                $matcher->describeMismatch($item, $mismatchDescription);\n\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendList('(', ' and ', ')', $this->_matchers);\n    }\n\n    /**\n     * Evaluates to true only if ALL of the passed in matchers evaluate to true.\n     *\n     * @factory ...\n     */\n    public static function allOf(/* args... */): self\n    {\n        $args = func_get_args();\n\n        return new self(Util::createMatcherArray($args));\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/AnyOf.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\Util;\n\n/**\n * Calculates the logical disjunction of multiple matchers. Evaluation is\n * shortcut, so subsequent matchers are not called if an earlier matcher\n * returns <code>true</code>.\n */\nclass AnyOf extends ShortcutCombination\n{\n\n    /**\n     * @param array<Matcher> $matchers\n     */\n    public function __construct(array $matchers)\n    {\n        parent::__construct($matchers);\n    }\n\n    public function matches($item): bool\n    {\n        return $this->matchesWithShortcut($item, true);\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $this->describeToWithOperator($description, 'or');\n    }\n\n    /**\n     * Evaluates to true if ANY of the passed in matchers evaluate to true.\n     *\n     * @factory ...\n     */\n    public static function anyOf(/* args... */): self\n    {\n        $args = func_get_args();\n\n        return new self(Util::createMatcherArray($args));\n    }\n\n    /**\n     * Evaluates to false if ANY of the passed in matchers evaluate to true.\n     *\n     * @factory ...\n     */\n    public static function noneOf(/* args... */): IsNot\n    {\n        $args = func_get_args();\n\n        return IsNot::not(\n            new self(Util::createMatcherArray($args))\n        );\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/CombinableMatcher.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\nuse Hamcrest\\BaseMatcher;\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\n\nclass CombinableMatcher extends BaseMatcher\n{\n\n    private Matcher $_matcher;\n\n    public function __construct(Matcher $matcher)\n    {\n        $this->_matcher = $matcher;\n    }\n\n    public function matches($item): bool\n    {\n        return $this->_matcher->matches($item);\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendDescriptionOf($this->_matcher);\n    }\n\n    /** Diversion from Hamcrest-Java... Logical \"and\" not permitted */\n    public function andAlso(Matcher $other): self\n    {\n        return new self(new AllOf($this->_templatedListWith($other)));\n    }\n\n    /** Diversion from Hamcrest-Java... Logical \"or\" not permitted */\n    public function orElse(Matcher $other): self\n    {\n        return new self(new AnyOf($this->_templatedListWith($other)));\n    }\n\n    /**\n     * This is useful for fluently combining matchers that must both pass.\n     * For example:\n     * <pre>\n     *   assertThat($string, both(containsString(\"a\"))->andAlso(containsString(\"b\")));\n     * </pre>\n     *\n     * @factory\n     */\n    public static function both(Matcher $matcher): self\n    {\n        return new self($matcher);\n    }\n\n    /**\n     * This is useful for fluently combining matchers where either may pass,\n     * for example:\n     * <pre>\n     *   assertThat($string, either(containsString(\"a\"))->orElse(containsString(\"b\")));\n     * </pre>\n     *\n     * @factory\n     */\n    public static function either(Matcher $matcher): self\n    {\n        return new self($matcher);\n    }\n\n    // -- Private Methods\n\n    /**\n     * @return list<Matcher>\n     */\n    private function _templatedListWith(Matcher $other): array\n    {\n        return array($this->_matcher, $other);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/DescribedAs.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\BaseMatcher;\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\n\n/**\n * Provides a custom description to another matcher.\n */\nclass DescribedAs extends BaseMatcher\n{\n\n    private string $_descriptionTemplate;\n    private Matcher $_matcher;\n    /**\n     * @var array<mixed>\n     */\n    private array $_values;\n\n    private const ARG_PATTERN = '/%([0-9]+)/';\n\n    /**\n     * @param array<mixed> $values\n     */\n    public function __construct(string $descriptionTemplate, Matcher $matcher, array $values)\n    {\n        $this->_descriptionTemplate = $descriptionTemplate;\n        $this->_matcher = $matcher;\n        $this->_values = $values;\n    }\n\n    public function matches($item): bool\n    {\n        return $this->_matcher->matches($item);\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $textStart = 0;\n        while (preg_match(self::ARG_PATTERN, $this->_descriptionTemplate, $matches, PREG_OFFSET_CAPTURE, $textStart)) {\n            $text = $matches[0][0];\n            $index = $matches[1][0];\n            $offset = $matches[0][1];\n\n            $description->appendText(substr($this->_descriptionTemplate, $textStart, $offset - $textStart));\n            $description->appendValue($this->_values[$index]);\n\n            $textStart = $offset + strlen($text);\n        }\n\n        if ($textStart < strlen($this->_descriptionTemplate)) {\n            $description->appendText(substr($this->_descriptionTemplate, $textStart));\n        }\n    }\n\n    /**\n     * Wraps an existing matcher and overrides the description when it fails.\n     *\n     * @factory ...\n     */\n    public static function describedAs(/* $description, Hamcrest\\Matcher $matcher, $values... */): self\n    {\n        $args = func_get_args();\n        $description = array_shift($args);\n        $matcher = array_shift($args);\n        $values = $args;\n\n        return new self($description, $matcher, $values);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/Every.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\TypeSafeDiagnosingMatcher;\n\nclass Every extends TypeSafeDiagnosingMatcher\n{\n\n    private Matcher $_matcher;\n\n    public function __construct(Matcher $matcher)\n    {\n        parent::__construct(self::TYPE_ARRAY);\n\n        $this->_matcher = $matcher;\n    }\n\n    protected function matchesSafelyWithDiagnosticDescription($items, Description $mismatchDescription): bool\n    {\n        foreach ($items as $item) {\n            if (!$this->_matcher->matches($item)) {\n                $mismatchDescription->appendText('an item ');\n                $this->_matcher->describeMismatch($item, $mismatchDescription);\n\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText('every item is ')->appendDescriptionOf($this->_matcher);\n    }\n\n    /**\n     * @param \\Hamcrest\\Matcher $itemMatcher\n     *   A matcher to apply to every element in an array.\n     *\n     * @return \\Hamcrest\\Core\\Every\n     *   Evaluates to TRUE for a collection in which every item matches $itemMatcher\n     *\n     * @factory\n     */\n    public static function everyItem(Matcher $itemMatcher): self\n    {\n        return new self($itemMatcher);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/HasToString.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\FeatureMatcher;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\Util;\n\n/**\n * A Matcher that checks the output of the <code>toString()</code> or <code>__toString()</code> method.\n */\nclass HasToString extends FeatureMatcher\n{\n\n    public function __construct(Matcher $toStringMatcher)\n    {\n        parent::__construct(\n            self::TYPE_OBJECT,\n            null,\n            $toStringMatcher,\n            'an object with toString()',\n            'toString()'\n        );\n    }\n\n    public function matchesSafelyWithDiagnosticDescription($actual, Description $mismatchDescription): bool\n    {\n        if (method_exists($actual, 'toString') || method_exists($actual, '__toString')) {\n            return parent::matchesSafelyWithDiagnosticDescription($actual, $mismatchDescription);\n        }\n\n        return false;\n    }\n\n    protected function featureValueOf($actual)\n    {\n        if (method_exists($actual, 'toString')) {\n            return $actual->toString();\n        }\n\n        return (string) $actual;\n    }\n\n    /**\n     * Creates a matcher that matches any examined object whose <code>toString</code> or\n     * <code>__toString()</code> method returns a value equalTo the specified string.\n     *\n     * @factory\n     * @param mixed $matcher\n     */\n    public static function hasToString($matcher): self\n    {\n        return new self(Util::wrapValueWithIsEqual($matcher));\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/Is.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\BaseMatcher;\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\Util;\n\n/**\n * Decorates another Matcher, retaining the behavior but allowing tests\n * to be slightly more expressive.\n *\n * For example:  assertThat($cheese, equalTo($smelly))\n *          vs.  assertThat($cheese, is(equalTo($smelly)))\n */\nclass Is extends BaseMatcher\n{\n\n    private Matcher $_matcher;\n\n    public function __construct(Matcher $matcher)\n    {\n        $this->_matcher = $matcher;\n    }\n\n    public function matches($arg): bool\n    {\n        return $this->_matcher->matches($arg);\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText('is ')->appendDescriptionOf($this->_matcher);\n    }\n\n    public function describeMismatch($item, Description $mismatchDescription): void\n    {\n        $this->_matcher->describeMismatch($item, $mismatchDescription);\n    }\n\n    /**\n     * Decorates another Matcher, retaining the behavior but allowing tests\n     * to be slightly more expressive.\n     *\n     * For example:  assertThat($cheese, equalTo($smelly))\n     *          vs.  assertThat($cheese, is(equalTo($smelly)))\n     *\n     * @factory\n     * @param mixed $value\n     */\n    public static function is($value): self\n    {\n        return new self(Util::wrapValueWithIsEqual($value));\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/IsAnything.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\BaseMatcher;\nuse Hamcrest\\Description;\n\n/**\n * A matcher that always returns <code>true</code>.\n */\nclass IsAnything extends BaseMatcher\n{\n\n    private string $_message;\n\n    public function __construct(string $message = 'ANYTHING')\n    {\n        $this->_message = $message;\n    }\n\n    public function matches($item): bool\n    {\n        return true;\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText($this->_message);\n    }\n\n    /**\n     * This matcher always evaluates to true.\n     *\n     * @param string $description A meaningful string used when describing itself.\n     *\n     * @factory\n     */\n    public static function anything(string $description = 'ANYTHING'): self\n    {\n        return new self($description);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/IsCollectionContaining.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\TypeSafeMatcher;\nuse Hamcrest\\Util;\n\n/**\n * Tests if an array contains values that match one or more Matchers.\n */\nclass IsCollectionContaining extends TypeSafeMatcher\n{\n\n    private Matcher $_elementMatcher;\n\n    public function __construct(Matcher $elementMatcher)\n    {\n        parent::__construct(self::TYPE_ARRAY);\n\n        $this->_elementMatcher = $elementMatcher;\n    }\n\n    protected function matchesSafely($items): bool\n    {\n        foreach ($items as $item) {\n            if ($this->_elementMatcher->matches($item)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    protected function describeMismatchSafely($items, Description $mismatchDescription): void\n    {\n        $mismatchDescription->appendText('was ')->appendValue($items);\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description\n                ->appendText('a collection containing ')\n                ->appendDescriptionOf($this->_elementMatcher)\n                ;\n    }\n\n    /**\n     * Test if the value is an array containing this matcher.\n     *\n     * Example:\n     * <pre>\n     * assertThat(array('a', 'b'), hasItem(equalTo('b')));\n     * //Convenience defaults to equalTo()\n     * assertThat(array('a', 'b'), hasItem('b'));\n     * </pre>\n     *\n     * @factory ...\n     */\n    public static function hasItem(): self\n    {\n        $args = func_get_args();\n        $firstArg = array_shift($args);\n\n        return new self(Util::wrapValueWithIsEqual($firstArg));\n    }\n\n    /**\n     * Test if the value is an array containing elements that match all of these\n     * matchers.\n     *\n     * Example:\n     * <pre>\n     * assertThat(array('a', 'b', 'c'), hasItems(equalTo('a'), equalTo('b')));\n     * </pre>\n     *\n     * @factory ...\n     */\n    public static function hasItems(/* args... */): AllOf\n    {\n        $args = func_get_args();\n        $matchers = array();\n\n        foreach ($args as $arg) {\n            $matchers[] = self::hasItem($arg);\n        }\n\n        return AllOf::allOf($matchers);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/IsEqual.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\BaseMatcher;\nuse Hamcrest\\Description;\n\n/**\n * Is the value equal to another value, as tested by the use of the \"==\"\n * comparison operator?\n */\nclass IsEqual extends BaseMatcher\n{\n    /**\n     * @var mixed\n     */\n    private $_item;\n\n    /**\n     * @param mixed $item\n     */\n    public function __construct($item)\n    {\n        $this->_item = $item;\n    }\n\n    public function matches($arg): bool\n    {\n        return (($arg == $this->_item) && ($this->_item == $arg));\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendValue($this->_item);\n    }\n\n    /**\n     * Is the value equal to another value, as tested by the use of the \"==\"\n     * comparison operator?\n     *\n     * @factory\n     * @param mixed $item\n     */\n    public static function equalTo($item): self\n    {\n        return new self($item);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/IsIdentical.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\n\n/**\n * The same as {@link Hamcrest\\Core\\IsSame} but with slightly different\n * semantics.\n */\nclass IsIdentical extends IsSame\n{\n\n    /**\n     * @var mixed $_value\n     */\n    private $_value;\n\n    /**\n     * @param mixed $value\n     */\n    public function __construct($value)\n    {\n        parent::__construct($value);\n        $this->_value = $value;\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendValue($this->_value);\n    }\n\n    /**\n     * Tests of the value is identical to $value as tested by the \"===\" operator.\n     *\n     * @factory\n     * @param mixed $value\n     */\n    public static function identicalTo($value): self\n    {\n        return new self($value);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/IsInstanceOf.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\DiagnosingMatcher;\n\n/**\n * Tests whether the value is an instance of a class.\n */\nclass IsInstanceOf extends DiagnosingMatcher\n{\n\n    private string $_theClass;\n\n    /**\n     * Creates a new instance of IsInstanceOf\n     *\n     * @param string $theClass\n     *   The predicate evaluates to true for instances of this class\n     *   or one of its subclasses.\n     */\n    public function __construct(string $theClass)\n    {\n        $this->_theClass = $theClass;\n    }\n\n    protected function matchesWithDiagnosticDescription($item, Description $mismatchDescription): bool\n    {\n        if (!is_object($item)) {\n            $mismatchDescription->appendText('was ')->appendValue($item);\n\n            return false;\n        }\n\n        if (!($item instanceof $this->_theClass)) {\n            $mismatchDescription->appendText('[' . get_class($item) . '] ')\n                                                    ->appendValue($item);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText('an instance of ')\n                                ->appendText($this->_theClass)\n                                ;\n    }\n\n    /**\n     * Is the value an instance of a particular type?\n     * This version assumes no relationship between the required type and\n     * the signature of the method that sets it up, for example in\n     * <code>assertThat($anObject, anInstanceOf('Thing'));</code>\n     *\n     * @factory any\n     */\n    public static function anInstanceOf(string $theClass): self\n    {\n        return new self($theClass);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/IsNot.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\BaseMatcher;\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\Util;\n\n/**\n * Calculates the logical negation of a matcher.\n */\nclass IsNot extends BaseMatcher\n{\n\n    private Matcher $_matcher;\n\n    public function __construct(Matcher $matcher)\n    {\n        $this->_matcher = $matcher;\n    }\n\n    public function matches($arg): bool\n    {\n        return !$this->_matcher->matches($arg);\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText('not ')->appendDescriptionOf($this->_matcher);\n    }\n\n    /**\n     * Matches if value does not match $value.\n     *\n     * @factory\n     * @param mixed $value\n     */\n    public static function not($value): self\n    {\n        return new self(Util::wrapValueWithIsEqual($value));\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/IsNull.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\BaseMatcher;\nuse Hamcrest\\Description;\n\n/**\n * Is the value null?\n */\nclass IsNull extends BaseMatcher\n{\n\n    private static ?self $_INSTANCE = null;\n    private static ?IsNot $_NOT_INSTANCE = null;\n\n    public function matches($item): bool\n    {\n        return is_null($item);\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText('null');\n    }\n\n    /**\n     * Matches if value is null.\n     *\n     * @factory\n     */\n    public static function nullValue(): self\n    {\n        if (!self::$_INSTANCE) {\n            self::$_INSTANCE = new self();\n        }\n\n        return self::$_INSTANCE;\n    }\n\n    /**\n     * Matches if value is not null.\n     *\n     * @factory\n     */\n    public static function notNullValue(): IsNot\n    {\n        if (!self::$_NOT_INSTANCE) {\n            self::$_NOT_INSTANCE = IsNot::not(self::nullValue());\n        }\n\n        return self::$_NOT_INSTANCE;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/IsSame.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\BaseMatcher;\nuse Hamcrest\\Description;\n\n/**\n * Is the value the same object as another value?\n * In PHP terms, does $a === $b?\n */\nclass IsSame extends BaseMatcher\n{\n\n    /**\n     * @var mixed object\n     */\n    private $_object;\n\n    /**\n     * @param mixed $object\n     */\n    public function __construct($object)\n    {\n        $this->_object = $object;\n    }\n\n    public function matches($object): bool\n    {\n        return ($object === $this->_object) && ($this->_object === $object);\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText('sameInstance(')\n                                ->appendValue($this->_object)\n                                ->appendText(')')\n                                ;\n    }\n\n    /**\n     * Creates a new instance of IsSame.\n     *\n     * @param mixed $object\n     *   The predicate evaluates to true only when the argument is\n     *   this object.\n     *\n     * @return \\Hamcrest\\Core\\IsSame\n     * @factory\n     */\n    public static function sameInstance($object): self\n    {\n        return new self($object);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/IsTypeOf.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2010 hamcrest.org\n */\nuse Hamcrest\\BaseMatcher;\nuse Hamcrest\\Description;\n\n/**\n * Tests whether the value has a built-in type.\n */\nclass IsTypeOf extends BaseMatcher\n{\n\n    private string $_theType;\n\n    /**\n     * Creates a new instance of IsTypeOf\n     *\n     * @param string $theType\n     *   The predicate evaluates to true for values with this built-in type.\n     */\n    public function __construct(string $theType)\n    {\n        $this->_theType = strtolower($theType);\n    }\n\n    public function matches($item): bool\n    {\n        return strtolower(gettype($item)) == $this->_theType;\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText(self::getTypeDescription($this->_theType));\n    }\n\n    public function describeMismatch($item, Description $description): void\n    {\n        if ($item === null) {\n            $description->appendText('was null');\n        } else {\n            $description->appendText('was ')\n                                    ->appendText(self::getTypeDescription(strtolower(gettype($item))))\n                                    ->appendText(' ')\n                                    ->appendValue($item)\n                                    ;\n        }\n    }\n\n    public static function getTypeDescription(string $type): string\n    {\n        if ($type == 'null') {\n            return 'null';\n        }\n\n        return (strpos('aeiou', substr($type, 0, 1)) === false ? 'a ' : 'an ')\n                . $type;\n    }\n\n    /**\n     * Is the value a particular built-in type?\n     *\n     * @factory\n     * @param string $theType\n     */\n    public static function typeOf(string $theType): self\n    {\n        return new self($theType);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/Set.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2010 hamcrest.org\n */\nuse Hamcrest\\BaseMatcher;\nuse Hamcrest\\Description;\n\n/**\n * Tests if a value (class, object, or array) has a named property.\n *\n * For example:\n * <pre>\n * assertThat(array('a', 'b'), set('b'));\n * assertThat($foo, set('bar'));\n * assertThat('Server', notSet('defaultPort'));\n * </pre>\n *\n * @todo Replace $property with a matcher and iterate all property names.\n */\nclass Set extends BaseMatcher\n{\n\n    /**\n     * @var mixed $_property\n     */\n    private $_property;\n    private bool $_not;\n\n    /**\n     * @param mixed $property\n     */\n    public function __construct($property, bool $not = false)\n    {\n        $this->_property = $property;\n        $this->_not = $not;\n    }\n\n    public function matches($item): bool\n    {\n        if ($item === null) {\n            return false;\n        }\n        $property = $this->_property;\n        if (is_array($item)) {\n            $result = isset($item[$property]);\n        } elseif (is_object($item)) {\n            $result = isset($item->$property);\n        } elseif (is_string($item)) {\n            $result = isset($item::$$property);\n        } else {\n            throw new \\InvalidArgumentException('Must pass an object, array, or class name');\n        }\n\n        return $this->_not ? !$result : $result;\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText($this->_not ? 'unset property ' : 'set property ')->appendText($this->_property);\n    }\n\n    public function describeMismatch($item, Description $description): void\n    {\n        $value = '';\n        if (!$this->_not) {\n            $description->appendText('was not set');\n        } else {\n            $property = $this->_property;\n            if (is_array($item)) {\n                $value = $item[$property];\n            } elseif (is_object($item)) {\n                $value = $item->$property;\n            } elseif (is_string($item)) {\n                $value = $item::$$property;\n            }\n            parent::describeMismatch($value, $description);\n        }\n    }\n\n    /**\n     * Matches if value (class, object, or array) has named $property.\n     *\n     * @factory\n     * @param mixed $property\n     */\n    public static function set($property): self\n    {\n        return new self($property);\n    }\n\n    /**\n     * Matches if value (class, object, or array) does not have named $property.\n     *\n     * @factory\n     * @param mixed $property\n     */\n    public static function notSet($property): self\n    {\n        return new self($property, true);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Core/ShortcutCombination.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\BaseMatcher;\nuse Hamcrest\\Description;\nuse Hamcrest\\Matcher;\nuse Hamcrest\\Util;\n\nabstract class ShortcutCombination extends BaseMatcher\n{\n\n    /**\n     * @var array<Matcher>\n     */\n    private $_matchers;\n\n    /**\n     * @param array<Matcher> $matchers\n     */\n    public function __construct(array $matchers)\n    {\n        Util::checkAllAreMatchers($matchers);\n\n        $this->_matchers = $matchers;\n    }\n\n    /**\n     * @param mixed $item\n     */\n    protected function matchesWithShortcut($item, bool $shortcut): bool\n    {\n        foreach ($this->_matchers as $matcher) {\n            if ($matcher->matches($item) == $shortcut) {\n                return $shortcut;\n            }\n        }\n\n        return !$shortcut;\n    }\n\n    public function describeToWithOperator(Description $description, string $operator): void\n    {\n        $description->appendList('(', ' ' . $operator . ' ', ')', $this->_matchers);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Description.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\n/**\n * A description of a Matcher. A Matcher will describe itself to a description\n * which can later be used for reporting.\n *\n * @see Hamcrest\\Matcher::describeTo()\n */\ninterface Description\n{\n\n    /**\n     * Appends some plain text to the description.\n     *\n     * @param string $text\n     *\n     * @return static\n     */\n    public function appendText(string $text): self;\n\n    /**\n     * Appends the description of a {@link Hamcrest\\SelfDescribing} value to\n     * this description.\n     *\n     * @param \\Hamcrest\\SelfDescribing $value\n     *\n     * @return static\n     */\n    public function appendDescriptionOf(SelfDescribing $value);\n\n    /**\n     * Appends an arbitrary value to the description.\n     *\n     * @param mixed $value\n     *\n     * @return static\n     */\n    public function appendValue($value): self;\n\n    /**\n     * Appends a list of values to the description.\n     *\n     * @param string $start\n     * @param string $separator\n     * @param string $end\n     * @param iterable<mixed> $values\n     *\n     * @return static\n     */\n    public function appendValueList(string $start, string $separator, string $end, iterable $values): self;\n\n    /**\n     * Appends a list of {@link Hamcrest\\SelfDescribing} objects to the\n     * description.\n     *\n     * @param string $start\n     * @param string $separator\n     * @param string $end\n     * @param iterable<SelfDescribing> $values\n     *\n     * @return static\n     */\n    public function appendList(string $start, string $separator, string $end, iterable $values): self;\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/DiagnosingMatcher.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\n/**\n * Official documentation for this class is missing.\n */\nabstract class DiagnosingMatcher extends BaseMatcher\n{\n\n    final public function matches($item): bool\n    {\n        return $this->matchesWithDiagnosticDescription($item, new NullDescription());\n    }\n\n    public function describeMismatch($item, Description $mismatchDescription): void\n    {\n        $this->matchesWithDiagnosticDescription($item, $mismatchDescription);\n    }\n\n    /**\n     * @param mixed $item\n     */\n    abstract protected function matchesWithDiagnosticDescription($item, Description $mismatchDescription): bool;\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/FeatureMatcher.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\n/**\n * Supporting class for matching a feature of an object. Implement\n * <code>featureValueOf()</code> in a subclass to pull out the feature to be\n * matched against.\n */\nabstract class FeatureMatcher extends TypeSafeDiagnosingMatcher\n{\n\n    private Matcher $_subMatcher;\n    private string $_featureDescription;\n    private string $_featureName;\n\n    /**\n     * Constructor.\n     *\n     * @param self::TYPE_* $type\n     * @param ?string $subtype\n     * @param \\Hamcrest\\Matcher $subMatcher The matcher to apply to the feature\n     * @param string $featureDescription Descriptive text to use in describeTo\n     * @param string $featureName Identifying text for mismatch message\n     */\n    public function __construct(int $type, ?string $subtype, Matcher $subMatcher, string $featureDescription, string $featureName)\n    {\n        parent::__construct($type, $subtype);\n\n        $this->_subMatcher = $subMatcher;\n        $this->_featureDescription = $featureDescription;\n        $this->_featureName = $featureName;\n    }\n\n    /**\n     * Implement this to extract the interesting feature.\n     *\n     * @param mixed $actual the target object\n     *\n     * @return mixed the feature to be matched\n     */\n    abstract protected function featureValueOf($actual);\n\n    public function matchesSafelyWithDiagnosticDescription($actual, Description $mismatchDescription): bool\n    {\n        $featureValue = $this->featureValueOf($actual);\n\n        if (!$this->_subMatcher->matches($featureValue)) {\n            $mismatchDescription->appendText($this->_featureName)\n                                                    ->appendText(' was ')->appendValue($featureValue);\n\n            return false;\n        }\n\n        return true;\n    }\n\n    final public function describeTo(Description $description): void\n    {\n        $description->appendText($this->_featureDescription)->appendText(' ')\n                                ->appendDescriptionOf($this->_subMatcher)\n                             ;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Internal/SelfDescribingValue.php",
    "content": "<?php\nnamespace Hamcrest\\Internal;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\SelfDescribing;\n\n/**\n * A wrapper around any value so that it describes itself.\n */\nclass SelfDescribingValue implements SelfDescribing\n{\n    /**\n     * @var mixed\n     */\n    private $_value;\n\n    /**\n     * @param mixed $value\n     */\n    public function __construct($value)\n    {\n        $this->_value = $value;\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendValue($this->_value);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Matcher.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\n/**\n * A matcher over acceptable values.\n * A matcher is able to describe itself to give feedback when it fails.\n * <p/>\n * Matcher implementations should <b>NOT directly implement this interface</b>.\n * Instead, <b>extend</b> the {@link Hamcrest\\BaseMatcher} abstract class,\n * which will ensure that the Matcher API can grow to support\n * new features and remain compatible with all Matcher implementations.\n * <p/>\n * For easy access to common Matcher implementations, use the static factory\n * methods in {@link Hamcrest\\CoreMatchers}.\n *\n * @see Hamcrest\\CoreMatchers\n * @see Hamcrest\\BaseMatcher\n */\ninterface Matcher extends SelfDescribing\n{\n\n    /**\n     * Evaluates the matcher for argument <var>$item</var>.\n     *\n     * @param mixed $item the object against which the matcher is evaluated.\n     *\n     * @return boolean <code>true</code> if <var>$item</var> matches,\n     *   otherwise <code>false</code>.\n     *\n     * @see Hamcrest\\BaseMatcher\n     */\n    public function matches($item): bool;\n\n        /**\n         * Generate a description of why the matcher has not accepted the item.\n         * The description will be part of a larger description of why a matching\n         * failed, so it should be concise.\n         * This method assumes that <code>matches($item)</code> is false, but\n         * will not check this.\n         *\n         * @param mixed $item The item that the Matcher has rejected.\n         * @param Description $description\n         * @return void\n         */\n    public function describeMismatch($item, Description $description): void;\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/MatcherAssert.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\nclass MatcherAssert\n{\n\n    /**\n     * Number of assertions performed.\n     *\n     * @var int\n     */\n    private static int $_count = 0;\n\n    /**\n     * Make an assertion and throw {@link Hamcrest\\AssertionError} if it fails.\n     *\n     * The first parameter may optionally be a string identifying the assertion\n     * to be included in the failure message.\n     *\n     * If the third parameter is not a matcher it is passed to\n     * {@link Hamcrest\\Core\\IsEqual#equalTo} to create one.\n     *\n     * Example:\n     * <pre>\n     * // With an identifier\n     * assertThat(\"apple flavour\", $apple->flavour(), equalTo(\"tasty\"));\n     * // Without an identifier\n     * assertThat($apple->flavour(), equalTo(\"tasty\"));\n     * // Evaluating a boolean expression\n     * assertThat(\"some error\", $a > $b);\n     * assertThat($a > $b);\n     * </pre>\n     */\n    public static function assertThat(/* $args ... */): void\n    {\n        $args = func_get_args();\n        switch (count($args)) {\n            case 1:\n                self::$_count++;\n                if (!$args[0]) {\n                    throw new AssertionError();\n                }\n                break;\n\n            case 2:\n                self::$_count++;\n                if ($args[1] instanceof Matcher) {\n                    self::doAssert('', $args[0], $args[1]);\n                } elseif (!$args[1]) {\n                    throw new AssertionError($args[0]);\n                }\n                break;\n\n            case 3:\n                self::$_count++;\n                self::doAssert(\n                    $args[0],\n                    $args[1],\n                    Util::wrapValueWithIsEqual($args[2])\n                );\n                break;\n\n            default:\n                throw new \\InvalidArgumentException('assertThat() requires one to three arguments');\n        }\n    }\n\n    /**\n     * Returns the number of assertions performed.\n     *\n     * @return int\n     */\n    public static function getCount(): int\n    {\n        return self::$_count;\n    }\n\n    /**\n     * Resets the number of assertions performed to zero.\n     */\n    public static function resetCount(): void\n    {\n        self::$_count = 0;\n    }\n\n    /**\n     * Performs the actual assertion logic.\n     *\n     * If <code>$matcher</code> doesn't match <code>$actual</code>,\n     * throws a {@link Hamcrest\\AssertionError} with a description\n     * of the failure along with the optional <code>$identifier</code>.\n     *\n     * @param string $identifier added to the message upon failure\n     * @param mixed $actual value to compare against <code>$matcher</code>\n     * @param \\Hamcrest\\Matcher $matcher applied to <code>$actual</code>\n     * @throws AssertionError\n     */\n    private static function doAssert($identifier, $actual, Matcher $matcher): void\n    {\n        if (!$matcher->matches($actual)) {\n            $description = new StringDescription();\n            if (!empty($identifier)) {\n                $description->appendText($identifier . PHP_EOL);\n            }\n            $description->appendText('Expected: ')\n                                    ->appendDescriptionOf($matcher)\n                                    ->appendText(PHP_EOL . '     but: ');\n\n            $matcher->describeMismatch($actual, $description);\n\n            throw new AssertionError((string) $description);\n        }\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Matchers.php",
    "content": "<?php\n\n/*\n Copyright (c) 2009-2010 hamcrest.org\n */\n\n// This file is generated from the static method @factory doctags.\n\nnamespace Hamcrest;\n\n/**\n * A series of static factories for all hamcrest matchers.\n */\nclass Matchers\n{\n\n    /**\n     * Evaluates to true only if each $matcher[$i] is satisfied by $array[$i].\n     */\n    public static function anArray(/* args... */): \\Hamcrest\\Arrays\\IsArray\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Arrays\\IsArray', 'anArray'), $args);\n    }\n\n    /**\n     * Evaluates to true if any item in an array satisfies the given matcher.\n     *\n     * @param mixed $item as a {@link Hamcrest\\Matcher} or a value.\n     *\n     * @return \\Hamcrest\\Arrays\\IsArrayContaining\n     */\n    public static function hasItemInArray($item): \\Hamcrest\\Arrays\\IsArrayContaining\n    {\n        return \\Hamcrest\\Arrays\\IsArrayContaining::hasItemInArray($item);\n    }\n\n    /**\n     * Evaluates to true if any item in an array satisfies the given matcher.\n     *\n     * @param mixed $item as a {@link Hamcrest\\Matcher} or a value.\n     *\n     * @return \\Hamcrest\\Arrays\\IsArrayContaining\n     */\n    public static function hasValue($item): \\Hamcrest\\Arrays\\IsArrayContaining\n    {\n        return \\Hamcrest\\Arrays\\IsArrayContaining::hasItemInArray($item);\n    }\n\n    /**\n     * An array with elements that match the given matchers.\n     */\n    public static function arrayContainingInAnyOrder(/* args... */): \\Hamcrest\\Arrays\\IsArrayContainingInAnyOrder\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Arrays\\IsArrayContainingInAnyOrder', 'arrayContainingInAnyOrder'), $args);\n    }\n\n    /**\n     * An array with elements that match the given matchers.\n     */\n    public static function containsInAnyOrder(/* args... */): \\Hamcrest\\Arrays\\IsArrayContainingInAnyOrder\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Arrays\\IsArrayContainingInAnyOrder', 'arrayContainingInAnyOrder'), $args);\n    }\n\n    /**\n     * An array with elements that match the given matchers in the same order.\n     */\n    public static function arrayContaining(/* args... */): \\Hamcrest\\Arrays\\IsArrayContainingInOrder\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Arrays\\IsArrayContainingInOrder', 'arrayContaining'), $args);\n    }\n\n    /**\n     * An array with elements that match the given matchers in the same order.\n     */\n    public static function contains(/* args... */): \\Hamcrest\\Arrays\\IsArrayContainingInOrder\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Arrays\\IsArrayContainingInOrder', 'arrayContaining'), $args);\n    }\n\n    /**\n     * Evaluates to true if any key in an array matches the given matcher.\n     *\n     * @param mixed $key as a {@link Hamcrest\\Matcher} or a value.\n     *\n     * @return \\Hamcrest\\Arrays\\IsArrayContainingKey\n     */\n    public static function hasKeyInArray($key): \\Hamcrest\\Arrays\\IsArrayContainingKey\n    {\n        return \\Hamcrest\\Arrays\\IsArrayContainingKey::hasKeyInArray($key);\n    }\n\n    /**\n     * Evaluates to true if any key in an array matches the given matcher.\n     *\n     * @param mixed $key as a {@link Hamcrest\\Matcher} or a value.\n     *\n     * @return \\Hamcrest\\Arrays\\IsArrayContainingKey\n     */\n    public static function hasKey($key): \\Hamcrest\\Arrays\\IsArrayContainingKey\n    {\n        return \\Hamcrest\\Arrays\\IsArrayContainingKey::hasKeyInArray($key);\n    }\n\n    /**\n     * Test if an array has both an key and value in parity with each other.\n     *\n     * @param mixed $key\n     * @param mixed $value\n     */\n    public static function hasKeyValuePair($key, $value): \\Hamcrest\\Arrays\\IsArrayContainingKeyValuePair\n    {\n        return \\Hamcrest\\Arrays\\IsArrayContainingKeyValuePair::hasKeyValuePair($key, $value);\n    }\n\n    /**\n     * Test if an array has both an key and value in parity with each other.\n     *\n     * @param mixed $key\n     * @param mixed $value\n     */\n    public static function hasEntry($key, $value): \\Hamcrest\\Arrays\\IsArrayContainingKeyValuePair\n    {\n        return \\Hamcrest\\Arrays\\IsArrayContainingKeyValuePair::hasKeyValuePair($key, $value);\n    }\n\n    /**\n     * Does array size satisfy a given matcher?\n     *\n     * @param \\Hamcrest\\Matcher|int $size as a {@link Hamcrest\\Matcher} or a value.\n     *\n     * @return \\Hamcrest\\Arrays\\IsArrayWithSize\n     */\n    public static function arrayWithSize($size): \\Hamcrest\\Arrays\\IsArrayWithSize\n    {\n        return \\Hamcrest\\Arrays\\IsArrayWithSize::arrayWithSize($size);\n    }\n\n    /**\n     * Matches an empty array.\n     */\n    public static function emptyArray(): \\Hamcrest\\Core\\DescribedAs\n    {\n        return \\Hamcrest\\Arrays\\IsArrayWithSize::emptyArray();\n    }\n\n    /**\n     * Matches an empty array.\n     */\n    public static function nonEmptyArray(): \\Hamcrest\\Core\\DescribedAs\n    {\n        return \\Hamcrest\\Arrays\\IsArrayWithSize::nonEmptyArray();\n    }\n\n    /**\n     * Returns true if traversable is empty.\n     */\n    public static function emptyTraversable(): \\Hamcrest\\Collection\\IsEmptyTraversable\n    {\n        return \\Hamcrest\\Collection\\IsEmptyTraversable::emptyTraversable();\n    }\n\n    /**\n     * Returns true if traversable is not empty.\n     */\n    public static function nonEmptyTraversable(): \\Hamcrest\\Collection\\IsEmptyTraversable\n    {\n        return \\Hamcrest\\Collection\\IsEmptyTraversable::nonEmptyTraversable();\n    }\n\n    /**\n     * Does traversable size satisfy a given matcher?\n     *\n     * @param mixed $size\n     */\n    public static function traversableWithSize($size): \\Hamcrest\\Collection\\IsTraversableWithSize\n    {\n        return \\Hamcrest\\Collection\\IsTraversableWithSize::traversableWithSize($size);\n    }\n\n    /**\n     * Evaluates to true only if ALL of the passed in matchers evaluate to true.\n     */\n    public static function allOf(/* args... */): \\Hamcrest\\Core\\AllOf\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Core\\AllOf', 'allOf'), $args);\n    }\n\n    /**\n     * Evaluates to true if ANY of the passed in matchers evaluate to true.\n     */\n    public static function anyOf(/* args... */): \\Hamcrest\\Core\\AnyOf\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Core\\AnyOf', 'anyOf'), $args);\n    }\n\n    /**\n     * Evaluates to false if ANY of the passed in matchers evaluate to true.\n     */\n    public static function noneOf(/* args... */): \\Hamcrest\\Core\\IsNot\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Core\\AnyOf', 'noneOf'), $args);\n    }\n\n    /**\n     * This is useful for fluently combining matchers that must both pass.\n     * For example:\n     * <pre>\n     *   assertThat($string, both(containsString(\"a\"))->andAlso(containsString(\"b\")));\n     * </pre>\n     */\n    public static function both(\\Hamcrest\\Matcher $matcher): \\Hamcrest\\Core\\CombinableMatcher\n    {\n        return \\Hamcrest\\Core\\CombinableMatcher::both($matcher);\n    }\n\n    /**\n     * This is useful for fluently combining matchers where either may pass,\n     * for example:\n     * <pre>\n     *   assertThat($string, either(containsString(\"a\"))->orElse(containsString(\"b\")));\n     * </pre>\n     */\n    public static function either(\\Hamcrest\\Matcher $matcher): \\Hamcrest\\Core\\CombinableMatcher\n    {\n        return \\Hamcrest\\Core\\CombinableMatcher::either($matcher);\n    }\n\n    /**\n     * Wraps an existing matcher and overrides the description when it fails.\n     */\n    public static function describedAs(/* args... */): \\Hamcrest\\Core\\DescribedAs\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Core\\DescribedAs', 'describedAs'), $args);\n    }\n\n    /**\n     * @param \\Hamcrest\\Matcher $itemMatcher\n     *   A matcher to apply to every element in an array.\n     *\n     * @return \\Hamcrest\\Core\\Every\n     *   Evaluates to TRUE for a collection in which every item matches $itemMatcher\n     */\n    public static function everyItem(\\Hamcrest\\Matcher $itemMatcher): \\Hamcrest\\Core\\Every\n    {\n        return \\Hamcrest\\Core\\Every::everyItem($itemMatcher);\n    }\n\n    /**\n     * Creates a matcher that matches any examined object whose <code>toString</code> or\n     * <code>__toString()</code> method returns a value equalTo the specified string.\n     *\n     * @param mixed $matcher\n     */\n    public static function hasToString($matcher): \\Hamcrest\\Core\\HasToString\n    {\n        return \\Hamcrest\\Core\\HasToString::hasToString($matcher);\n    }\n\n    /**\n     * Decorates another Matcher, retaining the behavior but allowing tests\n     * to be slightly more expressive.\n     *\n     * For example:  assertThat($cheese, equalTo($smelly))\n     *          vs.  assertThat($cheese, is(equalTo($smelly)))\n     *\n     * @param mixed $value\n     */\n    public static function is($value): \\Hamcrest\\Core\\Is\n    {\n        return \\Hamcrest\\Core\\Is::is($value);\n    }\n\n    /**\n     * This matcher always evaluates to true.\n     *\n     * @param string $description A meaningful string used when describing itself.\n     */\n    public static function anything(string $description = 'ANYTHING'): \\Hamcrest\\Core\\IsAnything\n    {\n        return \\Hamcrest\\Core\\IsAnything::anything($description);\n    }\n\n    /**\n     * Test if the value is an array containing this matcher.\n     *\n     * Example:\n     * <pre>\n     * assertThat(array('a', 'b'), hasItem(equalTo('b')));\n     * //Convenience defaults to equalTo()\n     * assertThat(array('a', 'b'), hasItem('b'));\n     * </pre>\n     */\n    public static function hasItem(/* args... */): \\Hamcrest\\Core\\IsCollectionContaining\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Core\\IsCollectionContaining', 'hasItem'), $args);\n    }\n\n    /**\n     * Test if the value is an array containing elements that match all of these\n     * matchers.\n     *\n     * Example:\n     * <pre>\n     * assertThat(array('a', 'b', 'c'), hasItems(equalTo('a'), equalTo('b')));\n     * </pre>\n     */\n    public static function hasItems(/* args... */): \\Hamcrest\\Core\\AllOf\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Core\\IsCollectionContaining', 'hasItems'), $args);\n    }\n\n    /**\n     * Is the value equal to another value, as tested by the use of the \"==\"\n     * comparison operator?\n     *\n     * @param mixed $item\n     */\n    public static function equalTo($item): \\Hamcrest\\Core\\IsEqual\n    {\n        return \\Hamcrest\\Core\\IsEqual::equalTo($item);\n    }\n\n    /**\n     * Tests of the value is identical to $value as tested by the \"===\" operator.\n     *\n     * @param mixed $value\n     */\n    public static function identicalTo($value): \\Hamcrest\\Core\\IsIdentical\n    {\n        return \\Hamcrest\\Core\\IsIdentical::identicalTo($value);\n    }\n\n    /**\n     * Is the value an instance of a particular type?\n     * This version assumes no relationship between the required type and\n     * the signature of the method that sets it up, for example in\n     * <code>assertThat($anObject, anInstanceOf('Thing'));</code>\n     */\n    public static function anInstanceOf(string $theClass): \\Hamcrest\\Core\\IsInstanceOf\n    {\n        return \\Hamcrest\\Core\\IsInstanceOf::anInstanceOf($theClass);\n    }\n\n    /**\n     * Is the value an instance of a particular type?\n     * This version assumes no relationship between the required type and\n     * the signature of the method that sets it up, for example in\n     * <code>assertThat($anObject, anInstanceOf('Thing'));</code>\n     */\n    public static function any(string $theClass): \\Hamcrest\\Core\\IsInstanceOf\n    {\n        return \\Hamcrest\\Core\\IsInstanceOf::anInstanceOf($theClass);\n    }\n\n    /**\n     * Matches if value does not match $value.\n     *\n     * @param mixed $value\n     */\n    public static function not($value): \\Hamcrest\\Core\\IsNot\n    {\n        return \\Hamcrest\\Core\\IsNot::not($value);\n    }\n\n    /**\n     * Matches if value is null.\n     */\n    public static function nullValue(): \\Hamcrest\\Core\\IsNull\n    {\n        return \\Hamcrest\\Core\\IsNull::nullValue();\n    }\n\n    /**\n     * Matches if value is not null.\n     */\n    public static function notNullValue(): \\Hamcrest\\Core\\IsNot\n    {\n        return \\Hamcrest\\Core\\IsNull::notNullValue();\n    }\n\n    /**\n     * Creates a new instance of IsSame.\n     *\n     * @param mixed $object\n     *   The predicate evaluates to true only when the argument is\n     *   this object.\n     *\n     * @return \\Hamcrest\\Core\\IsSame\n     */\n    public static function sameInstance($object): \\Hamcrest\\Core\\IsSame\n    {\n        return \\Hamcrest\\Core\\IsSame::sameInstance($object);\n    }\n\n    /**\n     * Is the value a particular built-in type?\n     *\n     * @param string $theType\n     */\n    public static function typeOf(string $theType): \\Hamcrest\\Core\\IsTypeOf\n    {\n        return \\Hamcrest\\Core\\IsTypeOf::typeOf($theType);\n    }\n\n    /**\n     * Matches if value (class, object, or array) has named $property.\n     *\n     * @param mixed $property\n     */\n    public static function set($property): \\Hamcrest\\Core\\Set\n    {\n        return \\Hamcrest\\Core\\Set::set($property);\n    }\n\n    /**\n     * Matches if value (class, object, or array) does not have named $property.\n     *\n     * @param mixed $property\n     */\n    public static function notSet($property): \\Hamcrest\\Core\\Set\n    {\n        return \\Hamcrest\\Core\\Set::notSet($property);\n    }\n\n    /**\n     * Matches if value is a number equal to $value within some range of\n     * acceptable error $delta.\n     *\n     * @param mixed $value\n     * @param mixed $delta\n     */\n    public static function closeTo($value, $delta): \\Hamcrest\\Number\\IsCloseTo\n    {\n        return \\Hamcrest\\Number\\IsCloseTo::closeTo($value, $delta);\n    }\n\n    /**\n     * The value is not > $value, nor < $value.\n     *\n     * @param mixed $value\n     */\n    public static function comparesEqualTo($value): \\Hamcrest\\Number\\OrderingComparison\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::comparesEqualTo($value);\n    }\n\n    /**\n     * The value is > $value.\n     *\n     * @param mixed $value\n     */\n    public static function greaterThan($value): \\Hamcrest\\Number\\OrderingComparison\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::greaterThan($value);\n    }\n\n    /**\n     * The value is >= $value.\n     *\n     * @param mixed $value\n     */\n    public static function greaterThanOrEqualTo($value): \\Hamcrest\\Number\\OrderingComparison\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::greaterThanOrEqualTo($value);\n    }\n\n    /**\n     * The value is >= $value.\n     *\n     * @param mixed $value\n     */\n    public static function atLeast($value): \\Hamcrest\\Number\\OrderingComparison\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::greaterThanOrEqualTo($value);\n    }\n\n    /**\n     * The value is < $value.\n     *\n     * @param mixed $value\n     */\n    public static function lessThan($value): \\Hamcrest\\Number\\OrderingComparison\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::lessThan($value);\n    }\n\n    /**\n     * The value is <= $value.\n     *\n     * @param mixed $value\n     */\n    public static function lessThanOrEqualTo($value): \\Hamcrest\\Number\\OrderingComparison\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::lessThanOrEqualTo($value);\n    }\n\n    /**\n     * The value is <= $value.\n     *\n     * @param mixed $value\n     */\n    public static function atMost($value): \\Hamcrest\\Number\\OrderingComparison\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::lessThanOrEqualTo($value);\n    }\n\n    /**\n     * Matches if value is a zero-length string.\n     */\n    public static function isEmptyString(): \\Hamcrest\\Text\\IsEmptyString\n    {\n        return \\Hamcrest\\Text\\IsEmptyString::isEmptyString();\n    }\n\n    /**\n     * Matches if value is a zero-length string.\n     */\n    public static function emptyString(): \\Hamcrest\\Text\\IsEmptyString\n    {\n        return \\Hamcrest\\Text\\IsEmptyString::isEmptyString();\n    }\n\n    /**\n     * Matches if value is null or a zero-length string.\n     */\n    public static function isEmptyOrNullString(): \\Hamcrest\\Core\\AnyOf\n    {\n        return \\Hamcrest\\Text\\IsEmptyString::isEmptyOrNullString();\n    }\n\n    /**\n     * Matches if value is null or a zero-length string.\n     */\n    public static function nullOrEmptyString(): \\Hamcrest\\Core\\AnyOf\n    {\n        return \\Hamcrest\\Text\\IsEmptyString::isEmptyOrNullString();\n    }\n\n    /**\n     * Matches if value is a non-zero-length string.\n     */\n    public static function isNonEmptyString(): \\Hamcrest\\Text\\IsEmptyString\n    {\n        return \\Hamcrest\\Text\\IsEmptyString::isNonEmptyString();\n    }\n\n    /**\n     * Matches if value is a non-zero-length string.\n     */\n    public static function nonEmptyString(): \\Hamcrest\\Text\\IsEmptyString\n    {\n        return \\Hamcrest\\Text\\IsEmptyString::isNonEmptyString();\n    }\n\n    /**\n     * Matches if value is a string equal to $string, regardless of the case.\n     *\n     * @param mixed $string\n     */\n    public static function equalToIgnoringCase($string): \\Hamcrest\\Text\\IsEqualIgnoringCase\n    {\n        return \\Hamcrest\\Text\\IsEqualIgnoringCase::equalToIgnoringCase($string);\n    }\n\n    /**\n     * Matches if value is a string equal to $string, regardless of whitespace.\n     *\n     * @param mixed $string\n     */\n    public static function equalToIgnoringWhiteSpace($string): \\Hamcrest\\Text\\IsEqualIgnoringWhiteSpace\n    {\n        return \\Hamcrest\\Text\\IsEqualIgnoringWhiteSpace::equalToIgnoringWhiteSpace($string);\n    }\n\n    /**\n     * Matches if value is a string that matches regular expression $pattern.\n     *\n     * @param mixed $pattern\n     */\n    public static function matchesPattern($pattern): \\Hamcrest\\Text\\MatchesPattern\n    {\n        return \\Hamcrest\\Text\\MatchesPattern::matchesPattern($pattern);\n    }\n\n    /**\n     * Matches if value is a string that contains $substring.\n     *\n     * @param mixed $substring\n     */\n    public static function containsString($substring): \\Hamcrest\\Text\\StringContains\n    {\n        return \\Hamcrest\\Text\\StringContains::containsString($substring);\n    }\n\n    /**\n     * Matches if value is a string that contains $substring regardless of the case.\n     *\n     * @param mixed $substring\n     */\n    public static function containsStringIgnoringCase($substring): \\Hamcrest\\Text\\StringContainsIgnoringCase\n    {\n        return \\Hamcrest\\Text\\StringContainsIgnoringCase::containsStringIgnoringCase($substring);\n    }\n\n    /**\n     * Matches if value contains $substrings in a constrained order.\n     */\n    public static function stringContainsInOrder(/* args... */): \\Hamcrest\\Text\\StringContainsInOrder\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Text\\StringContainsInOrder', 'stringContainsInOrder'), $args);\n    }\n\n    /**\n     * Matches if value is a string that ends with $substring.\n     *\n     * @param mixed $substring\n     */\n    public static function endsWith($substring): \\Hamcrest\\Text\\StringEndsWith\n    {\n        return \\Hamcrest\\Text\\StringEndsWith::endsWith($substring);\n    }\n\n    /**\n     * Matches if value is a string that starts with $substring.\n     *\n     * @param mixed $substring\n     */\n    public static function startsWith($substring): \\Hamcrest\\Text\\StringStartsWith\n    {\n        return \\Hamcrest\\Text\\StringStartsWith::startsWith($substring);\n    }\n\n    /**\n     * Is the value an array?\n     */\n    public static function arrayValue(): \\Hamcrest\\Type\\IsArray\n    {\n        return \\Hamcrest\\Type\\IsArray::arrayValue();\n    }\n\n    /**\n     * Is the value a boolean?\n     */\n    public static function booleanValue(): \\Hamcrest\\Type\\IsBoolean\n    {\n        return \\Hamcrest\\Type\\IsBoolean::booleanValue();\n    }\n\n    /**\n     * Is the value a boolean?\n     */\n    public static function boolValue(): \\Hamcrest\\Type\\IsBoolean\n    {\n        return \\Hamcrest\\Type\\IsBoolean::booleanValue();\n    }\n\n    /**\n     * Is the value callable?\n     */\n    public static function callableValue(): \\Hamcrest\\Type\\IsCallable\n    {\n        return \\Hamcrest\\Type\\IsCallable::callableValue();\n    }\n\n    /**\n     * Is the value a float/double?\n     */\n    public static function doubleValue(): \\Hamcrest\\Type\\IsDouble\n    {\n        return \\Hamcrest\\Type\\IsDouble::doubleValue();\n    }\n\n    /**\n     * Is the value a float/double?\n     */\n    public static function floatValue(): \\Hamcrest\\Type\\IsDouble\n    {\n        return \\Hamcrest\\Type\\IsDouble::doubleValue();\n    }\n\n    /**\n     * Is the value an integer?\n     */\n    public static function integerValue(): \\Hamcrest\\Type\\IsInteger\n    {\n        return \\Hamcrest\\Type\\IsInteger::integerValue();\n    }\n\n    /**\n     * Is the value an integer?\n     */\n    public static function intValue(): \\Hamcrest\\Type\\IsInteger\n    {\n        return \\Hamcrest\\Type\\IsInteger::integerValue();\n    }\n\n    /**\n     * Is the value a numeric?\n     */\n    public static function numericValue(): \\Hamcrest\\Type\\IsNumeric\n    {\n        return \\Hamcrest\\Type\\IsNumeric::numericValue();\n    }\n\n    /**\n     * Is the value an object?\n     */\n    public static function objectValue(): \\Hamcrest\\Type\\IsObject\n    {\n        return \\Hamcrest\\Type\\IsObject::objectValue();\n    }\n\n    /**\n     * Is the value an object?\n     */\n    public static function anObject(): \\Hamcrest\\Type\\IsObject\n    {\n        return \\Hamcrest\\Type\\IsObject::objectValue();\n    }\n\n    /**\n     * Is the value a resource?\n     */\n    public static function resourceValue(): \\Hamcrest\\Type\\IsResource\n    {\n        return \\Hamcrest\\Type\\IsResource::resourceValue();\n    }\n\n    /**\n     * Is the value a scalar (boolean, integer, double, or string)?\n     */\n    public static function scalarValue(): \\Hamcrest\\Type\\IsScalar\n    {\n        return \\Hamcrest\\Type\\IsScalar::scalarValue();\n    }\n\n    /**\n     * Is the value a string?\n     */\n    public static function stringValue(): \\Hamcrest\\Type\\IsString\n    {\n        return \\Hamcrest\\Type\\IsString::stringValue();\n    }\n\n    /**\n     * Wraps <code>$matcher</code> with {@link Hamcrest\\Core\\IsEqual)\n     * if it's not a matcher and the XPath in <code>count()</code>\n     * if it's an integer.\n     *\n     * @param string $xpath\n     * @param null|Matcher|int|mixed $matcher\n     */\n    public static function hasXPath(string $xpath, $matcher = null): \\Hamcrest\\Xml\\HasXPath\n    {\n        return \\Hamcrest\\Xml\\HasXPath::hasXPath($xpath, $matcher);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/NullDescription.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\n/**\n * Null implementation of {@link Hamcrest\\Description}.\n */\nclass NullDescription implements Description\n{\n\n    public function appendText(string $text): self\n    {\n        return $this;\n    }\n\n    public function appendDescriptionOf(SelfDescribing $value): self\n    {\n        return $this;\n    }\n\n    public function appendValue($value): self\n    {\n        return $this;\n    }\n\n    public function appendValueList(string $start, string $separator, string $end, $values): self\n    {\n        return $this;\n    }\n\n    public function appendList(string $start, string $separator, string $end, $values): self\n    {\n        return $this;\n    }\n\n    public function __toString()\n    {\n        return '';\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Number/IsCloseTo.php",
    "content": "<?php\nnamespace Hamcrest\\Number;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\TypeSafeMatcher;\n\n/**\n * Is the value a number equal to a value within some range of\n * acceptable error?\n */\nclass IsCloseTo extends TypeSafeMatcher\n{\n\n    /**\n     * @var mixed\n     */\n    private $_value;\n    /**\n     * @var mixed\n     */\n    private $_delta;\n\n    /**\n     * @param mixed $value\n     * @param mixed $delta\n     */\n    public function __construct($value, $delta)\n    {\n        parent::__construct(self::TYPE_NUMERIC);\n\n        $this->_value = $value;\n        $this->_delta = $delta;\n    }\n\n    protected function matchesSafely($item): bool\n    {\n        return $this->_actualDelta($item) <= 0.0;\n    }\n\n    protected function describeMismatchSafely($item, Description $mismatchDescription): void\n    {\n        $mismatchDescription->appendValue($item)\n                                                ->appendText(' differed by ')\n                                                ->appendValue($this->_actualDelta($item))\n                                                ;\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText('a numeric value within ')\n                                ->appendValue($this->_delta)\n                                ->appendText(' of ')\n                                ->appendValue($this->_value)\n                                ;\n    }\n\n    /**\n     * Matches if value is a number equal to $value within some range of\n     * acceptable error $delta.\n     *\n     * @factory\n     * @param mixed $value\n     * @param mixed $delta\n     */\n    public static function closeTo($value, $delta): self\n    {\n        return new self($value, $delta);\n    }\n\n    // -- Private Methods\n\n    /**\n     * @param mixed $item\n     * @return int|float\n     */\n    private function _actualDelta($item)\n    {\n        return (abs(($item - $this->_value)) - $this->_delta);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Number/OrderingComparison.php",
    "content": "<?php\nnamespace Hamcrest\\Number;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\nuse Hamcrest\\Description;\nuse Hamcrest\\TypeSafeMatcher;\n\nclass OrderingComparison extends TypeSafeMatcher\n{\n\n    /**\n     * @var mixed\n     */\n    private $_value;\n    /**\n     * @var mixed\n     */\n    private $_minCompare;\n    /**\n     * @var mixed\n     */\n    private $_maxCompare;\n\n    /**\n     * @param mixed $value\n     * @param mixed $maxCompare\n     * @param mixed $minCompare\n     */\n    public function __construct($value, $minCompare, $maxCompare)\n    {\n        parent::__construct(self::TYPE_NUMERIC);\n\n        $this->_value = $value;\n        $this->_minCompare = $minCompare;\n        $this->_maxCompare = $maxCompare;\n    }\n\n    protected function matchesSafely($other): bool\n    {\n        $compare = $this->_compare($this->_value, $other);\n\n        return ($this->_minCompare <= $compare) && ($compare <= $this->_maxCompare);\n    }\n\n    protected function describeMismatchSafely($item, Description $mismatchDescription): void\n    {\n        $mismatchDescription\n            ->appendValue($item)->appendText(' was ')\n            ->appendText($this->_comparison($this->_compare($this->_value, $item)))\n            ->appendText(' ')->appendValue($this->_value)\n            ;\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText('a value ')\n            ->appendText($this->_comparison($this->_minCompare))\n            ;\n        if ($this->_minCompare != $this->_maxCompare) {\n            $description->appendText(' or ')\n                ->appendText($this->_comparison($this->_maxCompare))\n                ;\n        }\n        $description->appendText(' ')->appendValue($this->_value);\n    }\n\n    /**\n     * The value is not > $value, nor < $value.\n     *\n     * @factory\n     * @param mixed $value\n     */\n    public static function comparesEqualTo($value): self\n    {\n        return new self($value, 0, 0);\n    }\n\n    /**\n     * The value is > $value.\n     *\n     * @factory\n     * @param mixed $value\n     */\n    public static function greaterThan($value): self\n    {\n        return new self($value, -1, -1);\n    }\n\n    /**\n     * The value is >= $value.\n     *\n     * @factory atLeast\n     * @param mixed $value\n     */\n    public static function greaterThanOrEqualTo($value): self\n    {\n        return new self($value, -1, 0);\n    }\n\n    /**\n     * The value is < $value.\n     *\n     * @factory\n     * @param mixed $value\n     */\n    public static function lessThan($value): self\n    {\n        return new self($value, 1, 1);\n    }\n\n    /**\n     * The value is <= $value.\n     *\n     * @factory atMost\n     * @param mixed $value\n     */\n    public static function lessThanOrEqualTo($value): self\n    {\n        return new self($value, 0, 1);\n    }\n\n    // -- Private Methods\n\n    /**\n     * @param mixed $left\n     * @param mixed $right\n     */\n    private function _compare($left, $right): int\n    {\n        $a = $left;\n        $b = $right;\n\n        if ($a < $b) {\n            return -1;\n        } elseif ($a == $b) {\n            return 0;\n        } else {\n            return 1;\n        }\n    }\n\n    /**\n     * @param mixed $compare\n     */\n    private function _comparison($compare): string\n    {\n        if ($compare > 0) {\n            return 'less than';\n        } elseif ($compare == 0) {\n            return 'equal to';\n        } else {\n            return 'greater than';\n        }\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/SelfDescribing.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\n/**\n * The ability of an object to describe itself.\n */\ninterface SelfDescribing\n{\n\n    /**\n     * Generates a description of the object.  The description may be part\n     * of a description of a larger object of which this is just a component,\n     * so it should be worded appropriately.\n     *\n     * @param \\Hamcrest\\Description $description\n     *   The description to be built or appended to.\n     */\n    public function describeTo(Description $description): void;\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/StringDescription.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\n/**\n * A {@link Hamcrest\\Description} that is stored as a string.\n */\nclass StringDescription extends BaseDescription\n{\n\n    private string $_out;\n\n    /**\n     * @param mixed $out\n     */\n    public function __construct($out = '')\n    {\n        $this->_out = (string) $out;\n    }\n\n    public function __toString()\n    {\n        return $this->_out;\n    }\n\n    /**\n     * Return the description of a {@link Hamcrest\\SelfDescribing} object as a\n     * String.\n     *\n     * @param \\Hamcrest\\SelfDescribing $selfDescribing\n     *   The object to be described.\n     *\n     * @return string\n     *   The description of the object.\n     */\n    public static function toString(SelfDescribing $selfDescribing): string\n    {\n        $self = new self();\n\n        return (string) $self->appendDescriptionOf($selfDescribing);\n    }\n\n    /**\n     * Alias for {@link toString()}.\n     */\n    public static function asString(SelfDescribing $selfDescribing): string\n    {\n        return self::toString($selfDescribing);\n    }\n\n    // -- Protected Methods\n\n    protected function append($str): void\n    {\n        $this->_out .= $str;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Text/IsEmptyString.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\BaseMatcher;\nuse Hamcrest\\Core\\AnyOf;\nuse Hamcrest\\Core\\IsNull;\nuse Hamcrest\\Description;\n\n/**\n * Matches empty Strings (and null).\n */\nclass IsEmptyString extends BaseMatcher\n{\n\n    private static ?self $_INSTANCE = null;\n    private static ?AnyOf $_NULL_OR_EMPTY_INSTANCE = null;\n    private static ?self $_NOT_INSTANCE = null;\n\n    private bool $_empty;\n\n    public function __construct(bool $empty = true)\n    {\n        $this->_empty = $empty;\n    }\n\n    public function matches($item): bool\n    {\n        return $this->_empty\n            ? ($item === '')\n            : is_string($item) && $item !== '';\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText($this->_empty ? 'an empty string' : 'a non-empty string');\n    }\n\n    /**\n     * Matches if value is a zero-length string.\n     *\n     * @factory emptyString\n     */\n    public static function isEmptyString(): self\n    {\n        if (!self::$_INSTANCE) {\n            self::$_INSTANCE = new self(true);\n        }\n\n        return self::$_INSTANCE;\n    }\n\n    /**\n     * Matches if value is null or a zero-length string.\n     *\n     * @factory nullOrEmptyString\n     */\n    public static function isEmptyOrNullString(): AnyOf\n    {\n        if (!self::$_NULL_OR_EMPTY_INSTANCE) {\n            self::$_NULL_OR_EMPTY_INSTANCE = AnyOf::anyOf(\n                IsNull::nullvalue(),\n                self::isEmptyString()\n            );\n        }\n\n        return self::$_NULL_OR_EMPTY_INSTANCE;\n    }\n\n    /**\n     * Matches if value is a non-zero-length string.\n     *\n     * @factory nonEmptyString\n     */\n    public static function isNonEmptyString(): self\n    {\n        if (!self::$_NOT_INSTANCE) {\n            self::$_NOT_INSTANCE = new self(false);\n        }\n\n        return self::$_NOT_INSTANCE;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Text/IsEqualIgnoringCase.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\TypeSafeMatcher;\n\n/**\n * Tests if a string is equal to another string, regardless of the case.\n */\nclass IsEqualIgnoringCase extends TypeSafeMatcher\n{\n    /**\n     * @var mixed\n     */\n    private $_string;\n\n    /**\n     * @param mixed $string\n     */\n    public function __construct($string)\n    {\n        parent::__construct(self::TYPE_STRING);\n\n        $this->_string = $string;\n    }\n\n    protected function matchesSafely($item): bool\n    {\n        return strtolower($this->_string) === strtolower($item);\n    }\n\n    protected function describeMismatchSafely($item, Description $mismatchDescription): void\n    {\n        $mismatchDescription->appendText('was ')->appendText($item);\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText('equalToIgnoringCase(')\n                                ->appendValue($this->_string)\n                                ->appendText(')')\n                                ;\n    }\n\n    /**\n     * Matches if value is a string equal to $string, regardless of the case.\n     *\n     * @factory\n     * @param mixed $string\n     */\n    public static function equalToIgnoringCase($string): self\n    {\n        return new self($string);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Text/IsEqualIgnoringWhiteSpace.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\TypeSafeMatcher;\n\n/**\n * Tests if a string is equal to another string, ignoring any changes in\n * whitespace.\n */\nclass IsEqualIgnoringWhiteSpace extends TypeSafeMatcher\n{\n    /**\n     * @var mixed\n     */\n    private $_string;\n\n    /**\n     * @param mixed $string\n     */\n    public function __construct($string)\n    {\n        parent::__construct(self::TYPE_STRING);\n\n        $this->_string = $string;\n    }\n\n    protected function matchesSafely($item): bool\n    {\n        return (strtolower($this->_stripSpace($item))\n                === strtolower($this->_stripSpace($this->_string)));\n    }\n\n    protected function describeMismatchSafely($item, Description $mismatchDescription): void\n    {\n        $mismatchDescription->appendText('was ')->appendText($item);\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText('equalToIgnoringWhiteSpace(')\n                                ->appendValue($this->_string)\n                                ->appendText(')')\n                                ;\n    }\n\n    /**\n     * Matches if value is a string equal to $string, regardless of whitespace.\n     *\n     * @factory\n     * @param mixed $string\n     */\n    public static function equalToIgnoringWhiteSpace($string): self\n    {\n        return new self($string);\n    }\n\n    // -- Private Methods\n\n    private function _stripSpace(string $string): string\n    {\n        $parts = preg_split(\"/[\\r\\n\\t ]+/\", $string);\n        foreach ($parts as $i => $part) {\n            $parts[$i] = trim($part, \" \\r\\n\\t\");\n        }\n\n        return trim(implode(' ', $parts), \" \\r\\n\\t\");\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Text/MatchesPattern.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\n/*\n Copyright (c) 2010 hamcrest.org\n */\n\n/**\n * Tests if the argument is a string that matches a regular expression.\n */\nclass MatchesPattern extends SubstringMatcher\n{\n    /**\n     * @param mixed $pattern\n     */\n    public function __construct($pattern)\n    {\n        parent::__construct($pattern);\n    }\n\n    /**\n     * Matches if value is a string that matches regular expression $pattern.\n     *\n     * @factory\n     * @param mixed $pattern\n     */\n    public static function matchesPattern($pattern): self\n    {\n        return new self($pattern);\n    }\n\n    // -- Protected Methods\n\n    protected function evalSubstringOf(string $item): bool\n    {\n        return preg_match($this->_substring, (string) $item) >= 1;\n    }\n\n    protected function relationship(): string\n    {\n        return 'matching';\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Text/StringContains.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\n/**\n * Tests if the argument is a string that contains a substring.\n */\nclass StringContains extends SubstringMatcher\n{\n    /**\n     * @param mixed $substring\n     */\n    public function __construct($substring)\n    {\n        parent::__construct($substring);\n    }\n\n    public function ignoringCase(): StringContainsIgnoringCase\n    {\n        return new StringContainsIgnoringCase($this->_substring);\n    }\n\n    /**\n     * Matches if value is a string that contains $substring.\n     *\n     * @factory\n     * @param mixed $substring\n     */\n    public static function containsString($substring): self\n    {\n        return new self($substring);\n    }\n\n    // -- Protected Methods\n\n    protected function evalSubstringOf(string $item): bool\n    {\n        return (false !== strpos((string) $item, $this->_substring));\n    }\n\n    protected function relationship(): string\n    {\n        return 'containing';\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Text/StringContainsIgnoringCase.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\n/*\n Copyright (c) 2010 hamcrest.org\n */\n\n/**\n * Tests if the argument is a string that contains a substring ignoring case.\n */\nclass StringContainsIgnoringCase extends SubstringMatcher\n{\n\n    /**\n     * @param mixed $substring\n     */\n    public function __construct($substring)\n    {\n        parent::__construct($substring);\n    }\n\n    /**\n     * Matches if value is a string that contains $substring regardless of the case.\n     *\n     * @factory\n     * @param mixed $substring\n     */\n    public static function containsStringIgnoringCase($substring): self\n    {\n        return new self($substring);\n    }\n\n    // -- Protected Methods\n\n    protected function evalSubstringOf(string $item): bool\n    {\n        return (false !== stripos((string) $item, $this->_substring));\n    }\n\n    protected function relationship(): string\n    {\n        return 'containing in any case';\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Text/StringContainsInOrder.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Description;\nuse Hamcrest\\TypeSafeMatcher;\n\n/**\n * Tests if the value contains a series of substrings in a constrained order.\n */\nclass StringContainsInOrder extends TypeSafeMatcher\n{\n    /**\n     * @var array<string>\n     */\n    private array $_substrings;\n\n    /**\n     * @param array<string> $substrings\n     */\n    public function __construct(array $substrings)\n    {\n        parent::__construct(self::TYPE_STRING);\n\n        $this->_substrings = $substrings;\n    }\n\n    protected function matchesSafely($item): bool\n    {\n        $fromIndex = 0;\n\n        foreach ($this->_substrings as $substring) {\n            if (false === $fromIndex = strpos($item, $substring, $fromIndex)) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    protected function describeMismatchSafely($item, Description $mismatchDescription): void\n    {\n        $mismatchDescription->appendText('was ')->appendText($item);\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText('a string containing ')\n                                ->appendValueList('', ', ', '', $this->_substrings)\n                                ->appendText(' in order')\n                                ;\n    }\n\n    /**\n     * Matches if value contains $substrings in a constrained order.\n     *\n     * @factory ...\n     */\n    public static function stringContainsInOrder(/* args... */): self\n    {\n        $args = func_get_args();\n\n        if (isset($args[0]) && is_array($args[0])) {\n            $args = $args[0];\n        }\n\n        return new self($args);\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Text/StringEndsWith.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\n/**\n * Tests if the argument is a string that ends with a substring.\n */\nclass StringEndsWith extends SubstringMatcher\n{\n\n    /**\n     * @param mixed $substring\n     */\n    public function __construct($substring)\n    {\n        parent::__construct($substring);\n    }\n\n    /**\n     * Matches if value is a string that ends with $substring.\n     *\n     * @factory\n     * @param mixed $substring\n     */\n    public static function endsWith($substring): self\n    {\n        return new self($substring);\n    }\n\n    // -- Protected Methods\n\n    protected function evalSubstringOf(string $string): bool\n    {\n        return (substr($string, (-1 * strlen($this->_substring))) === $this->_substring);\n    }\n\n    protected function relationship(): string\n    {\n        return 'ending with';\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Text/StringStartsWith.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\n/**\n * Tests if the argument is a string that contains a substring.\n */\nclass StringStartsWith extends SubstringMatcher\n{\n\n    /**\n     * @param mixed $substring\n     */\n    public function __construct($substring)\n    {\n        parent::__construct($substring);\n    }\n\n    /**\n     * Matches if value is a string that starts with $substring.\n     *\n     * @factory\n     * @param mixed $substring\n     */\n    public static function startsWith($substring): self\n    {\n        return new self($substring);\n    }\n\n    // -- Protected Methods\n\n    protected function evalSubstringOf(string $string): bool\n    {\n        return (substr($string, 0, strlen($this->_substring)) === $this->_substring);\n    }\n\n    protected function relationship(): string\n    {\n        return 'starting with';\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Text/SubstringMatcher.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\n\nuse Hamcrest\\Description;\nuse Hamcrest\\TypeSafeMatcher;\n\nabstract class SubstringMatcher extends TypeSafeMatcher\n{\n\n    /**\n     * @var mixed\n     */\n    protected $_substring;\n\n    /**\n     * @param mixed $substring\n     */\n    public function __construct($substring)\n    {\n        parent::__construct(self::TYPE_STRING);\n\n        $this->_substring = $substring;\n    }\n\n    protected function matchesSafely($item): bool\n    {\n        return $this->evalSubstringOf($item);\n    }\n\n    protected function describeMismatchSafely($item, Description $mismatchDescription): void\n    {\n        $mismatchDescription->appendText('was \"')->appendText($item)->appendText('\"');\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText('a string ')\n                                ->appendText($this->relationship())\n                                ->appendText(' ')\n                                ->appendValue($this->_substring)\n                                ;\n    }\n\n    abstract protected function evalSubstringOf(string $string): bool;\n\n    abstract protected function relationship(): string;\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Type/IsArray.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\n/*\n Copyright (c) 2010 hamcrest.org\n */\nuse Hamcrest\\Core\\IsTypeOf;\n\n/**\n * Tests whether the value is an array.\n */\nclass IsArray extends IsTypeOf\n{\n\n    /**\n     * Creates a new instance of IsArray\n     */\n    public function __construct()\n    {\n        parent::__construct('array');\n    }\n\n    /**\n     * Is the value an array?\n     *\n     * @factory\n     */\n    public static function arrayValue(): self\n    {\n        return new self;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Type/IsBoolean.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\n/*\n Copyright (c) 2010 hamcrest.org\n */\nuse Hamcrest\\Core\\IsTypeOf;\n\n/**\n * Tests whether the value is a boolean.\n */\nclass IsBoolean extends IsTypeOf\n{\n\n    /**\n     * Creates a new instance of IsBoolean\n     */\n    public function __construct()\n    {\n        parent::__construct('boolean');\n    }\n\n    /**\n     * Is the value a boolean?\n     *\n     * @factory boolValue\n     */\n    public static function booleanValue(): self\n    {\n        return new self;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Type/IsCallable.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\n/*\n Copyright (c) 2010 hamcrest.org\n */\nuse Hamcrest\\Core\\IsTypeOf;\n\n/**\n * Tests whether the value is callable.\n */\nclass IsCallable extends IsTypeOf\n{\n\n    /**\n     * Creates a new instance of IsCallable\n     */\n    public function __construct()\n    {\n        parent::__construct('callable');\n    }\n\n    public function matches($item): bool\n    {\n        return is_callable($item);\n    }\n\n    /**\n     * Is the value callable?\n     *\n     * @factory\n     */\n    public static function callableValue(): self\n    {\n        return new self;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Type/IsDouble.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\n/*\n Copyright (c) 2010 hamcrest.org\n */\nuse Hamcrest\\Core\\IsTypeOf;\n\n/**\n * Tests whether the value is a float/double.\n *\n * PHP returns \"double\" for values of type \"float\".\n */\nclass IsDouble extends IsTypeOf\n{\n\n    /**\n     * Creates a new instance of IsDouble\n     */\n    public function __construct()\n    {\n        parent::__construct('double');\n    }\n\n    /**\n     * Is the value a float/double?\n     *\n     * @factory floatValue\n     */\n    public static function doubleValue(): self\n    {\n        return new self;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Type/IsInteger.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\n/*\n Copyright (c) 2010 hamcrest.org\n */\nuse Hamcrest\\Core\\IsTypeOf;\n\n/**\n * Tests whether the value is an integer.\n */\nclass IsInteger extends IsTypeOf\n{\n\n    /**\n     * Creates a new instance of IsInteger\n     */\n    public function __construct()\n    {\n        parent::__construct('integer');\n    }\n\n    /**\n     * Is the value an integer?\n     *\n     * @factory intValue\n     */\n    public static function integerValue(): self\n    {\n        return new self;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Type/IsNumeric.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\n/*\n Copyright (c) 2010 hamcrest.org\n */\nuse Hamcrest\\Core\\IsTypeOf;\n\n/**\n * Tests whether the value is numeric.\n */\nclass IsNumeric extends IsTypeOf\n{\n\n    public function __construct()\n    {\n        parent::__construct('number');\n    }\n\n    public function matches($item): bool\n    {\n        if ($this->isHexadecimal($item)) {\n            return true;\n        }\n\n        return is_numeric($item);\n    }\n\n    /**\n     * Return if the string passed is a valid hexadecimal number.\n     * This check is necessary because PHP 7 doesn't recognize hexadecimal string as numeric anymore.\n     *\n     * @param mixed $item\n     * @return boolean\n     */\n    private function isHexadecimal($item)\n    {\n        if (is_string($item) && preg_match('/^0x(.*)$/', $item, $matches)) {\n            return ctype_xdigit($matches[1]);\n        }\n\n        return false;\n    }\n\n    /**\n     * Is the value a numeric?\n     *\n     * @factory\n     */\n    public static function numericValue(): self\n    {\n        return new self;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Type/IsObject.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\n/*\n Copyright (c) 2010 hamcrest.org\n */\nuse Hamcrest\\Core\\IsTypeOf;\n\n/**\n * Tests whether the value is an object.\n */\nclass IsObject extends IsTypeOf\n{\n\n    /**\n     * Creates a new instance of IsObject\n     */\n    public function __construct()\n    {\n        parent::__construct('object');\n    }\n\n    /**\n     * Is the value an object?\n     *\n     * @factory anObject\n     */\n    public static function objectValue(): self\n    {\n        return new self;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Type/IsResource.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\n/*\n Copyright (c) 2010 hamcrest.org\n */\nuse Hamcrest\\Core\\IsTypeOf;\n\n/**\n * Tests whether the value is a resource.\n */\nclass IsResource extends IsTypeOf\n{\n\n    /**\n     * Creates a new instance of IsResource\n     */\n    public function __construct()\n    {\n        parent::__construct('resource');\n    }\n\n    /**\n     * Is the value a resource?\n     *\n     * @factory\n     */\n    public static function resourceValue(): self\n    {\n        return new self;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Type/IsScalar.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\n/*\n Copyright (c) 2010 hamcrest.org\n */\nuse Hamcrest\\Core\\IsTypeOf;\n\n/**\n * Tests whether the value is a scalar (boolean, integer, double, or string).\n */\nclass IsScalar extends IsTypeOf\n{\n\n    public function __construct()\n    {\n        parent::__construct('scalar');\n    }\n\n    public function matches($item): bool\n    {\n        return is_scalar($item);\n    }\n\n    /**\n     * Is the value a scalar (boolean, integer, double, or string)?\n     *\n     * @factory\n     */\n    public static function scalarValue(): self\n    {\n        return new self;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Type/IsString.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\n/*\n Copyright (c) 2010 hamcrest.org\n */\nuse Hamcrest\\Core\\IsTypeOf;\n\n/**\n * Tests whether the value is a string.\n */\nclass IsString extends IsTypeOf\n{\n\n    /**\n     * Creates a new instance of IsString\n     */\n    public function __construct()\n    {\n        parent::__construct('string');\n    }\n\n    /**\n     * Is the value a string?\n     *\n     * @factory\n     */\n    public static function stringValue(): self\n    {\n        return new self;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/TypeSafeDiagnosingMatcher.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/**\n * Convenient base class for Matchers that require a value of a specific type.\n * This simply checks the type and then casts.\n */\n\nabstract class TypeSafeDiagnosingMatcher extends TypeSafeMatcher\n{\n\n    final public function matchesSafely($actual): bool\n    {\n        return $this->matchesSafelyWithDiagnosticDescription($actual, new NullDescription());\n    }\n\n    final public function describeMismatchSafely($actual, Description $mismatchDescription): void\n    {\n        $this->matchesSafelyWithDiagnosticDescription($actual, $mismatchDescription);\n    }\n\n    // -- Protected Methods\n\n    /**\n     * Subclasses should implement these. The item will already have been checked for\n     * the specific type.\n     * @param mixed $actual\n     */\n    abstract protected function matchesSafelyWithDiagnosticDescription($actual, Description $mismatchDescription): bool;\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/TypeSafeMatcher.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/**\n * Convenient base class for Matchers that require a value of a specific type.\n * This simply checks the type.\n *\n * While it may seem a useless exercise to have this in PHP, objects cannot\n * be cast to certain data types such as numerics (or even strings if\n * __toString() has not be defined).\n */\n\nabstract class TypeSafeMatcher extends BaseMatcher\n{\n\n    /* Types that PHP can compare against */\n    protected const TYPE_ANY = 0;\n    protected const TYPE_STRING = 1;\n    protected const TYPE_NUMERIC = 2;\n    protected const TYPE_ARRAY = 3;\n    protected const TYPE_OBJECT = 4;\n    protected const TYPE_RESOURCE = 5;\n    protected const TYPE_BOOLEAN = 6;\n\n    /**\n     * The type that is required for a safe comparison\n     *\n     * @var int\n     */\n    private int $_expectedType;\n\n    /**\n     * The subtype (e.g. class for objects) that is required\n     *\n     * @var string\n     */\n    private ?string $_expectedSubtype;\n\n    /**\n     * @param self::TYPE_* $expectedType\n     * @param string|null $expectedSubtype\n     */\n    public function __construct(int $expectedType, ?string $expectedSubtype = null)\n    {\n        $this->_expectedType = $expectedType;\n        $this->_expectedSubtype = $expectedSubtype;\n    }\n\n    final public function matches($item): bool\n    {\n        return $this->_isSafeType($item) && $this->matchesSafely($item);\n    }\n\n    final public function describeMismatch($item, Description $mismatchDescription): void\n    {\n        if (!$this->_isSafeType($item)) {\n            parent::describeMismatch($item, $mismatchDescription);\n        } else {\n            $this->describeMismatchSafely($item, $mismatchDescription);\n        }\n    }\n\n    // -- Protected Methods\n\n    /**\n     * The item will already have been checked for the specific type and subtype.\n     * @param mixed $item\n     */\n    abstract protected function matchesSafely($item): bool;\n\n    /**\n     * The item will already have been checked for the specific type and subtype.\n     * @param mixed $item\n     */\n    abstract protected function describeMismatchSafely($item, Description $mismatchDescription): void;\n\n    // -- Private Methods\n\n    /**\n     * @param mixed $value\n     */\n    private function _isSafeType($value): bool\n    {\n        switch ($this->_expectedType) {\n\n            case self::TYPE_ANY:\n                return true;\n\n            case self::TYPE_STRING:\n                return is_string($value) || is_numeric($value);\n\n            case self::TYPE_NUMERIC:\n                return is_numeric($value) || is_string($value);\n\n            case self::TYPE_ARRAY:\n                return is_array($value);\n\n            case self::TYPE_OBJECT:\n                return is_object($value)\n                        && ($this->_expectedSubtype === null\n                                || $value instanceof $this->_expectedSubtype);\n\n            case self::TYPE_RESOURCE:\n                return is_resource($value)\n                        && ($this->_expectedSubtype === null\n                                || get_resource_type($value) == $this->_expectedSubtype);\n\n            case self::TYPE_BOOLEAN:\n                return true;\n\n            default:\n                return true;\n\n        }\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Util.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/*\n Copyright (c) 2012 hamcrest.org\n */\n\n/**\n * Contains utility methods for handling Hamcrest matchers.\n *\n * @see Hamcrest\\Matcher\n */\nclass Util\n{\n    public static function registerGlobalFunctions(): void\n    {\n        require_once __DIR__.'/../Hamcrest.php';\n    }\n\n    /**\n     * Wraps the item with an IsEqual matcher if it isn't a matcher already.\n     *\n     * @param mixed $item matcher or any value\n     * @return \\Hamcrest\\Matcher\n     */\n    public static function wrapValueWithIsEqual($item)\n    {\n        return ($item instanceof Matcher)\n            ? $item\n            : Core\\IsEqual::equalTo($item)\n            ;\n    }\n\n    /**\n     * Throws an exception if any item in $matchers is not a Hamcrest\\Matcher.\n     *\n     * @param array<mixed> $matchers expected to contain only matchers\n     * @throws \\InvalidArgumentException if any item is not a matcher\n     */\n    public static function checkAllAreMatchers(array $matchers): void\n    {\n        foreach ($matchers as $m) {\n            if (!($m instanceof Matcher)) {\n                throw new \\InvalidArgumentException(\n                    'Each argument or element must be a Hamcrest matcher'\n                );\n            }\n        }\n    }\n\n    /**\n     * Returns a copy of $items where each non-Matcher item is replaced by\n     * a Hamcrest\\Core\\IsEqual matcher for the item. If the first and only item\n     * is an array, it is used as the $items array to support the old style\n     * of passing an array as the sole argument to a matcher.\n     *\n     * @param array<mixed> $items contains items and matchers\n     * @return array<Matcher> all items are\n     */\n    public static function createMatcherArray(array $items)\n    {\n        //Extract single array item\n        if (count($items) == 1 && is_array($items[0])) {\n            $items = $items[0];\n        }\n\n        //Replace non-matchers\n        foreach ($items as &$item) {\n            if (!($item instanceof Matcher)) {\n                $item = Core\\IsEqual::equalTo($item);\n            }\n        }\n\n        return $items;\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest/Xml/HasXPath.php",
    "content": "<?php\nnamespace Hamcrest\\Xml;\n\n/*\n Copyright (c) 2009 hamcrest.org\n */\nuse Hamcrest\\Core\\IsEqual;\nuse Hamcrest\\Description;\nuse Hamcrest\\DiagnosingMatcher;\nuse Hamcrest\\Matcher;\n\n/**\n * Matches if XPath applied to XML/HTML/XHTML document either\n * evaluates to result matching the matcher or returns at least\n * one node, matching the matcher if present.\n */\nclass HasXPath extends DiagnosingMatcher\n{\n\n    /**\n     * XPath to apply to the DOM.\n     *\n     * @var string\n     */\n    private string $_xpath;\n\n    /**\n     * Optional matcher to apply to the XPath expression result\n     * or the content of the returned nodes.\n     *\n     * @var ?Matcher\n     */\n    private ?Matcher $_matcher;\n\n    /**\n     * @param string $xpath\n     */\n    public function __construct(string $xpath, ?Matcher $matcher = null)\n    {\n        $this->_xpath = $xpath;\n        $this->_matcher = $matcher;\n    }\n\n    /**\n     * Matches if the XPath matches against the DOM node and the matcher.\n     *\n     * @param string|\\DOMNode $actual\n     * @param Description $mismatchDescription\n     * @return bool\n     */\n    protected function matchesWithDiagnosticDescription($actual, Description $mismatchDescription): bool\n    {\n        if (is_string($actual)) {\n            $actual = $this->createDocument($actual);\n        } elseif (!$actual instanceof \\DOMNode) { // @phpstan-ignore instanceof.alwaysTrue (unless actual is a native union type, we want to check this)\n            $mismatchDescription->appendText('was ')->appendValue($actual);\n\n            return false;\n        }\n        $result = $this->evaluate($actual);\n        if ($result instanceof \\DOMNodeList) {\n            return $this->matchesContent($result, $mismatchDescription);\n        } else {\n            return $this->matchesExpression($result, $mismatchDescription);\n        }\n    }\n\n    /**\n     * Creates and returns a <code>DOMDocument</code> from the given\n     * XML or HTML string.\n     *\n     * @param string $text\n     * @return \\DOMDocument built from <code>$text</code>\n     * @throws \\InvalidArgumentException if the document is not valid\n     */\n    protected function createDocument($text)\n    {\n        $document = new \\DOMDocument();\n        if (preg_match('/^\\s*<\\?xml/', $text)) {\n            if (!@$document->loadXML($text)) {\n                throw new \\InvalidArgumentException('Must pass a valid XML document');\n            }\n        } else {\n            if (!@$document->loadHTML($text)) {\n                throw new \\InvalidArgumentException('Must pass a valid HTML or XHTML document');\n            }\n        }\n\n        return $document;\n    }\n\n    /**\n     * Applies the configured XPath to the DOM node and returns either\n     * the result if it's an expression or the node list if it's a query.\n     *\n     * @param \\DOMNode $node context from which to issue query\n     * @return mixed result of expression or DOMNodeList from query\n     */\n    protected function evaluate(\\DOMNode $node)\n    {\n        if ($node instanceof \\DOMDocument) {\n            $xpathDocument = new \\DOMXPath($node);\n\n            return $xpathDocument->evaluate($this->_xpath);\n        } else {\n            $xpathDocument = new \\DOMXPath($node->ownerDocument);\n\n            return $xpathDocument->evaluate($this->_xpath, $node);\n        }\n    }\n\n    /**\n     * Matches if the list of nodes is not empty and the content of at least\n     * one node matches the configured matcher, if supplied.\n     *\n     * @param \\DOMNodeList $nodes selected by the XPath query\n     * @param Description $mismatchDescription\n     * @return bool\n     */\n    protected function matchesContent(\\DOMNodeList $nodes, Description $mismatchDescription): bool\n    {\n        if ($nodes->length == 0) {\n            $mismatchDescription->appendText('XPath returned no results');\n        } elseif ($this->_matcher === null) {\n            return true;\n        } else {\n            foreach ($nodes as $node) {\n                if ($this->_matcher->matches($node->textContent)) {\n                    return true;\n                }\n            }\n            $content = array();\n            foreach ($nodes as $node) {\n                $content[] = $node->textContent;\n            }\n            $mismatchDescription->appendText('XPath returned ')\n                                                    ->appendValue($content);\n        }\n\n        return false;\n    }\n\n    /**\n     * Matches if the result of the XPath expression matches the configured\n     * matcher or evaluates to <code>true</code> if there is none.\n     *\n     * @param mixed $result result of the XPath expression\n     * @param Description $mismatchDescription\n     * @return bool\n     */\n    protected function matchesExpression($result, Description $mismatchDescription): bool\n    {\n        if ($this->_matcher === null) {\n            if ($result) {\n                return true;\n            }\n            $mismatchDescription->appendText('XPath expression result was ')\n                                                    ->appendValue($result);\n        } else {\n            if ($this->_matcher->matches($result)) {\n                return true;\n            }\n            $mismatchDescription->appendText('XPath expression result ');\n            $this->_matcher->describeMismatch($result, $mismatchDescription);\n        }\n\n        return false;\n    }\n\n    public function describeTo(Description $description): void\n    {\n        $description->appendText('XML or HTML document with XPath \"')\n                                ->appendText($this->_xpath)\n                                ->appendText('\"');\n        if ($this->_matcher !== null) {\n            $description->appendText(' ');\n            $this->_matcher->describeTo($description);\n        }\n    }\n\n    /**\n     * Wraps <code>$matcher</code> with {@link Hamcrest\\Core\\IsEqual)\n     * if it's not a matcher and the XPath in <code>count()</code>\n     * if it's an integer.\n     *\n     * @factory\n     * @param string $xpath\n     * @param null|Matcher|int|mixed $matcher\n     */\n    public static function hasXPath(string $xpath, $matcher = null): self\n    {\n        if ($matcher === null || $matcher instanceof Matcher) {\n            return new self($xpath, $matcher);\n        } elseif (is_int($matcher) && strpos($xpath, 'count(') !== 0) {\n            $xpath = 'count(' . $xpath . ')';\n        }\n\n        return new self($xpath, IsEqual::equalTo($matcher));\n    }\n}\n"
  },
  {
    "path": "hamcrest/Hamcrest.php",
    "content": "<?php\n\n/*\n Copyright (c) 2009-2010 hamcrest.org\n */\n\n// This file is generated from the static method @factory doctags.\n\nif (!function_exists('assertThat')) {\n    /**\n     * Make an assertion and throw {@link Hamcrest_AssertionError} if it fails.\n     *\n     * Example:\n     * <pre>\n     * //With an identifier\n     * assertThat(\"assertion identifier\", $apple->flavour(), equalTo(\"tasty\"));\n     * //Without an identifier\n     * assertThat($apple->flavour(), equalTo(\"tasty\"));\n     * //Evaluating a boolean expression\n     * assertThat(\"some error\", $a > $b);\n     * </pre>\n     */\n    function assertThat(): void\n    {\n        $args = func_get_args();\n        call_user_func_array(\n            array('Hamcrest\\MatcherAssert', 'assertThat'),\n            $args\n        );\n    }\n}\n\nif (!function_exists('anArray')) {\n    /**\n     * Evaluates to true only if each $matcher[$i] is satisfied by $array[$i].\n     */\n    function anArray(/* args... */): \\Hamcrest\\Arrays\\IsArray\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Arrays\\IsArray', 'anArray'), $args);\n    }\n}\n\nif (!function_exists('hasItemInArray')) {\n    /**\n     * Evaluates to true if any item in an array satisfies the given matcher.\n     *\n     * @param mixed $item as a {@link Hamcrest\\Matcher} or a value.\n     *\n     * @return \\Hamcrest\\Arrays\\IsArrayContaining\n     */\n    function hasItemInArray($item): \\Hamcrest\\Arrays\\IsArrayContaining\n    {\n        return \\Hamcrest\\Arrays\\IsArrayContaining::hasItemInArray($item);\n    }\n}\n\nif (!function_exists('hasValue')) {\n    /**\n     * Evaluates to true if any item in an array satisfies the given matcher.\n     *\n     * @param mixed $item as a {@link Hamcrest\\Matcher} or a value.\n     *\n     * @return \\Hamcrest\\Arrays\\IsArrayContaining\n     */\n    function hasValue($item): \\Hamcrest\\Arrays\\IsArrayContaining\n    {\n        return \\Hamcrest\\Arrays\\IsArrayContaining::hasItemInArray($item);\n    }\n}\n\nif (!function_exists('arrayContainingInAnyOrder')) {\n    /**\n     * An array with elements that match the given matchers.\n     */\n    function arrayContainingInAnyOrder(/* args... */): \\Hamcrest\\Arrays\\IsArrayContainingInAnyOrder\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Arrays\\IsArrayContainingInAnyOrder', 'arrayContainingInAnyOrder'), $args);\n    }\n}\n\nif (!function_exists('containsInAnyOrder')) {\n    /**\n     * An array with elements that match the given matchers.\n     */\n    function containsInAnyOrder(/* args... */): \\Hamcrest\\Arrays\\IsArrayContainingInAnyOrder\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Arrays\\IsArrayContainingInAnyOrder', 'arrayContainingInAnyOrder'), $args);\n    }\n}\n\nif (!function_exists('arrayContaining')) {\n    /**\n     * An array with elements that match the given matchers in the same order.\n     */\n    function arrayContaining(/* args... */): \\Hamcrest\\Arrays\\IsArrayContainingInOrder\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Arrays\\IsArrayContainingInOrder', 'arrayContaining'), $args);\n    }\n}\n\nif (!function_exists('contains')) {\n    /**\n     * An array with elements that match the given matchers in the same order.\n     */\n    function contains(/* args... */): \\Hamcrest\\Arrays\\IsArrayContainingInOrder\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Arrays\\IsArrayContainingInOrder', 'arrayContaining'), $args);\n    }\n}\n\nif (!function_exists('hasKeyInArray')) {\n    /**\n     * Evaluates to true if any key in an array matches the given matcher.\n     *\n     * @param mixed $key as a {@link Hamcrest\\Matcher} or a value.\n     *\n     * @return \\Hamcrest\\Arrays\\IsArrayContainingKey\n     */\n    function hasKeyInArray($key): \\Hamcrest\\Arrays\\IsArrayContainingKey\n    {\n        return \\Hamcrest\\Arrays\\IsArrayContainingKey::hasKeyInArray($key);\n    }\n}\n\nif (!function_exists('hasKey')) {\n    /**\n     * Evaluates to true if any key in an array matches the given matcher.\n     *\n     * @param mixed $key as a {@link Hamcrest\\Matcher} or a value.\n     *\n     * @return \\Hamcrest\\Arrays\\IsArrayContainingKey\n     */\n    function hasKey($key): \\Hamcrest\\Arrays\\IsArrayContainingKey\n    {\n        return \\Hamcrest\\Arrays\\IsArrayContainingKey::hasKeyInArray($key);\n    }\n}\n\nif (!function_exists('hasKeyValuePair')) {\n    /**\n     * Test if an array has both an key and value in parity with each other.\n     *\n     * @param mixed $key\n     * @param mixed $value\n     */\n    function hasKeyValuePair($key, $value): \\Hamcrest\\Arrays\\IsArrayContainingKeyValuePair\n    {\n        return \\Hamcrest\\Arrays\\IsArrayContainingKeyValuePair::hasKeyValuePair($key, $value);\n    }\n}\n\nif (!function_exists('hasEntry')) {\n    /**\n     * Test if an array has both an key and value in parity with each other.\n     *\n     * @param mixed $key\n     * @param mixed $value\n     */\n    function hasEntry($key, $value): \\Hamcrest\\Arrays\\IsArrayContainingKeyValuePair\n    {\n        return \\Hamcrest\\Arrays\\IsArrayContainingKeyValuePair::hasKeyValuePair($key, $value);\n    }\n}\n\nif (!function_exists('arrayWithSize')) {\n    /**\n     * Does array size satisfy a given matcher?\n     *\n     * @param \\Hamcrest\\Matcher|int $size as a {@link Hamcrest\\Matcher} or a value.\n     *\n     * @return \\Hamcrest\\Arrays\\IsArrayWithSize\n     */\n    function arrayWithSize($size): \\Hamcrest\\Arrays\\IsArrayWithSize\n    {\n        return \\Hamcrest\\Arrays\\IsArrayWithSize::arrayWithSize($size);\n    }\n}\n\nif (!function_exists('emptyArray')) {\n    /**\n     * Matches an empty array.\n     */\n    function emptyArray(): \\Hamcrest\\Core\\DescribedAs\n    {\n        return \\Hamcrest\\Arrays\\IsArrayWithSize::emptyArray();\n    }\n}\n\nif (!function_exists('nonEmptyArray')) {\n    /**\n     * Matches an empty array.\n     */\n    function nonEmptyArray(): \\Hamcrest\\Core\\DescribedAs\n    {\n        return \\Hamcrest\\Arrays\\IsArrayWithSize::nonEmptyArray();\n    }\n}\n\nif (!function_exists('emptyTraversable')) {\n    /**\n     * Returns true if traversable is empty.\n     */\n    function emptyTraversable(): \\Hamcrest\\Collection\\IsEmptyTraversable\n    {\n        return \\Hamcrest\\Collection\\IsEmptyTraversable::emptyTraversable();\n    }\n}\n\nif (!function_exists('nonEmptyTraversable')) {\n    /**\n     * Returns true if traversable is not empty.\n     */\n    function nonEmptyTraversable(): \\Hamcrest\\Collection\\IsEmptyTraversable\n    {\n        return \\Hamcrest\\Collection\\IsEmptyTraversable::nonEmptyTraversable();\n    }\n}\n\nif (!function_exists('traversableWithSize')) {\n    /**\n     * Does traversable size satisfy a given matcher?\n     *\n     * @param mixed $size\n     */\n    function traversableWithSize($size): \\Hamcrest\\Collection\\IsTraversableWithSize\n    {\n        return \\Hamcrest\\Collection\\IsTraversableWithSize::traversableWithSize($size);\n    }\n}\n\nif (!function_exists('allOf')) {\n    /**\n     * Evaluates to true only if ALL of the passed in matchers evaluate to true.\n     */\n    function allOf(/* args... */): \\Hamcrest\\Core\\AllOf\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Core\\AllOf', 'allOf'), $args);\n    }\n}\n\nif (!function_exists('anyOf')) {\n    /**\n     * Evaluates to true if ANY of the passed in matchers evaluate to true.\n     */\n    function anyOf(/* args... */): \\Hamcrest\\Core\\AnyOf\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Core\\AnyOf', 'anyOf'), $args);\n    }\n}\n\nif (!function_exists('noneOf')) {\n    /**\n     * Evaluates to false if ANY of the passed in matchers evaluate to true.\n     */\n    function noneOf(/* args... */): \\Hamcrest\\Core\\IsNot\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Core\\AnyOf', 'noneOf'), $args);\n    }\n}\n\nif (!function_exists('both')) {\n    /**\n     * This is useful for fluently combining matchers that must both pass.\n     * For example:\n     * <pre>\n     *   assertThat($string, both(containsString(\"a\"))->andAlso(containsString(\"b\")));\n     * </pre>\n     */\n    function both(\\Hamcrest\\Matcher $matcher): \\Hamcrest\\Core\\CombinableMatcher\n    {\n        return \\Hamcrest\\Core\\CombinableMatcher::both($matcher);\n    }\n}\n\nif (!function_exists('either')) {\n    /**\n     * This is useful for fluently combining matchers where either may pass,\n     * for example:\n     * <pre>\n     *   assertThat($string, either(containsString(\"a\"))->orElse(containsString(\"b\")));\n     * </pre>\n     */\n    function either(\\Hamcrest\\Matcher $matcher): \\Hamcrest\\Core\\CombinableMatcher\n    {\n        return \\Hamcrest\\Core\\CombinableMatcher::either($matcher);\n    }\n}\n\nif (!function_exists('describedAs')) {\n    /**\n     * Wraps an existing matcher and overrides the description when it fails.\n     */\n    function describedAs(/* args... */): \\Hamcrest\\Core\\DescribedAs\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Core\\DescribedAs', 'describedAs'), $args);\n    }\n}\n\nif (!function_exists('everyItem')) {\n    /**\n     * @param \\Hamcrest\\Matcher $itemMatcher\n     *   A matcher to apply to every element in an array.\n     *\n     * @return \\Hamcrest\\Core\\Every\n     *   Evaluates to TRUE for a collection in which every item matches $itemMatcher\n     */\n    function everyItem(\\Hamcrest\\Matcher $itemMatcher): \\Hamcrest\\Core\\Every\n    {\n        return \\Hamcrest\\Core\\Every::everyItem($itemMatcher);\n    }\n}\n\nif (!function_exists('hasToString')) {\n    /**\n     * Creates a matcher that matches any examined object whose <code>toString</code> or\n     * <code>__toString()</code> method returns a value equalTo the specified string.\n     *\n     * @param mixed $matcher\n     */\n    function hasToString($matcher): \\Hamcrest\\Core\\HasToString\n    {\n        return \\Hamcrest\\Core\\HasToString::hasToString($matcher);\n    }\n}\n\nif (!function_exists('is')) {\n    /**\n     * Decorates another Matcher, retaining the behavior but allowing tests\n     * to be slightly more expressive.\n     *\n     * For example:  assertThat($cheese, equalTo($smelly))\n     *          vs.  assertThat($cheese, is(equalTo($smelly)))\n     *\n     * @param mixed $value\n     */\n    function is($value): \\Hamcrest\\Core\\Is\n    {\n        return \\Hamcrest\\Core\\Is::is($value);\n    }\n}\n\nif (!function_exists('anything')) {\n    /**\n     * This matcher always evaluates to true.\n     *\n     * @param string $description A meaningful string used when describing itself.\n     */\n    function anything(string $description = 'ANYTHING'): \\Hamcrest\\Core\\IsAnything\n    {\n        return \\Hamcrest\\Core\\IsAnything::anything($description);\n    }\n}\n\nif (!function_exists('hasItem')) {\n    /**\n     * Test if the value is an array containing this matcher.\n     *\n     * Example:\n     * <pre>\n     * assertThat(array('a', 'b'), hasItem(equalTo('b')));\n     * //Convenience defaults to equalTo()\n     * assertThat(array('a', 'b'), hasItem('b'));\n     * </pre>\n     */\n    function hasItem(/* args... */): \\Hamcrest\\Core\\IsCollectionContaining\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Core\\IsCollectionContaining', 'hasItem'), $args);\n    }\n}\n\nif (!function_exists('hasItems')) {\n    /**\n     * Test if the value is an array containing elements that match all of these\n     * matchers.\n     *\n     * Example:\n     * <pre>\n     * assertThat(array('a', 'b', 'c'), hasItems(equalTo('a'), equalTo('b')));\n     * </pre>\n     */\n    function hasItems(/* args... */): \\Hamcrest\\Core\\AllOf\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Core\\IsCollectionContaining', 'hasItems'), $args);\n    }\n}\n\nif (!function_exists('equalTo')) {\n    /**\n     * Is the value equal to another value, as tested by the use of the \"==\"\n     * comparison operator?\n     *\n     * @param mixed $item\n     */\n    function equalTo($item): \\Hamcrest\\Core\\IsEqual\n    {\n        return \\Hamcrest\\Core\\IsEqual::equalTo($item);\n    }\n}\n\nif (!function_exists('identicalTo')) {\n    /**\n     * Tests of the value is identical to $value as tested by the \"===\" operator.\n     *\n     * @param mixed $value\n     */\n    function identicalTo($value): \\Hamcrest\\Core\\IsIdentical\n    {\n        return \\Hamcrest\\Core\\IsIdentical::identicalTo($value);\n    }\n}\n\nif (!function_exists('anInstanceOf')) {\n    /**\n     * Is the value an instance of a particular type?\n     * This version assumes no relationship between the required type and\n     * the signature of the method that sets it up, for example in\n     * <code>assertThat($anObject, anInstanceOf('Thing'));</code>\n     */\n    function anInstanceOf(string $theClass): \\Hamcrest\\Core\\IsInstanceOf\n    {\n        return \\Hamcrest\\Core\\IsInstanceOf::anInstanceOf($theClass);\n    }\n}\n\nif (!function_exists('any')) {\n    /**\n     * Is the value an instance of a particular type?\n     * This version assumes no relationship between the required type and\n     * the signature of the method that sets it up, for example in\n     * <code>assertThat($anObject, anInstanceOf('Thing'));</code>\n     */\n    function any(string $theClass): \\Hamcrest\\Core\\IsInstanceOf\n    {\n        return \\Hamcrest\\Core\\IsInstanceOf::anInstanceOf($theClass);\n    }\n}\n\nif (!function_exists('not')) {\n    /**\n     * Matches if value does not match $value.\n     *\n     * @param mixed $value\n     */\n    function not($value): \\Hamcrest\\Core\\IsNot\n    {\n        return \\Hamcrest\\Core\\IsNot::not($value);\n    }\n}\n\nif (!function_exists('nullValue')) {\n    /**\n     * Matches if value is null.\n     */\n    function nullValue(): \\Hamcrest\\Core\\IsNull\n    {\n        return \\Hamcrest\\Core\\IsNull::nullValue();\n    }\n}\n\nif (!function_exists('notNullValue')) {\n    /**\n     * Matches if value is not null.\n     */\n    function notNullValue(): \\Hamcrest\\Core\\IsNot\n    {\n        return \\Hamcrest\\Core\\IsNull::notNullValue();\n    }\n}\n\nif (!function_exists('sameInstance')) {\n    /**\n     * Creates a new instance of IsSame.\n     *\n     * @param mixed $object\n     *   The predicate evaluates to true only when the argument is\n     *   this object.\n     *\n     * @return \\Hamcrest\\Core\\IsSame\n     */\n    function sameInstance($object): \\Hamcrest\\Core\\IsSame\n    {\n        return \\Hamcrest\\Core\\IsSame::sameInstance($object);\n    }\n}\n\nif (!function_exists('typeOf')) {\n    /**\n     * Is the value a particular built-in type?\n     *\n     * @param string $theType\n     */\n    function typeOf(string $theType): \\Hamcrest\\Core\\IsTypeOf\n    {\n        return \\Hamcrest\\Core\\IsTypeOf::typeOf($theType);\n    }\n}\n\nif (!function_exists('set')) {\n    /**\n     * Matches if value (class, object, or array) has named $property.\n     *\n     * @param mixed $property\n     */\n    function set($property): \\Hamcrest\\Core\\Set\n    {\n        return \\Hamcrest\\Core\\Set::set($property);\n    }\n}\n\nif (!function_exists('notSet')) {\n    /**\n     * Matches if value (class, object, or array) does not have named $property.\n     *\n     * @param mixed $property\n     */\n    function notSet($property): \\Hamcrest\\Core\\Set\n    {\n        return \\Hamcrest\\Core\\Set::notSet($property);\n    }\n}\n\nif (!function_exists('closeTo')) {\n    /**\n     * Matches if value is a number equal to $value within some range of\n     * acceptable error $delta.\n     *\n     * @param mixed $value\n     * @param mixed $delta\n     */\n    function closeTo($value, $delta): \\Hamcrest\\Number\\IsCloseTo\n    {\n        return \\Hamcrest\\Number\\IsCloseTo::closeTo($value, $delta);\n    }\n}\n\nif (!function_exists('comparesEqualTo')) {\n    /**\n     * The value is not > $value, nor < $value.\n     *\n     * @param mixed $value\n     */\n    function comparesEqualTo($value): \\Hamcrest\\Number\\OrderingComparison\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::comparesEqualTo($value);\n    }\n}\n\nif (!function_exists('greaterThan')) {\n    /**\n     * The value is > $value.\n     *\n     * @param mixed $value\n     */\n    function greaterThan($value): \\Hamcrest\\Number\\OrderingComparison\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::greaterThan($value);\n    }\n}\n\nif (!function_exists('greaterThanOrEqualTo')) {\n    /**\n     * The value is >= $value.\n     *\n     * @param mixed $value\n     */\n    function greaterThanOrEqualTo($value): \\Hamcrest\\Number\\OrderingComparison\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::greaterThanOrEqualTo($value);\n    }\n}\n\nif (!function_exists('atLeast')) {\n    /**\n     * The value is >= $value.\n     *\n     * @param mixed $value\n     */\n    function atLeast($value): \\Hamcrest\\Number\\OrderingComparison\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::greaterThanOrEqualTo($value);\n    }\n}\n\nif (!function_exists('lessThan')) {\n    /**\n     * The value is < $value.\n     *\n     * @param mixed $value\n     */\n    function lessThan($value): \\Hamcrest\\Number\\OrderingComparison\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::lessThan($value);\n    }\n}\n\nif (!function_exists('lessThanOrEqualTo')) {\n    /**\n     * The value is <= $value.\n     *\n     * @param mixed $value\n     */\n    function lessThanOrEqualTo($value): \\Hamcrest\\Number\\OrderingComparison\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::lessThanOrEqualTo($value);\n    }\n}\n\nif (!function_exists('atMost')) {\n    /**\n     * The value is <= $value.\n     *\n     * @param mixed $value\n     */\n    function atMost($value): \\Hamcrest\\Number\\OrderingComparison\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::lessThanOrEqualTo($value);\n    }\n}\n\nif (!function_exists('isEmptyString')) {\n    /**\n     * Matches if value is a zero-length string.\n     */\n    function isEmptyString(): \\Hamcrest\\Text\\IsEmptyString\n    {\n        return \\Hamcrest\\Text\\IsEmptyString::isEmptyString();\n    }\n}\n\nif (!function_exists('emptyString')) {\n    /**\n     * Matches if value is a zero-length string.\n     */\n    function emptyString(): \\Hamcrest\\Text\\IsEmptyString\n    {\n        return \\Hamcrest\\Text\\IsEmptyString::isEmptyString();\n    }\n}\n\nif (!function_exists('isEmptyOrNullString')) {\n    /**\n     * Matches if value is null or a zero-length string.\n     */\n    function isEmptyOrNullString(): \\Hamcrest\\Core\\AnyOf\n    {\n        return \\Hamcrest\\Text\\IsEmptyString::isEmptyOrNullString();\n    }\n}\n\nif (!function_exists('nullOrEmptyString')) {\n    /**\n     * Matches if value is null or a zero-length string.\n     */\n    function nullOrEmptyString(): \\Hamcrest\\Core\\AnyOf\n    {\n        return \\Hamcrest\\Text\\IsEmptyString::isEmptyOrNullString();\n    }\n}\n\nif (!function_exists('isNonEmptyString')) {\n    /**\n     * Matches if value is a non-zero-length string.\n     */\n    function isNonEmptyString(): \\Hamcrest\\Text\\IsEmptyString\n    {\n        return \\Hamcrest\\Text\\IsEmptyString::isNonEmptyString();\n    }\n}\n\nif (!function_exists('nonEmptyString')) {\n    /**\n     * Matches if value is a non-zero-length string.\n     */\n    function nonEmptyString(): \\Hamcrest\\Text\\IsEmptyString\n    {\n        return \\Hamcrest\\Text\\IsEmptyString::isNonEmptyString();\n    }\n}\n\nif (!function_exists('equalToIgnoringCase')) {\n    /**\n     * Matches if value is a string equal to $string, regardless of the case.\n     *\n     * @param mixed $string\n     */\n    function equalToIgnoringCase($string): \\Hamcrest\\Text\\IsEqualIgnoringCase\n    {\n        return \\Hamcrest\\Text\\IsEqualIgnoringCase::equalToIgnoringCase($string);\n    }\n}\n\nif (!function_exists('equalToIgnoringWhiteSpace')) {\n    /**\n     * Matches if value is a string equal to $string, regardless of whitespace.\n     *\n     * @param mixed $string\n     */\n    function equalToIgnoringWhiteSpace($string): \\Hamcrest\\Text\\IsEqualIgnoringWhiteSpace\n    {\n        return \\Hamcrest\\Text\\IsEqualIgnoringWhiteSpace::equalToIgnoringWhiteSpace($string);\n    }\n}\n\nif (!function_exists('matchesPattern')) {\n    /**\n     * Matches if value is a string that matches regular expression $pattern.\n     *\n     * @param mixed $pattern\n     */\n    function matchesPattern($pattern): \\Hamcrest\\Text\\MatchesPattern\n    {\n        return \\Hamcrest\\Text\\MatchesPattern::matchesPattern($pattern);\n    }\n}\n\nif (!function_exists('containsString')) {\n    /**\n     * Matches if value is a string that contains $substring.\n     *\n     * @param mixed $substring\n     */\n    function containsString($substring): \\Hamcrest\\Text\\StringContains\n    {\n        return \\Hamcrest\\Text\\StringContains::containsString($substring);\n    }\n}\n\nif (!function_exists('containsStringIgnoringCase')) {\n    /**\n     * Matches if value is a string that contains $substring regardless of the case.\n     *\n     * @param mixed $substring\n     */\n    function containsStringIgnoringCase($substring): \\Hamcrest\\Text\\StringContainsIgnoringCase\n    {\n        return \\Hamcrest\\Text\\StringContainsIgnoringCase::containsStringIgnoringCase($substring);\n    }\n}\n\nif (!function_exists('stringContainsInOrder')) {\n    /**\n     * Matches if value contains $substrings in a constrained order.\n     */\n    function stringContainsInOrder(/* args... */): \\Hamcrest\\Text\\StringContainsInOrder\n    {\n        $args = func_get_args();\n        return call_user_func_array(array('\\Hamcrest\\Text\\StringContainsInOrder', 'stringContainsInOrder'), $args);\n    }\n}\n\nif (!function_exists('endsWith')) {\n    /**\n     * Matches if value is a string that ends with $substring.\n     *\n     * @param mixed $substring\n     */\n    function endsWith($substring): \\Hamcrest\\Text\\StringEndsWith\n    {\n        return \\Hamcrest\\Text\\StringEndsWith::endsWith($substring);\n    }\n}\n\nif (!function_exists('startsWith')) {\n    /**\n     * Matches if value is a string that starts with $substring.\n     *\n     * @param mixed $substring\n     */\n    function startsWith($substring): \\Hamcrest\\Text\\StringStartsWith\n    {\n        return \\Hamcrest\\Text\\StringStartsWith::startsWith($substring);\n    }\n}\n\nif (!function_exists('arrayValue')) {\n    /**\n     * Is the value an array?\n     */\n    function arrayValue(): \\Hamcrest\\Type\\IsArray\n    {\n        return \\Hamcrest\\Type\\IsArray::arrayValue();\n    }\n}\n\nif (!function_exists('booleanValue')) {\n    /**\n     * Is the value a boolean?\n     */\n    function booleanValue(): \\Hamcrest\\Type\\IsBoolean\n    {\n        return \\Hamcrest\\Type\\IsBoolean::booleanValue();\n    }\n}\n\nif (!function_exists('boolValue')) {\n    /**\n     * Is the value a boolean?\n     */\n    function boolValue(): \\Hamcrest\\Type\\IsBoolean\n    {\n        return \\Hamcrest\\Type\\IsBoolean::booleanValue();\n    }\n}\n\nif (!function_exists('callableValue')) {\n    /**\n     * Is the value callable?\n     */\n    function callableValue(): \\Hamcrest\\Type\\IsCallable\n    {\n        return \\Hamcrest\\Type\\IsCallable::callableValue();\n    }\n}\n\nif (!function_exists('doubleValue')) {\n    /**\n     * Is the value a float/double?\n     */\n    function doubleValue(): \\Hamcrest\\Type\\IsDouble\n    {\n        return \\Hamcrest\\Type\\IsDouble::doubleValue();\n    }\n}\n\nif (!function_exists('floatValue')) {\n    /**\n     * Is the value a float/double?\n     */\n    function floatValue(): \\Hamcrest\\Type\\IsDouble\n    {\n        return \\Hamcrest\\Type\\IsDouble::doubleValue();\n    }\n}\n\nif (!function_exists('integerValue')) {\n    /**\n     * Is the value an integer?\n     */\n    function integerValue(): \\Hamcrest\\Type\\IsInteger\n    {\n        return \\Hamcrest\\Type\\IsInteger::integerValue();\n    }\n}\n\nif (!function_exists('intValue')) {\n    /**\n     * Is the value an integer?\n     */\n    function intValue(): \\Hamcrest\\Type\\IsInteger\n    {\n        return \\Hamcrest\\Type\\IsInteger::integerValue();\n    }\n}\n\nif (!function_exists('numericValue')) {\n    /**\n     * Is the value a numeric?\n     */\n    function numericValue(): \\Hamcrest\\Type\\IsNumeric\n    {\n        return \\Hamcrest\\Type\\IsNumeric::numericValue();\n    }\n}\n\nif (!function_exists('objectValue')) {\n    /**\n     * Is the value an object?\n     */\n    function objectValue(): \\Hamcrest\\Type\\IsObject\n    {\n        return \\Hamcrest\\Type\\IsObject::objectValue();\n    }\n}\n\nif (!function_exists('anObject')) {\n    /**\n     * Is the value an object?\n     */\n    function anObject(): \\Hamcrest\\Type\\IsObject\n    {\n        return \\Hamcrest\\Type\\IsObject::objectValue();\n    }\n}\n\nif (!function_exists('resourceValue')) {\n    /**\n     * Is the value a resource?\n     */\n    function resourceValue(): \\Hamcrest\\Type\\IsResource\n    {\n        return \\Hamcrest\\Type\\IsResource::resourceValue();\n    }\n}\n\nif (!function_exists('scalarValue')) {\n    /**\n     * Is the value a scalar (boolean, integer, double, or string)?\n     */\n    function scalarValue(): \\Hamcrest\\Type\\IsScalar\n    {\n        return \\Hamcrest\\Type\\IsScalar::scalarValue();\n    }\n}\n\nif (!function_exists('stringValue')) {\n    /**\n     * Is the value a string?\n     */\n    function stringValue(): \\Hamcrest\\Type\\IsString\n    {\n        return \\Hamcrest\\Type\\IsString::stringValue();\n    }\n}\n\nif (!function_exists('hasXPath')) {\n    /**\n     * Wraps <code>$matcher</code> with {@link Hamcrest\\Core\\IsEqual)\n     * if it's not a matcher and the XPath in <code>count()</code>\n     * if it's an integer.\n     *\n     * @param string $xpath\n     * @param null|Matcher|int|mixed $matcher\n     */\n    function hasXPath(string $xpath, $matcher = null): \\Hamcrest\\Xml\\HasXPath\n    {\n        return \\Hamcrest\\Xml\\HasXPath::hasXPath($xpath, $matcher);\n    }\n}\n"
  },
  {
    "path": "phpstan.neon",
    "content": "includes:\n\t- vendor/phpstan/phpstan-phpunit/extension.neon\n\t- tests/phpstan-baseline.neon\n\nparameters:\n    level: 8\n    paths:\n        - hamcrest\n        - tests\n\n    excludePaths:\n        analyse:\n            - tests/\n\n\n    editorUrl: 'phpstorm://open?file=%%file%%&line=%%line%%&project=hamcrest-php'\n\n    reportUnmatchedIgnoredErrors: false\n\n"
  },
  {
    "path": "tests/Hamcrest/AbstractMatcherTest.php",
    "content": "<?php\nnamespace Hamcrest;\n\nuse PHPUnit\\Framework\\TestCase;\n\nclass UnknownType {\n}\n\nabstract class AbstractMatcherTest extends TestCase\n{\n\n    const ARGUMENT_IGNORED = \"ignored\";\n    const ANY_NON_NULL_ARGUMENT = \"notnull\";\n\n    /**\n     * @before\n     */\n    protected function setUpTest()\n    {\n        MatcherAssert::resetCount();\n    }\n\n    abstract protected function createMatcher();\n\n    public function assertMatches(\\Hamcrest\\Matcher $matcher, $arg, $message)\n    {\n        $this->assertTrue($matcher->matches($arg), $message);\n    }\n\n    public function assertDoesNotMatch(\\Hamcrest\\Matcher $matcher, $arg, $message)\n    {\n        $this->assertFalse($matcher->matches($arg), $message);\n    }\n\n    public function assertDescription($expected, \\Hamcrest\\Matcher $matcher)\n    {\n        $description = new \\Hamcrest\\StringDescription();\n        $description->appendDescriptionOf($matcher);\n        $this->assertEquals($expected, (string) $description, 'Expected description');\n    }\n\n    public function assertMismatchDescription($expected, \\Hamcrest\\Matcher $matcher, $arg)\n    {\n        $description = new \\Hamcrest\\StringDescription();\n        $this->assertFalse(\n            $matcher->matches($arg),\n            'Precondtion: Matcher should not match item'\n        );\n        $matcher->describeMismatch($arg, $description);\n        $this->assertEquals(\n            $expected,\n            (string) $description,\n            'Expected mismatch description'\n        );\n    }\n\n    /**\n     * @doesNotPerformAssertions\n     */\n    public function testIsNullSafe()\n    {\n        //Should not generate any notices\n        $this->createMatcher()->matches(null);\n        $this->createMatcher()->describeMismatch(\n            null,\n            new \\Hamcrest\\NullDescription()\n        );\n    }\n\n    /**\n     * @doesNotPerformAssertions\n     */\n    public function testCopesWithUnknownTypes()\n    {\n        //Should not generate any notices\n        $this->createMatcher()->matches(new UnknownType());\n        $this->createMatcher()->describeMismatch(\n            new UnknownType(),\n            new NullDescription()\n        );\n    }\n\n    /**\n     * @after\n     */\n    protected function tearDownTest()\n    {\n        $this->addToAssertionCount(MatcherAssert::getCount());\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Array/IsArrayContainingInAnyOrderTest.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\nuse Hamcrest\\AbstractMatcherTest;\n\nclass IsArrayContainingInAnyOrderTest extends AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return IsArrayContainingInAnyOrder::arrayContainingInAnyOrder(array(1, 2));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('[<1>, <2>] in any order', containsInAnyOrder(array(1, 2)));\n    }\n\n    public function testMatchesItemsInAnyOrder()\n    {\n        $this->assertMatches(containsInAnyOrder(array(1, 2, 3)), array(1, 2, 3), 'in order');\n        $this->assertMatches(containsInAnyOrder(array(1, 2, 3)), array(3, 2, 1), 'out of order');\n        $this->assertMatches(containsInAnyOrder(array(1)), array(1), 'single');\n    }\n\n    public function testAppliesMatchersInAnyOrder()\n    {\n        $this->assertMatches(\n            containsInAnyOrder(array(1, 2, 3)),\n            array(1, 2, 3),\n            'in order'\n        );\n        $this->assertMatches(\n            containsInAnyOrder(array(1, 2, 3)),\n            array(3, 2, 1),\n            'out of order'\n        );\n        $this->assertMatches(\n            containsInAnyOrder(array(1)),\n            array(1),\n            'single'\n        );\n    }\n\n    public function testMismatchesItemsInAnyOrder()\n    {\n        $matcher = containsInAnyOrder(array(1, 2, 3));\n\n        $this->assertMismatchDescription('was null', $matcher, null);\n        $this->assertMismatchDescription('No item matches: <1>, <2>, <3> in []', $matcher, array());\n        $this->assertMismatchDescription('No item matches: <2>, <3> in [<1>]', $matcher, array(1));\n        $this->assertMismatchDescription('Not matched: <4>', $matcher, array(4, 3, 2, 1));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Array/IsArrayContainingInOrderTest.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\nuse Hamcrest\\AbstractMatcherTest;\n\nclass IsArrayContainingInOrderTest extends AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return IsArrayContainingInOrder::arrayContaining(array(1, 2));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('[<1>, <2>]', arrayContaining(array(1, 2)));\n    }\n\n    public function testMatchesItemsInOrder()\n    {\n        $this->assertMatches(arrayContaining(array(1, 2, 3)), array(1, 2, 3), 'in order');\n        $this->assertMatches(arrayContaining(array(1)), array(1), 'single');\n    }\n\n    public function testAppliesMatchersInOrder()\n    {\n        $this->assertMatches(\n            arrayContaining(array(1, 2, 3)),\n            array(1, 2, 3),\n            'in order'\n        );\n        $this->assertMatches(arrayContaining(array(1)), array(1), 'single');\n    }\n\n    public function testMismatchesItemsInAnyOrder()\n    {\n        if (defined('HHVM_VERSION')) {\n            $this->markTestSkipped('Broken on HHVM.');\n        }\n\n        $matcher = arrayContaining(array(1, 2, 3));\n        $this->assertMismatchDescription('was null', $matcher, null);\n        $this->assertMismatchDescription('No item matched: <1>', $matcher, array());\n        $this->assertMismatchDescription('No item matched: <2>', $matcher, array(1));\n        $this->assertMismatchDescription('item with key 0: was <4>', $matcher, array(4, 3, 2, 1));\n        $this->assertMismatchDescription('item with key 2: was <4>', $matcher, array(1, 2, 4));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Array/IsArrayContainingKeyTest.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\nuse Hamcrest\\AbstractMatcherTest;\n\nclass IsArrayContainingKeyTest extends AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return IsArrayContainingKey::hasKeyInArray('irrelevant');\n    }\n\n    public function testMatchesSingleElementArrayContainingKey()\n    {\n        $array = array('a'=>1);\n\n        $this->assertMatches(hasKey('a'), $array, 'Matches single key');\n    }\n\n    public function testMatchesArrayContainingKey()\n    {\n        $array = array('a'=>1, 'b'=>2, 'c'=>3);\n\n        $this->assertMatches(hasKey('a'), $array, 'Matches a');\n        $this->assertMatches(hasKey('c'), $array, 'Matches c');\n    }\n\n    public function testMatchesArrayContainingKeyWithIntegerKeys()\n    {\n        $array = array(1=>'A', 2=>'B');\n\n        assertThat($array, hasKey(1));\n    }\n\n    public function testMatchesArrayContainingKeyWithNumberKeys()\n    {\n        $array = array(1=>'A', 2=>'B');\n\n        assertThat($array, hasKey(1));\n\n        // very ugly version!\n        assertThat($array, IsArrayContainingKey::hasKeyInArray(2));\n    }\n\n    public function testHasReadableDescription()\n    {\n        $this->assertDescription('array with key \"a\"', hasKey('a'));\n    }\n\n    public function testDoesNotMatchEmptyArray()\n    {\n        $this->assertMismatchDescription('array was []', hasKey('Foo'), array());\n    }\n\n    public function testDoesNotMatchArrayMissingKey()\n    {\n        $array = array('a'=>1, 'b'=>2, 'c'=>3);\n\n        $this->assertMismatchDescription('array was [\"a\" => <1>, \"b\" => <2>, \"c\" => <3>]', hasKey('d'), $array);\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Array/IsArrayContainingKeyValuePairTest.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\nuse Hamcrest\\AbstractMatcherTest;\n\nclass IsArrayContainingKeyValuePairTest extends AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return IsArrayContainingKeyValuePair::hasKeyValuePair('irrelevant', 'irrelevant');\n    }\n\n    public function testMatchesArrayContainingMatchingKeyAndValue()\n    {\n        $array = array('a'=>1, 'b'=>2);\n\n        $this->assertMatches(hasKeyValuePair(equalTo('a'), equalTo(1)), $array, 'matcherA');\n        $this->assertMatches(hasKeyValuePair(equalTo('b'), equalTo(2)), $array, 'matcherB');\n        $this->assertMismatchDescription(\n            'array was [\"a\" => <1>, \"b\" => <2>]',\n            hasKeyValuePair(equalTo('c'), equalTo(3)),\n            $array\n        );\n    }\n\n    public function testDoesNotMatchNull()\n    {\n        $this->assertMismatchDescription('was null', hasKeyValuePair(anything(), anything()), null);\n    }\n\n    public function testHasReadableDescription()\n    {\n        $this->assertDescription('array containing [\"a\" => <2>]', hasKeyValuePair(equalTo('a'), equalTo(2)));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Array/IsArrayContainingTest.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\nuse Hamcrest\\AbstractMatcherTest;\n\nclass IsArrayContainingTest extends AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return IsArrayContaining::hasItemInArray('irrelevant');\n    }\n\n    public function testMatchesAnArrayThatContainsAnElementMatchingTheGivenMatcher()\n    {\n        $this->assertMatches(\n            hasItemInArray('a'),\n            array('a', 'b', 'c'),\n            \"should matches array that contains 'a'\"\n        );\n    }\n\n    public function testDoesNotMatchAnArrayThatDoesntContainAnElementMatchingTheGivenMatcher()\n    {\n        $this->assertDoesNotMatch(\n            hasItemInArray('a'),\n            array('b', 'c'),\n            \"should not matches array that doesn't contain 'a'\"\n        );\n        $this->assertDoesNotMatch(\n            hasItemInArray('a'),\n            array(),\n            'should not match empty array'\n        );\n    }\n\n    public function testDoesNotMatchNull()\n    {\n        $this->assertDoesNotMatch(\n            hasItemInArray('a'),\n            null,\n            'should not match null'\n        );\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('an array containing \"a\"', hasItemInArray('a'));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Array/IsArrayTest.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\nuse Hamcrest\\AbstractMatcherTest;\n\nclass IsArrayTest extends AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return IsArray::anArray(array(equalTo('irrelevant')));\n    }\n\n    public function testMatchesAnArrayThatMatchesAllTheElementMatchers()\n    {\n        $this->assertMatches(\n            anArray(array(equalTo('a'), equalTo('b'), equalTo('c'))),\n            array('a', 'b', 'c'),\n            'should match array with matching elements'\n        );\n    }\n\n    public function testDoesNotMatchAnArrayWhenElementsDoNotMatch()\n    {\n        $this->assertDoesNotMatch(\n            anArray(array(equalTo('a'), equalTo('b'))),\n            array('b', 'c'),\n            'should not match array with different elements'\n        );\n    }\n\n    public function testDoesNotMatchAnArrayOfDifferentSize()\n    {\n        $this->assertDoesNotMatch(\n            anArray(array(equalTo('a'), equalTo('b'))),\n            array('a', 'b', 'c'),\n            'should not match larger array'\n        );\n        $this->assertDoesNotMatch(\n            anArray(array(equalTo('a'), equalTo('b'))),\n            array('a'),\n            'should not match smaller array'\n        );\n    }\n\n    public function testDoesNotMatchNull()\n    {\n        $this->assertDoesNotMatch(\n            anArray(array(equalTo('a'))),\n            null,\n            'should not match null'\n        );\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription(\n            '[\"a\", \"b\"]',\n            anArray(array(equalTo('a'), equalTo('b')))\n        );\n    }\n\n    public function testHasAReadableMismatchDescriptionWhenKeysDontMatch()\n    {\n        $this->assertMismatchDescription(\n            'array keys were [<1>, <2>]',\n            anArray(array(equalTo('a'), equalTo('b'))),\n            array(1 => 'a', 2 => 'b')\n        );\n    }\n\n    public function testSupportsMatchesAssociativeArrays()\n    {\n        $this->assertMatches(\n            anArray(array('x'=>equalTo('a'), 'y'=>equalTo('b'), 'z'=>equalTo('c'))),\n            array('x'=>'a', 'y'=>'b', 'z'=>'c'),\n            'should match associative array with matching elements'\n        );\n    }\n\n    public function testDoesNotMatchAnAssociativeArrayWhenKeysDoNotMatch()\n    {\n        $this->assertDoesNotMatch(\n            anArray(array('x'=>equalTo('a'), 'y'=>equalTo('b'))),\n            array('x'=>'b', 'z'=>'c'),\n            'should not match array with different keys'\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Array/IsArrayWithSizeTest.php",
    "content": "<?php\nnamespace Hamcrest\\Arrays;\n\nuse Hamcrest\\AbstractMatcherTest;\n\nclass IsArrayWithSizeTest extends AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return IsArrayWithSize::arrayWithSize(equalTo(2));\n    }\n\n    public function testMatchesWhenSizeIsCorrect()\n    {\n        $this->assertMatches(arrayWithSize(equalTo(3)), array(1, 2, 3), 'correct size');\n        $this->assertDoesNotMatch(arrayWithSize(equalTo(2)), array(1, 2, 3), 'incorrect size');\n    }\n\n    public function testProvidesConvenientShortcutForArrayWithSizeEqualTo()\n    {\n        $this->assertMatches(arrayWithSize(3), array(1, 2, 3), 'correct size');\n        $this->assertDoesNotMatch(arrayWithSize(2), array(1, 2, 3), 'incorrect size');\n    }\n\n    public function testEmptyArray()\n    {\n        $this->assertMatches(emptyArray(), array(), 'correct size');\n        $this->assertDoesNotMatch(emptyArray(), array(1), 'incorrect size');\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('an array with size <3>', arrayWithSize(equalTo(3)));\n        $this->assertDescription('an empty array', emptyArray());\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/BaseMatcherTest.php",
    "content": "<?php\nnamespace Hamcrest;\n\n/* Test-specific subclass only */\nclass BaseMatcherTest extends \\Hamcrest\\BaseMatcher\n{\n\n    public function matches($item): bool\n    {\n        throw new \\RuntimeException();\n    }\n\n    public function describeTo(\\Hamcrest\\Description $description): void\n    {\n        $description->appendText('SOME DESCRIPTION');\n    }\n\n    public function testDescribesItselfWithToStringMethod()\n    {\n        $someMatcher = new \\Hamcrest\\SomeMatcher();\n        $this->assertEquals('SOME DESCRIPTION', (string) $someMatcher);\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Collection/IsEmptyTraversableTest.php",
    "content": "<?php\nnamespace Hamcrest\\Collection;\n\nuse Hamcrest\\AbstractMatcherTest;\n\nclass IsEmptyTraversableTest extends AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return IsEmptyTraversable::emptyTraversable();\n    }\n\n    public function testEmptyMatcherMatchesWhenEmpty()\n    {\n        $this->assertMatches(\n            emptyTraversable(),\n            new \\ArrayObject(array()),\n            'an empty traversable'\n        );\n    }\n\n    public function testEmptyMatcherDoesNotMatchWhenNotEmpty()\n    {\n        $this->assertDoesNotMatch(\n            emptyTraversable(),\n            new \\ArrayObject(array(1, 2, 3)),\n            'a non-empty traversable'\n        );\n    }\n\n    public function testEmptyMatcherDoesNotMatchNull()\n    {\n        $this->assertDoesNotMatch(\n            emptyTraversable(),\n            null,\n            'should not match null'\n        );\n    }\n\n    public function testEmptyMatcherHasAReadableDescription()\n    {\n        $this->assertDescription('an empty traversable', emptyTraversable());\n    }\n\n    public function testNonEmptyDoesNotMatchNull()\n    {\n        $this->assertDoesNotMatch(\n            nonEmptyTraversable(),\n            null,\n            'should not match null'\n        );\n    }\n\n    public function testNonEmptyDoesNotMatchWhenEmpty()\n    {\n        $this->assertDoesNotMatch(\n            nonEmptyTraversable(),\n            new \\ArrayObject(array()),\n            'an empty traversable'\n        );\n    }\n\n    public function testNonEmptyMatchesWhenNotEmpty()\n    {\n        $this->assertMatches(\n            nonEmptyTraversable(),\n            new \\ArrayObject(array(1, 2, 3)),\n            'a non-empty traversable'\n        );\n    }\n\n    public function testNonEmptyNonEmptyMatcherHasAReadableDescription()\n    {\n        $this->assertDescription('a non-empty traversable', nonEmptyTraversable());\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Collection/IsTraversableWithSizeTest.php",
    "content": "<?php\nnamespace Hamcrest\\Collection;\n\nclass IsTraversableWithSizeTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Collection\\IsTraversableWithSize::traversableWithSize(\n            equalTo(2)\n        );\n    }\n\n    public function testMatchesWhenSizeIsCorrect()\n    {\n        $this->assertMatches(\n            traversableWithSize(equalTo(3)),\n            new \\ArrayObject(array(1, 2, 3)),\n            'correct size'\n        );\n    }\n\n    public function testDoesNotMatchWhenSizeIsIncorrect()\n    {\n        $this->assertDoesNotMatch(\n            traversableWithSize(equalTo(2)),\n            new \\ArrayObject(array(1, 2, 3)),\n            'incorrect size'\n        );\n    }\n\n    public function testDoesNotMatchNull()\n    {\n        $this->assertDoesNotMatch(\n            traversableWithSize(3),\n            null,\n            'should not match null'\n        );\n    }\n\n    public function testProvidesConvenientShortcutForTraversableWithSizeEqualTo()\n    {\n        $this->assertMatches(\n            traversableWithSize(3),\n            new \\ArrayObject(array(1, 2, 3)),\n            'correct size'\n        );\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription(\n            'a traversable with size <3>',\n            traversableWithSize(equalTo(3))\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/AllOfTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass AllOfTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\AllOf::allOf('irrelevant');\n    }\n\n    public function testEvaluatesToTheLogicalConjunctionOfTwoOtherMatchers()\n    {\n        assertThat('good', allOf('good', 'good'));\n\n        assertThat('good', not(allOf('bad', 'good')));\n        assertThat('good', not(allOf('good', 'bad')));\n        assertThat('good', not(allOf('bad', 'bad')));\n    }\n\n    public function testEvaluatesToTheLogicalConjunctionOfManyOtherMatchers()\n    {\n        assertThat('good', allOf('good', 'good', 'good', 'good', 'good'));\n        assertThat('good', not(allOf('good', endsWith('d'), 'bad', 'good', 'good')));\n    }\n\n    public function testSupportsMixedTypes()\n    {\n        $all = allOf(\n            equalTo(new \\Hamcrest\\Core\\SampleBaseClass('good')),\n            equalTo(new \\Hamcrest\\Core\\SampleBaseClass('good')),\n            equalTo(new \\Hamcrest\\Core\\SampleSubClass('ugly'))\n        );\n\n        $negated = not($all);\n\n        assertThat(new \\Hamcrest\\Core\\SampleSubClass('good'), $negated);\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription(\n            '(\"good\" and \"bad\" and \"ugly\")',\n            allOf('good', 'bad', 'ugly')\n        );\n    }\n\n    public function testMismatchDescriptionDescribesFirstFailingMatch()\n    {\n        $this->assertMismatchDescription(\n            '\"good\" was \"bad\"',\n            allOf('bad', 'good'),\n            'bad'\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/AnyOfTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass AnyOfTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\AnyOf::anyOf('irrelevant');\n    }\n\n    public function testAnyOfEvaluatesToTheLogicalDisjunctionOfTwoOtherMatchers()\n    {\n        assertThat('good', anyOf('bad', 'good'));\n        assertThat('good', anyOf('good', 'good'));\n        assertThat('good', anyOf('good', 'bad'));\n\n        assertThat('good', not(anyOf('bad', startsWith('b'))));\n    }\n\n    public function testAnyOfEvaluatesToTheLogicalDisjunctionOfManyOtherMatchers()\n    {\n        assertThat('good', anyOf('bad', 'good', 'bad', 'bad', 'bad'));\n        assertThat('good', not(anyOf('bad', 'bad', 'bad', 'bad', 'bad')));\n    }\n\n    public function testAnyOfSupportsMixedTypes()\n    {\n        $combined = anyOf(\n            equalTo(new \\Hamcrest\\Core\\SampleBaseClass('good')),\n            equalTo(new \\Hamcrest\\Core\\SampleBaseClass('ugly')),\n            equalTo(new \\Hamcrest\\Core\\SampleSubClass('good'))\n        );\n\n        assertThat(new \\Hamcrest\\Core\\SampleSubClass('good'), $combined);\n    }\n\n    public function testAnyOfHasAReadableDescription()\n    {\n        $this->assertDescription(\n            '(\"good\" or \"bad\" or \"ugly\")',\n            anyOf('good', 'bad', 'ugly')\n        );\n    }\n\n    public function testNoneOfEvaluatesToTheLogicalDisjunctionOfTwoOtherMatchers()\n    {\n        assertThat('good', not(noneOf('bad', 'good')));\n        assertThat('good', not(noneOf('good', 'good')));\n        assertThat('good', not(noneOf('good', 'bad')));\n\n        assertThat('good', noneOf('bad', startsWith('b')));\n    }\n\n    public function testNoneOfEvaluatesToTheLogicalDisjunctionOfManyOtherMatchers()\n    {\n        assertThat('good', not(noneOf('bad', 'good', 'bad', 'bad', 'bad')));\n        assertThat('good', noneOf('bad', 'bad', 'bad', 'bad', 'bad'));\n    }\n\n    public function testNoneOfSupportsMixedTypes()\n    {\n        $combined = noneOf(\n            equalTo(new \\Hamcrest\\Core\\SampleBaseClass('good')),\n            equalTo(new \\Hamcrest\\Core\\SampleBaseClass('ugly')),\n            equalTo(new \\Hamcrest\\Core\\SampleSubClass('good'))\n        );\n\n        assertThat(new \\Hamcrest\\Core\\SampleSubClass('bad'), $combined);\n    }\n\n    public function testNoneOfHasAReadableDescription()\n    {\n        $this->assertDescription(\n            'not (\"good\" or \"bad\" or \"ugly\")',\n            noneOf('good', 'bad', 'ugly')\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/CombinableMatcherTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass CombinableMatcherTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    private $_either_3_or_4;\n    private $_not_3_and_not_4;\n\n    /**\n     * @before\n     */\n    protected function setUpTest()\n    {\n        parent::setUpTest();\n\n        $this->_either_3_or_4 = \\Hamcrest\\Core\\CombinableMatcher::either(equalTo(3))->orElse(equalTo(4));\n        $this->_not_3_and_not_4 = \\Hamcrest\\Core\\CombinableMatcher::both(not(equalTo(3)))->andAlso(not(equalTo(4)));\n    }\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\CombinableMatcher::either(equalTo('irrelevant'))->orElse(equalTo('ignored'));\n    }\n\n    public function testBothAcceptsAndRejects()\n    {\n        assertThat(2, $this->_not_3_and_not_4);\n        assertThat(3, not($this->_not_3_and_not_4));\n    }\n\n    public function testAcceptsAndRejectsThreeAnds()\n    {\n        $tripleAnd = $this->_not_3_and_not_4->andAlso(equalTo(2));\n        assertThat(2, $tripleAnd);\n        assertThat(3, not($tripleAnd));\n    }\n\n    public function testBothDescribesItself()\n    {\n        $this->assertEquals('(not <3> and not <4>)', (string) $this->_not_3_and_not_4);\n        $this->assertMismatchDescription('was <3>', $this->_not_3_and_not_4, 3);\n    }\n\n    public function testEitherAcceptsAndRejects()\n    {\n        assertThat(3, $this->_either_3_or_4);\n        assertThat(6, not($this->_either_3_or_4));\n    }\n\n    public function testAcceptsAndRejectsThreeOrs()\n    {\n        $orTriple = $this->_either_3_or_4->orElse(greaterThan(10));\n\n        assertThat(11, $orTriple);\n        assertThat(9, not($orTriple));\n    }\n\n    public function testEitherDescribesItself()\n    {\n        $this->assertEquals('(<3> or <4>)', (string) $this->_either_3_or_4);\n        $this->assertMismatchDescription('was <6>', $this->_either_3_or_4, 6);\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/DescribedAsTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass DescribedAsTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\DescribedAs::describedAs('irrelevant', anything());\n    }\n\n    public function testOverridesDescriptionOfOtherMatcherWithThatPassedToConstructor()\n    {\n        $m1 = describedAs('m1 description', anything());\n        $m2 = describedAs('m2 description', not(anything()));\n\n        $this->assertDescription('m1 description', $m1);\n        $this->assertDescription('m2 description', $m2);\n    }\n\n    public function testAppendsValuesToDescription()\n    {\n        $m = describedAs('value 1 = %0, value 2 = %1', anything(), 33, 97);\n\n        $this->assertDescription('value 1 = <33>, value 2 = <97>', $m);\n    }\n\n    public function testDelegatesMatchingToAnotherMatcher()\n    {\n        $m1 = describedAs('irrelevant', anything());\n        $m2 = describedAs('irrelevant', not(anything()));\n\n        $this->assertTrue($m1->matches(new \\stdClass()));\n        $this->assertFalse($m2->matches('hi'));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/EveryTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass EveryTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\Every::everyItem(anything());\n    }\n\n    public function testIsTrueWhenEveryValueMatches()\n    {\n        assertThat(array('AaA', 'BaB', 'CaC'), everyItem(containsString('a')));\n        assertThat(array('AbA', 'BbB', 'CbC'), not(everyItem(containsString('a'))));\n    }\n\n    public function testIsAlwaysTrueForEmptyLists()\n    {\n        assertThat(array(), everyItem(containsString('a')));\n    }\n\n    public function testDescribesItself()\n    {\n        $each = everyItem(containsString('a'));\n        $this->assertEquals('every item is a string containing \"a\"', (string) $each);\n\n        $this->assertMismatchDescription('an item was \"BbB\"', $each, array('BbB'));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/HasToStringTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass PhpForm\n{\n    public function __toString()\n    {\n        return 'php';\n    }\n}\n\nclass JavaForm\n{\n    public function toString()\n    {\n        return 'java';\n    }\n}\n\nclass BothForms\n{\n    public function __toString()\n    {\n        return 'php';\n    }\n\n    public function toString()\n    {\n        return 'java';\n    }\n}\n\nclass HasToStringTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\HasToString::hasToString('foo');\n    }\n\n    public function testMatchesWhenToStringMatches()\n    {\n        $this->assertMatches(\n            hasToString(equalTo('php')),\n            new \\Hamcrest\\Core\\PhpForm(),\n            'correct __toString'\n        );\n        $this->assertMatches(\n            hasToString(equalTo('java')),\n            new \\Hamcrest\\Core\\JavaForm(),\n            'correct toString'\n        );\n    }\n\n    public function testPicksJavaOverPhpToString()\n    {\n        $this->assertMatches(\n            hasToString(equalTo('java')),\n            new \\Hamcrest\\Core\\BothForms(),\n            'correct toString'\n        );\n    }\n\n    public function testDoesNotMatchWhenToStringDoesNotMatch()\n    {\n        $this->assertDoesNotMatch(\n            hasToString(equalTo('mismatch')),\n            new \\Hamcrest\\Core\\PhpForm(),\n            'incorrect __toString'\n        );\n        $this->assertDoesNotMatch(\n            hasToString(equalTo('mismatch')),\n            new \\Hamcrest\\Core\\JavaForm(),\n            'incorrect toString'\n        );\n        $this->assertDoesNotMatch(\n            hasToString(equalTo('mismatch')),\n            new \\Hamcrest\\Core\\BothForms(),\n            'incorrect __toString'\n        );\n    }\n\n    public function testDoesNotMatchNull()\n    {\n        $this->assertDoesNotMatch(\n            hasToString(equalTo('a')),\n            null,\n            'should not match null'\n        );\n    }\n\n    public function testProvidesConvenientShortcutForTraversableWithSizeEqualTo()\n    {\n        $this->assertMatches(\n            hasToString(equalTo('php')),\n            new \\Hamcrest\\Core\\PhpForm(),\n            'correct __toString'\n        );\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription(\n            'an object with toString() \"php\"',\n            hasToString(equalTo('php'))\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/IsAnythingTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass IsAnythingTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\IsAnything::anything();\n    }\n\n    public function testAlwaysEvaluatesToTrue()\n    {\n        assertThat(null, anything());\n        assertThat(new \\stdClass(), anything());\n        assertThat('hi', anything());\n    }\n\n    public function testHasUsefulDefaultDescription()\n    {\n        $this->assertDescription('ANYTHING', anything());\n    }\n\n    public function testCanOverrideDescription()\n    {\n        $description = 'description';\n        $this->assertDescription($description, anything($description));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/IsCollectionContainingTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass IsCollectionContainingTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\IsCollectionContaining::hasItem(equalTo('irrelevant'));\n    }\n\n    public function testMatchesACollectionThatContainsAnElementMatchingTheGivenMatcher()\n    {\n        $itemMatcher = hasItem(equalTo('a'));\n\n        $this->assertMatches(\n            $itemMatcher,\n            array('a', 'b', 'c'),\n            \"should match list that contains 'a'\"\n        );\n    }\n\n    public function testDoesNotMatchCollectionThatDoesntContainAnElementMatchingTheGivenMatcher()\n    {\n        $matcher1 = hasItem(equalTo('a'));\n        $this->assertDoesNotMatch(\n            $matcher1,\n            array('b', 'c'),\n            \"should not match list that doesn't contain 'a'\"\n        );\n\n        $matcher2 = hasItem(equalTo('a'));\n        $this->assertDoesNotMatch(\n            $matcher2,\n            array(),\n            'should not match the empty list'\n        );\n    }\n\n    public function testDoesNotMatchNull()\n    {\n        $this->assertDoesNotMatch(\n            hasItem(equalTo('a')),\n            null,\n            'should not match null'\n        );\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('a collection containing \"a\"', hasItem(equalTo('a')));\n    }\n\n    public function testMatchesAllItemsInCollection()\n    {\n        $matcher1 = hasItems(equalTo('a'), equalTo('b'), equalTo('c'));\n        $this->assertMatches(\n            $matcher1,\n            array('a', 'b', 'c'),\n            'should match list containing all items'\n        );\n\n        $matcher2 = hasItems('a', 'b', 'c');\n        $this->assertMatches(\n            $matcher2,\n            array('a', 'b', 'c'),\n            'should match list containing all items (without matchers)'\n        );\n\n        $matcher3 = hasItems(equalTo('a'), equalTo('b'), equalTo('c'));\n        $this->assertMatches(\n            $matcher3,\n            array('c', 'b', 'a'),\n            'should match list containing all items in any order'\n        );\n\n        $matcher4 = hasItems(equalTo('a'), equalTo('b'), equalTo('c'));\n        $this->assertMatches(\n            $matcher4,\n            array('e', 'c', 'b', 'a', 'd'),\n            'should match list containing all items plus others'\n        );\n\n        $matcher5 = hasItems(equalTo('a'), equalTo('b'), equalTo('c'));\n        $this->assertDoesNotMatch(\n            $matcher5,\n            array('e', 'c', 'b', 'd'), // 'a' missing\n            'should not match list unless it contains all items'\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/IsEqualTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass DummyToStringClass\n{\n    private $_arg;\n\n    public function __construct($arg)\n    {\n        $this->_arg = $arg;\n    }\n\n    public function __toString()\n    {\n        return $this->_arg;\n    }\n}\n\nclass IsEqualTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\IsEqual::equalTo('irrelevant');\n    }\n\n    public function testComparesObjectsUsingEqualityOperator()\n    {\n        assertThat(\"hi\", equalTo(\"hi\"));\n        assertThat(\"bye\", not(equalTo(\"hi\")));\n\n        assertThat(1, equalTo(1));\n        assertThat(1, not(equalTo(2)));\n\n        assertThat(\"2\", equalTo(2));\n    }\n\n    public function testCanCompareNullValues()\n    {\n        assertThat(null, equalTo(null));\n\n        assertThat(null, not(equalTo('hi')));\n        assertThat('hi', not(equalTo(null)));\n    }\n\n    public function testComparesTheElementsOfAnArray()\n    {\n        $s1 = array('a', 'b');\n        $s2 = array('a', 'b');\n        $s3 = array('c', 'd');\n        $s4 = array('a', 'b', 'c', 'd');\n\n        assertThat($s1, equalTo($s1));\n        assertThat($s2, equalTo($s1));\n        assertThat($s3, not(equalTo($s1)));\n        assertThat($s4, not(equalTo($s1)));\n    }\n\n    public function testComparesTheElementsOfAnArrayOfPrimitiveTypes()\n    {\n        $i1 = array(1, 2);\n        $i2 = array(1, 2);\n        $i3 = array(3, 4);\n        $i4 = array(1, 2, 3, 4);\n\n        assertThat($i1, equalTo($i1));\n        assertThat($i2, equalTo($i1));\n        assertThat($i3, not(equalTo($i1)));\n        assertThat($i4, not(equalTo($i1)));\n    }\n\n    public function testRecursivelyTestsElementsOfArrays()\n    {\n        $i1 = array(array(1, 2), array(3, 4));\n        $i2 = array(array(1, 2), array(3, 4));\n        $i3 = array(array(5, 6), array(7, 8));\n        $i4 = array(array(1, 2, 3, 4), array(3, 4));\n\n        assertThat($i1, equalTo($i1));\n        assertThat($i2, equalTo($i1));\n        assertThat($i3, not(equalTo($i1)));\n        assertThat($i4, not(equalTo($i1)));\n    }\n\n    public function testIncludesTheResultOfCallingToStringOnItsArgumentInTheDescription()\n    {\n        $argumentDescription = 'ARGUMENT DESCRIPTION';\n        $argument = new \\Hamcrest\\Core\\DummyToStringClass($argumentDescription);\n        $this->assertDescription('<' . $argumentDescription . '>', equalTo($argument));\n    }\n\n    public function testReturnsAnObviousDescriptionIfCreatedWithANestedMatcherByMistake()\n    {\n        $innerMatcher = equalTo('NestedMatcher');\n        $this->assertDescription('<' . (string) $innerMatcher . '>', equalTo($innerMatcher));\n    }\n\n    public function testReturnsGoodDescriptionIfCreatedWithNullReference()\n    {\n        $this->assertDescription('null', equalTo(null));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/IsIdenticalTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass IsIdenticalTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\IsIdentical::identicalTo('irrelevant');\n    }\n\n    public function testEvaluatesToTrueIfArgumentIsReferenceToASpecifiedObject()\n    {\n        $o1 = new \\stdClass();\n        $o2 = new \\stdClass();\n\n        assertThat($o1, identicalTo($o1));\n        assertThat($o2, not(identicalTo($o1)));\n    }\n\n    public function testReturnsReadableDescriptionFromToString()\n    {\n        $this->assertDescription('\"ARG\"', identicalTo('ARG'));\n    }\n\n    public function testReturnsReadableDescriptionFromToStringWhenInitialisedWithNull()\n    {\n        $this->assertDescription('null', identicalTo(null));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/IsInstanceOfTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass IsInstanceOfTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    private $_baseClassInstance;\n    private $_subClassInstance;\n\n    /**\n     * @before\n     */\n    protected function setUpTest()\n    {\n        parent::setUpTest();\n\n        $this->_baseClassInstance = new \\Hamcrest\\Core\\SampleBaseClass('good');\n        $this->_subClassInstance = new \\Hamcrest\\Core\\SampleSubClass('good');\n    }\n\n    protected function createMatcher(): IsInstanceOf\n    {\n        return \\Hamcrest\\Core\\IsInstanceOf::anInstanceOf('stdClass');\n    }\n\n    public function testEvaluatesToTrueIfArgumentIsInstanceOfASpecificClass()\n    {\n        assertThat($this->_baseClassInstance, anInstanceOf('Hamcrest\\Core\\SampleBaseClass'));\n        assertThat($this->_subClassInstance, anInstanceOf('Hamcrest\\Core\\SampleSubClass'));\n        assertThat(null, not(anInstanceOf('Hamcrest\\Core\\SampleBaseClass')));\n        assertThat(new \\stdClass(), not(anInstanceOf('Hamcrest\\Core\\SampleBaseClass')));\n    }\n\n    public function testEvaluatesToFalseIfArgumentIsNotAnObject()\n    {\n        assertThat(null, not(anInstanceOf('Hamcrest\\Core\\SampleBaseClass')));\n        assertThat(false, not(anInstanceOf('Hamcrest\\Core\\SampleBaseClass')));\n        assertThat(5, not(anInstanceOf('Hamcrest\\Core\\SampleBaseClass')));\n        assertThat('foo', not(anInstanceOf('Hamcrest\\Core\\SampleBaseClass')));\n        assertThat(array(1, 2, 3), not(anInstanceOf('Hamcrest\\Core\\SampleBaseClass')));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('an instance of stdClass', anInstanceOf('stdClass'));\n    }\n\n    public function testDecribesActualClassInMismatchMessage()\n    {\n        $this->assertMismatchDescription(\n            '[Hamcrest\\Core\\SampleBaseClass] <good>',\n            anInstanceOf('Hamcrest\\Core\\SampleSubClass'),\n            $this->_baseClassInstance\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/IsNotTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass IsNotTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\IsNot::not('something');\n    }\n\n    public function testEvaluatesToTheTheLogicalNegationOfAnotherMatcher()\n    {\n        $this->assertMatches(not(equalTo('A')), 'B', 'should match');\n        $this->assertDoesNotMatch(not(equalTo('B')), 'B', 'should not match');\n    }\n\n    public function testProvidesConvenientShortcutForNotEqualTo()\n    {\n        $this->assertMatches(not('A'), 'B', 'should match');\n        $this->assertMatches(not('B'), 'A', 'should match');\n        $this->assertDoesNotMatch(not('A'), 'A', 'should not match');\n        $this->assertDoesNotMatch(not('B'), 'B', 'should not match');\n    }\n\n    public function testUsesDescriptionOfNegatedMatcherWithPrefix()\n    {\n        $this->assertDescription('not a value greater than <2>', not(greaterThan(2)));\n        $this->assertDescription('not \"A\"', not('A'));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/IsNullTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass IsNullTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\IsNull::nullValue();\n    }\n\n    public function testEvaluatesToTrueIfArgumentIsNull()\n    {\n        assertThat(null, nullValue());\n        assertThat(self::ANY_NON_NULL_ARGUMENT, not(nullValue()));\n\n        assertThat(self::ANY_NON_NULL_ARGUMENT, notNullValue());\n        assertThat(null, not(notNullValue()));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/IsSameTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass IsSameTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\IsSame::sameInstance(new \\stdClass());\n    }\n\n    public function testEvaluatesToTrueIfArgumentIsReferenceToASpecifiedObject()\n    {\n        $o1 = new \\stdClass();\n        $o2 = new \\stdClass();\n\n        assertThat($o1, sameInstance($o1));\n        assertThat($o2, not(sameInstance($o1)));\n    }\n\n    public function testReturnsReadableDescriptionFromToString()\n    {\n        $this->assertDescription('sameInstance(\"ARG\")', sameInstance('ARG'));\n    }\n\n    public function testReturnsReadableDescriptionFromToStringWhenInitialisedWithNull()\n    {\n        $this->assertDescription('sameInstance(null)', sameInstance(null));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/IsTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass IsTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\Is::is('something');\n    }\n\n    public function testJustMatchesTheSameWayTheUnderylingMatcherDoes()\n    {\n        $this->assertMatches(is(equalTo(true)), true, 'should match');\n        $this->assertMatches(is(equalTo(false)), false, 'should match');\n        $this->assertDoesNotMatch(is(equalTo(true)), false, 'should not match');\n        $this->assertDoesNotMatch(is(equalTo(false)), true, 'should not match');\n    }\n\n    public function testGeneratesIsPrefixInDescription()\n    {\n        $this->assertDescription('is <true>', is(equalTo(true)));\n    }\n\n    public function testProvidesConvenientShortcutForIsEqualTo()\n    {\n        $this->assertMatches(is('A'), 'A', 'should match');\n        $this->assertMatches(is('B'), 'B', 'should match');\n        $this->assertDoesNotMatch(is('A'), 'B', 'should not match');\n        $this->assertDoesNotMatch(is('B'), 'A', 'should not match');\n        $this->assertDescription('is \"A\"', is('A'));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/IsTypeOfTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass IsTypeOfTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\IsTypeOf::typeOf('integer');\n    }\n\n    public function testEvaluatesToTrueIfArgumentMatchesType()\n    {\n        assertThat(array('5', 5), typeOf('array'));\n        assertThat(false, typeOf('boolean'));\n        assertThat(5, typeOf('integer'));\n        assertThat(5.2, typeOf('double'));\n        assertThat(null, typeOf('null'));\n        assertThat(tmpfile(), typeOf('resource'));\n        assertThat('a string', typeOf('string'));\n    }\n\n    public function testEvaluatesToFalseIfArgumentDoesntMatchType()\n    {\n        assertThat(false, not(typeOf('array')));\n        assertThat(array('5', 5), not(typeOf('boolean')));\n        assertThat(5.2, not(typeOf('integer')));\n        assertThat(5, not(typeOf('double')));\n        assertThat(false, not(typeOf('null')));\n        assertThat('a string', not(typeOf('resource')));\n        assertThat(tmpfile(), not(typeOf('string')));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('a double', typeOf('double'));\n        $this->assertDescription('an integer', typeOf('integer'));\n    }\n\n    public function testDecribesActualTypeInMismatchMessage()\n    {\n        $this->assertMismatchDescription('was null', typeOf('boolean'), null);\n        $this->assertMismatchDescription('was an integer <5>', typeOf('float'), 5);\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/SampleBaseClass.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass SampleBaseClass\n{\n\n    private $_arg;\n\n    public function __construct($arg)\n    {\n        $this->_arg = $arg;\n    }\n\n    public function __toString()\n    {\n        return $this->_arg;\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/SampleSubClass.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass SampleSubClass extends \\Hamcrest\\Core\\SampleBaseClass\n{\n}\n"
  },
  {
    "path": "tests/Hamcrest/Core/SetTest.php",
    "content": "<?php\nnamespace Hamcrest\\Core;\n\nclass SetTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    public static $_classProperty;\n    public $_instanceProperty;\n\n    /**\n     * @before\n     */\n    protected function setUpTest()\n    {\n        parent::setUpTest();\n\n        self::$_classProperty = null;\n        unset($this->_instanceProperty);\n    }\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Core\\Set::set('property_name');\n    }\n\n    public function testEvaluatesToTrueIfArrayPropertyIsSet()\n    {\n        assertThat(array('foo' => 'bar'), set('foo'));\n    }\n\n    public function testNegatedEvaluatesToFalseIfArrayPropertyIsSet()\n    {\n        assertThat(array('foo' => 'bar'), not(notSet('foo')));\n    }\n\n    public function testEvaluatesToTrueIfClassPropertyIsSet()\n    {\n        self::$_classProperty = 'bar';\n        assertThat('Hamcrest\\Core\\SetTest', set('_classProperty'));\n    }\n\n    public function testNegatedEvaluatesToFalseIfClassPropertyIsSet()\n    {\n        self::$_classProperty = 'bar';\n        assertThat('Hamcrest\\Core\\SetTest', not(notSet('_classProperty')));\n    }\n\n    public function testEvaluatesToTrueIfObjectPropertyIsSet()\n    {\n        $this->_instanceProperty = 'bar';\n        assertThat($this, set('_instanceProperty'));\n    }\n\n    public function testNegatedEvaluatesToFalseIfObjectPropertyIsSet()\n    {\n        $this->_instanceProperty = 'bar';\n        assertThat($this, not(notSet('_instanceProperty')));\n    }\n\n    public function testEvaluatesToFalseIfArrayPropertyIsNotSet()\n    {\n        assertThat(array('foo' => 'bar'), not(set('baz')));\n    }\n\n    public function testNegatedEvaluatesToTrueIfArrayPropertyIsNotSet()\n    {\n        assertThat(array('foo' => 'bar'), notSet('baz'));\n    }\n\n    public function testEvaluatesToFalseIfClassPropertyIsNotSet()\n    {\n        assertThat('Hamcrest\\Core\\SetTest', not(set('_classProperty')));\n    }\n\n    public function testNegatedEvaluatesToTrueIfClassPropertyIsNotSet()\n    {\n        assertThat('Hamcrest\\Core\\SetTest', notSet('_classProperty'));\n    }\n\n    public function testEvaluatesToFalseIfObjectPropertyIsNotSet()\n    {\n        assertThat($this, not(set('_instanceProperty')));\n    }\n\n    public function testNegatedEvaluatesToTrueIfObjectPropertyIsNotSet()\n    {\n        assertThat($this, notSet('_instanceProperty'));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('set property foo', set('foo'));\n        $this->assertDescription('unset property bar', notSet('bar'));\n    }\n\n    public function testDecribesPropertySettingInMismatchMessage()\n    {\n        $this->assertMismatchDescription(\n            'was not set',\n            set('bar'),\n            array('foo' => 'bar')\n        );\n        $this->assertMismatchDescription(\n            'was \"bar\"',\n            notSet('foo'),\n            array('foo' => 'bar')\n        );\n        self::$_classProperty = 'bar';\n        $this->assertMismatchDescription(\n            'was \"bar\"',\n            notSet('_classProperty'),\n            'Hamcrest\\Core\\SetTest'\n        );\n        $this->_instanceProperty = 'bar';\n        $this->assertMismatchDescription(\n            'was \"bar\"',\n            notSet('_instanceProperty'),\n            $this\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/FeatureMatcherTest.php",
    "content": "<?php\nnamespace Hamcrest;\n\nclass Thingy\n{\n    private $_result;\n    public function __construct($result)\n    {\n        $this->_result = $result;\n    }\n    public function getResult()\n    {\n        return $this->_result;\n    }\n}\n\n/* Test-specific subclass only */\nclass ResultMatcher extends \\Hamcrest\\FeatureMatcher\n{\n    public function __construct()\n    {\n        parent::__construct(self::TYPE_ANY, null, equalTo('bar'), 'Thingy with result', 'result');\n    }\n    public function featureValueOf($actual)\n    {\n        if ($actual instanceof \\Hamcrest\\Thingy) {\n            return $actual->getResult();\n        }\n    }\n}\n\nclass FeatureMatcherTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    private $_resultMatcher;\n\n    /**\n     * @before\n     */\n    protected function setUpTest()\n    {\n        parent::setUpTest();\n\n        $this->_resultMatcher = $this->_resultMatcher();\n    }\n\n    protected function createMatcher()\n    {\n        return $this->_resultMatcher();\n    }\n\n    public function testMatchesPartOfAnObject()\n    {\n        $this->assertMatches($this->_resultMatcher, new \\Hamcrest\\Thingy('bar'), 'feature');\n        $this->assertDescription('Thingy with result \"bar\"', $this->_resultMatcher);\n    }\n\n    public function testMismatchesPartOfAnObject()\n    {\n        $this->assertMismatchDescription(\n            'result was \"foo\"',\n            $this->_resultMatcher,\n            new \\Hamcrest\\Thingy('foo')\n        );\n    }\n\n    public function testDoesNotGenerateNoticesForNull()\n    {\n        $this->assertMismatchDescription('result was null', $this->_resultMatcher, null);\n    }\n\n    // -- Creation Methods\n\n    private function _resultMatcher()\n    {\n        return new \\Hamcrest\\ResultMatcher();\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/InvokedMatcherTest.php",
    "content": "<?php\nnamespace Hamcrest;\n\nuse PHPUnit\\Framework\\TestCase;\n\nclass SampleInvokeMatcher extends BaseMatcherTest\n{\n    private $matchAgainst;\n\n    public function __construct($matchAgainst)\n    {\n        $this->matchAgainst = $matchAgainst;\n    }\n\n    public function matches($item): bool\n    {\n        return $item == $this->matchAgainst;\n    }\n\n}\n\nclass InvokedMatcherTest extends TestCase\n{\n    public function testInvokedMatchersCallMatches()\n    {\n        $sampleMatcher = new SampleInvokeMatcher('foo');\n\n        $this->assertTrue($sampleMatcher('foo'));\n        $this->assertFalse($sampleMatcher('bar'));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/MatcherAssertTest.php",
    "content": "<?php\nnamespace Hamcrest;\n\nuse PHPUnit\\Framework\\TestCase;\n\nclass MatcherAssertTest extends TestCase\n{\n\n    /**\n     * @before\n     */\n    protected function setUpTest()\n    {\n        \\Hamcrest\\MatcherAssert::resetCount();\n    }\n\n    public function testResetCount()\n    {\n        \\Hamcrest\\MatcherAssert::assertThat(true);\n        self::assertEquals(1, \\Hamcrest\\MatcherAssert::getCount(), 'assertion count');\n        \\Hamcrest\\MatcherAssert::resetCount();\n        self::assertEquals(0, \\Hamcrest\\MatcherAssert::getCount(), 'assertion count');\n    }\n\n    public function testAssertThatWithTrueArgPasses()\n    {\n        \\Hamcrest\\MatcherAssert::assertThat(true);\n        \\Hamcrest\\MatcherAssert::assertThat('non-empty');\n        \\Hamcrest\\MatcherAssert::assertThat(1);\n        \\Hamcrest\\MatcherAssert::assertThat(3.14159);\n        \\Hamcrest\\MatcherAssert::assertThat(array(true));\n        self::assertEquals(5, \\Hamcrest\\MatcherAssert::getCount(), 'assertion count');\n    }\n\n    public function testAssertThatWithFalseArgFails()\n    {\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat(false);\n            self::fail('expected assertion failure');\n        } catch (\\Hamcrest\\AssertionError $ex) {\n            self::assertEquals('', $ex->getMessage());\n        }\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat(null);\n            self::fail('expected assertion failure');\n        } catch (\\Hamcrest\\AssertionError $ex) {\n            self::assertEquals('', $ex->getMessage());\n        }\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat('');\n            self::fail('expected assertion failure');\n        } catch (\\Hamcrest\\AssertionError $ex) {\n            self::assertEquals('', $ex->getMessage());\n        }\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat(0);\n            self::fail('expected assertion failure');\n        } catch (\\Hamcrest\\AssertionError $ex) {\n            self::assertEquals('', $ex->getMessage());\n        }\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat(0.0);\n            self::fail('expected assertion failure');\n        } catch (\\Hamcrest\\AssertionError $ex) {\n            self::assertEquals('', $ex->getMessage());\n        }\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat(array());\n            self::fail('expected assertion failure');\n        } catch (\\Hamcrest\\AssertionError $ex) {\n            self::assertEquals('', $ex->getMessage());\n        }\n        self::assertEquals(6, \\Hamcrest\\MatcherAssert::getCount(), 'assertion count');\n    }\n\n    public function testAssertThatWithIdentifierAndTrueArgPasses()\n    {\n        \\Hamcrest\\MatcherAssert::assertThat('identifier', true);\n        \\Hamcrest\\MatcherAssert::assertThat('identifier', 'non-empty');\n        \\Hamcrest\\MatcherAssert::assertThat('identifier', 1);\n        \\Hamcrest\\MatcherAssert::assertThat('identifier', 3.14159);\n        \\Hamcrest\\MatcherAssert::assertThat('identifier', array(true));\n        self::assertEquals(5, \\Hamcrest\\MatcherAssert::getCount(), 'assertion count');\n    }\n\n    public function testAssertThatWithIdentifierAndFalseArgFails()\n    {\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat('identifier', false);\n            self::fail('expected assertion failure');\n        } catch (\\Hamcrest\\AssertionError $ex) {\n            self::assertEquals('identifier', $ex->getMessage());\n        }\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat('identifier', null);\n            self::fail('expected assertion failure');\n        } catch (\\Hamcrest\\AssertionError $ex) {\n            self::assertEquals('identifier', $ex->getMessage());\n        }\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat('identifier', '');\n            self::fail('expected assertion failure');\n        } catch (\\Hamcrest\\AssertionError $ex) {\n            self::assertEquals('identifier', $ex->getMessage());\n        }\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat('identifier', 0);\n            self::fail('expected assertion failure');\n        } catch (\\Hamcrest\\AssertionError $ex) {\n            self::assertEquals('identifier', $ex->getMessage());\n        }\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat('identifier', 0.0);\n            self::fail('expected assertion failure');\n        } catch (\\Hamcrest\\AssertionError $ex) {\n            self::assertEquals('identifier', $ex->getMessage());\n        }\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat('identifier', array());\n            self::fail('expected assertion failure');\n        } catch (\\Hamcrest\\AssertionError $ex) {\n            self::assertEquals('identifier', $ex->getMessage());\n        }\n        self::assertEquals(6, \\Hamcrest\\MatcherAssert::getCount(), 'assertion count');\n    }\n\n    public function testAssertThatWithActualValueAndMatcherArgsThatMatchPasses()\n    {\n        \\Hamcrest\\MatcherAssert::assertThat(true, is(true));\n        self::assertEquals(1, \\Hamcrest\\MatcherAssert::getCount(), 'assertion count');\n    }\n\n    public function testAssertThatWithActualValueAndMatcherArgsThatDontMatchFails()\n    {\n        $expected = 'expected';\n        $actual = 'actual';\n\n        $expectedMessage =\n            'Expected: \"expected\"' . PHP_EOL .\n            '     but: was \"actual\"';\n\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat($actual, equalTo($expected));\n            self::fail('expected assertion failure');\n        } catch (\\Hamcrest\\AssertionError $ex) {\n            self::assertEquals($expectedMessage, $ex->getMessage());\n            self::assertEquals(1, \\Hamcrest\\MatcherAssert::getCount(), 'assertion count');\n        }\n    }\n\n    public function testAssertThatWithIdentifierAndActualValueAndMatcherArgsThatMatchPasses()\n    {\n        \\Hamcrest\\MatcherAssert::assertThat('identifier', true, is(true));\n        self::assertEquals(1, \\Hamcrest\\MatcherAssert::getCount(), 'assertion count');\n    }\n\n    public function testAssertThatWithIdentifierAndActualValueAndMatcherArgsThatDontMatchFails()\n    {\n        $expected = 'expected';\n        $actual = 'actual';\n\n        $expectedMessage =\n            'identifier' . PHP_EOL .\n            'Expected: \"expected\"' . PHP_EOL .\n            '     but: was \"actual\"';\n\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat('identifier', $actual, equalTo($expected));\n            self::fail('expected assertion failure');\n        } catch (\\Hamcrest\\AssertionError $ex) {\n            self::assertEquals($expectedMessage, $ex->getMessage());\n            self::assertEquals(1, \\Hamcrest\\MatcherAssert::getCount(), 'assertion count');\n        }\n    }\n\n    public function testAssertThatWithNoArgsThrowsErrorAndDoesntIncrementCount()\n    {\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat();\n            self::fail('expected invalid argument exception');\n        } catch (\\InvalidArgumentException $ex) {\n            self::assertEquals(0, \\Hamcrest\\MatcherAssert::getCount(), 'assertion count');\n        }\n    }\n\n    public function testAssertThatWithFourArgsThrowsErrorAndDoesntIncrementCount()\n    {\n        try {\n            \\Hamcrest\\MatcherAssert::assertThat(1, 2, 3, 4);\n            self::fail('expected invalid argument exception');\n        } catch (\\InvalidArgumentException $ex) {\n            self::assertEquals(0, \\Hamcrest\\MatcherAssert::getCount(), 'assertion count');\n        }\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Number/IsCloseToTest.php",
    "content": "<?php\nnamespace Hamcrest\\Number;\n\nclass IsCloseToTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        $irrelevant = 0.1;\n\n        return \\Hamcrest\\Number\\IsCloseTo::closeTo($irrelevant, $irrelevant);\n    }\n\n    public function testEvaluatesToTrueIfArgumentIsEqualToADoubleValueWithinSomeError()\n    {\n        $p = closeTo(1.0, 0.5);\n\n        $this->assertTrue($p->matches(1.0));\n        $this->assertTrue($p->matches(0.5));\n        $this->assertTrue($p->matches(1.5));\n\n        $this->assertDoesNotMatch($p, 2.0, 'too large');\n        $this->assertMismatchDescription('<2F> differed by <0.5F>', $p, 2.0);\n        $this->assertDoesNotMatch($p, 0.0, 'number too small');\n        $this->assertMismatchDescription('<0F> differed by <0.5F>', $p, 0.0);\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Number/OrderingComparisonTest.php",
    "content": "<?php\nnamespace Hamcrest\\Number;\n\nclass OrderingComparisonTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Number\\OrderingComparison::greaterThan(1);\n    }\n\n    public function testComparesValuesForGreaterThan()\n    {\n        assertThat(2, greaterThan(1));\n        assertThat(0, not(greaterThan(1)));\n    }\n\n    public function testComparesValuesForLessThan()\n    {\n        assertThat(2, lessThan(3));\n        assertThat(0, lessThan(1));\n    }\n\n    public function testComparesValuesForEquality()\n    {\n        assertThat(3, comparesEqualTo(3));\n        assertThat('aa', comparesEqualTo('aa'));\n    }\n\n    public function testAllowsForInclusiveComparisons()\n    {\n        assertThat(1, lessThanOrEqualTo(1));\n        assertThat(1, greaterThanOrEqualTo(1));\n    }\n\n    public function testSupportsDifferentTypesOfComparableValues()\n    {\n        assertThat(1.1, greaterThan(1.0));\n        assertThat(\"cc\", greaterThan(\"bb\"));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/StringDescriptionTest.php",
    "content": "<?php\nnamespace Hamcrest;\n\nuse PHPUnit\\Framework\\TestCase;\n\nclass SampleSelfDescriber implements \\Hamcrest\\SelfDescribing\n{\n    private $_text;\n\n    public function __construct($text)\n    {\n        $this->_text = $text;\n    }\n\n    public function describeTo(\\Hamcrest\\Description $description): void\n    {\n        $description->appendText($this->_text);\n    }\n}\n\nclass StringDescriptionTest extends TestCase\n{\n\n    private $_description;\n\n    /**\n     * @before\n     */\n    protected function setUpTest()\n    {\n        $this->_description = new \\Hamcrest\\StringDescription();\n    }\n\n    public function testAppendTextAppendsTextInformation()\n    {\n        $this->_description->appendText('foo')->appendText('bar');\n        $this->assertEquals('foobar', (string) $this->_description);\n    }\n\n    public function testAppendValueCanAppendTextTypes()\n    {\n        $this->_description->appendValue('foo');\n        $this->assertEquals('\"foo\"', (string) $this->_description);\n    }\n\n    public function testSpecialCharactersAreEscapedForStringTypes()\n    {\n        $this->_description->appendValue(\"foo\\\\bar\\\"zip\\r\\n\");\n        $this->assertEquals('\"foo\\\\bar\\\\\"zip\\r\\n\"', (string) $this->_description);\n    }\n\n    public function testIntegerValuesCanBeAppended()\n    {\n        $this->_description->appendValue(42);\n        $this->assertEquals('<42>', (string) $this->_description);\n    }\n\n    public function testFloatValuesCanBeAppended()\n    {\n        $this->_description->appendValue(42.78);\n        $this->assertEquals('<42.78F>', (string) $this->_description);\n    }\n\n    public function testNullValuesCanBeAppended()\n    {\n        $this->_description->appendValue(null);\n        $this->assertEquals('null', (string) $this->_description);\n    }\n\n    public function testArraysCanBeAppended()\n    {\n        $this->_description->appendValue(array('foo', 42.78));\n        $this->assertEquals('[\"foo\", <42.78F>]', (string) $this->_description);\n    }\n\n    public function testObjectsCanBeAppended()\n    {\n        $this->_description->appendValue(new \\stdClass());\n        $this->assertEquals('<stdClass>', (string) $this->_description);\n    }\n\n    public function testBooleanValuesCanBeAppended()\n    {\n        $this->_description->appendValue(false);\n        $this->assertEquals('<false>', (string) $this->_description);\n    }\n\n    public function testListsOfvaluesCanBeAppended()\n    {\n        $this->_description->appendValue(array('foo', 42.78));\n        $this->assertEquals('[\"foo\", <42.78F>]', (string) $this->_description);\n    }\n\n    public function testIterableOfvaluesCanBeAppended()\n    {\n        $items = new \\ArrayObject(array('foo', 42.78));\n        $this->_description->appendValue($items);\n        $this->assertEquals('[\"foo\", <42.78F>]', (string) $this->_description);\n    }\n\n    public function testIteratorOfvaluesCanBeAppended()\n    {\n        $items = new \\ArrayObject(array('foo', 42.78));\n        $this->_description->appendValue($items->getIterator());\n        $this->assertEquals('[\"foo\", <42.78F>]', (string) $this->_description);\n    }\n\n    public function testListsOfvaluesCanBeAppendedManually()\n    {\n        $this->_description->appendValueList('@start@', '@sep@ ', '@end@', array('foo', 42.78));\n        $this->assertEquals('@start@\"foo\"@sep@ <42.78F>@end@', (string) $this->_description);\n    }\n\n    public function testIterableOfvaluesCanBeAppendedManually()\n    {\n        $items = new \\ArrayObject(array('foo', 42.78));\n        $this->_description->appendValueList('@start@', '@sep@ ', '@end@', $items);\n        $this->assertEquals('@start@\"foo\"@sep@ <42.78F>@end@', (string) $this->_description);\n    }\n\n    public function testIteratorOfvaluesCanBeAppendedManually()\n    {\n        $items = new \\ArrayObject(array('foo', 42.78));\n        $this->_description->appendValueList('@start@', '@sep@ ', '@end@', $items->getIterator());\n        $this->assertEquals('@start@\"foo\"@sep@ <42.78F>@end@', (string) $this->_description);\n    }\n\n    public function testSelfDescribingObjectsCanBeAppended()\n    {\n        $this->_description\n            ->appendDescriptionOf(new \\Hamcrest\\SampleSelfDescriber('foo'))\n            ->appendDescriptionOf(new \\Hamcrest\\SampleSelfDescriber('bar'))\n            ;\n        $this->assertEquals('foobar', (string) $this->_description);\n    }\n\n    public function testSelfDescribingObjectsCanBeAppendedAsLists()\n    {\n        $this->_description->appendList('@start@', '@sep@ ', '@end@', array(\n            new \\Hamcrest\\SampleSelfDescriber('foo'),\n            new \\Hamcrest\\SampleSelfDescriber('bar')\n        ));\n        $this->assertEquals('@start@foo@sep@ bar@end@', (string) $this->_description);\n    }\n\n    public function testSelfDescribingObjectsCanBeAppendedAsIteratedLists()\n    {\n        $items = new \\ArrayObject(array(\n            new \\Hamcrest\\SampleSelfDescriber('foo'),\n            new \\Hamcrest\\SampleSelfDescriber('bar')\n        ));\n        $this->_description->appendList('@start@', '@sep@ ', '@end@', $items);\n        $this->assertEquals('@start@foo@sep@ bar@end@', (string) $this->_description);\n    }\n\n    public function testSelfDescribingObjectsCanBeAppendedAsIterators()\n    {\n        $items = new \\ArrayObject(array(\n            new \\Hamcrest\\SampleSelfDescriber('foo'),\n            new \\Hamcrest\\SampleSelfDescriber('bar')\n        ));\n        $this->_description->appendList('@start@', '@sep@ ', '@end@', $items->getIterator());\n        $this->assertEquals('@start@foo@sep@ bar@end@', (string) $this->_description);\n    }\n\n    public function testToStringAppendsSelfDescribing()\n    {\n        $description = $this->_description->toString(new \\Hamcrest\\SampleSelfDescriber('foo'));\n        $this->assertEquals('foo', $description);\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Text/IsEmptyStringTest.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\nclass IsEmptyStringTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Text\\IsEmptyString::isEmptyOrNullString();\n    }\n\n    public function testEmptyDoesNotMatchNull()\n    {\n        $this->assertDoesNotMatch(emptyString(), null, 'null');\n    }\n\n    public function testEmptyDoesNotMatchZero()\n    {\n        $this->assertDoesNotMatch(emptyString(), 0, 'zero');\n    }\n\n    public function testEmptyDoesNotMatchFalse()\n    {\n        $this->assertDoesNotMatch(emptyString(), false, 'false');\n    }\n\n    public function testEmptyDoesNotMatchEmptyArray()\n    {\n        $this->assertDoesNotMatch(emptyString(), array(), 'empty array');\n    }\n\n    public function testEmptyMatchesEmptyString()\n    {\n        $this->assertMatches(emptyString(), '', 'empty string');\n    }\n\n    public function testEmptyDoesNotMatchNonEmptyString()\n    {\n        $this->assertDoesNotMatch(emptyString(), 'foo', 'non-empty string');\n    }\n\n    public function testEmptyHasAReadableDescription()\n    {\n        $this->assertDescription('an empty string', emptyString());\n    }\n\n    public function testEmptyOrNullMatchesNull()\n    {\n        $this->assertMatches(nullOrEmptyString(), null, 'null');\n    }\n\n    public function testEmptyOrNullMatchesEmptyString()\n    {\n        $this->assertMatches(nullOrEmptyString(), '', 'empty string');\n    }\n\n    public function testEmptyOrNullDoesNotMatchNonEmptyString()\n    {\n        $this->assertDoesNotMatch(nullOrEmptyString(), 'foo', 'non-empty string');\n    }\n\n    public function testEmptyOrNullHasAReadableDescription()\n    {\n        $this->assertDescription('(null or an empty string)', nullOrEmptyString());\n    }\n\n    public function testNonEmptyDoesNotMatchNull()\n    {\n        $this->assertDoesNotMatch(nonEmptyString(), null, 'null');\n    }\n\n    public function testNonEmptyDoesNotMatchEmptyString()\n    {\n        $this->assertDoesNotMatch(nonEmptyString(), '', 'empty string');\n    }\n\n    public function testNonEmptyMatchesNonEmptyString()\n    {\n        $this->assertMatches(nonEmptyString(), 'foo', 'non-empty string');\n    }\n\n    public function testNonEmptyHasAReadableDescription()\n    {\n        $this->assertDescription('a non-empty string', nonEmptyString());\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Text/IsEqualIgnoringCaseTest.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\nclass IsEqualIgnoringCaseTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Text\\IsEqualIgnoringCase::equalToIgnoringCase('irrelevant');\n    }\n\n    public function testIgnoresCaseOfCharsInString()\n    {\n        assertThat('HELLO', equalToIgnoringCase('heLLo'));\n        assertThat('hello', equalToIgnoringCase('heLLo'));\n        assertThat('HelLo', equalToIgnoringCase('heLLo'));\n\n        assertThat('bye', not(equalToIgnoringCase('heLLo')));\n    }\n\n    public function testFailsIfAdditionalWhitespaceIsPresent()\n    {\n        assertThat('heLLo ', not(equalToIgnoringCase('heLLo')));\n        assertThat(' heLLo', not(equalToIgnoringCase('heLLo')));\n        assertThat('hello', not(equalToIgnoringCase(' heLLo')));\n    }\n\n    public function testFailsIfMatchingAgainstNull()\n    {\n        assertThat(null, not(equalToIgnoringCase('heLLo')));\n    }\n\n    public function testDescribesItselfAsCaseInsensitive()\n    {\n        $this->assertDescription(\n            'equalToIgnoringCase(\"heLLo\")',\n            equalToIgnoringCase('heLLo')\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Text/IsEqualIgnoringWhiteSpaceTest.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\nclass IsEqualIgnoringWhiteSpaceTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    private $_matcher;\n\n    /**\n     * @before\n     */\n    protected function setUpTest()\n    {\n        parent::setUpTest();\n\n        $this->_matcher = \\Hamcrest\\Text\\IsEqualIgnoringWhiteSpace::equalToIgnoringWhiteSpace(\n            \"Hello World   how\\n are we? \"\n        );\n    }\n\n    protected function createMatcher()\n    {\n        return $this->_matcher;\n    }\n\n    public function testPassesIfWordsAreSameButWhitespaceDiffers()\n    {\n        assertThat('Hello World how are we?', $this->_matcher);\n        assertThat(\"   Hello \\rWorld \\t  how are\\nwe?\", $this->_matcher);\n    }\n\n    public function testFailsIfTextOtherThanWhitespaceDiffers()\n    {\n        assertThat('Hello PLANET how are we?', not($this->_matcher));\n        assertThat('Hello World how are we', not($this->_matcher));\n    }\n\n    public function testFailsIfWhitespaceIsAddedOrRemovedInMidWord()\n    {\n        assertThat('HelloWorld how are we?', not($this->_matcher));\n        assertThat('Hello Wo rld how are we?', not($this->_matcher));\n    }\n\n    public function testFailsIfMatchingAgainstNull()\n    {\n        assertThat(null, not($this->_matcher));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription(\n            \"equalToIgnoringWhiteSpace(\\\"Hello World   how\\\\n are we? \\\")\",\n            $this->_matcher\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Text/MatchesPatternTest.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\nclass MatchesPatternTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return matchesPattern('/o+b/');\n    }\n\n    public function testEvaluatesToTrueIfArgumentmatchesPattern()\n    {\n        assertThat('foobar', matchesPattern('/o+b/'));\n        assertThat('foobar', matchesPattern('/^foo/'));\n        assertThat('foobar', matchesPattern('/ba*r$/'));\n        assertThat('foobar', matchesPattern('/^foobar$/'));\n    }\n\n    public function testEvaluatesToFalseIfArgumentDoesntMatchRegex()\n    {\n        assertThat('foobar', not(matchesPattern('/^foob$/')));\n        assertThat('foobar', not(matchesPattern('/oobe/')));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('a string matching \"pattern\"', matchesPattern('pattern'));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Text/StringContainsIgnoringCaseTest.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\nclass StringContainsIgnoringCaseTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    const EXCERPT = 'ExcErPt';\n\n    private $_stringContains;\n\n    /**\n     * @before\n     */\n    protected function setUpTest()\n    {\n        parent::setUpTest();\n\n        $this->_stringContains = \\Hamcrest\\Text\\StringContainsIgnoringCase::containsStringIgnoringCase(\n            strtolower(self::EXCERPT)\n        );\n    }\n\n    protected function createMatcher()\n    {\n        return $this->_stringContains;\n    }\n\n    public function testEvaluatesToTrueIfArgumentContainsSpecifiedSubstring()\n    {\n        $this->assertTrue(\n            $this->_stringContains->matches(self::EXCERPT . 'END'),\n            'should be true if excerpt at beginning'\n        );\n        $this->assertTrue(\n            $this->_stringContains->matches('START' . self::EXCERPT),\n            'should be true if excerpt at end'\n        );\n        $this->assertTrue(\n            $this->_stringContains->matches('START' . self::EXCERPT . 'END'),\n            'should be true if excerpt in middle'\n        );\n        $this->assertTrue(\n            $this->_stringContains->matches(self::EXCERPT . self::EXCERPT),\n            'should be true if excerpt is repeated'\n        );\n\n        $this->assertFalse(\n            $this->_stringContains->matches('Something else'),\n            'should not be true if excerpt is not in string'\n        );\n        $this->assertFalse(\n            $this->_stringContains->matches(substr(self::EXCERPT, 1)),\n            'should not be true if part of excerpt is in string'\n        );\n    }\n\n    public function testEvaluatesToTrueIfArgumentIsEqualToSubstring()\n    {\n        $this->assertTrue(\n            $this->_stringContains->matches(self::EXCERPT),\n            'should be true if excerpt is entire string'\n        );\n    }\n\n    public function testEvaluatesToTrueIfArgumentContainsExactSubstring()\n    {\n        $this->assertTrue(\n            $this->_stringContains->matches(strtolower(self::EXCERPT)),\n            'should be false if excerpt is entire string ignoring case'\n        );\n        $this->assertTrue(\n            $this->_stringContains->matches('START' . strtolower(self::EXCERPT) . 'END'),\n            'should be false if excerpt is contained in string ignoring case'\n        );\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription(\n            'a string containing in any case \"'\n            . strtolower(self::EXCERPT) . '\"',\n            $this->_stringContains\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Text/StringContainsInOrderTest.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\nclass StringContainsInOrderTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    private $_m;\n\n    /**\n     * @before\n     */\n    protected function setUpTest()\n    {\n        parent::setUpTest();\n\n        $this->_m = \\Hamcrest\\Text\\StringContainsInOrder::stringContainsInOrder(array('a', 'b', 'c'));\n    }\n\n    protected function createMatcher()\n    {\n        return $this->_m;\n    }\n\n    public function testMatchesOnlyIfStringContainsGivenSubstringsInTheSameOrder()\n    {\n        $this->assertMatches($this->_m, 'abc', 'substrings in order');\n        $this->assertMatches($this->_m, '1a2b3c4', 'substrings separated');\n\n        $this->assertDoesNotMatch($this->_m, 'cab', 'substrings out of order');\n        $this->assertDoesNotMatch($this->_m, 'xyz', 'no substrings in string');\n        $this->assertDoesNotMatch($this->_m, 'ac', 'substring missing');\n        $this->assertDoesNotMatch($this->_m, '', 'empty string');\n    }\n\n    public function testAcceptsVariableArguments()\n    {\n        $this->assertMatches(stringContainsInOrder('a', 'b', 'c'), 'abc', 'substrings as variable arguments');\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription(\n            'a string containing \"a\", \"b\", \"c\" in order',\n            $this->_m\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Text/StringContainsTest.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\nclass StringContainsTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    const EXCERPT = 'EXCERPT';\n\n    private $_stringContains;\n\n    /**\n     * @before\n     */\n    protected function setUpTest()\n    {\n        parent::setUpTest();\n\n        $this->_stringContains = \\Hamcrest\\Text\\StringContains::containsString(self::EXCERPT);\n    }\n\n    protected function createMatcher()\n    {\n        return $this->_stringContains;\n    }\n\n    public function testEvaluatesToTrueIfArgumentContainsSubstring()\n    {\n        $this->assertTrue(\n            $this->_stringContains->matches(self::EXCERPT . 'END'),\n            'should be true if excerpt at beginning'\n        );\n        $this->assertTrue(\n            $this->_stringContains->matches('START' . self::EXCERPT),\n            'should be true if excerpt at end'\n        );\n        $this->assertTrue(\n            $this->_stringContains->matches('START' . self::EXCERPT . 'END'),\n            'should be true if excerpt in middle'\n        );\n        $this->assertTrue(\n            $this->_stringContains->matches(self::EXCERPT . self::EXCERPT),\n            'should be true if excerpt is repeated'\n        );\n\n        $this->assertFalse(\n            $this->_stringContains->matches('Something else'),\n            'should not be true if excerpt is not in string'\n        );\n        $this->assertFalse(\n            $this->_stringContains->matches(substr(self::EXCERPT, 1)),\n            'should not be true if part of excerpt is in string'\n        );\n    }\n\n    public function testEvaluatesToTrueIfArgumentIsEqualToSubstring()\n    {\n        $this->assertTrue(\n            $this->_stringContains->matches(self::EXCERPT),\n            'should be true if excerpt is entire string'\n        );\n    }\n\n    public function testEvaluatesToFalseIfArgumentContainsSubstringIgnoringCase()\n    {\n        $this->assertFalse(\n            $this->_stringContains->matches(strtolower(self::EXCERPT)),\n            'should be false if excerpt is entire string ignoring case'\n        );\n        $this->assertFalse(\n            $this->_stringContains->matches('START' . strtolower(self::EXCERPT) . 'END'),\n            'should be false if excerpt is contained in string ignoring case'\n        );\n    }\n\n    public function testIgnoringCaseReturnsCorrectMatcher()\n    {\n        $this->assertTrue(\n            $this->_stringContains->ignoringCase()->matches('EXceRpT'),\n            'should be true if excerpt is entire string ignoring case'\n        );\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription(\n            'a string containing \"'\n            . self::EXCERPT . '\"',\n            $this->_stringContains\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Text/StringEndsWithTest.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\nclass StringEndsWithTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    const EXCERPT = 'EXCERPT';\n\n    private $_stringEndsWith;\n\n    /**\n     * @before\n     */\n    protected function setUpTest()\n    {\n        parent::setUpTest();\n\n        $this->_stringEndsWith = \\Hamcrest\\Text\\StringEndsWith::endsWith(self::EXCERPT);\n    }\n\n    protected function createMatcher()\n    {\n        return $this->_stringEndsWith;\n    }\n\n    public function testEvaluatesToTrueIfArgumentContainsSpecifiedSubstring()\n    {\n        $this->assertFalse(\n            $this->_stringEndsWith->matches(self::EXCERPT . 'END'),\n            'should be false if excerpt at beginning'\n        );\n        $this->assertTrue(\n            $this->_stringEndsWith->matches('START' . self::EXCERPT),\n            'should be true if excerpt at end'\n        );\n        $this->assertFalse(\n            $this->_stringEndsWith->matches('START' . self::EXCERPT . 'END'),\n            'should be false if excerpt in middle'\n        );\n        $this->assertTrue(\n            $this->_stringEndsWith->matches(self::EXCERPT . self::EXCERPT),\n            'should be true if excerpt is at end and repeated'\n        );\n\n        $this->assertFalse(\n            $this->_stringEndsWith->matches('Something else'),\n            'should be false if excerpt is not in string'\n        );\n        $this->assertFalse(\n            $this->_stringEndsWith->matches(substr(self::EXCERPT, 0, strlen(self::EXCERPT) - 2)),\n            'should be false if part of excerpt is at end of string'\n        );\n    }\n\n    public function testEvaluatesToTrueIfArgumentIsEqualToSubstring()\n    {\n        $this->assertTrue(\n            $this->_stringEndsWith->matches(self::EXCERPT),\n            'should be true if excerpt is entire string'\n        );\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('a string ending with \"EXCERPT\"', $this->_stringEndsWith);\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Text/StringStartsWithTest.php",
    "content": "<?php\nnamespace Hamcrest\\Text;\n\nclass StringStartsWithTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    const EXCERPT = 'EXCERPT';\n\n    private $_stringStartsWith;\n\n    /**\n     * @before\n     */\n    protected function setUpTest()\n    {\n        parent::setUpTest();\n\n        $this->_stringStartsWith = \\Hamcrest\\Text\\StringStartsWith::startsWith(self::EXCERPT);\n    }\n\n    protected function createMatcher()\n    {\n        return $this->_stringStartsWith;\n    }\n\n    public function testEvaluatesToTrueIfArgumentContainsSpecifiedSubstring()\n    {\n        $this->assertTrue(\n            $this->_stringStartsWith->matches(self::EXCERPT . 'END'),\n            'should be true if excerpt at beginning'\n        );\n        $this->assertFalse(\n            $this->_stringStartsWith->matches('START' . self::EXCERPT),\n            'should be false if excerpt at end'\n        );\n        $this->assertFalse(\n            $this->_stringStartsWith->matches('START' . self::EXCERPT . 'END'),\n            'should be false if excerpt in middle'\n        );\n        $this->assertTrue(\n            $this->_stringStartsWith->matches(self::EXCERPT . self::EXCERPT),\n            'should be true if excerpt is at beginning and repeated'\n        );\n\n        $this->assertFalse(\n            $this->_stringStartsWith->matches('Something else'),\n            'should be false if excerpt is not in string'\n        );\n        $this->assertFalse(\n            $this->_stringStartsWith->matches(substr(self::EXCERPT, 1)),\n            'should be false if part of excerpt is at start of string'\n        );\n    }\n\n    public function testEvaluatesToTrueIfArgumentIsEqualToSubstring()\n    {\n        $this->assertTrue(\n            $this->_stringStartsWith->matches(self::EXCERPT),\n            'should be true if excerpt is entire string'\n        );\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('a string starting with \"EXCERPT\"', $this->_stringStartsWith);\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Type/IsArrayTest.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\nclass IsArrayTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Type\\IsArray::arrayValue();\n    }\n\n    public function testEvaluatesToTrueIfArgumentMatchesType()\n    {\n        assertThat(array('5', 5), arrayValue());\n        assertThat(array(), arrayValue());\n    }\n\n    public function testEvaluatesToFalseIfArgumentDoesntMatchType()\n    {\n        assertThat(false, not(arrayValue()));\n        assertThat(5, not(arrayValue()));\n        assertThat('foo', not(arrayValue()));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('an array', arrayValue());\n    }\n\n    public function testDecribesActualTypeInMismatchMessage()\n    {\n        $this->assertMismatchDescription('was null', arrayValue(), null);\n        $this->assertMismatchDescription('was a string \"foo\"', arrayValue(), 'foo');\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Type/IsBooleanTest.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\nclass IsBooleanTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Type\\IsBoolean::booleanValue();\n    }\n\n    public function testEvaluatesToTrueIfArgumentMatchesType()\n    {\n        assertThat(false, booleanValue());\n        assertThat(true, booleanValue());\n    }\n\n    public function testEvaluatesToFalseIfArgumentDoesntMatchType()\n    {\n        assertThat(array(), not(booleanValue()));\n        assertThat(5, not(booleanValue()));\n        assertThat('foo', not(booleanValue()));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('a boolean', booleanValue());\n    }\n\n    public function testDecribesActualTypeInMismatchMessage()\n    {\n        $this->assertMismatchDescription('was null', booleanValue(), null);\n        $this->assertMismatchDescription('was a string \"foo\"', booleanValue(), 'foo');\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Type/IsCallableTest.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\nclass IsCallableTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    public static function callableFunction()\n    {\n    }\n\n    public function __invoke()\n    {\n    }\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Type\\IsCallable::callableValue();\n    }\n\n    public function testEvaluatesToTrueIfArgumentIsFunctionName()\n    {\n        assertThat('preg_match', callableValue());\n    }\n\n    public function testEvaluatesToTrueIfArgumentIsStaticMethodCallback()\n    {\n        assertThat(\n            array('Hamcrest\\Type\\IsCallableTest', 'callableFunction'),\n            callableValue()\n        );\n    }\n\n    public function testEvaluatesToTrueIfArgumentIsInstanceMethodCallback()\n    {\n        assertThat(\n            array($this, 'testEvaluatesToTrueIfArgumentIsInstanceMethodCallback'),\n            callableValue()\n        );\n    }\n\n    public function testEvaluatesToTrueIfArgumentIsClosure()\n    {\n        if (!version_compare(PHP_VERSION, '5.3', '>=')) {\n            $this->markTestSkipped('Closures require php 5.3');\n        }\n        eval('assertThat(function () {}, callableValue());');\n    }\n\n    public function testEvaluatesToTrueIfArgumentImplementsInvoke()\n    {\n        if (!version_compare(PHP_VERSION, '5.3', '>=')) {\n            $this->markTestSkipped('Magic method __invoke() requires php 5.3');\n        }\n        assertThat($this, callableValue());\n    }\n\n    public function testEvaluatesToFalseIfArgumentIsInvalidFunctionName()\n    {\n        if (function_exists('not_a_Hamcrest_function')) {\n            $this->markTestSkipped('Function \"not_a_Hamcrest_function\" must not exist');\n        }\n\n        assertThat('not_a_Hamcrest_function', not(callableValue()));\n    }\n\n    public function testEvaluatesToFalseIfArgumentIsInvalidStaticMethodCallback()\n    {\n        assertThat(\n            array('Hamcrest\\Type\\IsCallableTest', 'noMethod'),\n            not(callableValue())\n        );\n    }\n\n    public function testEvaluatesToFalseIfArgumentIsInvalidInstanceMethodCallback()\n    {\n        assertThat(array($this, 'noMethod'), not(callableValue()));\n    }\n\n    public function testEvaluatesToFalseIfArgumentDoesntImplementInvoke()\n    {\n        assertThat(new \\stdClass(), not(callableValue()));\n    }\n\n    public function testEvaluatesToFalseIfArgumentDoesntMatchType()\n    {\n        assertThat(false, not(callableValue()));\n        assertThat(5.2, not(callableValue()));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('a callable', callableValue());\n    }\n\n    public function testDecribesActualTypeInMismatchMessage()\n    {\n        $this->assertMismatchDescription(\n            'was a string \"invalid-function\"',\n            callableValue(),\n            'invalid-function'\n        );\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Type/IsDoubleTest.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\nclass IsDoubleTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Type\\IsDouble::doubleValue();\n    }\n\n    public function testEvaluatesToTrueIfArgumentMatchesType()\n    {\n        assertThat((float) 5.2, floatValue());\n        assertThat((double) 5.3, doubleValue());\n    }\n\n    public function testEvaluatesToFalseIfArgumentDoesntMatchType()\n    {\n        assertThat(false, not(doubleValue()));\n        assertThat(5, not(doubleValue()));\n        assertThat('foo', not(doubleValue()));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('a double', doubleValue());\n    }\n\n    public function testDecribesActualTypeInMismatchMessage()\n    {\n        $this->assertMismatchDescription('was null', doubleValue(), null);\n        $this->assertMismatchDescription('was a string \"foo\"', doubleValue(), 'foo');\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Type/IsIntegerTest.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\nclass IsIntegerTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Type\\IsInteger::integerValue();\n    }\n\n    public function testEvaluatesToTrueIfArgumentMatchesType()\n    {\n        assertThat(5, integerValue());\n        assertThat(0, integerValue());\n        assertThat(-5, integerValue());\n    }\n\n    public function testEvaluatesToFalseIfArgumentDoesntMatchType()\n    {\n        assertThat(false, not(integerValue()));\n        assertThat(5.2, not(integerValue()));\n        assertThat('foo', not(integerValue()));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('an integer', integerValue());\n    }\n\n    public function testDecribesActualTypeInMismatchMessage()\n    {\n        $this->assertMismatchDescription('was null', integerValue(), null);\n        $this->assertMismatchDescription('was a string \"foo\"', integerValue(), 'foo');\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Type/IsNumericTest.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\nclass IsNumericTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Type\\IsNumeric::numericValue();\n    }\n\n    public function testEvaluatesToTrueIfArgumentMatchesType()\n    {\n        assertThat(5, numericValue());\n        assertThat(0, numericValue());\n        assertThat(-5, numericValue());\n        assertThat(5.3, numericValue());\n        assertThat(0.53, numericValue());\n        assertThat(-5.3, numericValue());\n        assertThat('5', numericValue());\n        assertThat('0', numericValue());\n        assertThat('-5', numericValue());\n        assertThat('5.3', numericValue());\n        assertThat('5e+3', numericValue());\n        assertThat('0.053e-2', numericValue());\n        assertThat('-53.253e+25', numericValue());\n        assertThat('+53.253e+25', numericValue());\n        assertThat(0x4F2a04, numericValue());\n        assertThat('0x4F2a04', numericValue());\n    }\n\n    public function testEvaluatesToFalseIfArgumentDoesntMatchType()\n    {\n        assertThat(false, not(numericValue()));\n        assertThat('foo', not(numericValue()));\n        assertThat('foo5', not(numericValue()));\n        assertThat('5foo', not(numericValue()));\n        assertThat('0x42A04G', not(numericValue())); // G is not in the hexadecimal range.\n        assertThat('1x42A04', not(numericValue())); // 1x is not a valid hexadecimal sequence.\n        assertThat('0x', not(numericValue()));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('a number', numericValue());\n    }\n\n    public function testDecribesActualTypeInMismatchMessage()\n    {\n        $this->assertMismatchDescription('was null', numericValue(), null);\n        $this->assertMismatchDescription('was a string \"foo\"', numericValue(), 'foo');\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Type/IsObjectTest.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\nclass IsObjectTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Type\\IsObject::objectValue();\n    }\n\n    public function testEvaluatesToTrueIfArgumentMatchesType()\n    {\n        assertThat(new \\stdClass, objectValue());\n    }\n\n    public function testEvaluatesToFalseIfArgumentDoesntMatchType()\n    {\n        assertThat(false, not(objectValue()));\n        assertThat(5, not(objectValue()));\n        assertThat('foo', not(objectValue()));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('an object', objectValue());\n    }\n\n    public function testDecribesActualTypeInMismatchMessage()\n    {\n        $this->assertMismatchDescription('was null', objectValue(), null);\n        $this->assertMismatchDescription('was a string \"foo\"', objectValue(), 'foo');\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Type/IsResourceTest.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\nclass IsResourceTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Type\\IsResource::resourceValue();\n    }\n\n    public function testEvaluatesToTrueIfArgumentMatchesType()\n    {\n        assertThat(tmpfile(), resourceValue());\n    }\n\n    public function testEvaluatesToFalseIfArgumentDoesntMatchType()\n    {\n        assertThat(false, not(resourceValue()));\n        assertThat(5, not(resourceValue()));\n        assertThat('foo', not(resourceValue()));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('a resource', resourceValue());\n    }\n\n    public function testDecribesActualTypeInMismatchMessage()\n    {\n        $this->assertMismatchDescription('was null', resourceValue(), null);\n        $this->assertMismatchDescription('was a string \"foo\"', resourceValue(), 'foo');\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Type/IsScalarTest.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\nclass IsScalarTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Type\\IsScalar::scalarValue();\n    }\n\n    public function testEvaluatesToTrueIfArgumentMatchesType()\n    {\n        assertThat(true, scalarValue());\n        assertThat(5, scalarValue());\n        assertThat(5.3, scalarValue());\n        assertThat('5', scalarValue());\n    }\n\n    public function testEvaluatesToFalseIfArgumentDoesntMatchType()\n    {\n        assertThat(null, not(scalarValue()));\n        assertThat(array(), not(scalarValue()));\n        assertThat(array(5), not(scalarValue()));\n        assertThat(tmpfile(), not(scalarValue()));\n        assertThat(new \\stdClass(), not(scalarValue()));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('a scalar', scalarValue());\n    }\n\n    public function testDecribesActualTypeInMismatchMessage()\n    {\n        $this->assertMismatchDescription('was null', scalarValue(), null);\n        $this->assertMismatchDescription('was an array [\"foo\"]', scalarValue(), array('foo'));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Type/IsStringTest.php",
    "content": "<?php\nnamespace Hamcrest\\Type;\n\nclass IsStringTest extends \\Hamcrest\\AbstractMatcherTest\n{\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Type\\IsString::stringValue();\n    }\n\n    public function testEvaluatesToTrueIfArgumentMatchesType()\n    {\n        assertThat('', stringValue());\n        assertThat(\"foo\", stringValue());\n    }\n\n    public function testEvaluatesToFalseIfArgumentDoesntMatchType()\n    {\n        assertThat(false, not(stringValue()));\n        assertThat(5, not(stringValue()));\n        assertThat(array(1, 2, 3), not(stringValue()));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription('a string', stringValue());\n    }\n\n    public function testDecribesActualTypeInMismatchMessage()\n    {\n        $this->assertMismatchDescription('was null', stringValue(), null);\n        $this->assertMismatchDescription('was a double <5.2F>', stringValue(), 5.2);\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/UtilTest.php",
    "content": "<?php\nnamespace Hamcrest;\n\nuse PHPUnit\\Framework\\TestCase;\n\nclass UtilTest extends TestCase\n{\n\n    public function testWrapValueWithIsEqualLeavesMatchersUntouched()\n    {\n        $matcher = new \\Hamcrest\\Text\\MatchesPattern('/fo+/');\n        $newMatcher = \\Hamcrest\\Util::wrapValueWithIsEqual($matcher);\n        $this->assertSame($matcher, $newMatcher);\n    }\n\n    public function testWrapValueWithIsEqualWrapsPrimitive()\n    {\n        $matcher = \\Hamcrest\\Util::wrapValueWithIsEqual('foo');\n        $this->assertInstanceOf('Hamcrest\\Core\\IsEqual', $matcher);\n        $this->assertTrue($matcher->matches('foo'));\n    }\n\n    /**\n     * @doesNotPerformAssertions\n     */\n    public function testCheckAllAreMatchersAcceptsMatchers()\n    {\n        \\Hamcrest\\Util::checkAllAreMatchers(array(\n            new \\Hamcrest\\Text\\MatchesPattern('/fo+/'),\n            new \\Hamcrest\\Core\\IsEqual('foo'),\n        ));\n    }\n\n    public function testCheckAllAreMatchersFailsForPrimitive()\n    {\n        $exceptionThrown = false;\n        try {\n            \\Hamcrest\\Util::checkAllAreMatchers(array(\n                new \\Hamcrest\\Text\\MatchesPattern('/fo+/'),\n                'foo',\n            ));\n        } catch (\\InvalidArgumentException $exception) {\n            $exceptionThrown = true;\n        }\n\n        $this->assertTrue(\n            $exceptionThrown,\n            'Failed asserting that exception of type \"InvalidArgumentException\" is thrown.'\n        );\n    }\n\n    private function callAndAssertCreateMatcherArray($items)\n    {\n        $matchers = \\Hamcrest\\Util::createMatcherArray($items);\n        $this->assertTrue(is_array($matchers), sprintf('Type \"array\" expected, but got \"%s\" instead', gettype($matchers)));\n        $this->assertSameSize($items, $matchers);\n        foreach ($matchers as $matcher) {\n            $this->assertInstanceOf('\\Hamcrest\\Matcher', $matcher);\n        }\n\n        return $matchers;\n    }\n\n    public function testCreateMatcherArrayLeavesMatchersUntouched()\n    {\n        $matcher = new \\Hamcrest\\Text\\MatchesPattern('/fo+/');\n        $items = array($matcher);\n        $matchers = $this->callAndAssertCreateMatcherArray($items);\n        $this->assertSame($matcher, $matchers[0]);\n    }\n\n    public function testCreateMatcherArrayWrapsPrimitiveWithIsEqualMatcher()\n    {\n        $matchers = $this->callAndAssertCreateMatcherArray(array('foo'));\n        $this->assertInstanceOf('Hamcrest\\Core\\IsEqual', $matchers[0]);\n        $this->assertTrue($matchers[0]->matches('foo'));\n    }\n\n    public function testCreateMatcherArrayDoesntModifyOriginalArray()\n    {\n        $items = array('foo');\n        $this->callAndAssertCreateMatcherArray($items);\n        $this->assertSame('foo', $items[0]);\n    }\n\n    public function testCreateMatcherArrayUnwrapsSingleArrayElement()\n    {\n        $matchers = $this->callAndAssertCreateMatcherArray(array(array('foo')));\n        $this->assertInstanceOf('Hamcrest\\Core\\IsEqual', $matchers[0]);\n        $this->assertTrue($matchers[0]->matches('foo'));\n    }\n}\n"
  },
  {
    "path": "tests/Hamcrest/Xml/HasXPathTest.php",
    "content": "<?php\nnamespace Hamcrest\\Xml;\n\nclass HasXPathTest extends \\Hamcrest\\AbstractMatcherTest\n{\n    protected static $xml;\n    protected static $doc;\n    protected static $html;\n\n    /**\n     * @beforeClass\n     */\n    public static function setUpBeforeClassTest()\n    {\n        self::$xml = <<<XML\n<?xml version=\"1.0\"?>\n<users>\n    <user>\n        <id>alice</id>\n        <name>Alice Frankel</name>\n        <role>admin</role>\n    </user>\n    <user>\n        <id>bob</id>\n        <name>Bob Frankel</name>\n        <role>user</role>\n    </user>\n    <user>\n        <id>charlie</id>\n        <name>Charlie Chan</name>\n        <role>user</role>\n    </user>\n</users>\nXML;\n        self::$doc = new \\DOMDocument();\n        self::$doc->loadXML(self::$xml);\n\n        self::$html = <<<HTML\n<html>\n    <head>\n        <title>Home Page</title>\n    </head>\n    <body>\n        <h1>Heading</h1>\n        <p>Some text</p>\n    </body>\n</html>\nHTML;\n    }\n\n    protected function createMatcher()\n    {\n        return \\Hamcrest\\Xml\\HasXPath::hasXPath('/users/user');\n    }\n\n    public function testMatchesWhenXPathIsFound()\n    {\n        assertThat('one match', self::$doc, hasXPath('user[id = \"bob\"]'));\n        assertThat('two matches', self::$doc, hasXPath('user[role = \"user\"]'));\n    }\n\n    public function testDoesNotMatchWhenXPathIsNotFound()\n    {\n        assertThat(\n            'no match',\n            self::$doc,\n            not(hasXPath('user[contains(id, \"frank\")]'))\n        );\n    }\n\n    public function testMatchesWhenExpressionWithoutMatcherEvaluatesToTrue()\n    {\n        assertThat(\n            'one match',\n            self::$doc,\n            hasXPath('count(user[id = \"bob\"])')\n        );\n    }\n\n    public function testDoesNotMatchWhenExpressionWithoutMatcherEvaluatesToFalse()\n    {\n        assertThat(\n            'no matches',\n            self::$doc,\n            not(hasXPath('count(user[id = \"frank\"])'))\n        );\n    }\n\n    public function testMatchesWhenExpressionIsEqual()\n    {\n        assertThat(\n            'one match',\n            self::$doc,\n            hasXPath('count(user[id = \"bob\"])', 1)\n        );\n        assertThat(\n            'two matches',\n            self::$doc,\n            hasXPath('count(user[role = \"user\"])', 2)\n        );\n    }\n\n    public function testDoesNotMatchWhenExpressionIsNotEqual()\n    {\n        assertThat(\n            'no match',\n            self::$doc,\n            not(hasXPath('count(user[id = \"frank\"])', 2))\n        );\n        assertThat(\n            'one match',\n            self::$doc,\n            not(hasXPath('count(user[role = \"admin\"])', 2))\n        );\n    }\n\n    public function testMatchesWhenContentMatches()\n    {\n        assertThat(\n            'one match',\n            self::$doc,\n            hasXPath('user/name', containsString('ice'))\n        );\n        assertThat(\n            'two matches',\n            self::$doc,\n            hasXPath('user/role', equalTo('user'))\n        );\n    }\n\n    public function testDoesNotMatchWhenContentDoesNotMatch()\n    {\n        assertThat(\n            'no match',\n            self::$doc,\n            not(hasXPath('user/name', containsString('Bobby')))\n        );\n        assertThat(\n            'no matches',\n            self::$doc,\n            not(hasXPath('user/role', equalTo('owner')))\n        );\n    }\n\n    public function testProvidesConvenientShortcutForHasXPathEqualTo()\n    {\n        assertThat('matches', self::$doc, hasXPath('count(user)', 3));\n        assertThat('matches', self::$doc, hasXPath('user[2]/id', 'bob'));\n    }\n\n    public function testProvidesConvenientShortcutForHasXPathCountEqualTo()\n    {\n        assertThat('matches', self::$doc, hasXPath('user[id = \"charlie\"]', 1));\n    }\n\n    public function testMatchesAcceptsXmlString()\n    {\n        assertThat('accepts XML string', self::$xml, hasXPath('user'));\n    }\n\n    public function testMatchesAcceptsHtmlString()\n    {\n        assertThat('accepts HTML string', self::$html, hasXPath('body/h1', 'Heading'));\n    }\n\n    public function testHasAReadableDescription()\n    {\n        $this->assertDescription(\n            'XML or HTML document with XPath \"/users/user\"',\n            hasXPath('/users/user')\n        );\n        $this->assertDescription(\n            'XML or HTML document with XPath \"count(/users/user)\" <2>',\n            hasXPath('/users/user', 2)\n        );\n        $this->assertDescription(\n            'XML or HTML document with XPath \"/users/user/name\"'\n            . ' a string starting with \"Alice\"',\n            hasXPath('/users/user/name', startsWith('Alice'))\n        );\n    }\n\n    public function testHasAReadableMismatchDescription()\n    {\n        $this->assertMismatchDescription(\n            'XPath returned no results',\n            hasXPath('/users/name'),\n            self::$doc\n        );\n        $this->assertMismatchDescription(\n            'XPath expression result was <3F>',\n            hasXPath('/users/user', 2),\n            self::$doc\n        );\n        $this->assertMismatchDescription(\n            'XPath returned [\"alice\", \"bob\", \"charlie\"]',\n            hasXPath('/users/user/id', 'Frank'),\n            self::$doc\n        );\n    }\n}\n"
  },
  {
    "path": "tests/bootstrap.php",
    "content": "<?php\n\nerror_reporting(E_ALL | E_STRICT);\n\nrequire __DIR__ . '/../vendor/autoload.php';\n\nif (defined('E_DEPRECATED')) {\n    error_reporting(error_reporting() | E_DEPRECATED);\n}\n\nHamcrest\\Util::registerGlobalFunctions();\n"
  },
  {
    "path": "tests/phpstan-baseline.neon",
    "content": "parameters:\n\tignoreErrors:\n\t\t-\n\t\t\tmessage: '#^Cannot call method matches\\(\\) on Hamcrest\\\\Matcher\\|null\\.$#'\n\t\t\tidentifier: method.nonObject\n\t\t\tcount: 1\n\t\t\tpath: ../hamcrest/Hamcrest/Arrays/SeriesMatchingOnce.php\n\n\t\t-\n\t\t\tmessage: '#^Parameter \\#1 \\$matcher of method Hamcrest\\\\Arrays\\\\SeriesMatchingOnce\\:\\:_describeMismatch\\(\\) expects Hamcrest\\\\Matcher, Hamcrest\\\\Matcher\\|null given\\.$#'\n\t\t\tidentifier: argument.type\n\t\t\tcount: 1\n\t\t\tpath: ../hamcrest/Hamcrest/Arrays/SeriesMatchingOnce.php\n\n\t\t-\n\t\t\tmessage: '#^Cannot call method toString\\(\\) on class\\-string\\|object\\.$#'\n\t\t\tidentifier: method.nonObject\n\t\t\tcount: 1\n\t\t\tpath: ../hamcrest/Hamcrest/Core/HasToString.php\n\n\t\t-\n\t\t\tmessage: '#^Argument of an invalid type list\\<string\\>\\|false supplied for foreach, only iterables are supported\\.$#'\n\t\t\tidentifier: foreach.nonIterable\n\t\t\tcount: 1\n\t\t\tpath: ../hamcrest/Hamcrest/Text/IsEqualIgnoringWhiteSpace.php\n\n\t\t-\n\t\t\tmessage: '#^Cannot access offset int\\<0, max\\> on non\\-empty\\-array\\<int\\<0, max\\>, string\\>\\|false\\.$#'\n\t\t\tidentifier: offsetAccess.nonOffsetAccessible\n\t\t\tcount: 1\n\t\t\tpath: ../hamcrest/Hamcrest/Text/IsEqualIgnoringWhiteSpace.php\n\n\t\t-\n\t\t\tmessage: '#^Method Hamcrest\\\\Xml\\\\HasXPath\\:\\:matchesContent\\(\\) has parameter \\$nodes with generic class DOMNodeList but does not specify its types\\: TNode$#'\n\t\t\tidentifier: missingType.generics\n\t\t\tcount: 1\n\t\t\tpath: ../hamcrest/Hamcrest/Xml/HasXPath.php\n\n\t\t-\n\t\t\tmessage: '#^Parameter \\#1 \\$document of class DOMXPath constructor expects DOMDocument, DOMDocument\\|null given\\.$#'\n\t\t\tidentifier: argument.type\n\t\t\tcount: 1\n\t\t\tpath: ../hamcrest/Hamcrest/Xml/HasXPath.php\n"
  },
  {
    "path": "tests/phpunit.xml.dist",
    "content": "<phpunit backupGlobals=\"false\"\n         backupStaticAttributes=\"false\"\n         bootstrap=\"bootstrap.php\"\n         colors=\"false\"\n         convertErrorsToExceptions=\"true\"\n         convertNoticesToExceptions=\"true\"\n         convertWarningsToExceptions=\"true\"\n         processIsolation=\"false\"\n         stopOnFailure=\"false\">\n  <testsuites>\n    <testsuite name=\"hamcrest-php\">\n      <directory suffix=\"Test.php\">.</directory>\n    </testsuite>\n  </testsuites>\n\n  <filter>\n    <whitelist addUncoveredFilesFromWhitelist=\"true\">\n      <directory suffix=\".php\">../hamcrest</directory>\n    </whitelist>\n  </filter>\n</phpunit>\n"
  }
]