diff -Nru php-phpspec-prophecy-1.8.0/CHANGES.md php-phpspec-prophecy-1.8.1/CHANGES.md --- php-phpspec-prophecy-1.8.0/CHANGES.md 2018-08-05 17:53:17.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/CHANGES.md 2019-06-17 19:05:31.000000000 +0000 @@ -1,3 +1,8 @@ +1.8.1 / 2019/06/13 +================== + +* [fixed] Don't try to patch final constructors (@NiR) + 1.8.0 / 2018/08/05 ================== diff -Nru php-phpspec-prophecy-1.8.0/composer.json php-phpspec-prophecy-1.8.1/composer.json --- php-phpspec-prophecy-1.8.0/composer.json 2018-08-05 17:53:17.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/composer.json 2019-06-17 19:05:31.000000000 +0000 @@ -31,8 +31,8 @@ }, "autoload": { - "psr-0": { - "Prophecy\\": "src/" + "psr-4": { + "Prophecy\\": "src/Prophecy" } }, diff -Nru php-phpspec-prophecy-1.8.0/CONTRIBUTING.md php-phpspec-prophecy-1.8.1/CONTRIBUTING.md --- php-phpspec-prophecy-1.8.0/CONTRIBUTING.md 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/CONTRIBUTING.md 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,22 @@ +Contributing +------------ + +Prophecy 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: + +- Make your feature addition or bug fix, +- Add either specs or examples for any changes you're making (bugfixes or additions) + (please look into `spec/` folder for some examples). This is important so we don't break + it in a future version unintentionally, +- Commit your code, but do not mess with `CHANGES.md`, + +Running tests +------------- + +Make sure that you don't break anything with your changes by running: + +```bash +$> composer install --prefer-dist +$> vendor/bin/phpspec run +$> vendor/bin/phpunit +``` diff -Nru php-phpspec-prophecy-1.8.0/debian/autoload.php.ci.tpl php-phpspec-prophecy-1.8.1/debian/autoload.php.ci.tpl --- php-phpspec-prophecy-1.8.0/debian/autoload.php.ci.tpl 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/debian/autoload.php.ci.tpl 2019-06-17 19:22:46.000000000 +0000 @@ -0,0 +1,22 @@ + Wed, 14 Aug 2019 12:31:54 -1000 + +php-phpspec-prophecy (1.8.1-1) experimental; urgency=medium + + * Upload to experimental during the freeze + + [ Ciaran McNulty ] + * 1.8.1 changelog + + [ David Prévot ] + * Use https in Format + * Drop get-orig-source target + * Use debhelper-compat 12 + * Update Standards-Version to 4.3.0 + * Document gbp import-ref usage + * Restore testsuite + + -- David Prévot Mon, 17 Jun 2019 09:02:15 -1000 + php-phpspec-prophecy (1.8.0-1) unstable; urgency=medium [ Ciaran McNulty ] diff -Nru php-phpspec-prophecy-1.8.0/debian/clean php-phpspec-prophecy-1.8.1/debian/clean --- php-phpspec-prophecy-1.8.0/debian/clean 2016-11-26 00:08:51.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/debian/clean 2019-08-14 22:31:39.000000000 +0000 @@ -1 +1,3 @@ +.phpunit.result.cache src/Prophecy/autoload.php +vendor/ diff -Nru php-phpspec-prophecy-1.8.0/debian/compat php-phpspec-prophecy-1.8.1/debian/compat --- php-phpspec-prophecy-1.8.0/debian/compat 2016-11-26 00:08:51.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -9 diff -Nru php-phpspec-prophecy-1.8.0/debian/control php-phpspec-prophecy-1.8.1/debian/control --- php-phpspec-prophecy-1.8.0/debian/control 2018-08-09 11:37:51.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/debian/control 2019-08-14 22:30:34.000000000 +0000 @@ -4,8 +4,8 @@ Maintainer: Debian PHP PEAR Maintainers Uploaders: David Prévot , Prach Pongpanich -Build-Depends: debhelper (>= 9), phpab, pkg-php-tools (>= 1.29~) -Standards-Version: 4.2.0 +Build-Depends: debhelper-compat (= 12), phpab, phpunit, pkg-php-tools (>= 1.29~) +Standards-Version: 4.4.0 Homepage: https://github.com/phpspec/prophecy Vcs-Git: https://salsa.debian.org/php-team/pear/php-phpspec-prophecy.git Vcs-Browser: https://salsa.debian.org/php-team/pear/php-phpspec-prophecy diff -Nru php-phpspec-prophecy-1.8.0/debian/copyright php-phpspec-prophecy-1.8.1/debian/copyright --- php-phpspec-prophecy-1.8.0/debian/copyright 2017-01-26 04:07:29.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/debian/copyright 2019-08-14 22:30:35.000000000 +0000 @@ -1,4 +1,4 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: Prophecy Upstream-Contact: 2013, Konstantin Kudryashov Source: https://github.com/phpspec/prophecy diff -Nru php-phpspec-prophecy-1.8.0/debian/gbp.conf php-phpspec-prophecy-1.8.1/debian/gbp.conf --- php-phpspec-prophecy-1.8.0/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/debian/gbp.conf 2019-06-17 19:22:46.000000000 +0000 @@ -0,0 +1,8 @@ +[DEFAULT] +pristine-tar = True +pristine-tar-commit = True + +## Once --filter support gets added to gbp import-ref, we should be able +## to simplify the workflow and ignore the upstream branch. +# filter = [ '.gitattributes' ] +# upstream-tag = %(version%~%-)s diff -Nru php-phpspec-prophecy-1.8.0/debian/README.source php-phpspec-prophecy-1.8.1/debian/README.source --- php-phpspec-prophecy-1.8.0/debian/README.source 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/debian/README.source 2019-06-17 19:22:46.000000000 +0000 @@ -0,0 +1,8 @@ +Starting with 1.8.1, we are merging the upstream “signed” tags as +upstream, instead of using the tarball that doesn’t ship tests. + +# Example to import upstream 1.8.2 version +version=1.8.2 +# We still use the upstream branch to drop the .gitattributes file from upstream +gbp import-ref --upstream-tag=%\(version%~%-\)s -u$version --debian-branch=upstream +gbp import-ref --upstream-tree=BRANCH -u$version diff -Nru php-phpspec-prophecy-1.8.0/debian/rules php-phpspec-prophecy-1.8.1/debian/rules --- php-phpspec-prophecy-1.8.0/debian/rules 2017-09-07 04:12:04.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/debian/rules 2019-08-14 22:30:34.000000000 +0000 @@ -7,9 +7,17 @@ phpab --output src/Prophecy/autoload.php \ --template debian/autoload.php.tpl \ src + mkdir --parents vendor + phpab --output vendor/autoload.php \ + --template debian/autoload.php.test.tpl \ + fixtures + +override_dh_auto_test: +ifeq (,$(findstring nocheck, $(DEB_BUILD_OPTIONS))) + phpunit +else + @echo "** tests disabled" +endif override_dh_installchangelogs: dh_installchangelogs CHANGES.md - -get-orig-source: - uscan --force --verbose --rename diff -Nru php-phpspec-prophecy-1.8.0/debian/tests/control php-phpspec-prophecy-1.8.1/debian/tests/control --- php-phpspec-prophecy-1.8.0/debian/tests/control 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/debian/tests/control 2019-06-17 19:22:46.000000000 +0000 @@ -0,0 +1,3 @@ +Test-Command: mkdir --parents vendor && phpab --output vendor/autoload.php --template debian/autoload.php.ci.tpl fixtures && phpunit +Restrictions: rw-build-tree +Depends: @, phpab, phpunit diff -Nru php-phpspec-prophecy-1.8.0/debian/upstream/metadata php-phpspec-prophecy-1.8.1/debian/upstream/metadata --- php-phpspec-prophecy-1.8.0/debian/upstream/metadata 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/debian/upstream/metadata 2019-08-10 00:57:51.000000000 +0000 @@ -0,0 +1,2 @@ +Name: Prophecy +Contact: 2013, Konstantin Kudryashov diff -Nru php-phpspec-prophecy-1.8.0/fixtures/EmptyClass.php php-phpspec-prophecy-1.8.1/fixtures/EmptyClass.php --- php-phpspec-prophecy-1.8.0/fixtures/EmptyClass.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/fixtures/EmptyClass.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,7 @@ + + + + + + + + + + tests + + + + + + ./src/ + + + diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/ArgumentsWildcardSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/ArgumentsWildcardSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/ArgumentsWildcardSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/ArgumentsWildcardSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,128 @@ +beConstructedWith(array(42, 'zet', $object)); + + $class = get_class($object->getWrappedObject()); + $hash = spl_object_hash($object->getWrappedObject()); + + $this->__toString()->shouldReturn("exact(42), exact(\"zet\"), exact($class:$hash Object (\n 'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)\n))"); + } + + function it_generates_string_representation_from_all_tokens_imploded( + TokenInterface $token1, + TokenInterface $token2, + TokenInterface $token3 + ) { + $token1->__toString()->willReturn('token_1'); + $token2->__toString()->willReturn('token_2'); + $token3->__toString()->willReturn('token_3'); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->__toString()->shouldReturn('token_1, token_2, token_3'); + } + + function it_exposes_list_of_tokens(TokenInterface $token) + { + $this->beConstructedWith(array($token)); + + $this->getTokens()->shouldReturn(array($token)); + } + + function it_returns_score_of_1_if_there_are_no_tokens_and_arguments() + { + $this->beConstructedWith(array()); + + $this->scoreArguments(array())->shouldReturn(1); + } + + function it_should_return_match_score_based_on_all_tokens_score( + TokenInterface $token1, + TokenInterface $token2, + TokenInterface $token3 + ) { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + $token2->scoreArgument(2)->willReturn(5); + $token2->isLast()->willReturn(false); + $token3->scoreArgument($obj = new \stdClass())->willReturn(10); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2, $obj))->shouldReturn(18); + } + + function it_returns_false_if_there_is_less_arguments_than_tokens( + TokenInterface $token1, + TokenInterface $token2, + TokenInterface $token3 + ) { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + $token2->scoreArgument(2)->willReturn(5); + $token2->isLast()->willReturn(false); + $token3->scoreArgument(null)->willReturn(false); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2))->shouldReturn(false); + } + + function it_returns_false_if_there_is_less_tokens_than_arguments( + TokenInterface $token1, + TokenInterface $token2, + TokenInterface $token3 + ) { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + $token2->scoreArgument(2)->willReturn(5); + $token2->isLast()->willReturn(false); + $token3->scoreArgument($obj = new \stdClass())->willReturn(10); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2, $obj, 4))->shouldReturn(false); + } + + function it_should_return_false_if_one_of_the_tokens_returns_false( + TokenInterface $token1, + TokenInterface $token2, + TokenInterface $token3 + ) { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + $token2->scoreArgument(2)->willReturn(false); + $token2->isLast()->willReturn(false); + $token3->scoreArgument($obj = new \stdClass())->willReturn(10); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2, $obj))->shouldReturn(false); + } + + function it_should_calculate_score_until_last_token( + TokenInterface $token1, + TokenInterface $token2, + TokenInterface $token3 + ) { + $token1->scoreArgument('one')->willReturn(3); + $token1->isLast()->willReturn(false); + + $token2->scoreArgument(2)->willReturn(7); + $token2->isLast()->willReturn(true); + + $token3->scoreArgument($obj = new \stdClass())->willReturn(10); + $token3->isLast()->willReturn(false); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->scoreArguments(array('one', 2, $obj))->shouldReturn(10); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/AnyValuesTokenSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/AnyValuesTokenSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/AnyValuesTokenSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/AnyValuesTokenSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,28 @@ +shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_last() + { + $this->shouldBeLast(); + } + + function its_string_representation_is_star_with_followup() + { + $this->__toString()->shouldReturn('* [, ...]'); + } + + function it_scores_any_argument_as_2() + { + $this->scoreArgument(42)->shouldReturn(2); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/AnyValueTokenSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/AnyValueTokenSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/AnyValueTokenSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/AnyValueTokenSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,28 @@ +shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function its_string_representation_is_star() + { + $this->__toString()->shouldReturn('*'); + } + + function it_scores_any_argument_as_3() + { + $this->scoreArgument(42)->shouldReturn(3); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/ApproximateValueTokenSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/ApproximateValueTokenSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/ApproximateValueTokenSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/ApproximateValueTokenSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,55 @@ +beConstructedWith(10.12345678, 4); + } + + function it_is_initializable() + { + $this->shouldHaveType('Prophecy\Argument\Token\ApproximateValueToken'); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_10_if_rounded_argument_matches_rounded_value() + { + $this->scoreArgument(10.12345)->shouldReturn(10); + } + + function it_does_not_score_if_rounded_argument_does_not_match_rounded_value() + { + $this->scoreArgument(10.1234)->shouldReturn(false); + } + + function it_uses_a_default_precision_of_zero() + { + $this->beConstructedWith(10.7); + $this->scoreArgument(11.4)->shouldReturn(10); + } + + function it_does_not_score_if_rounded_argument_is_not_numeric() + { + $this->scoreArgument('hello')->shouldReturn(false); + } + + function it_has_simple_string_representation() + { + $this->__toString()->shouldBe('≅10.1235'); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/ArrayCountTokenSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/ArrayCountTokenSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/ArrayCountTokenSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/ArrayCountTokenSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,58 @@ +beConstructedWith(2); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_6_if_argument_array_has_proper_count() + { + $this->scoreArgument(array(1,2))->shouldReturn(6); + } + + function it_scores_6_if_argument_countable_object_has_proper_count(\Countable $countable) + { + $countable->count()->willReturn(2); + $this->scoreArgument($countable)->shouldReturn(6); + } + + function it_does_not_score_if_argument_is_neither_array_nor_countable_object() + { + $this->scoreArgument('string')->shouldBe(false); + $this->scoreArgument(5)->shouldBe(false); + $this->scoreArgument(new \stdClass)->shouldBe(false); + } + + function it_does_not_score_if_argument_array_has_wrong_count() + { + $this->scoreArgument(array(1))->shouldReturn(false); + } + + function it_does_not_score_if_argument_countable_object_has_wrong_count(\Countable $countable) + { + $countable->count()->willReturn(3); + $this->scoreArgument($countable)->shouldReturn(false); + } + + function it_has_simple_string_representation() + { + $this->__toString()->shouldBe('count(2)'); + } + +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/ArrayEntryTokenSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/ArrayEntryTokenSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/ArrayEntryTokenSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/ArrayEntryTokenSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,202 @@ +beConstructedWith($key, $value); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_holds_key_and_value($key, $value) + { + $this->getKey()->shouldBe($key); + $this->getValue()->shouldBe($value); + } + + function its_string_representation_tells_that_its_an_array_containing_the_key_value_pair($key, $value) + { + $key->__toString()->willReturn('key'); + $value->__toString()->willReturn('value'); + $this->__toString()->shouldBe('[..., key => value, ...]'); + } + + function it_wraps_non_token_value_into_ExactValueToken(TokenInterface $key, \stdClass $object) + { + $this->beConstructedWith($key, $object); + $this->getValue()->shouldHaveType('\Prophecy\Argument\Token\ExactValueToken'); + } + + function it_wraps_non_token_key_into_ExactValueToken(\stdClass $object, TokenInterface $value) + { + $this->beConstructedWith($object, $value); + $this->getKey()->shouldHaveType('\Prophecy\Argument\Token\ExactValueToken'); + } + + function it_scores_array_half_of_combined_scores_from_key_and_value_tokens($key, $value) + { + $key->scoreArgument('key')->willReturn(4); + $value->scoreArgument('value')->willReturn(6); + $this->scoreArgument(array('key'=>'value'))->shouldBe(5); + } + + function it_scores_traversable_object_half_of_combined_scores_from_key_and_value_tokens( + TokenInterface $key, + TokenInterface $value, + \Iterator $object + ) { + $object->current()->will(function () use ($object) { + $object->valid()->willReturn(false); + + return 'value'; + }); + $object->key()->willReturn('key'); + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(true); + $key->scoreArgument('key')->willReturn(6); + $value->scoreArgument('value')->willReturn(2); + $this->scoreArgument($object)->shouldBe(4); + } + + function it_throws_exception_during_scoring_of_array_accessible_object_if_key_is_not_ExactValueToken( + TokenInterface $key, + TokenInterface $value, + \ArrayAccess $object + ) { + $key->__toString()->willReturn('any_token'); + $this->beConstructedWith($key,$value); + $errorMessage = 'You can only use exact value tokens to match key of ArrayAccess object'.PHP_EOL. + 'But you used `any_token`.'; + $this->shouldThrow(new InvalidArgumentException($errorMessage))->duringScoreArgument($object); + } + + function it_scores_array_accessible_object_half_of_combined_scores_from_key_and_value_tokens( + ExactValueToken $key, + TokenInterface $value, + \ArrayAccess $object + ) { + $object->offsetExists('key')->willReturn(true); + $object->offsetGet('key')->willReturn('value'); + $key->getValue()->willReturn('key'); + $key->scoreArgument('key')->willReturn(3); + $value->scoreArgument('value')->willReturn(1); + $this->scoreArgument($object)->shouldBe(2); + } + + function it_accepts_any_key_token_type_to_score_object_that_is_both_traversable_and_array_accessible( + TokenInterface $key, + TokenInterface $value, + \ArrayIterator $object + ) { + $this->beConstructedWith($key, $value); + $object->current()->will(function () use ($object) { + $object->valid()->willReturn(false); + + return 'value'; + }); + $object->key()->willReturn('key'); + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(true); + $this->shouldNotThrow(new InvalidArgumentException)->duringScoreArgument($object); + } + + function it_does_not_score_if_argument_is_neither_array_nor_traversable_nor_array_accessible() + { + $this->scoreArgument('string')->shouldBe(false); + $this->scoreArgument(new \stdClass)->shouldBe(false); + } + + function it_does_not_score_empty_array() + { + $this->scoreArgument(array())->shouldBe(false); + } + + function it_does_not_score_array_if_key_and_value_tokens_do_not_score_same_entry($key, $value) + { + $argument = array(1 => 'foo', 2 => 'bar'); + $key->scoreArgument(1)->willReturn(true); + $key->scoreArgument(2)->willReturn(false); + $value->scoreArgument('foo')->willReturn(false); + $value->scoreArgument('bar')->willReturn(true); + $this->scoreArgument($argument)->shouldBe(false); + } + + function it_does_not_score_traversable_object_without_entries(\Iterator $object) + { + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(false); + $this->scoreArgument($object)->shouldBe(false); + } + + function it_does_not_score_traversable_object_if_key_and_value_tokens_do_not_score_same_entry( + TokenInterface $key, + TokenInterface $value, + \Iterator $object + ) { + $object->current()->willReturn('foo'); + $object->current()->will(function () use ($object) { + $object->valid()->willReturn(false); + + return 'bar'; + }); + $object->key()->willReturn(1); + $object->key()->willReturn(2); + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(true); + $key->scoreArgument(1)->willReturn(true); + $key->scoreArgument(2)->willReturn(false); + $value->scoreArgument('foo')->willReturn(false); + $value->scoreArgument('bar')->willReturn(true); + $this->scoreArgument($object)->shouldBe(false); + } + + function it_does_not_score_array_accessible_object_if_it_has_no_offset_with_key_token_value( + ExactValueToken $key, + \ArrayAccess $object + ) { + $object->offsetExists('key')->willReturn(false); + $key->getValue()->willReturn('key'); + $this->scoreArgument($object)->shouldBe(false); + } + + function it_does_not_score_array_accessible_object_if_key_and_value_tokens_do_not_score_same_entry( + ExactValueToken $key, + TokenInterface $value, + \ArrayAccess $object + ) { + $object->offsetExists('key')->willReturn(true); + $object->offsetGet('key')->willReturn('value'); + $key->getValue()->willReturn('key'); + $value->scoreArgument('value')->willReturn(false); + $key->scoreArgument('key')->willReturn(true); + $this->scoreArgument($object)->shouldBe(false); + } + + function its_score_is_capped_at_8($key, $value) + { + $key->scoreArgument('key')->willReturn(10); + $value->scoreArgument('value')->willReturn(10); + $this->scoreArgument(array('key'=>'value'))->shouldBe(8); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/ArrayEveryEntryTokenSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/ArrayEveryEntryTokenSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/ArrayEveryEntryTokenSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/ArrayEveryEntryTokenSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,96 @@ +beConstructedWith($value); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_holds_value($value) + { + $this->getValue()->shouldBe($value); + } + + function its_string_representation_tells_that_its_an_array_containing_only_value($value) + { + $value->__toString()->willReturn('value'); + $this->__toString()->shouldBe('[value, ..., value]'); + } + + function it_wraps_non_token_value_into_ExactValueToken(\stdClass $stdClass) + { + $this->beConstructedWith($stdClass); + $this->getValue()->shouldHaveType('Prophecy\Argument\Token\ExactValueToken'); + } + + function it_does_not_score_if_argument_is_neither_array_nor_traversable() + { + $this->scoreArgument('string')->shouldBe(false); + $this->scoreArgument(new \stdClass)->shouldBe(false); + } + + function it_does_not_score_empty_array() + { + $this->scoreArgument(array())->shouldBe(false); + } + + function it_does_not_score_traversable_object_without_entries(\Iterator $object) + { + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(false); + $this->scoreArgument($object)->shouldBe(false); + } + + function it_scores_avg_of_scores_from_value_tokens($value) + { + $value->scoreArgument('value1')->willReturn(6); + $value->scoreArgument('value2')->willReturn(3); + $this->scoreArgument(array('value1', 'value2'))->shouldBe(4.5); + } + + function it_scores_false_if_entry_scores_false($value) + { + $value->scoreArgument('value1')->willReturn(6); + $value->scoreArgument('value2')->willReturn(false); + $this->scoreArgument(array('value1', 'value2'))->shouldBe(false); + } + + function it_does_not_score_array_keys($value) + { + $value->scoreArgument('value')->willReturn(6); + $value->scoreArgument('key')->shouldNotBeCalled(0); + $this->scoreArgument(array('key' => 'value'))->shouldBe(6); + } + + function it_scores_traversable_object_from_value_token(TokenInterface $value, \Iterator $object) + { + $object->current()->will(function ($args, $object) { + $object->valid()->willReturn(false); + + return 'value'; + }); + $object->key()->willReturn('key'); + $object->rewind()->willReturn(null); + $object->next()->willReturn(null); + $object->valid()->willReturn(true); + $value->scoreArgument('value')->willReturn(2); + $this->scoreArgument($object)->shouldBe(2); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/CallbackTokenSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/CallbackTokenSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/CallbackTokenSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/CallbackTokenSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,42 @@ +beConstructedWith('get_class'); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_7_if_argument_matches_callback() + { + $this->beConstructedWith(function ($argument) { return 2 === $argument; }); + + $this->scoreArgument(2)->shouldReturn(7); + } + + function it_does_not_scores_if_argument_does_not_match_callback() + { + $this->beConstructedWith(function ($argument) { return 2 === $argument; }); + + $this->scoreArgument(5)->shouldReturn(false); + } + + function its_string_representation_should_tell_that_its_callback() + { + $this->__toString()->shouldReturn('callback()'); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/ExactValueTokenSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/ExactValueTokenSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/ExactValueTokenSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/ExactValueTokenSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,152 @@ +beConstructedWith(42); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_holds_value() + { + $this->getValue()->shouldReturn(42); + } + + function it_scores_10_if_value_is_equal_to_argument() + { + $this->scoreArgument(42)->shouldReturn(10); + $this->scoreArgument('42')->shouldReturn(10); + } + + function it_scores_10_if_value_is_an_object_and_equal_to_argument() + { + $value = new \DateTime(); + $value2 = clone $value; + + $this->beConstructedWith($value); + $this->scoreArgument($value2)->shouldReturn(10); + } + + function it_does_not_scores_if_value_is_not_equal_to_argument() + { + $this->scoreArgument(50)->shouldReturn(false); + $this->scoreArgument(new \stdClass())->shouldReturn(false); + } + + function it_does_not_scores_if_value_an_object_and_is_not_equal_to_argument() + { + $value = new ExactValueTokenFixtureB('ABC'); + $value2 = new ExactValueTokenFixtureB('CBA'); + + $this->beConstructedWith($value); + $this->scoreArgument($value2)->shouldReturn(false); + } + + function it_does_not_scores_if_value_type_and_is_not_equal_to_argument() + { + $this->beConstructedWith(false); + $this->scoreArgument(0)->shouldReturn(false); + } + + function it_generates_proper_string_representation_for_integer() + { + $this->beConstructedWith(42); + $this->__toString()->shouldReturn('exact(42)'); + } + + function it_generates_proper_string_representation_for_string() + { + $this->beConstructedWith('some string'); + $this->__toString()->shouldReturn('exact("some string")'); + } + + function it_generates_single_line_representation_for_multiline_string() + { + $this->beConstructedWith("some\nstring"); + $this->__toString()->shouldReturn('exact("some\\nstring")'); + } + + function it_generates_proper_string_representation_for_double() + { + $this->beConstructedWith(42.3); + $this->__toString()->shouldReturn('exact(42.3)'); + } + + function it_generates_proper_string_representation_for_boolean_true() + { + $this->beConstructedWith(true); + $this->__toString()->shouldReturn('exact(true)'); + } + + function it_generates_proper_string_representation_for_boolean_false() + { + $this->beConstructedWith(false); + $this->__toString()->shouldReturn('exact(false)'); + } + + function it_generates_proper_string_representation_for_null() + { + $this->beConstructedWith(null); + $this->__toString()->shouldReturn('exact(null)'); + } + + function it_generates_proper_string_representation_for_empty_array() + { + $this->beConstructedWith(array()); + $this->__toString()->shouldReturn('exact([])'); + } + + function it_generates_proper_string_representation_for_array() + { + $this->beConstructedWith(array('zet', 42)); + $this->__toString()->shouldReturn('exact(["zet", 42])'); + } + + function it_generates_proper_string_representation_for_resource() + { + $resource = fopen(__FILE__, 'r'); + $this->beConstructedWith($resource); + $this->__toString()->shouldReturn('exact(stream:'.$resource.')'); + } + + function it_generates_proper_string_representation_for_object(\stdClass $object) + { + $objHash = sprintf('%s:%s', + get_class($object->getWrappedObject()), + spl_object_hash($object->getWrappedObject()) + ); + + $this->beConstructedWith($object); + $this->__toString()->shouldReturn("exact($objHash Object (\n 'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)\n))"); + } +} + +class ExactValueTokenFixtureA +{ + public $errors; +} + +class ExactValueTokenFixtureB extends ExactValueTokenFixtureA +{ + public $errors; + public $value = null; + + public function __construct($value) + { + $this->value = $value; + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/IdenticalValueTokenSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/IdenticalValueTokenSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/IdenticalValueTokenSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/IdenticalValueTokenSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,152 @@ +beConstructedWith(42); + } + + function it_is_initializable() + { + $this->shouldHaveType('Prophecy\Argument\Token\IdenticalValueToken'); + } + + function it_scores_11_if_string_value_is_identical_to_argument() + { + $this->beConstructedWith('foo'); + $this->scoreArgument('foo')->shouldReturn(11); + } + + function it_scores_11_if_boolean_value_is_identical_to_argument() + { + $this->beConstructedWith(false); + $this->scoreArgument(false)->shouldReturn(11); + } + + function it_scores_11_if_integer_value_is_identical_to_argument() + { + $this->beConstructedWith(31); + $this->scoreArgument(31)->shouldReturn(11); + } + + function it_scores_11_if_float_value_is_identical_to_argument() + { + $this->beConstructedWith(31.12); + $this->scoreArgument(31.12)->shouldReturn(11); + } + + function it_scores_11_if_array_value_is_identical_to_argument() + { + $this->beConstructedWith(array('foo' => 'bar')); + $this->scoreArgument(array('foo' => 'bar'))->shouldReturn(11); + } + + function it_scores_11_if_object_value_is_identical_to_argument() + { + $object = new \stdClass(); + + $this->beConstructedWith($object); + $this->scoreArgument($object)->shouldReturn(11); + } + + function it_scores_false_if_value_is_not_identical_to_argument() + { + $this->beConstructedWith(new \stdClass()); + $this->scoreArgument('foo')->shouldReturn(false); + } + + function it_scores_false_if_object_value_is_not_the_same_instance_than_argument() + { + $this->beConstructedWith(new \stdClass()); + $this->scoreArgument(new \stdClass())->shouldReturn(false); + } + + function it_scores_false_if_integer_value_is_not_identical_to_boolean_argument() + { + $this->beConstructedWith(1); + $this->scoreArgument(true)->shouldReturn(false); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_generates_proper_string_representation_for_integer() + { + $this->beConstructedWith(42); + $this->__toString()->shouldReturn('identical(42)'); + } + + function it_generates_proper_string_representation_for_string() + { + $this->beConstructedWith('some string'); + $this->__toString()->shouldReturn('identical("some string")'); + } + + function it_generates_single_line_representation_for_multiline_string() + { + $this->beConstructedWith("some\nstring"); + $this->__toString()->shouldReturn('identical("some\\nstring")'); + } + + function it_generates_proper_string_representation_for_double() + { + $this->beConstructedWith(42.3); + $this->__toString()->shouldReturn('identical(42.3)'); + } + + function it_generates_proper_string_representation_for_boolean_true() + { + $this->beConstructedWith(true); + $this->__toString()->shouldReturn('identical(true)'); + } + + function it_generates_proper_string_representation_for_boolean_false() + { + $this->beConstructedWith(false); + $this->__toString()->shouldReturn('identical(false)'); + } + + function it_generates_proper_string_representation_for_null() + { + $this->beConstructedWith(null); + $this->__toString()->shouldReturn('identical(null)'); + } + + function it_generates_proper_string_representation_for_empty_array() + { + $this->beConstructedWith(array()); + $this->__toString()->shouldReturn('identical([])'); + } + + function it_generates_proper_string_representation_for_array() + { + $this->beConstructedWith(array('zet', 42)); + $this->__toString()->shouldReturn('identical(["zet", 42])'); + } + + function it_generates_proper_string_representation_for_resource() + { + $resource = fopen(__FILE__, 'r'); + $this->beConstructedWith($resource); + $this->__toString()->shouldReturn('identical(stream:'.$resource.')'); + } + + function it_generates_proper_string_representation_for_object($object) + { + $objHash = sprintf('%s:%s', + get_class($object->getWrappedObject()), + spl_object_hash($object->getWrappedObject()) + ); + + $this->beConstructedWith($object); + $this->__toString()->shouldReturn("identical($objHash Object (\n 'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)\n))"); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/LogicalAndTokenSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/LogicalAndTokenSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/LogicalAndTokenSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/LogicalAndTokenSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,69 @@ +beConstructedWith(array()); + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->beConstructedWith(array()); + $this->shouldNotBeLast(); + } + + function it_generates_string_representation_from_all_tokens_imploded( + TokenInterface $token1, + TokenInterface $token2, + TokenInterface $token3 + ) { + $token1->__toString()->willReturn('token_1'); + $token2->__toString()->willReturn('token_2'); + $token3->__toString()->willReturn('token_3'); + + $this->beConstructedWith(array($token1, $token2, $token3)); + $this->__toString()->shouldReturn('bool(token_1 AND token_2 AND token_3)'); + } + + function it_wraps_non_token_arguments_into_ExactValueToken() + { + $this->beConstructedWith(array(15, '1985')); + $this->__toString()->shouldReturn("bool(exact(15) AND exact(\"1985\"))"); + } + + function it_scores_the_maximum_score_from_all_scores_returned_by_tokens(TokenInterface $token1, TokenInterface $token2) + { + $token1->scoreArgument(1)->willReturn(10); + $token2->scoreArgument(1)->willReturn(5); + $this->beConstructedWith(array($token1, $token2)); + $this->scoreArgument(1)->shouldReturn(10); + } + + function it_does_not_score_if_there_are_no_arguments_or_tokens() + { + $this->beConstructedWith(array()); + $this->scoreArgument('any')->shouldReturn(false); + } + + function it_does_not_score_if_either_of_tokens_does_not_score(TokenInterface $token1, TokenInterface $token2) + { + $token1->scoreArgument(1)->willReturn(10); + $token1->scoreArgument(2)->willReturn(false); + + $token2->scoreArgument(1)->willReturn(false); + $token2->scoreArgument(2)->willReturn(10); + + $this->beConstructedWith(array($token1, $token2)); + + $this->scoreArgument(1)->shouldReturn(false); + $this->scoreArgument(2)->shouldReturn(false); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/LogicalNotTokenSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/LogicalNotTokenSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/LogicalNotTokenSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/LogicalNotTokenSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,62 @@ +beConstructedWith($token); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_holds_originating_token($token) + { + $this->getOriginatingToken()->shouldReturn($token); + } + + function it_has_simple_string_representation($token) + { + $token->__toString()->willReturn('value'); + $this->__toString()->shouldBe('not(value)'); + } + + function it_wraps_non_token_argument_into_ExactValueToken() + { + $this->beConstructedWith(5); + $token = $this->getOriginatingToken(); + $token->shouldhaveType('Prophecy\Argument\Token\ExactValueToken'); + $token->getValue()->shouldBe(5); + } + + function it_scores_4_if_preset_token_does_not_match_the_argument($token) + { + $token->scoreArgument('argument')->willReturn(false); + $this->scoreArgument('argument')->shouldBe(4); + } + + function it_does_not_score_if_preset_token_matches_argument($token) + { + $token->scoreArgument('argument')->willReturn(5); + $this->scoreArgument('argument')->shouldBe(false); + } + + function it_is_last_if_preset_token_is_last($token) + { + $token->isLast()->willReturn(true); + $this->shouldBeLast(); + } + + function it_is_not_last_if_preset_token_is_not_last($token) + { + $token->isLast()->willReturn(false); + $this->shouldNotBeLast(); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/ObjectStateTokenSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/ObjectStateTokenSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/ObjectStateTokenSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/ObjectStateTokenSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,89 @@ +beConstructedWith('getName', 'stdClass'); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_8_if_argument_object_has_specific_method_state(\ReflectionClass $reflection) + { + $reflection->getName()->willReturn('stdClass'); + + $this->scoreArgument($reflection)->shouldReturn(8); + } + + function it_scores_8_if_argument_object_has_specific_property_state(\stdClass $class) + { + $class->getName = 'stdClass'; + + $this->scoreArgument($class)->shouldReturn(8); + } + + function it_does_not_score_if_argument_method_state_does_not_match() + { + $value = new ObjectStateTokenFixtureB('ABC'); + $value2 = new ObjectStateTokenFixtureB('CBA'); + + $this->beConstructedWith('getSelf', $value); + $this->scoreArgument($value2)->shouldReturn(false); + } + + function it_does_not_score_if_argument_property_state_does_not_match(\stdClass $class) + { + $class->getName = 'SplFileInfo'; + + $this->scoreArgument($class)->shouldReturn(false); + } + + function it_does_not_score_if_argument_object_does_not_have_method_or_property(ObjectStateTokenFixtureA $class) + { + $this->scoreArgument($class)->shouldReturn(false); + } + + function it_does_not_score_if_argument_is_not_object() + { + $this->scoreArgument(42)->shouldReturn(false); + } + + function it_has_simple_string_representation() + { + $this->__toString()->shouldReturn('state(getName(), "stdClass")'); + } +} + +class ObjectStateTokenFixtureA +{ + public $errors; +} + +class ObjectStateTokenFixtureB extends ObjectStateTokenFixtureA +{ + public $errors; + public $value = null; + + public function __construct($value) + { + $this->value = $value; + } + + public function getSelf() + { + return $this; + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/StringContainsTokenSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/StringContainsTokenSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/StringContainsTokenSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/StringContainsTokenSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,54 @@ +beConstructedWith('a substring'); + } + + function it_is_initializable() + { + $this->shouldHaveType('Prophecy\Argument\Token\StringContainsToken'); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_holds_value() + { + $this->getValue()->shouldReturn('a substring'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_6_if_the_argument_contains_the_value() + { + $this->scoreArgument('Argument containing a substring')->shouldReturn(6); + } + + function it_does_not_score_if_the_argument_does_not_contain_the_value() + { + $this->scoreArgument('Argument will not match')->shouldReturn(false); + } + + function it_does_not_score_if_the_argument_is_not_a_string() + { + $this->scoreArgument(array('a substring', 'other value'))->shouldReturn(false); + } + + function its_string_representation_shows_substring() + { + $this->__toString()->shouldReturn('contains("a substring")'); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/TypeTokenSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/TypeTokenSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Argument/Token/TypeTokenSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Argument/Token/TypeTokenSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,57 @@ +beConstructedWith('integer'); + } + + function it_implements_TokenInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Argument\Token\TokenInterface'); + } + + function it_is_not_last() + { + $this->shouldNotBeLast(); + } + + function it_scores_5_if_argument_matches_simple_type() + { + $this->beConstructedWith('integer'); + + $this->scoreArgument(42)->shouldReturn(5); + } + + function it_does_not_scores_if_argument_does_not_match_simple_type() + { + $this->beConstructedWith('integer'); + + $this->scoreArgument(42.0)->shouldReturn(false); + } + + function it_scores_5_if_argument_is_an_instance_of_specified_class(\ReflectionObject $object) + { + $this->beConstructedWith('ReflectionClass'); + + $this->scoreArgument($object)->shouldReturn(5); + } + + function it_has_simple_string_representation() + { + $this->__toString()->shouldReturn('type(integer)'); + } + + function it_scores_5_if_argument_is_an_instance_of_specified_interface(TokenInterface $interface) + { + $this->beConstructedWith('Prophecy\Argument\Token\TokenInterface'); + + $this->scoreArgument($interface)->shouldReturn(5); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/ArgumentSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/ArgumentSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/ArgumentSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/ArgumentSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,107 @@ +exact(42); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ExactValueToken'); + $token->getValue()->shouldReturn(42); + } + + function it_has_a_shortcut_for_any_argument_token() + { + $token = $this->any(); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\AnyValueToken'); + } + + function it_has_a_shortcut_for_multiple_arguments_token() + { + $token = $this->cetera(); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\AnyValuesToken'); + } + + function it_has_a_shortcut_for_type_token() + { + $token = $this->type('integer'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\TypeToken'); + } + + function it_has_a_shortcut_for_callback_token() + { + $token = $this->that('get_class'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\CallbackToken'); + } + + function it_has_a_shortcut_for_object_state_token() + { + $token = $this->which('getName', 'everzet'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ObjectStateToken'); + } + + function it_has_a_shortcut_for_logical_and_token() + { + $token = $this->allOf('integer', 5); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\LogicalAndToken'); + } + + function it_has_a_shortcut_for_array_count_token() + { + $token = $this->size(5); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayCountToken'); + } + + function it_has_a_shortcut_for_array_entry_token() + { + $token = $this->withEntry('key', 'value'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayEntryToken'); + } + + function it_has_a_shortcut_for_array_every_entry_token() + { + $token = $this->withEveryEntry('value'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayEveryEntryToken'); + } + + function it_has_a_shortcut_for_identical_value_token() + { + $token = $this->is('value'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\IdenticalValueToken'); + } + + function it_has_a_shortcut_for_array_entry_token_matching_any_key() + { + $token = $this->containing('value'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayEntryToken'); + $token->getKey()->shouldHaveType('Prophecy\Argument\Token\AnyValueToken'); + } + + function it_has_a_shortcut_for_array_entry_token_matching_any_value() + { + $token = $this->withKey('key'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ArrayEntryToken'); + $token->getValue()->shouldHaveType('Prophecy\Argument\Token\AnyValueToken'); + } + + function it_has_a_shortcut_for_logical_not_token() + { + $token = $this->not('kagux'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\LogicalNotToken'); + } + + function it_has_a_shortcut_for_string_contains_token() + { + $token = $this->containingString('string'); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\StringContainsToken'); + } + + function it_has_a_shortcut_for_approximate_token() + { + $token = $this->approximate(10); + $token->shouldBeAnInstanceOf('Prophecy\Argument\Token\ApproximateValueToken'); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Call/CallCenterSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Call/CallCenterSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Call/CallCenterSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Call/CallCenterSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,180 @@ +scoreArguments(array(5, 2, 3))->willReturn(10); + $objectProphecy->getMethodProphecies()->willReturn(array()); + + $this->makeCall($objectProphecy, 'setValues', array(5, 2, 3)); + + $calls = $this->findCalls('setValues', $wildcard); + $calls->shouldHaveCount(1); + + $calls[0]->shouldBeAnInstanceOf('Prophecy\Call\Call'); + $calls[0]->getMethodName()->shouldReturn('setValues'); + $calls[0]->getArguments()->shouldReturn(array(5, 2, 3)); + $calls[0]->getReturnValue()->shouldReturn(null); + } + + function it_returns_null_for_any_call_through_makeCall_if_no_method_prophecies_added( + $objectProphecy + ) + { + $objectProphecy->getMethodProphecies()->willReturn(array()); + + $this->makeCall($objectProphecy, 'setValues', array(5, 2, 3))->shouldReturn(null); + } + + function it_executes_promise_of_method_prophecy_that_matches_signature_passed_to_makeCall( + $objectProphecy, + MethodProphecy $method1, + MethodProphecy $method2, + MethodProphecy $method3, + ArgumentsWildcard $arguments1, + ArgumentsWildcard $arguments2, + ArgumentsWildcard $arguments3, + PromiseInterface $promise + ) { + $method1->hasReturnVoid()->willReturn(false); + $method1->getMethodName()->willReturn('getName'); + $method1->getArgumentsWildcard()->willReturn($arguments1); + $arguments1->scoreArguments(array('world', 'everything'))->willReturn(false); + + $method2->hasReturnVoid()->willReturn(false); + $method2->getMethodName()->willReturn('setTitle'); + $method2->getArgumentsWildcard()->willReturn($arguments2); + $arguments2->scoreArguments(array('world', 'everything'))->willReturn(false); + + $method3->hasReturnVoid()->willReturn(false); + $method3->getMethodName()->willReturn('getName'); + $method3->getArgumentsWildcard()->willReturn($arguments3); + $method3->getPromise()->willReturn($promise); + $arguments3->scoreArguments(array('world', 'everything'))->willReturn(200); + + $objectProphecy->getMethodProphecies()->willReturn(array( + 'method1' => array($method1), + 'method2' => array($method2, $method3) + )); + $objectProphecy->getMethodProphecies('getName')->willReturn(array($method1, $method3)); + $objectProphecy->reveal()->willReturn(new \stdClass()); + + $promise->execute(array('world', 'everything'), $objectProphecy->getWrappedObject(), $method3)->willReturn(42); + + $this->makeCall($objectProphecy, 'getName', array('world', 'everything'))->shouldReturn(42); + + $calls = $this->findCalls('getName', $arguments3); + $calls->shouldHaveCount(1); + $calls[0]->getReturnValue()->shouldReturn(42); + } + + function it_executes_promise_of_method_prophecy_that_matches_with_highest_score_to_makeCall( + $objectProphecy, + MethodProphecy $method1, + MethodProphecy $method2, + MethodProphecy $method3, + ArgumentsWildcard $arguments1, + ArgumentsWildcard $arguments2, + ArgumentsWildcard $arguments3, + PromiseInterface $promise + ) { + $method1->hasReturnVoid()->willReturn(false); + $method1->getMethodName()->willReturn('getName'); + $method1->getArgumentsWildcard()->willReturn($arguments1); + $arguments1->scoreArguments(array('world', 'everything'))->willReturn(50); + + $method2->hasReturnVoid()->willReturn(false); + $method2->getMethodName()->willReturn('getName'); + $method2->getArgumentsWildcard()->willReturn($arguments2); + $method2->getPromise()->willReturn($promise); + $arguments2->scoreArguments(array('world', 'everything'))->willReturn(300); + + $method3->hasReturnVoid()->willReturn(false); + $method3->getMethodName()->willReturn('getName'); + $method3->getArgumentsWildcard()->willReturn($arguments3); + $arguments3->scoreArguments(array('world', 'everything'))->willReturn(200); + + $objectProphecy->getMethodProphecies()->willReturn(array( + 'method1' => array($method1), + 'method2' => array($method2, $method3) + )); + $objectProphecy->getMethodProphecies('getName')->willReturn(array( + $method1, $method2, $method3 + )); + $objectProphecy->reveal()->willReturn(new \stdClass()); + + $promise->execute(array('world', 'everything'), $objectProphecy->getWrappedObject(), $method2) + ->willReturn('second'); + + $this->makeCall($objectProphecy, 'getName', array('world', 'everything')) + ->shouldReturn('second'); + } + + function it_throws_exception_if_call_does_not_match_any_of_defined_method_prophecies( + $objectProphecy, + MethodProphecy $method, + ArgumentsWildcard $arguments + ) { + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $arguments->scoreArguments(array('world', 'everything'))->willReturn(false); + $arguments->__toString()->willReturn('arg1, arg2'); + + $objectProphecy->getMethodProphecies()->willReturn(array('method1' => array($method))); + $objectProphecy->getMethodProphecies('getName')->willReturn(array($method)); + + $this->shouldThrow('Prophecy\Exception\Call\UnexpectedCallException') + ->duringMakeCall($objectProphecy, 'getName', array('world', 'everything')); + } + + function it_returns_null_if_method_prophecy_that_matches_makeCall_arguments_has_no_promise( + $objectProphecy, + MethodProphecy $method, + ArgumentsWildcard $arguments + ) { + $method->hasReturnVoid()->willReturn(false); + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $method->getPromise()->willReturn(null); + $arguments->scoreArguments(array('world', 'everything'))->willReturn(100); + + $objectProphecy->getMethodProphecies()->willReturn(array($method)); + $objectProphecy->getMethodProphecies('getName')->willReturn(array($method)); + + $this->makeCall($objectProphecy, 'getName', array('world', 'everything')) + ->shouldReturn(null); + } + + function it_finds_recorded_calls_by_a_method_name_and_arguments_wildcard( + $objectProphecy, + ArgumentsWildcard $wildcard + ) { + $objectProphecy->getMethodProphecies()->willReturn(array()); + + $this->makeCall($objectProphecy, 'getName', array('world')); + $this->makeCall($objectProphecy, 'getName', array('everything')); + $this->makeCall($objectProphecy, 'setName', array(42)); + + $wildcard->scoreArguments(array('world'))->willReturn(false); + $wildcard->scoreArguments(array('everything'))->willReturn(10); + + $calls = $this->findCalls('getName', $wildcard); + + $calls->shouldHaveCount(1); + $calls[0]->getMethodName()->shouldReturn('getName'); + $calls[0]->getArguments()->shouldReturn(array('everything')); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Call/CallSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Call/CallSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Call/CallSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Call/CallSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,65 @@ +beConstructedWith('setValues', array(5, 2), 42, $exception, 'some_file.php', 23); + } + + function it_exposes_method_name_through_getter() + { + $this->getMethodName()->shouldReturn('setValues'); + } + + function it_exposes_arguments_through_getter() + { + $this->getArguments()->shouldReturn(array(5, 2)); + } + + function it_exposes_return_value_through_getter() + { + $this->getReturnValue()->shouldReturn(42); + } + + function it_exposes_exception_through_getter($exception) + { + $this->getException()->shouldReturn($exception); + } + + function it_exposes_file_and_line_through_getter() + { + $this->getFile()->shouldReturn('some_file.php'); + $this->getLine()->shouldReturn(23); + } + + function it_returns_shortpath_to_callPlace() + { + $this->getCallPlace()->shouldReturn('some_file.php:23'); + } + + function it_returns_unknown_as_callPlace_if_no_file_or_line_provided() + { + $this->beConstructedWith('setValues', array(), 0, null, null, null); + + $this->getCallPlace()->shouldReturn('unknown'); + } + + function it_adds_wildcard_match_score(ArgumentsWildcard $wildcard) + { + $this->addScore($wildcard, 99)->shouldReturn($this); + $this->getScore($wildcard)->shouldReturn(99); + } + + function it_caches_and_returns_wildcard_match_score(ArgumentsWildcard $wildcard) + { + $wildcard->scoreArguments(array(5, 2))->willReturn(13)->shouldBeCalledTimes(1); + $this->getScore($wildcard)->shouldReturn(13); + $this->getScore($wildcard)->shouldReturn(13); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Comparator/ClosureComparatorSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Comparator/ClosureComparatorSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Comparator/ClosureComparatorSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Comparator/ClosureComparatorSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,39 @@ +shouldHaveType('SebastianBergmann\Comparator\Comparator'); + } + + function it_accepts_only_closures() + { + $this->accepts(123, 321)->shouldReturn(false); + $this->accepts('string', 'string')->shouldReturn(false); + $this->accepts(false, true)->shouldReturn(false); + $this->accepts(true, false)->shouldReturn(false); + $this->accepts((object)array(), (object)array())->shouldReturn(false); + $this->accepts(function(){}, (object)array())->shouldReturn(false); + $this->accepts(function(){}, (object)array())->shouldReturn(false); + + $this->accepts(function(){}, function(){})->shouldReturn(true); + } + + function it_asserts_that_all_closures_are_different() + { + $this->shouldThrow()->duringAssertEquals(function(){}, function(){}); + } + + function it_asserts_that_all_closures_are_different_even_if_its_the_same_closure() + { + $closure = function(){}; + + $this->shouldThrow()->duringAssertEquals($closure, $closure); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Comparator/FactorySpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Comparator/FactorySpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Comparator/FactorySpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Comparator/FactorySpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,20 @@ +shouldHaveType('SebastianBergmann\Comparator\Factory'); + } + + function it_should_have_ClosureComparator_registered() + { + $comparator = $this->getInstance()->getComparatorFor(function(){}, function(){}); + $comparator->shouldHaveType('Prophecy\Comparator\ClosureComparator'); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Comparator/ProphecyComparatorSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Comparator/ProphecyComparatorSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Comparator/ProphecyComparatorSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Comparator/ProphecyComparatorSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,40 @@ +shouldHaveType('SebastianBergmann\Comparator\ObjectComparator'); + } + + function it_accepts_only_prophecy_objects() + { + $this->accepts(123, 321)->shouldReturn(false); + $this->accepts('string', 'string')->shouldReturn(false); + $this->accepts(false, true)->shouldReturn(false); + $this->accepts(true, false)->shouldReturn(false); + $this->accepts((object)array(), (object)array())->shouldReturn(false); + $this->accepts(function(){}, (object)array())->shouldReturn(false); + $this->accepts(function(){}, function(){})->shouldReturn(false); + + $prophet = new Prophet(); + $prophecy = $prophet->prophesize('Prophecy\Prophecy\ObjectProphecy'); + + $this->accepts($prophecy, $prophecy)->shouldReturn(true); + } + + function it_asserts_that_an_object_is_equal_to_its_revealed_prophecy() + { + $prophet = new Prophet(); + $prophecy = $prophet->prophesize('Prophecy\Prophecy\ObjectProphecy'); + $prophecy->__call('reveal', array())->willReturn(new \stdClass()); + + $this->shouldNotThrow()->duringAssertEquals($prophecy->reveal(), $prophecy); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/DisableConstructorPatchSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/DisableConstructorPatchSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/DisableConstructorPatchSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/DisableConstructorPatchSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,63 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_100() + { + $this->getPriority()->shouldReturn(100); + } + + function it_supports_anything(ClassNode $node) + { + $this->supports($node)->shouldReturn(true); + } + + function it_makes_all_constructor_arguments_optional( + ClassNode $class, + MethodNode $method, + ArgumentNode $arg1, + ArgumentNode $arg2 + ) { + $class->isExtendable('__construct')->willReturn(true); + $class->hasMethod('__construct')->willReturn(true); + $class->getMethod('__construct')->willReturn($method); + $method->getArguments()->willReturn(array($arg1, $arg2)); + + $arg1->setDefault(null)->shouldBeCalled(); + $arg2->setDefault(null)->shouldBeCalled(); + + $method->setCode(Argument::type('string'))->shouldBeCalled(); + + $this->apply($class); + } + + function it_creates_new_constructor_if_object_has_none(ClassNode $class) + { + $class->isExtendable('__construct')->willReturn(true); + $class->hasMethod('__construct')->willReturn(false); + $class->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode')) + ->shouldBeCalled(); + + $this->apply($class); + } + + function it_ignores_final_constructor(ClassNode $class) + { + $class->isExtendable('__construct')->willReturn(false); + + $this->apply($class); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/HhvmExceptionPatchSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/HhvmExceptionPatchSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/HhvmExceptionPatchSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/HhvmExceptionPatchSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,34 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_minus_50() + { + $this->getPriority()->shouldReturn(-50); + } + + function it_uses_parent_code_for_setTraceOptions(ClassNode $node, MethodNode $method, MethodNode $getterMethod) + { + $node->hasMethod('setTraceOptions')->willReturn(true); + $node->getMethod('setTraceOptions')->willReturn($method); + $node->hasMethod('getTraceOptions')->willReturn(true); + $node->getMethod('getTraceOptions')->willReturn($getterMethod); + + $method->useParentCode()->shouldBeCalled(); + $getterMethod->useParentCode()->shouldBeCalled(); + + $this->apply($node); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/KeywordPatchSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/KeywordPatchSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/KeywordPatchSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/KeywordPatchSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,73 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_49() + { + $this->getPriority()->shouldReturn(49); + } + + function it_will_remove_echo_and_eval_methods( + ClassNode $node, + MethodNode $method1, + MethodNode $method2, + MethodNode $method3 + ) { + if (\PHP_VERSION_ID >= 70000) { + throw new SkippingException('Reserved keywords list in PHP 7 does not include most of PHP 5.6 keywords'); + } + + $node->removeMethod('eval')->shouldBeCalled(); + $node->removeMethod('echo')->shouldBeCalled(); + + $method1->getName()->willReturn('echo'); + $method2->getName()->willReturn('eval'); + $method3->getName()->willReturn('notKeyword'); + + $node->getMethods()->willReturn(array( + 'echo' => $method1, + 'eval' => $method2, + 'notKeyword' => $method3, + )); + + $this->apply($node); + } + + function it_will_remove_halt_compiler_method( + ClassNode $node, + MethodNode $method1, + MethodNode $method2, + MethodNode $method3 + ) { + if (\PHP_VERSION_ID < 70000) { + throw new SkippingException('Reserved keywords list in PHP 7 does not include most of PHP 5.6 keywords'); + } + + $node->removeMethod('__halt_compiler')->shouldBeCalled(); + + $method1->getName()->willReturn('__halt_compiler'); + $method2->getName()->willReturn('echo'); + $method3->getName()->willReturn('notKeyword'); + + $node->getMethods()->willReturn(array( + '__halt_compiler' => $method1, + 'echo' => $method2, + 'notKeyword' => $method3, + )); + + $this->apply($node); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/MagicCallPatchSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/MagicCallPatchSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/MagicCallPatchSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/MagicCallPatchSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,139 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function it_supports_anything(ClassNode $node) + { + $this->supports($node)->shouldReturn(true); + } + + function it_discovers_api_using_phpdoc(ClassNode $node) + { + $node->getParentClass()->willReturn('spec\Prophecy\Doubler\ClassPatch\MagicalApi'); + $node->getInterfaces()->willReturn(array()); + + $node->addMethod(new MethodNode('undefinedMethod'))->shouldBeCalled(); + + $this->apply($node); + } + + function it_ignores_existing_methods(ClassNode $node) + { + $node->getParentClass()->willReturn('spec\Prophecy\Doubler\ClassPatch\MagicalApiExtended'); + $node->getInterfaces()->willReturn(array()); + + $node->addMethod(new MethodNode('undefinedMethod'))->shouldBeCalled(); + $node->addMethod(new MethodNode('definedMethod'))->shouldNotBeCalled(); + + $this->apply($node); + } + + function it_ignores_empty_methods_from_phpdoc(ClassNode $node) + { + $node->getParentClass()->willReturn('spec\Prophecy\Doubler\ClassPatch\MagicalApiInvalidMethodDefinition'); + $node->getInterfaces()->willReturn(array()); + + $node->addMethod(new MethodNode(''))->shouldNotBeCalled(); + + $this->apply($node); + } + + function it_discovers_api_using_phpdoc_from_implemented_interfaces(ClassNode $node) + { + $node->getParentClass()->willReturn('spec\Prophecy\Doubler\ClassPatch\MagicalApiImplemented'); + $node->getInterfaces()->willReturn(array()); + + $node->addMethod(new MethodNode('implementedMethod'))->shouldBeCalled(); + + $this->apply($node); + } + + function it_discovers_api_using_phpdoc_from_own_interfaces(ClassNode $node) + { + $node->getParentClass()->willReturn('stdClass'); + $node->getInterfaces()->willReturn(array('spec\Prophecy\Doubler\ClassPatch\MagicalApiImplemented')); + + $node->addMethod(new MethodNode('implementedMethod'))->shouldBeCalled(); + + $this->apply($node); + } + + function it_discovers_api_using_phpdoc_from_extended_parent_interfaces(ClassNode $node) + { + $node->getParentClass()->willReturn('spec\Prophecy\Doubler\ClassPatch\MagicalApiImplementedExtended'); + $node->getInterfaces()->willReturn(array()); + + $node->addMethod(new MethodNode('implementedMethod'))->shouldBeCalled(); + + $this->apply($node); + } + + function it_has_50_priority() + { + $this->getPriority()->shouldReturn(50); + } +} + +/** + * @method void undefinedMethod() + */ +class MagicalApi +{ + /** + * @return void + */ + public function definedMethod() + { + + } +} + +/** + * @method void invalidMethodDefinition + * @method void + * @method + */ +class MagicalApiInvalidMethodDefinition +{ +} + +/** + * @method void definedMethod() + */ +class MagicalApiExtended extends MagicalApi +{ + +} + +/** + */ +class MagicalApiImplemented implements MagicalApiInterface +{ + +} + +/** + */ +class MagicalApiImplementedExtended extends MagicalApiImplemented +{ +} + +/** + * @method void implementedMethod() + */ +interface MagicalApiInterface +{ + +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/ProphecySubjectPatchSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/ProphecySubjectPatchSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/ProphecySubjectPatchSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/ProphecySubjectPatchSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,79 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function it_has_priority_of_0() + { + $this->getPriority()->shouldReturn(0); + } + + function it_supports_any_class(ClassNode $node) + { + $this->supports($node)->shouldReturn(true); + } + + function it_forces_class_to_implement_ProphecySubjectInterface(ClassNode $node) + { + $node->addInterface('Prophecy\Prophecy\ProphecySubjectInterface')->shouldBeCalled(); + + $node->addProperty('objectProphecy', 'private')->willReturn(null); + $node->getMethods()->willReturn(array()); + $node->hasMethod(Argument::any())->willReturn(false); + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'), true)->willReturn(null); + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'), true)->willReturn(null); + + $this->apply($node); + } + + function it_forces_all_class_methods_except_constructor_to_proxy_calls_into_prophecy_makeCall( + ClassNode $node, + MethodNode $constructor, + MethodNode $method1, + MethodNode $method2, + MethodNode $method3 + ) { + $node->addInterface('Prophecy\Prophecy\ProphecySubjectInterface')->willReturn(null); + $node->addProperty('objectProphecy', 'private')->willReturn(null); + $node->hasMethod(Argument::any())->willReturn(false); + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'), true)->willReturn(null); + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'), true)->willReturn(null); + + $constructor->getName()->willReturn('__construct'); + $method1->getName()->willReturn('method1'); + $method2->getName()->willReturn('method2'); + $method3->getName()->willReturn('method3'); + + $method1->getReturnType()->willReturn('int'); + $method2->getReturnType()->willReturn('int'); + $method3->getReturnType()->willReturn('void'); + + $node->getMethods()->willReturn(array( + 'method1' => $method1, + 'method2' => $method2, + 'method3' => $method3, + )); + + $constructor->setCode(Argument::any())->shouldNotBeCalled(); + + $method1->setCode('return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());') + ->shouldBeCalled(); + $method2->setCode('return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());') + ->shouldBeCalled(); + $method3->setCode('$this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());') + ->shouldBeCalled(); + + $this->apply($node); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatchSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatchSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatchSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatchSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,43 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_50() + { + $this->getPriority()->shouldReturn(50); + } + + function it_supports_ReflectionClass_only(ClassNode $reflectionClassNode, ClassNode $anotherClassNode) + { + $reflectionClassNode->getParentClass()->willReturn('ReflectionClass'); + $anotherClassNode->getParentClass()->willReturn('stdClass'); + + $this->supports($reflectionClassNode)->shouldReturn(true); + $this->supports($anotherClassNode)->shouldReturn(false); + } + + function it_makes_all_newInstance_arguments_optional( + ClassNode $class, + MethodNode $method, + ArgumentNode $arg1 + ) { + $class->getMethod('newInstance')->willReturn($method); + $method->getArguments()->willReturn(array($arg1)); + $arg1->setDefault(null)->shouldBeCalled(); + + $this->apply($class); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/SplFileInfoPatchSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/SplFileInfoPatchSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/SplFileInfoPatchSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/SplFileInfoPatchSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,98 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function its_priority_is_50() + { + $this->getPriority()->shouldReturn(50); + } + + function it_does_not_support_nodes_without_parent_class(ClassNode $node) + { + $node->getParentClass()->willReturn('stdClass'); + $this->supports($node)->shouldReturn(false); + } + + function it_supports_nodes_with_SplFileInfo_as_parent_class(ClassNode $node) + { + $node->getParentClass()->willReturn('SplFileInfo'); + $this->supports($node)->shouldReturn(true); + } + + function it_supports_nodes_with_derivative_of_SplFileInfo_as_parent_class(ClassNode $node) + { + $node->getParentClass()->willReturn('SplFileInfo'); + $this->supports($node)->shouldReturn(true); + } + + function it_adds_a_method_to_node_if_not_exists(ClassNode $node) + { + $node->hasMethod('__construct')->willReturn(false); + $node->addMethod(Argument::any())->shouldBeCalled(); + $node->getParentClass()->shouldBeCalled(); + + $this->apply($node); + } + + function it_updates_existing_method_if_found(ClassNode $node, MethodNode $method) + { + $node->hasMethod('__construct')->willReturn(true); + $node->getMethod('__construct')->willReturn($method); + $node->getParentClass()->shouldBeCalled(); + + $method->useParentCode()->shouldBeCalled(); + + $this->apply($node); + } + + function it_should_not_supply_a_file_for_a_directory_iterator(ClassNode $node, MethodNode $method) + { + $node->hasMethod('__construct')->willReturn(true); + $node->getMethod('__construct')->willReturn($method); + $node->getParentClass()->willReturn('DirectoryIterator'); + + $method->setCode(Argument::that(function($value) { + return strpos($value, '.php') === false; + }))->shouldBeCalled(); + + $this->apply($node); + } + + function it_should_supply_a_file_for_a_spl_file_object(ClassNode $node, MethodNode $method) + { + $node->hasMethod('__construct')->willReturn(true); + $node->getMethod('__construct')->willReturn($method); + $node->getParentClass()->willReturn('SplFileObject'); + + $method->setCode(Argument::that(function($value) { + return strpos($value, '.php') !== false; + }))->shouldBeCalled(); + + $this->apply($node); + } + + function it_should_supply_a_file_for_a_symfony_spl_file_info(ClassNode $node, MethodNode $method) + { + $node->hasMethod('__construct')->willReturn(true); + $node->getMethod('__construct')->willReturn($method); + $node->getParentClass()->willReturn('Symfony\\Component\\Finder\\SplFileInfo'); + + $method->setCode(Argument::that(function($value) { + return strpos($value, '.php') !== false; + }))->shouldBeCalled(); + + $this->apply($node); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/ThrowablePatchSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/ThrowablePatchSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/ThrowablePatchSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/ThrowablePatchSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,98 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function it_does_not_support_class_that_does_not_implement_throwable(ClassNode $node) + { + if (\PHP_VERSION_ID < 70000) { + throw new SkippingException('Throwable is not defined in PHP 5'); + } + + $node->getInterfaces()->willReturn(array()); + $node->getParentClass()->willReturn('stdClass'); + + $this->supports($node)->shouldReturn(false); + } + + function it_supports_class_that_extends_not_throwable_class(ClassNode $node) + { + if (\PHP_VERSION_ID < 70000) { + throw new SkippingException('Throwable is not defined in PHP 5'); + } + + $node->getInterfaces()->willReturn(array('Throwable')); + $node->getParentClass()->willReturn('stdClass'); + + $this->supports($node)->shouldReturn(true); + } + + function it_does_not_support_class_that_already_extends_a_throwable_class(ClassNode $node) + { + if (\PHP_VERSION_ID < 70000) { + throw new SkippingException('Throwable is not defined in PHP 5'); + } + + $node->getInterfaces()->willReturn(array('Throwable')); + $node->getParentClass()->willReturn('InvalidArgumentException'); + + $this->supports($node)->shouldReturn(false); + } + + function it_supports_class_implementing_interface_that_extends_throwable(ClassNode $node) + { + if (\PHP_VERSION_ID < 70000) { + throw new SkippingException('Throwable is not defined in PHP 5'); + } + + $node->getInterfaces()->willReturn(array('Fixtures\Prophecy\ThrowableInterface')); + $node->getParentClass()->willReturn('stdClass'); + + $this->supports($node)->shouldReturn(true); + } + + function it_sets_the_parent_class_to_exception(ClassNode $node) + { + if (\PHP_VERSION_ID < 70000) { + throw new SkippingException('Throwable is not defined in PHP 5'); + } + + $node->getParentClass()->willReturn('stdClass'); + + $node->setParentClass('Exception')->shouldBeCalled(); + + $node->removeMethod('getMessage')->shouldBeCalled(); + $node->removeMethod('getCode')->shouldBeCalled(); + $node->removeMethod('getFile')->shouldBeCalled(); + $node->removeMethod('getLine')->shouldBeCalled(); + $node->removeMethod('getTrace')->shouldBeCalled(); + $node->removeMethod('getPrevious')->shouldBeCalled(); + $node->removeMethod('getNext')->shouldBeCalled(); + $node->removeMethod('getTraceAsString')->shouldBeCalled(); + + $this->apply($node); + } + + function it_throws_error_when_trying_to_double_concrete_class_and_throwable_interface(ClassNode $node) + { + if (\PHP_VERSION_ID < 70000) { + throw new SkippingException('Throwable is not defined in PHP 5'); + } + + $node->getParentClass()->willReturn('ArrayObject'); + + $this->shouldThrow('Prophecy\Exception\Doubler\ClassCreatorException')->duringApply($node); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/TraversablePatchSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/TraversablePatchSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/ClassPatch/TraversablePatchSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/ClassPatch/TraversablePatchSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,50 @@ +shouldBeAnInstanceOf('Prophecy\Doubler\ClassPatch\ClassPatchInterface'); + } + + function it_supports_class_that_implements_only_Traversable(ClassNode $node) + { + $node->getInterfaces()->willReturn(array('Traversable')); + + $this->supports($node)->shouldReturn(true); + } + + function it_does_not_support_class_that_implements_Iterator(ClassNode $node) + { + $node->getInterfaces()->willReturn(array('Traversable', 'Iterator')); + + $this->supports($node)->shouldReturn(false); + } + + function it_does_not_support_class_that_implements_IteratorAggregate(ClassNode $node) + { + $node->getInterfaces()->willReturn(array('Traversable', 'IteratorAggregate')); + + $this->supports($node)->shouldReturn(false); + } + + function it_has_100_priority() + { + $this->getPriority()->shouldReturn(100); + } + + function it_forces_node_to_implement_IteratorAggregate(ClassNode $node) + { + $node->addInterface('Iterator')->shouldBeCalled(); + + $node->addMethod(Argument::type('Prophecy\Doubler\Generator\Node\MethodNode'))->willReturn(null); + + $this->apply($node); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/DoublerSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/DoublerSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/DoublerSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/DoublerSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,115 @@ +beConstructedWith($mirror, $creator, $namer); + } + + function it_does_not_have_patches_by_default() + { + $this->getClassPatches()->shouldHaveCount(0); + } + + function its_registerClassPatch_adds_a_patch_to_the_doubler(ClassPatchInterface $patch) + { + $this->registerClassPatch($patch); + $this->getClassPatches()->shouldReturn(array($patch)); + } + + function its_getClassPatches_sorts_patches_by_priority( + ClassPatchInterface $alt1, + ClassPatchInterface $alt2, + ClassPatchInterface $alt3, + ClassPatchInterface $alt4 + ) { + $alt1->getPriority()->willReturn(2); + $alt2->getPriority()->willReturn(50); + $alt3->getPriority()->willReturn(10); + $alt4->getPriority()->willReturn(0); + + $this->registerClassPatch($alt1); + $this->registerClassPatch($alt2); + $this->registerClassPatch($alt3); + $this->registerClassPatch($alt4); + + $this->getClassPatches()->shouldReturn(array($alt2, $alt3, $alt1, $alt4)); + } + + function its_double_mirrors_alterates_and_instantiates_provided_class( + $mirror, + $creator, + $namer, + ClassPatchInterface $alt1, + ClassPatchInterface $alt2, + \ReflectionClass $class, + \ReflectionClass $interface1, + \ReflectionClass $interface2, + ClassNode $node + ) { + $mirror->reflect($class, array($interface1, $interface2))->willReturn($node); + $alt1->supports($node)->willReturn(true); + $alt2->supports($node)->willReturn(false); + $alt1->getPriority()->willReturn(1); + $alt2->getPriority()->willReturn(2); + $namer->name($class, array($interface1, $interface2))->willReturn('SplStack'); + $class->getName()->willReturn('stdClass'); + $interface1->getName()->willReturn('ArrayAccess'); + $interface2->getName()->willReturn('Iterator'); + + $alt1->apply($node)->shouldBeCalled(); + $alt2->apply($node)->shouldNotBeCalled(); + $creator->create('SplStack', $node)->shouldBeCalled(); + + $this->registerClassPatch($alt1); + $this->registerClassPatch($alt2); + + $this->double($class, array($interface1, $interface2)) + ->shouldReturnAnInstanceOf('SplStack'); + } + + function it_double_instantiates_a_class_with_constructor_argument( + $mirror, + \ReflectionClass $class, + ClassNode $node, + $namer + ) { + $class->getName()->willReturn('ReflectionClass'); + $mirror->reflect($class, array())->willReturn($node); + $namer->name($class, array())->willReturn('ReflectionClass'); + + $double = $this->double($class, array(), array('stdClass')); + $double->shouldBeAnInstanceOf('ReflectionClass'); + $double->getName()->shouldReturn('stdClass'); + } + + function it_can_instantiate_class_with_final_constructor( + $mirror, + \ReflectionClass $class, + ClassNode $node, + $namer + ) { + $class->getName()->willReturn('spec\Prophecy\Doubler\WithFinalConstructor'); + $mirror->reflect($class, array())->willReturn($node); + $namer->name($class, array())->willReturn('spec\Prophecy\Doubler\WithFinalConstructor'); + + $double = $this->double($class, array()); + + $double->shouldBeAnInstanceOf('spec\Prophecy\Doubler\WithFinalConstructor'); + } +} + +class WithFinalConstructor +{ + final public function __construct() {} +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,416 @@ +getParentClass()->willReturn('RuntimeException'); + $class->getInterfaces()->willReturn(array( + 'Prophecy\Doubler\Generator\MirroredInterface', 'ArrayAccess', 'ArrayIterator' + )); + $class->getProperties()->willReturn(array('name' => 'public', 'email' => 'private')); + $class->getMethods()->willReturn(array($method1, $method2, $method3, $method4, $method5)); + + $method1->getName()->willReturn('getName'); + $method1->getVisibility()->willReturn('public'); + $method1->returnsReference()->willReturn(false); + $method1->isStatic()->willReturn(true); + $method1->getArguments()->willReturn(array($argument11, $argument12, $argument13)); + $method1->hasReturnType()->willReturn(true); + $method1->getReturnType()->willReturn('string'); + $method1->hasNullableReturnType()->willReturn(true); + $method1->getCode()->willReturn('return $this->name;'); + + $method2->getName()->willReturn('getEmail'); + $method2->getVisibility()->willReturn('protected'); + $method2->returnsReference()->willReturn(false); + $method2->isStatic()->willReturn(false); + $method2->getArguments()->willReturn(array($argument21)); + $method2->hasReturnType()->willReturn(false); + $method2->hasNullableReturnType()->willReturn(true); + $method2->getCode()->willReturn('return $this->email;'); + + $method3->getName()->willReturn('getRefValue'); + $method3->getVisibility()->willReturn('public'); + $method3->returnsReference()->willReturn(true); + $method3->isStatic()->willReturn(false); + $method3->getArguments()->willReturn(array($argument31)); + $method3->hasReturnType()->willReturn(true); + $method3->getReturnType()->willReturn('string'); + $method3->hasNullableReturnType()->willReturn(false); + $method3->getCode()->willReturn('return $this->refValue;'); + + $method4->getName()->willReturn('doSomething'); + $method4->getVisibility()->willReturn('public'); + $method4->returnsReference()->willReturn(false); + $method4->isStatic()->willReturn(false); + $method4->getArguments()->willReturn(array()); + $method4->hasReturnType()->willReturn(true); + $method4->getReturnType()->willReturn('void'); + $method4->hasNullableReturnType()->willReturn(false); + $method4->getCode()->willReturn('return;'); + + $method5->getName()->willReturn('returnObject'); + $method5->getVisibility()->willReturn('public'); + $method5->returnsReference()->willReturn(false); + $method5->isStatic()->willReturn(false); + $method5->getArguments()->willReturn(array()); + $method5->hasReturnType()->willReturn(true); + $method5->getReturnType()->willReturn(version_compare(PHP_VERSION, '7.2', '>=') ? 'object' : '\object'); + $method5->hasNullableReturnType()->willReturn(false); + $method5->getCode()->willReturn('return;'); + + $argument11->getName()->willReturn('fullname'); + $argument11->getTypeHint()->willReturn('array'); + $argument11->isOptional()->willReturn(true); + $argument11->getDefault()->willReturn(null); + $argument11->isPassedByReference()->willReturn(false); + $argument11->isVariadic()->willReturn(false); + $argument11->isNullable()->willReturn(false); + + $argument12->getName()->willReturn('class'); + $argument12->getTypeHint()->willReturn('ReflectionClass'); + $argument12->isOptional()->willReturn(false); + $argument12->isPassedByReference()->willReturn(false); + $argument12->isVariadic()->willReturn(false); + $argument12->isNullable()->willReturn(false); + + $argument13->getName()->willReturn('instance'); + $argument13->getTypeHint()->willReturn('object'); + $argument13->isOptional()->willReturn(false); + $argument13->isPassedByReference()->willReturn(false); + $argument13->isVariadic()->willReturn(false); + $argument13->isNullable()->willReturn(false); + + $argument21->getName()->willReturn('default'); + $argument21->getTypeHint()->willReturn('string'); + $argument21->isOptional()->willReturn(true); + $argument21->getDefault()->willReturn('ever.zet@gmail.com'); + $argument21->isPassedByReference()->willReturn(false); + $argument21->isVariadic()->willReturn(false); + $argument21->isNullable()->willReturn(true); + + $argument31->getName()->willReturn('refValue'); + $argument31->getTypeHint()->willReturn(null); + $argument31->isOptional()->willReturn(false); + $argument31->getDefault()->willReturn(); + $argument31->isPassedByReference()->willReturn(false); + $argument31->isVariadic()->willReturn(false); + $argument31->isNullable()->willReturn(false); + + $code = $this->generate('CustomClass', $class); + + if (version_compare(PHP_VERSION, '7.2', '>=')) { + $expected = <<<'PHP' +namespace { +class CustomClass extends \RuntimeException implements \Prophecy\Doubler\Generator\MirroredInterface, \ArrayAccess, \ArrayIterator { +public $name; +private $email; + +public static function getName(array $fullname = NULL, \ReflectionClass $class, object $instance): ?string { +return $this->name; +} +protected function getEmail(?string $default = 'ever.zet@gmail.com') { +return $this->email; +} +public function &getRefValue( $refValue): string { +return $this->refValue; +} +public function doSomething(): void { +return; +} +public function returnObject(): object { +return; +} + +} +} +PHP; + } elseif (version_compare(PHP_VERSION, '7.1', '>=')) { + $expected = <<<'PHP' +namespace { +class CustomClass extends \RuntimeException implements \Prophecy\Doubler\Generator\MirroredInterface, \ArrayAccess, \ArrayIterator { +public $name; +private $email; + +public static function getName(array $fullname = NULL, \ReflectionClass $class, \object $instance): ?string { +return $this->name; +} +protected function getEmail(?string $default = 'ever.zet@gmail.com') { +return $this->email; +} +public function &getRefValue( $refValue): string { +return $this->refValue; +} +public function doSomething(): void { +return; +} +public function returnObject(): \object { +return; +} + +} +} +PHP; + } elseif (version_compare(PHP_VERSION, '7.0', '>=')) { + $expected = <<<'PHP' +namespace { +class CustomClass extends \RuntimeException implements \Prophecy\Doubler\Generator\MirroredInterface, \ArrayAccess, \ArrayIterator { +public $name; +private $email; + +public static function getName(array $fullname = NULL, \ReflectionClass $class, \object $instance): string { +return $this->name; +} +protected function getEmail(string $default = 'ever.zet@gmail.com') { +return $this->email; +} +public function &getRefValue( $refValue): string { +return $this->refValue; +} +public function doSomething() { +return; +} +public function returnObject(): \object { +return; +} + +} +} +PHP; + } else { + $expected = <<<'PHP' +namespace { +class CustomClass extends \RuntimeException implements \Prophecy\Doubler\Generator\MirroredInterface, \ArrayAccess, \ArrayIterator { +public $name; +private $email; + +public static function getName(array $fullname = NULL, \ReflectionClass $class, \object $instance) { +return $this->name; +} +protected function getEmail(\string $default = 'ever.zet@gmail.com') { +return $this->email; +} +public function &getRefValue( $refValue) { +return $this->refValue; +} +public function doSomething() { +return; +} +public function returnObject() { +return; +} + +} +} +PHP; + } + $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); + $code->shouldBe($expected); + } + + function it_generates_proper_php_code_for_variadics( + ClassNode $class, + MethodNode $method1, + MethodNode $method2, + MethodNode $method3, + MethodNode $method4, + ArgumentNode $argument1, + ArgumentNode $argument2, + ArgumentNode $argument3, + ArgumentNode $argument4 + ) { + $class->getParentClass()->willReturn('stdClass'); + $class->getInterfaces()->willReturn(array('Prophecy\Doubler\Generator\MirroredInterface')); + $class->getProperties()->willReturn(array()); + $class->getMethods()->willReturn(array( + $method1, $method2, $method3, $method4 + )); + + $method1->getName()->willReturn('variadic'); + $method1->getVisibility()->willReturn('public'); + $method1->returnsReference()->willReturn(false); + $method1->isStatic()->willReturn(false); + $method1->getArguments()->willReturn(array($argument1)); + $method1->hasReturnType()->willReturn(false); + $method1->getCode()->willReturn(''); + + $method2->getName()->willReturn('variadicByRef'); + $method2->getVisibility()->willReturn('public'); + $method2->returnsReference()->willReturn(false); + $method2->isStatic()->willReturn(false); + $method2->getArguments()->willReturn(array($argument2)); + $method2->hasReturnType()->willReturn(false); + $method2->getCode()->willReturn(''); + + $method3->getName()->willReturn('variadicWithType'); + $method3->getVisibility()->willReturn('public'); + $method3->returnsReference()->willReturn(false); + $method3->isStatic()->willReturn(false); + $method3->getArguments()->willReturn(array($argument3)); + $method3->hasReturnType()->willReturn(false); + $method3->getCode()->willReturn(''); + + $method4->getName()->willReturn('variadicWithTypeByRef'); + $method4->getVisibility()->willReturn('public'); + $method4->returnsReference()->willReturn(false); + $method4->isStatic()->willReturn(false); + $method4->getArguments()->willReturn(array($argument4)); + $method4->hasReturnType()->willReturn(false); + $method4->getCode()->willReturn(''); + + $argument1->getName()->willReturn('args'); + $argument1->getTypeHint()->willReturn(null); + $argument1->isOptional()->willReturn(false); + $argument1->isPassedByReference()->willReturn(false); + $argument1->isVariadic()->willReturn(true); + $argument1->isNullable()->willReturn(false); + + $argument2->getName()->willReturn('args'); + $argument2->getTypeHint()->willReturn(null); + $argument2->isOptional()->willReturn(false); + $argument2->isPassedByReference()->willReturn(true); + $argument2->isVariadic()->willReturn(true); + $argument2->isNullable()->willReturn(false); + + $argument3->getName()->willReturn('args'); + $argument3->getTypeHint()->willReturn('\ReflectionClass'); + $argument3->isOptional()->willReturn(false); + $argument3->isPassedByReference()->willReturn(false); + $argument3->isVariadic()->willReturn(true); + $argument3->isNullable()->willReturn(false); + + $argument4->getName()->willReturn('args'); + $argument4->getTypeHint()->willReturn('\ReflectionClass'); + $argument4->isOptional()->willReturn(false); + $argument4->isPassedByReference()->willReturn(true); + $argument4->isVariadic()->willReturn(true); + $argument4->isNullable()->willReturn(false); + + $code = $this->generate('CustomClass', $class); + $expected = <<<'PHP' +namespace { +class CustomClass extends \stdClass implements \Prophecy\Doubler\Generator\MirroredInterface { + +public function variadic( ...$args) { + +} +public function variadicByRef( &...$args) { + +} +public function variadicWithType(\\ReflectionClass ...$args) { + +} +public function variadicWithTypeByRef(\\ReflectionClass &...$args) { + +} + +} +} +PHP; + $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); + $code->shouldBe($expected); + } + + function it_overrides_properly_methods_with_args_passed_by_reference( + ClassNode $class, + MethodNode $method, + ArgumentNode $argument + ) { + $class->getParentClass()->willReturn('RuntimeException'); + $class->getInterfaces()->willReturn(array('Prophecy\Doubler\Generator\MirroredInterface')); + $class->getProperties()->willReturn(array()); + $class->getMethods()->willReturn(array($method)); + + $method->getName()->willReturn('getName'); + $method->getVisibility()->willReturn('public'); + $method->isStatic()->willReturn(false); + $method->getArguments()->willReturn(array($argument)); + $method->hasReturnType()->willReturn(false); + $method->returnsReference()->willReturn(false); + $method->getCode()->willReturn('return $this->name;'); + + $argument->getName()->willReturn('fullname'); + $argument->getTypeHint()->willReturn('array'); + $argument->isOptional()->willReturn(true); + $argument->getDefault()->willReturn(null); + $argument->isPassedByReference()->willReturn(true); + $argument->isVariadic()->willReturn(false); + $argument->isNullable()->willReturn(false); + + $code = $this->generate('CustomClass', $class); + $expected =<<<'PHP' +namespace { +class CustomClass extends \RuntimeException implements \Prophecy\Doubler\Generator\MirroredInterface { + +public function getName(array &$fullname = NULL) { +return $this->name; +} + +} +} +PHP; + $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); + $code->shouldBe($expected); + } + + function it_generates_empty_class_for_empty_ClassNode(ClassNode $class) + { + $class->getParentClass()->willReturn('stdClass'); + $class->getInterfaces()->willReturn(array('Prophecy\Doubler\Generator\MirroredInterface')); + $class->getProperties()->willReturn(array()); + $class->getMethods()->willReturn(array()); + + $code = $this->generate('CustomClass', $class); + $expected =<<<'PHP' +namespace { +class CustomClass extends \stdClass implements \Prophecy\Doubler\Generator\MirroredInterface { + + +} +} +PHP; + $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); + $code->shouldBe($expected); + } + + function it_wraps_class_in_namespace_if_it_is_namespaced(ClassNode $class) + { + $class->getParentClass()->willReturn('stdClass'); + $class->getInterfaces()->willReturn(array('Prophecy\Doubler\Generator\MirroredInterface')); + $class->getProperties()->willReturn(array()); + $class->getMethods()->willReturn(array()); + + $code = $this->generate('My\Awesome\CustomClass', $class); + $expected =<<<'PHP' +namespace My\Awesome { +class CustomClass extends \stdClass implements \Prophecy\Doubler\Generator\MirroredInterface { + + +} +} +PHP; + $expected = strtr($expected, array("\r\n" => "\n", "\r" => "\n")); + $code->shouldBe($expected); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/Generator/ClassCreatorSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/Generator/ClassCreatorSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/Generator/ClassCreatorSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/Generator/ClassCreatorSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,37 @@ +beConstructedWith($generator); + } + + function it_evaluates_code_generated_by_ClassCodeGenerator($generator, ClassNode $class) + { + $generator->generate('stdClass', $class)->shouldBeCalled()->willReturn( + 'return 42;' + ); + + $this->create('stdClass', $class)->shouldReturn(42); + } + + function it_throws_an_exception_if_class_does_not_exist_after_evaluation($generator, ClassNode $class) + { + $generator->generate('CustomClass', $class)->shouldBeCalled()->willReturn( + 'return 42;' + ); + + $class->getParentClass()->willReturn('stdClass'); + $class->getInterfaces()->willReturn(array('Interface1', 'Interface2')); + + $this->shouldThrow('Prophecy\Exception\Doubler\ClassCreatorException') + ->duringCreate('CustomClass', $class); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/Generator/Node/ArgumentNodeSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/Generator/Node/ArgumentNodeSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/Generator/Node/ArgumentNodeSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/Generator/Node/ArgumentNodeSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,92 @@ +beConstructedWith('name'); + } + + function it_is_not_be_passed_by_reference_by_default() + { + $this->shouldNotBePassedByReference(); + } + + function it_is_passed_by_reference_if_marked() + { + $this->setAsPassedByReference(); + $this->shouldBePassedByReference(); + } + + function it_is_not_variadic_by_default() + { + $this->shouldNotBeVariadic(); + } + + function it_is_variadic_if_marked() + { + $this->setAsVariadic(); + $this->shouldBeVariadic(); + } + + function it_does_not_have_default_by_default() + { + $this->shouldNotHaveDefault(); + } + + function it_does_not_have_default_if_variadic() + { + $this->setDefault(null); + $this->setAsVariadic(); + $this->shouldNotHaveDefault(); + } + + function it_does_have_default_if_not_variadic() + { + $this->setDefault(null); + $this->setAsVariadic(false); + $this->hasDefault()->shouldReturn(true); + } + + function it_has_name_with_which_it_was_been_constructed() + { + $this->getName()->shouldReturn('name'); + } + + function it_has_no_typehint_by_default() + { + $this->getTypeHint()->shouldReturn(null); + } + + function its_typeHint_is_mutable() + { + $this->setTypeHint('array'); + $this->getTypeHint()->shouldReturn('array'); + } + + function it_does_not_have_default_value_by_default() + { + $this->getDefault()->shouldReturn(null); + } + + function it_is_not_optional_by_default() + { + $this->isOptional()->shouldReturn(false); + } + + function its_default_is_mutable() + { + $this->setDefault(array()); + $this->getDefault()->shouldReturn(array()); + } + + function it_is_marked_as_optional_when_default_is_set() + { + $this->setDefault(null); + $this->isOptional()->shouldReturn(true); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/Generator/Node/ClassNodeSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/Generator/Node/ClassNodeSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/Generator/Node/ClassNodeSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/Generator/Node/ClassNodeSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,185 @@ +getParentClass()->shouldReturn('stdClass'); + } + + function its_parentClass_is_mutable() + { + $this->setParentClass('Exception'); + $this->getParentClass()->shouldReturn('Exception'); + } + + function its_parentClass_is_set_to_stdClass_if_user_set_null() + { + $this->setParentClass(null); + $this->getParentClass()->shouldReturn('stdClass'); + } + + function it_does_not_implement_any_interface_by_default() + { + $this->getInterfaces()->shouldHaveCount(0); + } + + function its_addInterface_adds_item_to_the_list_of_implemented_interfaces() + { + $this->addInterface('MyInterface'); + $this->getInterfaces()->shouldHaveCount(1); + } + + function its_hasInterface_returns_true_if_class_implements_interface() + { + $this->addInterface('MyInterface'); + $this->hasInterface('MyInterface')->shouldReturn(true); + } + + function its_hasInterface_returns_false_if_class_does_not_implements_interface() + { + $this->hasInterface('MyInterface')->shouldReturn(false); + } + + function it_supports_implementation_of_multiple_interfaces() + { + $this->addInterface('MyInterface'); + $this->addInterface('MySecondInterface'); + $this->getInterfaces()->shouldHaveCount(2); + } + + function it_ignores_same_interfaces_added_twice() + { + $this->addInterface('MyInterface'); + $this->addInterface('MyInterface'); + + $this->getInterfaces()->shouldHaveCount(1); + $this->getInterfaces()->shouldReturn(array('MyInterface')); + } + + function it_does_not_have_methods_by_default() + { + $this->getMethods()->shouldHaveCount(0); + } + + function it_can_has_methods(MethodNode $method1, MethodNode $method2) + { + $method1->getName()->willReturn('__construct'); + $method2->getName()->willReturn('getName'); + + $this->addMethod($method1); + $this->addMethod($method2); + + $this->getMethods()->shouldReturn(array( + '__construct' => $method1, + 'getName' => $method2 + )); + } + + function its_hasMethod_returns_true_if_method_exists(MethodNode $method) + { + $method->getName()->willReturn('getName'); + + $this->addMethod($method); + + $this->hasMethod('getName')->shouldReturn(true); + } + + function its_getMethod_returns_method_by_name(MethodNode $method) + { + $method->getName()->willReturn('getName'); + + $this->addMethod($method); + + $this->getMethod('getName')->shouldReturn($method); + } + + function its_hasMethod_returns_false_if_method_does_not_exists() + { + $this->hasMethod('getName')->shouldReturn(false); + } + + function its_hasMethod_returns_false_if_method_has_been_removed(MethodNode $method) + { + $method->getName()->willReturn('getName'); + $this->addMethod($method); + $this->removeMethod('getName'); + + $this->hasMethod('getName')->shouldReturn(false); + } + + + function it_does_not_have_properties_by_default() + { + $this->getProperties()->shouldHaveCount(0); + } + + function it_is_able_to_have_properties() + { + $this->addProperty('title'); + $this->addProperty('text', 'private'); + $this->getProperties()->shouldReturn(array( + 'title' => 'public', + 'text' => 'private' + )); + } + + function its_addProperty_does_not_accept_unsupported_visibility() + { + $this->shouldThrow('InvalidArgumentException')->duringAddProperty('title', 'town'); + } + + function its_addProperty_lowercases_visibility_before_setting() + { + $this->addProperty('text', 'PRIVATE'); + $this->getProperties()->shouldReturn(array('text' => 'private')); + } + + function its_has_no_unextendable_methods_by_default() + { + $this->getUnextendableMethods()->shouldHaveCount(0); + } + + function its_addUnextendableMethods_adds_an_unextendable_method() + { + $this->addUnextendableMethod('testMethod'); + $this->getUnextendableMethods()->shouldHaveCount(1); + } + + function its_methods_are_extendable_by_default() + { + $this->isExtendable('testMethod')->shouldReturn(true); + } + + function its_unextendable_methods_are_not_extendable() + { + $this->addUnextendableMethod('testMethod'); + $this->isExtendable('testMethod')->shouldReturn(false); + } + + function its_addUnextendableMethods_doesnt_create_duplicates() + { + $this->addUnextendableMethod('testMethod'); + $this->addUnextendableMethod('testMethod'); + $this->getUnextendableMethods()->shouldHaveCount(1); + } + + function it_throws_an_exception_when_adding_a_method_that_isnt_extendable(MethodNode $method) + { + $this->addUnextendableMethod('testMethod'); + $method->getName()->willReturn('testMethod'); + + $expectedException = new MethodNotExtendableException( + "Method `testMethod` is not extendable, so can not be added.", + "stdClass", + "testMethod" + ); + $this->shouldThrow($expectedException)->duringAddMethod($method); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/Generator/Node/MethodNodeSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/Generator/Node/MethodNodeSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/Generator/Node/MethodNodeSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/Generator/Node/MethodNodeSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,161 @@ +beConstructedWith('getTitle'); + } + + function it_has_a_name() + { + $this->getName()->shouldReturn('getTitle'); + } + + function it_has_public_visibility_by_default() + { + $this->getVisibility()->shouldReturn('public'); + } + + function its_visibility_is_mutable() + { + $this->setVisibility('private'); + $this->getVisibility()->shouldReturn('private'); + } + + function it_is_not_static_by_default() + { + $this->shouldNotBeStatic(); + } + + function it_does_not_return_a_reference_by_default() + { + $this->returnsReference()->shouldReturn(false); + } + + function it_should_be_settable_as_returning_a_reference_through_setter() + { + $this->setReturnsReference(); + $this->returnsReference()->shouldReturn(true); + } + + function it_should_be_settable_as_static_through_setter() + { + $this->setStatic(); + $this->shouldBeStatic(); + } + + function it_accepts_only_supported_visibilities() + { + $this->shouldThrow('InvalidArgumentException')->duringSetVisibility('stealth'); + } + + function it_lowercases_visibility_before_setting_it() + { + $this->setVisibility('Public'); + $this->getVisibility()->shouldReturn('public'); + } + + function its_useParentCode_causes_method_to_call_parent(ArgumentNode $argument1, ArgumentNode $argument2) + { + $argument1->getName()->willReturn('objectName'); + $argument2->getName()->willReturn('default'); + + $argument1->isVariadic()->willReturn(false); + $argument2->isVariadic()->willReturn(true); + + $this->addArgument($argument1); + $this->addArgument($argument2); + + $this->useParentCode(); + + $this->getCode()->shouldReturn( + 'return parent::getTitle($objectName, ...$default);' + ); + } + + function its_code_is_mutable() + { + $this->setCode('echo "code";'); + $this->getCode()->shouldReturn('echo "code";'); + } + + function its_reference_returning_methods_will_generate_exceptions() + { + $this->setCode('echo "code";'); + $this->setReturnsReference(); + $this->getCode()->shouldReturn("throw new \Prophecy\Exception\Doubler\ReturnByReferenceException('Returning by reference not supported', get_class(\$this), 'getTitle');"); + } + + function its_setCode_provided_with_null_cleans_method_body() + { + $this->setCode(null); + $this->getCode()->shouldReturn(''); + } + + function it_is_constructable_with_code() + { + $this->beConstructedWith('getTitle', 'die();'); + $this->getCode()->shouldReturn('die();'); + } + + function it_does_not_have_arguments_by_default() + { + $this->getArguments()->shouldHaveCount(0); + } + + function it_supports_adding_arguments(ArgumentNode $argument1, ArgumentNode $argument2) + { + $this->addArgument($argument1); + $this->addArgument($argument2); + + $this->getArguments()->shouldReturn(array($argument1, $argument2)); + } + + function it_does_not_have_return_type_by_default() + { + $this->hasReturnType()->shouldReturn(false); + } + + function it_setReturnType_sets_return_type() + { + $returnType = 'array'; + + $this->setReturnType($returnType); + + $this->hasReturnType()->shouldReturn(true); + $this->getReturnType()->shouldReturn($returnType); + } + + function it_handles_object_return_type() + { + $this->setReturnType('object'); + $this->getReturnType()->shouldReturn(version_compare(PHP_VERSION, '7.2', '>=') ? 'object' : '\object'); + } + + function it_handles_type_aliases() + { + $this->setReturnType('double'); + $this->getReturnType()->shouldReturn(version_compare(PHP_VERSION, '7.0', '>=') ? 'float' : '\float'); + + $this->setReturnType('real'); + $this->getReturnType()->shouldReturn(version_compare(PHP_VERSION, '7.0', '>=') ? 'float' : '\float'); + + $this->setReturnType('boolean'); + $this->getReturnType()->shouldReturn(version_compare(PHP_VERSION, '7.0', '>=') ? 'bool' : '\bool'); + + $this->setReturnType('integer'); + $this->getReturnType()->shouldReturn(version_compare(PHP_VERSION, '7.0', '>=') ? 'int' : '\int'); + } + + function it_handles_null_return_type() + { + $this->setReturnType(null); + $this->getReturnType()->shouldReturn(null); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/LazyDoubleSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/LazyDoubleSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/LazyDoubleSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/LazyDoubleSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,79 @@ +beConstructedWith($doubler); + } + + function it_returns_anonymous_double_instance_by_default($doubler, ProphecySubjectInterface $double) + { + $doubler->double(null, array())->willReturn($double); + + $this->getInstance()->shouldReturn($double); + } + + function it_returns_class_double_instance_if_set($doubler, ProphecySubjectInterface $double, \ReflectionClass $class) + { + $doubler->double($class, array())->willReturn($double); + + $this->setParentClass($class); + + $this->getInstance()->shouldReturn($double); + } + + function it_returns_same_double_instance_if_called_2_times( + $doubler, + ProphecySubjectInterface $double1, + ProphecySubjectInterface $double2 + ) { + $doubler->double(null, array())->willReturn($double1); + $doubler->double(null, array())->willReturn($double2); + + $this->getInstance()->shouldReturn($double2); + $this->getInstance()->shouldReturn($double2); + } + + function its_setParentClass_throws_ClassNotFoundException_if_class_not_found() + { + $this->shouldThrow('Prophecy\Exception\Doubler\ClassNotFoundException') + ->duringSetParentClass('SomeUnexistingClass'); + } + + function its_setParentClass_throws_exception_if_prophecy_is_already_created( + $doubler, + ProphecySubjectInterface $double + ) { + $doubler->double(null, array())->willReturn($double); + + $this->getInstance(); + + $this->shouldThrow('Prophecy\Exception\Doubler\DoubleException') + ->duringSetParentClass('stdClass'); + } + + function its_addInterface_throws_InterfaceNotFoundException_if_no_interface_found() + { + $this->shouldThrow('Prophecy\Exception\Doubler\InterfaceNotFoundException') + ->duringAddInterface('SomeUnexistingInterface'); + } + + function its_addInterface_throws_exception_if_prophecy_is_already_created( + $doubler, + ProphecySubjectInterface $double + ) { + $doubler->double(null, array())->willReturn($double); + + $this->getInstance(); + + $this->shouldThrow('Prophecy\Exception\Doubler\DoubleException') + ->duringAddInterface('ArrayAccess'); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/NameGeneratorSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/NameGeneratorSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Doubler/NameGeneratorSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Doubler/NameGeneratorSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,60 @@ +getName()->willReturn('stdClass'); + $this->name($class, array())->shouldStartWith('Double\stdClass\\'); + } + + function its_name_generates_name_based_on_namespaced_class_reflection(\ReflectionClass $class) + { + $class->getName()->willReturn('Some\Custom\Class'); + $this->name($class, array())->shouldStartWith('Double\Some\Custom\Class\P'); + } + + function its_name_generates_name_based_on_interface_shortnames( + \ReflectionClass $interface1, + \ReflectionClass $interface2 + ) { + $interface1->getShortName()->willReturn('HandlerInterface'); + $interface2->getShortName()->willReturn('LoaderInterface'); + + $this->name(null, array($interface1, $interface2))->shouldStartWith( + 'Double\HandlerInterface\LoaderInterface\P' + ); + } + + function it_generates_proper_name_for_no_class_and_interfaces_list() + { + $this->name(null, array())->shouldStartWith('Double\stdClass\P'); + } + + function its_name_generates_name_based_only_on_class_if_its_available( + \ReflectionClass $class, + \ReflectionClass $interface1, + \ReflectionClass $interface2 + ) { + $class->getName()->willReturn('Some\Custom\Class'); + $interface1->getShortName()->willReturn('HandlerInterface'); + $interface2->getShortName()->willReturn('LoaderInterface'); + + $this->name($class, array($interface1, $interface2))->shouldStartWith( + 'Double\Some\Custom\Class\P' + ); + } + + public function getMatchers() + { + return array( + 'startWith' => function ($subject, $string) { + return 0 === strpos($subject, $string); + }, + ); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Call/UnexpectedCallExceptionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Call/UnexpectedCallExceptionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Call/UnexpectedCallExceptionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Call/UnexpectedCallExceptionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,30 @@ +beConstructedWith('msg', $objectProphecy, 'getName', array('arg1', 'arg2')); + } + + function it_is_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prophecy\ObjectProphecyException'); + } + + function it_exposes_method_name_through_getter() + { + $this->getMethodName()->shouldReturn('getName'); + } + + function it_exposes_arguments_through_getter() + { + $this->getArguments()->shouldReturn(array('arg1', 'arg2')); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Doubler/ClassCreatorExceptionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Doubler/ClassCreatorExceptionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Doubler/ClassCreatorExceptionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Doubler/ClassCreatorExceptionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,26 @@ +beConstructedWith('', $node); + } + + function it_is_a_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Exception'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\DoublerException'); + } + + function it_contains_a_reflected_node($node) + { + $this->getClassNode()->shouldReturn($node); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Doubler/ClassMirrorExceptionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Doubler/ClassMirrorExceptionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Doubler/ClassMirrorExceptionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Doubler/ClassMirrorExceptionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,24 @@ +beConstructedWith('', $class); + } + + function it_is_a_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Exception'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\DoublerException'); + } + + function it_contains_a_reflected_class_link($class) + { + $this->getReflectedClass()->shouldReturn($class); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Doubler/ClassNotFoundExceptionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Doubler/ClassNotFoundExceptionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Doubler/ClassNotFoundExceptionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Doubler/ClassNotFoundExceptionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,25 @@ +beConstructedWith('msg', 'CustomClass'); + } + + function it_is_a_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Exception'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\DoubleException'); + } + + function its_getClassname_returns_classname() + { + $this->getClassname()->shouldReturn('CustomClass'); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Doubler/DoubleExceptionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Doubler/DoubleExceptionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Doubler/DoubleExceptionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Doubler/DoubleExceptionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,14 @@ +shouldBeAnInstanceOf('RuntimeException'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\DoublerException'); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Doubler/InterfaceNotFoundExceptionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Doubler/InterfaceNotFoundExceptionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Doubler/InterfaceNotFoundExceptionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Doubler/InterfaceNotFoundExceptionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,24 @@ +beConstructedWith('msg', 'CustomInterface'); + } + + function it_extends_ClassNotFoundException() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Doubler\ClassNotFoundException'); + } + + function its_getClassname_returns_classname() + { + $this->getClassname()->shouldReturn('CustomInterface'); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Doubler/MethodNotExtendableExceptionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Doubler/MethodNotExtendableExceptionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Doubler/MethodNotExtendableExceptionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Doubler/MethodNotExtendableExceptionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,29 @@ +beConstructedWith('', 'User', 'getName'); + } + + function it_is_DoubleException() + { + $this->shouldHaveType('Prophecy\Exception\Doubler\DoubleException'); + } + + function it_has_MethodName() + { + $this->getMethodName()->shouldReturn('getName'); + } + + function it_has_classname() + { + $this->getClassName()->shouldReturn('User'); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Doubler/MethodNotFoundExceptionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Doubler/MethodNotFoundExceptionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Doubler/MethodNotFoundExceptionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Doubler/MethodNotFoundExceptionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,40 @@ +beConstructedWith('', 'User', 'getName', array(1, 2, 3)); + } + + function it_is_DoubleException() + { + $this->shouldHaveType('Prophecy\Exception\Doubler\DoubleException'); + } + + function it_has_MethodName() + { + $this->getMethodName()->shouldReturn('getName'); + } + + function it_has_classnamej() + { + $this->getClassname()->shouldReturn('User'); + } + + function it_has_an_arguments_list() + { + $this->getArguments()->shouldReturn(array(1, 2, 3)); + } + + function it_has_a_default_null_argument_list() + { + $this->beConstructedWith('', 'User', 'getName'); + $this->getArguments()->shouldReturn(null); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Prediction/AggregateExceptionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Prediction/AggregateExceptionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Prediction/AggregateExceptionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Prediction/AggregateExceptionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,64 @@ +beConstructedWith(null); + } + + function it_is_prediction_exception() + { + $this->shouldBeAnInstanceOf('RuntimeException'); + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prediction\PredictionException'); + } + + function it_can_store_objectProphecy_link(ObjectProphecy $object) + { + $this->setObjectProphecy($object); + $this->getObjectProphecy()->shouldReturn($object); + } + + function it_should_not_have_exceptions_at_the_beginning() + { + $this->getExceptions()->shouldHaveCount(0); + } + + function it_should_append_exception_through_append_method(PredictionException $exception) + { + $exception->getMessage()->willReturn('Exception #1'); + + $this->append($exception); + + $this->getExceptions()->shouldReturn(array($exception)); + } + + function it_should_update_message_during_append(PredictionException $exception) + { + $exception->getMessage()->willReturn('Exception #1'); + + $this->append($exception); + + $this->getMessage()->shouldReturn('Exception #1'); + } + + function it_should_update_message_during_append_more_exceptions( + PredictionException $exception1, + PredictionException $exception2 + ) { + $exception1->getMessage()->willReturn('Exception #1'); + $exception2->getMessage()->willReturn('Exception #2'); + + $this->append($exception1); + $this->getMessage()->shouldReturn('Exception #1'); + + $this->append($exception2); + $this->getMessage()->shouldReturn("Exception #1\nException #2"); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Prediction/NoCallsExceptionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Prediction/NoCallsExceptionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Prediction/NoCallsExceptionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Prediction/NoCallsExceptionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,27 @@ +getObjectProphecy()->willReturn($objectProphecy); + + $this->beConstructedWith('message', $methodProphecy); + } + + function it_is_PredictionException() + { + $this->shouldHaveType('Prophecy\Exception\Prediction\PredictionException'); + } + + function it_extends_MethodProphecyException() + { + $this->shouldHaveType('Prophecy\Exception\Prophecy\MethodProphecyException'); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Prediction/UnexpectedCallsCountExceptionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Prediction/UnexpectedCallsCountExceptionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Prediction/UnexpectedCallsCountExceptionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Prediction/UnexpectedCallsCountExceptionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,27 @@ +getObjectProphecy()->willReturn($objectProphecy); + + $this->beConstructedWith('message', $methodProphecy, 5, array($call1, $call2)); + } + + function it_extends_UnexpectedCallsException() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prediction\UnexpectedCallsException'); + } + + function it_should_expose_expectedCount_through_getter() + { + $this->getExpectedCount()->shouldReturn(5); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Prediction/UnexpectedCallsExceptionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Prediction/UnexpectedCallsExceptionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Prediction/UnexpectedCallsExceptionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Prediction/UnexpectedCallsExceptionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,33 @@ +getObjectProphecy()->willReturn($objectProphecy); + + $this->beConstructedWith('message', $methodProphecy, array($call1, $call2)); + } + + function it_is_PredictionException() + { + $this->shouldHaveType('Prophecy\Exception\Prediction\PredictionException'); + } + + function it_extends_MethodProphecyException() + { + $this->shouldHaveType('Prophecy\Exception\Prophecy\MethodProphecyException'); + } + + function it_should_expose_calls_list_through_getter($call1, $call2) + { + $this->getCalls()->shouldReturn(array($call1, $call2)); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Prophecy/MethodProphecyExceptionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Prophecy/MethodProphecyExceptionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Prophecy/MethodProphecyExceptionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Prophecy/MethodProphecyExceptionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,28 @@ +getObjectProphecy()->willReturn($objectProphecy); + + $this->beConstructedWith('message', $methodProphecy); + } + + function it_extends_DoubleException() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prophecy\ObjectProphecyException'); + } + + function it_holds_a_stub_reference($methodProphecy) + { + $this->getMethodProphecy()->shouldReturn($methodProphecy); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Prophecy/ObjectProphecyExceptionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Prophecy/ObjectProphecyExceptionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Exception/Prophecy/ObjectProphecyExceptionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Exception/Prophecy/ObjectProphecyExceptionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,24 @@ +beConstructedWith('message', $objectProphecy); + } + + function it_should_be_a_prophecy_exception() + { + $this->shouldBeAnInstanceOf('Prophecy\Exception\Prophecy\ProphecyException'); + } + + function it_holds_double_reference($objectProphecy) + { + $this->getObjectProphecy()->shouldReturn($objectProphecy); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Prediction/CallbackPredictionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Prediction/CallbackPredictionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Prediction/CallbackPredictionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Prediction/CallbackPredictionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,34 @@ +beConstructedWith('get_class'); + } + + function it_is_prediction() + { + $this->shouldHaveType('Prophecy\Prediction\PredictionInterface'); + } + + function it_proxies_call_to_callback(ObjectProphecy $object, MethodProphecy $method, Call $call) + { + $returnFirstCallCallback = function ($calls, $object, $method) { + throw new RuntimeException; + }; + + $this->beConstructedWith($returnFirstCallCallback); + + $this->shouldThrow('RuntimeException')->duringCheck(array($call), $object, $method); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Prediction/CallPredictionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Prediction/CallPredictionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Prediction/CallPredictionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Prediction/CallPredictionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,42 @@ +shouldHaveType('Prophecy\Prediction\PredictionInterface'); + } + + function it_does_nothing_if_there_is_more_than_one_call_been_made( + ObjectProphecy $object, + MethodProphecy $method, + Call $call + ) { + $this->check(array($call), $object, $method)->shouldReturn(null); + } + + function it_throws_NoCallsException_if_no_calls_found( + ObjectProphecy $object, + MethodProphecy $method, + ArgumentsWildcard $arguments + ) { + $method->getObjectProphecy()->willReturn($object); + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $arguments->__toString()->willReturn('123'); + $object->reveal()->willReturn(new \stdClass()); + $object->findProphecyMethodCalls('getName', Argument::any())->willReturn(array()); + + $this->shouldThrow('Prophecy\Exception\Prediction\NoCallsException') + ->duringCheck(array(), $object, $method); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Prediction/CallTimesPredictionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Prediction/CallTimesPredictionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Prediction/CallTimesPredictionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Prediction/CallTimesPredictionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,53 @@ +beConstructedWith(2); + } + + function it_is_prediction() + { + $this->shouldHaveType('Prophecy\Prediction\PredictionInterface'); + } + + function it_does_nothing_if_there_were_exact_amount_of_calls_being_made( + ObjectProphecy $object, + MethodProphecy $method, + Call $call1, + Call $call2 + ) { + $this->check(array($call1, $call2), $object, $method)->shouldReturn(null); + } + + function it_throws_UnexpectedCallsCountException_if_calls_found( + ObjectProphecy $object, + MethodProphecy $method, + Call $call, + ArgumentsWildcard $arguments + ) { + $object->reveal()->willReturn(new \stdClass()); + $object->findProphecyMethodCalls('getName', Argument::any())->willReturn(array()); + $method->getObjectProphecy()->willReturn($object); + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $arguments->__toString()->willReturn('123'); + + $call->getMethodName()->willReturn('getName'); + $call->getArguments()->willReturn(array(5, 4, 'three')); + $call->getCallPlace()->willReturn('unknown'); + + $this->shouldThrow('Prophecy\Exception\Prediction\UnexpectedCallsCountException') + ->duringCheck(array($call), $object, $method); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Prediction/NoCallsPredictionSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Prediction/NoCallsPredictionSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Prediction/NoCallsPredictionSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Prediction/NoCallsPredictionSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,42 @@ +shouldHaveType('Prophecy\Prediction\PredictionInterface'); + } + + function it_does_nothing_if_there_is_no_calls_made(ObjectProphecy $object, MethodProphecy $method) + { + $this->check(array(), $object, $method)->shouldReturn(null); + } + + function it_throws_UnexpectedCallsException_if_calls_found( + ObjectProphecy $object, + MethodProphecy $method, + Call $call, + ArgumentsWildcard $arguments + ) { + $object->reveal()->willReturn(new \stdClass); + $method->getObjectProphecy()->willReturn($object); + $method->getMethodName()->willReturn('getName'); + $method->getArgumentsWildcard()->willReturn($arguments); + $arguments->__toString()->willReturn('123'); + + $call->getMethodName()->willReturn('getName'); + $call->getArguments()->willReturn(array(5, 4, 'three')); + $call->getCallPlace()->willReturn('unknown'); + + $this->shouldThrow('Prophecy\Exception\Prediction\UnexpectedCallsException') + ->duringCheck(array($call), $object, $method); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Promise/CallbackPromiseSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Promise/CallbackPromiseSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Promise/CallbackPromiseSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Promise/CallbackPromiseSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,96 @@ +beConstructedWith('get_class'); + } + + function it_is_promise() + { + $this->shouldBeAnInstanceOf('Prophecy\Promise\PromiseInterface'); + } + + function it_should_execute_closure_callback(ObjectProphecy $object, MethodProphecy $method) + { + $firstArgumentCallback = function ($args) { + return $args[0]; + }; + + $this->beConstructedWith($firstArgumentCallback); + + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + + function it_should_execute_static_array_callback(ObjectProphecy $object, MethodProphecy $method) + { + $firstArgumentCallback = array('spec\Prophecy\Promise\ClassCallback', 'staticCallbackMethod'); + + $this->beConstructedWith($firstArgumentCallback); + + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + + function it_should_execute_instance_array_callback(ObjectProphecy $object, MethodProphecy $method) + { + $class = new ClassCallback(); + $firstArgumentCallback = array($class, 'callbackMethod'); + + $this->beConstructedWith($firstArgumentCallback); + + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + + function it_should_execute_string_function_callback(ObjectProphecy $object, MethodProphecy $method) + { + $firstArgumentCallback = 'spec\Prophecy\Promise\functionCallbackFirstArgument'; + + $this->beConstructedWith($firstArgumentCallback); + + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + +} + +/** + * Class used to test callbackpromise + * + * @param array + * @return string + */ +class ClassCallback +{ + /** + * @param array $args + */ + function callbackMethod($args) + { + return $args[0]; + } + + /** + * @param array $args + */ + static function staticCallbackMethod($args) + { + return $args[0]; + } +} + +/** + * Callback function used to test callbackpromise + * + * @param array + * @return string + */ +function functionCallbackFirstArgument($args) +{ + return $args[0]; +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Promise/ReturnArgumentPromiseSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Promise/ReturnArgumentPromiseSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Promise/ReturnArgumentPromiseSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Promise/ReturnArgumentPromiseSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,31 @@ +shouldBeAnInstanceOf('Prophecy\Promise\PromiseInterface'); + } + + function it_should_return_first_argument_if_provided(ObjectProphecy $object, MethodProphecy $method) + { + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('one'); + } + + function it_should_return_null_if_no_arguments_provided(ObjectProphecy $object, MethodProphecy $method) + { + $this->execute(array(), $object, $method)->shouldReturn(null); + } + + function it_should_return_nth_argument_if_provided(ObjectProphecy $object, MethodProphecy $method) + { + $this->beConstructedWith(1); + $this->execute(array('one', 'two'), $object, $method)->shouldReturn('two'); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Promise/ReturnPromiseSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Promise/ReturnPromiseSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Promise/ReturnPromiseSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Promise/ReturnPromiseSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,49 @@ +beConstructedWith(array(42)); + } + + function it_is_promise() + { + $this->shouldBeAnInstanceOf('Prophecy\Promise\PromiseInterface'); + } + + function it_returns_value_it_was_constructed_with(ObjectProphecy $object, MethodProphecy $method) + { + $this->execute(array(), $object, $method)->shouldReturn(42); + } + + function it_always_returns_last_value_left_in_the_return_values(ObjectProphecy $object, MethodProphecy $method) + { + $this->execute(array(), $object, $method)->shouldReturn(42); + $this->execute(array(), $object, $method)->shouldReturn(42); + } + + function it_consequently_returns_multiple_values_it_was_constructed_with( + ObjectProphecy $object, + MethodProphecy $method + ) { + $this->beConstructedWith(array(42, 24, 12)); + + $this->execute(array(), $object, $method)->shouldReturn(42); + $this->execute(array(), $object, $method)->shouldReturn(24); + $this->execute(array(), $object, $method)->shouldReturn(12); + } + + function it_returns_null_if_constructed_with_empty_array(ObjectProphecy $object, MethodProphecy $method) + { + $this->beConstructedWith(array()); + + $this->execute(array(), $object, $method)->shouldReturn(null); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Promise/ThrowPromiseSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Promise/ThrowPromiseSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Promise/ThrowPromiseSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Promise/ThrowPromiseSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,92 @@ +beConstructedWith('RuntimeException'); + } + + function it_is_promise() + { + $this->shouldBeAnInstanceOf('Prophecy\Promise\PromiseInterface'); + } + + function it_instantiates_and_throws_exception_from_provided_classname(ObjectProphecy $object, MethodProphecy $method) + { + $this->beConstructedWith('InvalidArgumentException'); + + $this->shouldThrow('InvalidArgumentException') + ->duringExecute(array(), $object, $method); + } + + function it_instantiates_exceptions_with_required_arguments(ObjectProphecy $object, MethodProphecy $method) + { + $this->beConstructedWith('spec\Prophecy\Promise\RequiredArgumentException'); + + $this->shouldThrow('spec\Prophecy\Promise\RequiredArgumentException') + ->duringExecute(array(), $object, $method); + } + + function it_throws_provided_exception(ObjectProphecy $object, MethodProphecy $method) + { + $this->beConstructedWith($exc = new \RuntimeException('Some exception')); + + $this->shouldThrow($exc)->duringExecute(array(), $object, $method); + } + + function it_throws_error_instances(ObjectProphecy $object, MethodProphecy $method) + { + if (!class_exists('\Error')) { + throw new SkippingException('The class Error, introduced in PHP 7, does not exist'); + } + + $this->beConstructedWith($exc = new \Error('Error exception')); + + $this->shouldThrow($exc)->duringExecute(array(), $object, $method); + } + + function it_throws_errors_by_class_name() + { + if (!class_exists('\Error')) { + throw new SkippingException('The class Error, introduced in PHP 7, does not exist'); + } + + $this->beConstructedWith('\Error'); + + $this->shouldNotThrow('Prophecy\Exception\InvalidArgumentException')->duringInstantiation(); + } + + function it_does_not_throw_something_that_is_not_throwable_by_class_name() + { + $this->beConstructedWith('\stdClass'); + + $this->shouldThrow('Prophecy\Exception\InvalidArgumentException')->duringInstantiation(); + } + + function it_does_not_throw_something_that_is_not_throwable_by_instance() + { + $this->beConstructedWith(new \stdClass()); + + $this->shouldThrow('Prophecy\Exception\InvalidArgumentException')->duringInstantiation(); + } + + function it_throws_an_exception_by_class_name() + { + $this->beConstructedWith('\Exception'); + + $this->shouldNotThrow('Prophecy\Exception\InvalidArgumentException')->duringInstantiation(); + } +} + +class RequiredArgumentException extends \Exception +{ + final public function __construct($message, $code) {} +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Prophecy/MethodProphecySpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Prophecy/MethodProphecySpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Prophecy/MethodProphecySpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Prophecy/MethodProphecySpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,411 @@ +reveal()->willReturn($reflection); + + $this->beConstructedWith($objectProphecy, 'getName', null); + } + + function it_is_initializable() + { + $this->shouldHaveType('Prophecy\Prophecy\MethodProphecy'); + } + + function its_constructor_throws_MethodNotFoundException_for_unexisting_method($objectProphecy) + { + $this->shouldThrow('Prophecy\Exception\Doubler\MethodNotFoundException')->during( + '__construct', array($objectProphecy, 'getUnexisting', null) + ); + } + + function its_constructor_throws_MethodProphecyException_for_final_methods($objectProphecy, ClassWithFinalMethod $subject) + { + $objectProphecy->reveal()->willReturn($subject); + + $this->shouldThrow('Prophecy\Exception\Prophecy\MethodProphecyException')->during( + '__construct', array($objectProphecy, 'finalMethod', null) + ); + } + + function its_constructor_transforms_array_passed_as_3rd_argument_to_ArgumentsWildcard( + $objectProphecy + ) + { + $this->beConstructedWith($objectProphecy, 'getName', array(42, 33)); + + $wildcard = $this->getArgumentsWildcard(); + $wildcard->shouldNotBe(null); + $wildcard->__toString()->shouldReturn('exact(42), exact(33)'); + } + + function its_constructor_does_not_touch_third_argument_if_it_is_null($objectProphecy) + { + $this->beConstructedWith($objectProphecy, 'getName', null); + + $wildcard = $this->getArgumentsWildcard(); + $wildcard->shouldBe(null); + } + + function its_constructor_records_default_callback_promise_for_return_type_hinted_methods( + $objectProphecy, ClassWithVoidTypeHintedMethods $subject + ) + { + // Return void type hint language feature only introduced in >=7.1 + if (version_compare(PHP_VERSION, '7.1', '>=')) + { + $objectProphecy->addMethodProphecy(Argument::cetera())->willReturn(null); + $objectProphecy->reveal()->willReturn($subject); + + $this->beConstructedWith($objectProphecy, 'getVoid'); + $this->getPromise()->shouldBeAnInstanceOf(CallbackPromise::class); + } + } + + function its_constructor_records_promise_that_returns_null_for_void_type_hinted_methods( + $objectProphecy, ClassWithVoidTypeHintedMethods $subject + ) + { + // Return void type hint language feature only introduced in >=7.1 + if (version_compare(PHP_VERSION, '7.1', '>=')) + { + $objectProphecy->addMethodProphecy(Argument::cetera())->willReturn(null); + $objectProphecy->reveal()->willReturn($subject); + + $this->beConstructedWith($objectProphecy, 'getVoid'); + $this->getPromise()->execute([], $objectProphecy, $this)->shouldBeNull(); + } + } + + function its_constructor_adds_itself_to_ObjectProphecy_for_return_type_hinted_methods( + $objectProphecy, ClassWithVoidTypeHintedMethods $subject + ) + { + // Return void type hint language feature only introduced in >=7.1 + if (version_compare(PHP_VERSION, '7.1', '>=')) + { + $objectProphecy->addMethodProphecy(Argument::cetera())->willReturn(null); + $objectProphecy->reveal()->willReturn($subject); + + $this->beConstructedWith($objectProphecy, 'getVoid'); + $objectProphecy->addMethodProphecy($this)->shouldHaveBeenCalled(); + } + } + + function it_records_promise_through_will_method(PromiseInterface $promise, $objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->will($promise); + $this->getPromise()->shouldReturn($promise); + } + + function it_adds_itself_to_ObjectProphecy_during_call_to_will(PromiseInterface $objectProphecy, $promise) + { + $objectProphecy->addMethodProphecy($this)->shouldBeCalled(); + + $this->will($promise); + } + + function it_adds_ReturnPromise_during_willReturn_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->willReturn(42); + $this->getPromise()->shouldBeAnInstanceOf('Prophecy\Promise\ReturnPromise'); + } + + function it_adds_ThrowPromise_during_willThrow_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->willThrow('RuntimeException'); + $this->getPromise()->shouldBeAnInstanceOf('Prophecy\Promise\ThrowPromise'); + } + + function it_adds_ReturnArgumentPromise_during_willReturnArgument_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->willReturnArgument(); + $this->getPromise()->shouldBeAnInstanceOf('Prophecy\Promise\ReturnArgumentPromise'); + } + + function it_adds_ReturnArgumentPromise_during_willReturnArgument_call_with_index_argument($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->willReturnArgument(1); + $promise = $this->getPromise(); + $promise->shouldBeAnInstanceOf('Prophecy\Promise\ReturnArgumentPromise'); + $promise->execute(array('one', 'two'), $objectProphecy, $this)->shouldReturn('two'); + } + + function it_adds_CallbackPromise_during_will_call_with_callback_argument($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $callback = function () {}; + + $this->will($callback); + $this->getPromise()->shouldBeAnInstanceOf('Prophecy\Promise\CallbackPromise'); + } + + function it_records_prediction_through_should_method(PredictionInterface $prediction, $objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->callOnWrappedObject('should', array($prediction)); + $this->getPrediction()->shouldReturn($prediction); + } + + function it_adds_CallbackPrediction_during_should_call_with_callback_argument($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $callback = function () {}; + + $this->callOnWrappedObject('should', array($callback)); + $this->getPrediction()->shouldBeAnInstanceOf('Prophecy\Prediction\CallbackPrediction'); + } + + function it_adds_itself_to_ObjectProphecy_during_call_to_should($objectProphecy, PredictionInterface $prediction) + { + $objectProphecy->addMethodProphecy($this)->shouldBeCalled(); + + $this->callOnWrappedObject('should', array($prediction)); + } + + function it_adds_CallPrediction_during_shouldBeCalled_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->callOnWrappedObject('shouldBeCalled', array()); + $this->getPrediction()->shouldBeAnInstanceOf('Prophecy\Prediction\CallPrediction'); + } + + function it_adds_NoCallsPrediction_during_shouldNotBeCalled_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->callOnWrappedObject('shouldNotBeCalled', array()); + $this->getPrediction()->shouldBeAnInstanceOf('Prophecy\Prediction\NoCallsPrediction'); + } + + function it_adds_CallTimesPrediction_during_shouldBeCalledTimes_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->callOnWrappedObject('shouldBeCalledTimes', array(5)); + $this->getPrediction()->shouldBeAnInstanceOf('Prophecy\Prediction\CallTimesPrediction'); + } + + function it_adds_CallTimesPrediction_during_shouldBeCalledOnce_call($objectProphecy) + { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->callOnWrappedObject('shouldBeCalledOnce'); + $this->getPrediction()->shouldBeAnInstanceOf('Prophecy\Prediction\CallTimesPrediction'); + } + + function it_checks_prediction_via_shouldHave_method_call( + $objectProphecy, + ArgumentsWildcard $arguments, + PredictionInterface $prediction, + Call $call1, + Call $call2 + ) { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->shouldBeCalled(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->withArguments($arguments); + $this->callOnWrappedObject('shouldHave', array($prediction)); + } + + function it_sets_return_promise_during_shouldHave_call_if_none_was_set_before( + $objectProphecy, + ArgumentsWildcard $arguments, + PredictionInterface $prediction, + Call $call1, + Call $call2 + ) { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->shouldBeCalled(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->withArguments($arguments); + $this->callOnWrappedObject('shouldHave', array($prediction)); + + $this->getPromise()->shouldReturnAnInstanceOf('Prophecy\Promise\ReturnPromise'); + } + + function it_does_not_set_return_promise_during_shouldHave_call_if_it_was_set_before( + $objectProphecy, + ArgumentsWildcard $arguments, + PredictionInterface $prediction, + Call $call1, + Call $call2, + PromiseInterface $promise + ) { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->shouldBeCalled(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->will($promise); + $this->withArguments($arguments); + $this->callOnWrappedObject('shouldHave', array($prediction)); + + $this->getPromise()->shouldReturn($promise); + } + + function it_records_checked_predictions( + $objectProphecy, + ArgumentsWildcard $arguments, + PredictionInterface $prediction1, + PredictionInterface $prediction2, + Call $call1, + Call $call2, + PromiseInterface $promise + ) { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction1->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->willReturn(); + $prediction2->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->willReturn(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->will($promise); + $this->withArguments($arguments); + $this->callOnWrappedObject('shouldHave', array($prediction1)); + $this->callOnWrappedObject('shouldHave', array($prediction2)); + + $this->getCheckedPredictions()->shouldReturn(array($prediction1, $prediction2)); + } + + function it_records_even_failed_checked_predictions( + $objectProphecy, + ArgumentsWildcard $arguments, + PredictionInterface $prediction, + Call $call1, + Call $call2, + PromiseInterface $promise + ) { + $objectProphecy->addMethodProphecy($this)->willReturn(null); + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->willThrow(new \RuntimeException()); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->will($promise); + $this->withArguments($arguments); + + try { + $this->callOnWrappedObject('shouldHave', array($prediction)); + } catch (\Exception $e) {} + + $this->getCheckedPredictions()->shouldReturn(array($prediction)); + } + + function it_checks_prediction_via_shouldHave_method_call_with_callback( + $objectProphecy, + ArgumentsWildcard $arguments, + Call $call1, + Call $call2 + ) { + $callback = function ($calls, $object, $method) { + throw new \RuntimeException; + }; + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + + $this->withArguments($arguments); + $this->shouldThrow('RuntimeException')->duringShouldHave($callback); + } + + function it_does_nothing_during_checkPrediction_if_no_prediction_set() + { + $this->checkPrediction()->shouldReturn(null); + } + + function it_checks_set_prediction_during_checkPrediction( + $objectProphecy, + ArgumentsWildcard $arguments, + PredictionInterface $prediction, + Call $call1, + Call $call2 + ) { + $prediction->check(array($call1, $call2), $objectProphecy->getWrappedObject(), $this)->shouldBeCalled(); + $objectProphecy->findProphecyMethodCalls('getName', $arguments)->willReturn(array($call1, $call2)); + $objectProphecy->addMethodProphecy($this)->willReturn(null); + + $this->withArguments($arguments); + $this->callOnWrappedObject('should', array($prediction)); + $this->checkPrediction(); + } + + function it_links_back_to_ObjectProphecy_through_getter($objectProphecy) + { + $this->getObjectProphecy()->shouldReturn($objectProphecy); + } + + function it_has_MethodName() + { + $this->getMethodName()->shouldReturn('getName'); + } + + function it_contains_ArgumentsWildcard_it_was_constructed_with($objectProphecy, ArgumentsWildcard $wildcard) + { + $this->beConstructedWith($objectProphecy, 'getName', $wildcard); + + $this->getArgumentsWildcard()->shouldReturn($wildcard); + } + + function its_ArgumentWildcard_is_mutable_through_setter(ArgumentsWildcard $wildcard) + { + $this->withArguments($wildcard); + + $this->getArgumentsWildcard()->shouldReturn($wildcard); + } + + function its_withArguments_transforms_passed_array_into_ArgumentsWildcard() + { + $this->withArguments(array(42, 33)); + + $wildcard = $this->getArgumentsWildcard(); + $wildcard->shouldNotBe(null); + $wildcard->__toString()->shouldReturn('exact(42), exact(33)'); + } + + function its_withArguments_throws_exception_if_wrong_arguments_provided() + { + $this->shouldThrow('Prophecy\Exception\InvalidArgumentException')->duringWithArguments(42); + } +} + +// Return void type hint language feature only introduced in >=7.1 +if (version_compare(PHP_VERSION, '7.1', '>=')) { + class ClassWithVoidTypeHintedMethods + { + public function getVoid(): void + { + } + } +} else { + class ClassWithVoidTypeHintedMethods + { + } +} \ No newline at end of file diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Prophecy/ObjectProphecySpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Prophecy/ObjectProphecySpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Prophecy/ObjectProphecySpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Prophecy/ObjectProphecySpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,283 @@ +beConstructedWith($lazyDouble); + + $lazyDouble->getInstance()->willReturn($double); + } + + function it_implements_ProphecyInterface() + { + $this->shouldBeAnInstanceOf('Prophecy\Prophecy\ProphecyInterface'); + } + + function it_sets_parentClass_during_willExtend_call($lazyDouble) + { + $lazyDouble->setParentClass('123')->shouldBeCalled(); + + $this->willExtend('123'); + } + + function it_adds_interface_during_willImplement_call($lazyDouble) + { + $lazyDouble->addInterface('222')->shouldBeCalled(); + + $this->willImplement('222'); + } + + function it_sets_constructor_arguments_during_willBeConstructedWith_call($lazyDouble) + { + $lazyDouble->setArguments(array(1, 2, 5))->shouldBeCalled(); + + $this->willBeConstructedWith(array(1, 2, 5)); + } + + function it_does_not_have_method_prophecies_by_default() + { + $this->getMethodProphecies()->shouldHaveCount(0); + } + + function it_should_get_method_prophecies_by_method_name( + MethodProphecy $method1, + MethodProphecy $method2, + ArgumentsWildcard $arguments + ) { + $method1->getMethodName()->willReturn('getName'); + $method1->getArgumentsWildcard()->willReturn($arguments); + $method2->getMethodName()->willReturn('setName'); + $method2->getArgumentsWildcard()->willReturn($arguments); + + $this->addMethodProphecy($method1); + $this->addMethodProphecy($method2); + + $methods = $this->getMethodProphecies('setName'); + $methods->shouldHaveCount(1); + $methods[0]->getMethodName()->shouldReturn('setName'); + } + + function it_should_return_empty_array_if_no_method_prophecies_found() + { + $methods = $this->getMethodProphecies('setName'); + $methods->shouldHaveCount(0); + } + + function it_should_proxy_makeProphecyMethodCall_to_CallCenter($lazyDouble, CallCenter $callCenter) + { + $this->beConstructedWith($lazyDouble, $callCenter); + + $callCenter->makeCall($this->getWrappedObject(), 'setName', array('everzet'))->willReturn(42); + + $this->makeProphecyMethodCall('setName', array('everzet'))->shouldReturn(42); + } + + function it_should_reveal_arguments_and_return_values_from_callCenter( + $lazyDouble, + CallCenter $callCenter, + RevealerInterface $revealer + ) { + $this->beConstructedWith($lazyDouble, $callCenter, $revealer); + + $revealer->reveal(array('question'))->willReturn(array('life')); + $revealer->reveal('answer')->willReturn(42); + + $callCenter->makeCall($this->getWrappedObject(), 'setName', array('life'))->willReturn('answer'); + + $this->makeProphecyMethodCall('setName', array('question'))->shouldReturn(42); + } + + function it_should_proxy_getProphecyMethodCalls_to_CallCenter( + $lazyDouble, + CallCenter $callCenter, + ArgumentsWildcard $wildcard, + Call $call + ) { + $this->beConstructedWith($lazyDouble, $callCenter); + + $callCenter->findCalls('setName', $wildcard)->willReturn(array($call)); + + $this->findProphecyMethodCalls('setName', $wildcard)->shouldReturn(array($call)); + } + + function its_addMethodProphecy_adds_method_prophecy( + MethodProphecy $methodProphecy, + ArgumentsWildcard $argumentsWildcard + ) { + $methodProphecy->getArgumentsWildcard()->willReturn($argumentsWildcard); + $methodProphecy->getMethodName()->willReturn('getUsername'); + + $this->addMethodProphecy($methodProphecy); + + $this->getMethodProphecies()->shouldReturn(array( + 'getUsername' => array($methodProphecy) + )); + } + + function its_addMethodProphecy_handles_prophecies_with_different_arguments( + MethodProphecy $methodProphecy1, + MethodProphecy $methodProphecy2, + ArgumentsWildcard $argumentsWildcard1, + ArgumentsWildcard $argumentsWildcard2 + ) { + $methodProphecy1->getArgumentsWildcard()->willReturn($argumentsWildcard1); + $methodProphecy1->getMethodName()->willReturn('getUsername'); + + $methodProphecy2->getArgumentsWildcard()->willReturn($argumentsWildcard2); + $methodProphecy2->getMethodName()->willReturn('getUsername'); + + $this->addMethodProphecy($methodProphecy1); + $this->addMethodProphecy($methodProphecy2); + + $this->getMethodProphecies()->shouldReturn(array( + 'getUsername' => array( + $methodProphecy1, + $methodProphecy2, + ) + )); + } + + function its_addMethodProphecy_handles_prophecies_for_different_methods( + MethodProphecy $methodProphecy1, + MethodProphecy $methodProphecy2, + ArgumentsWildcard $argumentsWildcard1, + ArgumentsWildcard $argumentsWildcard2 + ) { + $methodProphecy1->getArgumentsWildcard()->willReturn($argumentsWildcard1); + $methodProphecy1->getMethodName()->willReturn('getUsername'); + + $methodProphecy2->getArgumentsWildcard()->willReturn($argumentsWildcard2); + $methodProphecy2->getMethodName()->willReturn('isUsername'); + + $this->addMethodProphecy($methodProphecy1); + $this->addMethodProphecy($methodProphecy2); + + $this->getMethodProphecies()->shouldReturn(array( + 'getUsername' => array( + $methodProphecy1 + ), + 'isUsername' => array( + $methodProphecy2 + ) + )); + } + + function its_addMethodProphecy_throws_exception_when_method_has_no_ArgumentsWildcard(MethodProphecy $methodProphecy) + { + $methodProphecy->getArgumentsWildcard()->willReturn(null); + $methodProphecy->getObjectProphecy()->willReturn($this); + $methodProphecy->getMethodName()->willReturn('getTitle'); + + $this->shouldThrow('Prophecy\Exception\Prophecy\MethodProphecyException')->duringAddMethodProphecy( + $methodProphecy + ); + } + + function it_returns_null_after_checkPredictions_call_if_there_is_no_method_prophecies() + { + $this->checkProphecyMethodsPredictions()->shouldReturn(null); + } + + function it_throws_AggregateException_during_checkPredictions_if_predictions_fail( + MethodProphecy $methodProphecy1, MethodProphecy $methodProphecy2, + ArgumentsWildcard $argumentsWildcard1, + ArgumentsWildcard $argumentsWildcard2 + ) { + $methodProphecy1->getMethodName()->willReturn('getName'); + $methodProphecy1->getArgumentsWildcard()->willReturn($argumentsWildcard1); + $methodProphecy1->checkPrediction() + ->willThrow('Prophecy\Exception\Prediction\AggregateException'); + + $methodProphecy2->getMethodName()->willReturn('setName'); + $methodProphecy2->getArgumentsWildcard()->willReturn($argumentsWildcard2); + $methodProphecy2->checkPrediction() + ->willThrow('Prophecy\Exception\Prediction\AggregateException'); + + $this->addMethodProphecy($methodProphecy1); + $this->addMethodProphecy($methodProphecy2); + + $this->shouldThrow('Prophecy\Exception\Prediction\AggregateException') + ->duringCheckProphecyMethodsPredictions(); + } + + function it_returns_new_MethodProphecy_instance_for_arbitrary_call( + Doubler $doubler, + ProphecySubjectInterface $reflection + ) { + $doubler->double(Argument::any())->willReturn($reflection); + + $return = $this->getProphecy(); + $return->shouldBeAnInstanceOf('Prophecy\Prophecy\MethodProphecy'); + $return->getMethodName()->shouldReturn('getProphecy'); + } + + function it_returns_same_MethodProphecy_for_same_registered_signature( + Doubler $doubler, + ProphecySubjectInterface $reflection + ) { + $doubler->double(Argument::any())->willReturn($reflection); + + $this->addMethodProphecy($methodProphecy1 = $this->getProphecy(1, 2, 3)); + $methodProphecy2 = $this->getProphecy(1, 2, 3); + + $methodProphecy2->shouldBe($methodProphecy1); + } + + function it_returns_new_MethodProphecy_for_different_signatures( + Doubler $doubler, + ProphecySubjectInterface $reflection + ) { + $doubler->double(Argument::any())->willReturn($reflection); + + $value = new ObjectProphecySpecFixtureB('ABC'); + $value2 = new ObjectProphecySpecFixtureB('CBA'); + + $this->addMethodProphecy($methodProphecy1 = $this->getProphecy(1, 2, 3, $value)); + $methodProphecy2 = $this->getProphecy(1, 2, 3, $value2); + + $methodProphecy2->shouldNotBe($methodProphecy1); + } + + function it_returns_new_MethodProphecy_for_all_callback_signatures( + Doubler $doubler, + ProphecySubjectInterface $reflection + ) { + $doubler->double(Argument::any())->willReturn($reflection); + + $this->addMethodProphecy($methodProphecy1 = $this->getProphecy(function(){})); + $methodProphecy2 = $this->getProphecy(function(){}); + + $methodProphecy2->shouldNotBe($methodProphecy1); + } +} + +class ObjectProphecySpecFixtureA +{ + public $errors; +} + +class ObjectProphecySpecFixtureB extends ObjectProphecySpecFixtureA +{ + public $errors; + public $value = null; + + public function __construct($value) + { + $this->value = $value; + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Prophecy/RevealerSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Prophecy/RevealerSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Prophecy/RevealerSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Prophecy/RevealerSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,44 @@ +shouldBeAnInstanceOf('Prophecy\Prophecy\RevealerInterface'); + } + + function it_reveals_single_instance_of_ProphecyInterface(ProphecyInterface $prophecy, \stdClass $object) + { + $prophecy->reveal()->willReturn($object); + + $this->reveal($prophecy)->shouldReturn($object); + } + + function it_reveals_instances_of_ProphecyInterface_inside_array( + ProphecyInterface $prophecy1, + ProphecyInterface $prophecy2, + \stdClass $object1, + \stdClass $object2 + ) { + $prophecy1->reveal()->willReturn($object1); + $prophecy2->reveal()->willReturn($object2); + + $this->reveal(array( + array('item' => $prophecy2), + $prophecy1 + ))->shouldReturn(array( + array('item' => $object2), + $object1 + )); + } + + function it_does_not_touch_non_prophecy_interface() + { + $this->reveal(42)->shouldReturn(42); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/ProphetSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/ProphetSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/ProphetSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/ProphetSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,81 @@ +double(null, array())->willReturn($double); + + $this->beConstructedWith($doubler); + } + + function it_constructs_new_prophecy_on_prophesize_call() + { + $prophecy = $this->prophesize(); + $prophecy->shouldBeAnInstanceOf('Prophecy\Prophecy\ObjectProphecy'); + } + + function it_constructs_new_prophecy_with_parent_class_if_specified($doubler, ProphecySubjectInterface $newDouble) + { + $doubler->double(Argument::any(), array())->willReturn($newDouble); + + $this->prophesize('Prophecy\Prophet')->reveal()->shouldReturn($newDouble); + } + + function it_constructs_new_prophecy_with_interface_if_specified($doubler, ProphecySubjectInterface $newDouble) + { + $doubler->double(null, Argument::any())->willReturn($newDouble); + + $this->prophesize('ArrayAccess')->reveal()->shouldReturn($newDouble); + } + + function it_exposes_all_created_prophecies_through_getter() + { + $prophecy1 = $this->prophesize(); + $prophecy2 = $this->prophesize(); + + $this->getProphecies()->shouldReturn(array($prophecy1, $prophecy2)); + } + + function it_does_nothing_during_checkPredictions_call_if_no_predictions_defined() + { + $this->checkPredictions()->shouldReturn(null); + } + + function it_throws_AggregateException_if_defined_predictions_fail( + MethodProphecy $method1, + MethodProphecy $method2, + ArgumentsWildcard $arguments1, + ArgumentsWildcard $arguments2 + ) { + $method1->getMethodName()->willReturn('getName'); + $method1->getArgumentsWildcard()->willReturn($arguments1); + $method1->checkPrediction()->willReturn(null); + + $method2->getMethodName()->willReturn('isSet'); + $method2->getArgumentsWildcard()->willReturn($arguments2); + $method2->checkPrediction()->willThrow( + 'Prophecy\Exception\Prediction\AggregateException' + ); + + $this->prophesize()->addMethodProphecy($method1); + $this->prophesize()->addMethodProphecy($method2); + + $this->shouldThrow('Prophecy\Exception\Prediction\AggregateException') + ->duringCheckPredictions(); + } + + function it_exposes_doubler_through_getter($doubler) + { + $this->getDoubler()->shouldReturn($doubler); + } +} diff -Nru php-phpspec-prophecy-1.8.0/spec/Prophecy/Util/StringUtilSpec.php php-phpspec-prophecy-1.8.1/spec/Prophecy/Util/StringUtilSpec.php --- php-phpspec-prophecy-1.8.0/spec/Prophecy/Util/StringUtilSpec.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/spec/Prophecy/Util/StringUtilSpec.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,91 @@ +stringify(42)->shouldReturn('42'); + } + + function it_generates_proper_string_representation_for_string() + { + $this->stringify('some string')->shouldReturn('"some string"'); + } + + function it_generates_single_line_representation_for_multiline_string() + { + $this->stringify("some\nstring")->shouldReturn('"some\\nstring"'); + } + + function it_generates_proper_string_representation_for_double() + { + $this->stringify(42.3)->shouldReturn('42.3'); + } + + function it_generates_proper_string_representation_for_boolean_true() + { + $this->stringify(true)->shouldReturn('true'); + } + + function it_generates_proper_string_representation_for_boolean_false() + { + $this->stringify(false)->shouldReturn('false'); + } + + function it_generates_proper_string_representation_for_null() + { + $this->stringify(null)->shouldReturn('null'); + } + + function it_generates_proper_string_representation_for_empty_array() + { + $this->stringify(array())->shouldReturn('[]'); + } + + function it_generates_proper_string_representation_for_array() + { + $this->stringify(array('zet', 42))->shouldReturn('["zet", 42]'); + } + + function it_generates_proper_string_representation_for_hash_containing_one_value() + { + $this->stringify(array('ever' => 'zet'))->shouldReturn('["ever" => "zet"]'); + } + + function it_generates_proper_string_representation_for_hash() + { + $this->stringify(array('ever' => 'zet', 52 => 'hey', 'num' => 42))->shouldReturn( + '["ever" => "zet", 52 => "hey", "num" => 42]' + ); + } + + function it_generates_proper_string_representation_for_resource() + { + $resource = fopen(__FILE__, 'r'); + $this->stringify($resource)->shouldReturn('stream:'.$resource); + } + + function it_generates_proper_string_representation_for_object(\stdClass $object) + { + $objHash = sprintf('%s:%s', + get_class($object->getWrappedObject()), + spl_object_hash($object->getWrappedObject()) + ) . " Object (\n 'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)\n)"; + + $this->stringify($object)->shouldReturn("$objHash"); + } + + function it_generates_proper_string_representation_for_object_without_exporting(\stdClass $object) + { + $objHash = sprintf('%s:%s', + get_class($object->getWrappedObject()), + spl_object_hash($object->getWrappedObject()) + ); + + $this->stringify($object, false)->shouldReturn("$objHash"); + } +} diff -Nru php-phpspec-prophecy-1.8.0/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php php-phpspec-prophecy-1.8.1/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php --- php-phpspec-prophecy-1.8.0/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php 2018-08-05 17:53:17.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php 2019-06-17 19:05:31.000000000 +0000 @@ -41,6 +41,10 @@ */ public function apply(ClassNode $node) { + if (!$node->isExtendable('__construct')) { + return; + } + if (!$node->hasMethod('__construct')) { $node->addMethod(new MethodNode('__construct', '')); diff -Nru php-phpspec-prophecy-1.8.0/tests/Doubler/Generator/ClassMirrorTest.php php-phpspec-prophecy-1.8.1/tests/Doubler/Generator/ClassMirrorTest.php --- php-phpspec-prophecy-1.8.0/tests/Doubler/Generator/ClassMirrorTest.php 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/tests/Doubler/Generator/ClassMirrorTest.php 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,501 @@ +reflect($class, array()); + + $this->assertCount(7, $node->getMethods()); + } + + /** + * @test + */ + public function it_reflects_protected_abstract_methods() + { + $class = new \ReflectionClass('Fixtures\Prophecy\WithProtectedAbstractMethod'); + + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect($class, array()); + + $this->assertEquals('Fixtures\Prophecy\WithProtectedAbstractMethod', $classNode->getParentClass()); + + $methodNodes = $classNode->getMethods(); + $this->assertCount(1, $methodNodes); + + $this->assertEquals('protected', $methodNodes['innerDetail']->getVisibility()); + } + + /** + * @test + */ + public function it_reflects_public_static_methods() + { + $class = new \ReflectionClass('Fixtures\Prophecy\WithStaticMethod'); + + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect($class, array()); + + $this->assertEquals('Fixtures\Prophecy\WithStaticMethod', $classNode->getParentClass()); + + $methodNodes = $classNode->getMethods(); + $this->assertCount(1, $methodNodes); + + $this->assertTrue($methodNodes['innerDetail']->isStatic()); + } + + /** + * @test + */ + public function it_marks_required_args_without_types_as_not_optional() + { + $class = new \ReflectionClass('Fixtures\Prophecy\WithArguments'); + + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect($class, array()); + $methodNode = $classNode->getMethod('methodWithoutTypeHints'); + $argNodes = $methodNode->getArguments(); + + $this->assertCount(1, $argNodes); + + $this->assertEquals('arg', $argNodes[0]->getName()); + $this->assertNull($argNodes[0]->getTypeHint()); + $this->assertFalse($argNodes[0]->isOptional()); + $this->assertNull($argNodes[0]->getDefault()); + $this->assertFalse($argNodes[0]->isPassedByReference()); + $this->assertFalse($argNodes[0]->isVariadic()); + } + + /** + * @test + */ + public function it_properly_reads_methods_arguments_with_types() + { + $class = new \ReflectionClass('Fixtures\Prophecy\WithArguments'); + + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect($class, array()); + $methodNode = $classNode->getMethod('methodWithArgs'); + $argNodes = $methodNode->getArguments(); + + $this->assertCount(3, $argNodes); + + $this->assertEquals('arg_1', $argNodes[0]->getName()); + $this->assertEquals('array', $argNodes[0]->getTypeHint()); + $this->assertTrue($argNodes[0]->isOptional()); + $this->assertEquals(array(), $argNodes[0]->getDefault()); + $this->assertFalse($argNodes[0]->isPassedByReference()); + $this->assertFalse($argNodes[0]->isVariadic()); + + $this->assertEquals('arg_2', $argNodes[1]->getName()); + $this->assertEquals('ArrayAccess', $argNodes[1]->getTypeHint()); + $this->assertFalse($argNodes[1]->isOptional()); + + $this->assertEquals('arg_3', $argNodes[2]->getName()); + $this->assertEquals('ArrayAccess', $argNodes[2]->getTypeHint()); + $this->assertTrue($argNodes[2]->isOptional()); + $this->assertNull($argNodes[2]->getDefault()); + $this->assertFalse($argNodes[2]->isPassedByReference()); + $this->assertFalse($argNodes[2]->isVariadic()); + } + + /** + * @test + * @requires PHP 5.4 + */ + public function it_properly_reads_methods_arguments_with_callable_types() + { + $class = new \ReflectionClass('Fixtures\Prophecy\WithCallableArgument'); + + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect($class, array()); + $methodNode = $classNode->getMethod('methodWithArgs'); + $argNodes = $methodNode->getArguments(); + + $this->assertCount(2, $argNodes); + + $this->assertEquals('arg_1', $argNodes[0]->getName()); + $this->assertEquals('callable', $argNodes[0]->getTypeHint()); + $this->assertFalse($argNodes[0]->isOptional()); + $this->assertFalse($argNodes[0]->isPassedByReference()); + $this->assertFalse($argNodes[0]->isVariadic()); + + $this->assertEquals('arg_2', $argNodes[1]->getName()); + $this->assertEquals('callable', $argNodes[1]->getTypeHint()); + $this->assertTrue($argNodes[1]->isOptional()); + $this->assertNull($argNodes[1]->getDefault()); + $this->assertFalse($argNodes[1]->isPassedByReference()); + $this->assertFalse($argNodes[1]->isVariadic()); + } + + /** + * @test + * @requires PHP 5.6 + */ + public function it_properly_reads_methods_variadic_arguments() + { + $class = new \ReflectionClass('Fixtures\Prophecy\WithVariadicArgument'); + + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect($class, array()); + $methodNode = $classNode->getMethod('methodWithArgs'); + $argNodes = $methodNode->getArguments(); + + $this->assertCount(1, $argNodes); + + $this->assertEquals('args', $argNodes[0]->getName()); + $this->assertNull($argNodes[0]->getTypeHint()); + $this->assertFalse($argNodes[0]->isOptional()); + $this->assertFalse($argNodes[0]->isPassedByReference()); + $this->assertTrue($argNodes[0]->isVariadic()); + } + + /** + * @test + * @requires PHP 5.6 + */ + public function it_properly_reads_methods_typehinted_variadic_arguments() + { + if (defined('HHVM_VERSION_ID')) { + $this->markTestSkipped('HHVM does not support typehints on variadic arguments.'); + } + + $class = new \ReflectionClass('Fixtures\Prophecy\WithTypehintedVariadicArgument'); + + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect($class, array()); + $methodNode = $classNode->getMethod('methodWithTypeHintedArgs'); + $argNodes = $methodNode->getArguments(); + + $this->assertCount(1, $argNodes); + + $this->assertEquals('args', $argNodes[0]->getName()); + $this->assertEquals('array', $argNodes[0]->getTypeHint()); + $this->assertFalse($argNodes[0]->isOptional()); + $this->assertFalse($argNodes[0]->isPassedByReference()); + $this->assertTrue($argNodes[0]->isVariadic()); + } + + /** + * @test + */ + public function it_marks_passed_by_reference_args_as_passed_by_reference() + { + $class = new \ReflectionClass('Fixtures\Prophecy\WithReferences'); + + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect($class, array()); + + $this->assertTrue($classNode->hasMethod('methodWithReferenceArgument')); + + $argNodes = $classNode->getMethod('methodWithReferenceArgument')->getArguments(); + + $this->assertCount(2, $argNodes); + + $this->assertTrue($argNodes[0]->isPassedByReference()); + $this->assertTrue($argNodes[1]->isPassedByReference()); + } + + /** + * @test + * @expectedException Prophecy\Exception\Doubler\ClassMirrorException + */ + public function it_throws_an_exception_if_class_is_final() + { + $class = new \ReflectionClass('Fixtures\Prophecy\FinalClass'); + + $mirror = new ClassMirror(); + + $mirror->reflect($class, array()); + } + + /** + * @test + */ + public function it_ignores_final_methods() + { + $class = new \ReflectionClass('Fixtures\Prophecy\WithFinalMethod'); + + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect($class, array()); + + $this->assertCount(0, $classNode->getMethods()); + } + + /** + * @test + */ + public function it_marks_final_methods_as_unextendable() + { + $class = new \ReflectionClass('Fixtures\Prophecy\WithFinalMethod'); + + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect($class, array()); + + $this->assertCount(1, $classNode->getUnextendableMethods()); + $this->assertFalse($classNode->isExtendable('finalImplementation')); + } + + /** + * @test + * @expectedException Prophecy\Exception\InvalidArgumentException + */ + public function it_throws_an_exception_if_interface_provided_instead_of_class() + { + $class = new \ReflectionClass('Fixtures\Prophecy\EmptyInterface'); + + $mirror = new ClassMirror(); + + $mirror->reflect($class, array()); + } + + /** + * @test + */ + public function it_reflects_all_interfaces_methods() + { + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect(null, array( + new \ReflectionClass('Fixtures\Prophecy\Named'), + new \ReflectionClass('Fixtures\Prophecy\ModifierInterface'), + )); + + $this->assertEquals('stdClass', $classNode->getParentClass()); + $this->assertEquals(array( + 'Prophecy\Doubler\Generator\ReflectionInterface', + 'Fixtures\Prophecy\ModifierInterface', + 'Fixtures\Prophecy\Named', + ), $classNode->getInterfaces()); + + $this->assertCount(3, $classNode->getMethods()); + $this->assertTrue($classNode->hasMethod('getName')); + $this->assertTrue($classNode->hasMethod('isAbstract')); + $this->assertTrue($classNode->hasMethod('getVisibility')); + } + + /** + * @test + */ + public function it_ignores_virtually_private_methods() + { + $class = new \ReflectionClass('Fixtures\Prophecy\WithVirtuallyPrivateMethod'); + + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect($class, array()); + + $this->assertCount(2, $classNode->getMethods()); + $this->assertTrue($classNode->hasMethod('isAbstract')); + $this->assertTrue($classNode->hasMethod('__toString')); + $this->assertFalse($classNode->hasMethod('_getName')); + } + + /** + * @test + */ + public function it_does_not_throw_exception_for_virtually_private_finals() + { + $class = new \ReflectionClass('Fixtures\Prophecy\WithFinalVirtuallyPrivateMethod'); + + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect($class, array()); + + $this->assertCount(0, $classNode->getMethods()); + } + + /** + * @test + * @requires PHP 7 + */ + public function it_reflects_return_typehints() + { + $class = new \ReflectionClass('Fixtures\Prophecy\WithReturnTypehints'); + + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect($class, array()); + + $this->assertCount(3, $classNode->getMethods()); + $this->assertTrue($classNode->hasMethod('getName')); + $this->assertTrue($classNode->hasMethod('getSelf')); + $this->assertTrue($classNode->hasMethod('getParent')); + + $this->assertEquals('string', $classNode->getMethod('getName')->getReturnType()); + $this->assertEquals('\Fixtures\Prophecy\WithReturnTypehints', $classNode->getMethod('getSelf')->getReturnType()); + $this->assertEquals('\Fixtures\Prophecy\EmptyClass', $classNode->getMethod('getParent')->getReturnType()); + } + + /** + * @test + * @expectedException InvalidArgumentException + */ + public function it_throws_an_exception_if_class_provided_in_interfaces_list() + { + $class = new \ReflectionClass('Fixtures\Prophecy\EmptyClass'); + + $mirror = new ClassMirror(); + + $mirror->reflect(null, array($class)); + } + + /** + * @test + * @expectedException InvalidArgumentException + */ + public function it_throws_an_exception_if_not_reflection_provided_as_interface() + { + $mirror = new ClassMirror(); + + $mirror->reflect(null, array(null)); + } + + /** + * @test + */ + public function it_doesnt_use_scalar_typehints() + { + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect(new \ReflectionClass('ReflectionMethod'), array()); + $method = $classNode->getMethod('export'); + $arguments = $method->getArguments(); + + $this->assertNull($arguments[0]->getTypeHint()); + $this->assertNull($arguments[1]->getTypeHint()); + $this->assertNull($arguments[2]->getTypeHint()); + } + + /** + * @test + */ + public function it_doesnt_fail_to_typehint_nonexistent_FQCN() + { + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect(new \ReflectionClass('Fixtures\Prophecy\OptionalDepsClass'), array()); + $method = $classNode->getMethod('iHaveAStrangeTypeHintedArg'); + $arguments = $method->getArguments(); + $this->assertEquals('I\Simply\Am\Nonexistent', $arguments[0]->getTypeHint()); + } + + /** + * @test + * @requires PHP 7.1 + */ + public function it_doesnt_fail_on_array_nullable_parameter_with_not_null_default_value() + { + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect(new \ReflectionClass('Fixtures\Prophecy\NullableArrayParameter'), array()); + $method = $classNode->getMethod('iHaveNullableArrayParameterWithNotNullDefaultValue'); + $arguments = $method->getArguments(); + $this->assertSame('array', $arguments[0]->getTypeHint()); + $this->assertTrue($arguments[0]->isNullable()); + } + + /** + * @test + */ + public function it_doesnt_fail_to_typehint_nonexistent_RQCN() + { + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect(new \ReflectionClass('Fixtures\Prophecy\OptionalDepsClass'), array()); + $method = $classNode->getMethod('iHaveAnEvenStrangerTypeHintedArg'); + $arguments = $method->getArguments(); + $this->assertEquals('I\Simply\Am\Not', $arguments[0]->getTypeHint()); + } + + /** + * @test + * @requires PHP 7.2 + */ + function it_doesnt_fail_when_method_is_extended_with_more_params() + { + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect( + new \ReflectionClass('Fixtures\Prophecy\MethodWithAdditionalParam'), + array(new \ReflectionClass('Fixtures\Prophecy\Named')) + ); + $method = $classNode->getMethod('getName'); + $this->assertCount(1, $method->getArguments()); + + $method = $classNode->getMethod('methodWithoutTypeHints'); + $this->assertCount(2, $method->getArguments()); + } + + /** + * @test + */ + function it_changes_argument_names_if_they_are_varying() + { + // Use test doubles in this test, as arguments named ... in the Reflection API can only happen for internal classes + $class = $this->prophesize('ReflectionClass'); + $method = $this->prophesize('ReflectionMethod'); + $parameter = $this->prophesize('ReflectionParameter'); + + $class->getName()->willReturn('Custom\ClassName'); + $class->isInterface()->willReturn(false); + $class->isFinal()->willReturn(false); + $class->getMethods(\ReflectionMethod::IS_PUBLIC)->willReturn(array($method)); + $class->getMethods(\ReflectionMethod::IS_ABSTRACT)->willReturn(array()); + + $method->getParameters()->willReturn(array($parameter)); + $method->getName()->willReturn('methodName'); + $method->isFinal()->willReturn(false); + $method->isProtected()->willReturn(false); + $method->isStatic()->willReturn(false); + $method->returnsReference()->willReturn(false); + + if (version_compare(PHP_VERSION, '7.0', '>=')) { + $method->hasReturnType()->willReturn(false); + } + + $parameter->getName()->willReturn('...'); + $parameter->isDefaultValueAvailable()->willReturn(true); + $parameter->getDefaultValue()->willReturn(null); + $parameter->isPassedByReference()->willReturn(false); + $parameter->allowsNull()->willReturn(true); + $parameter->getClass()->willReturn($class); + if (version_compare(PHP_VERSION, '5.6', '>=')) { + $parameter->isVariadic()->willReturn(false); + } + + $mirror = new ClassMirror(); + + $classNode = $mirror->reflect($class->reveal(), array()); + + $methodNodes = $classNode->getMethods(); + + $argumentNodes = $methodNodes['methodName']->getArguments(); + $argumentNode = $argumentNodes[0]; + + $this->assertEquals('__dot_dot_dot__', $argumentNode->getName()); + } +} diff -Nru php-phpspec-prophecy-1.8.0/.travis.yml php-phpspec-prophecy-1.8.1/.travis.yml --- php-phpspec-prophecy-1.8.0/.travis.yml 1970-01-01 00:00:00.000000000 +0000 +++ php-phpspec-prophecy-1.8.1/.travis.yml 2019-06-17 19:05:31.000000000 +0000 @@ -0,0 +1,37 @@ +language: php + +sudo: false + +cache: + directories: + - $HOME/.composer/cache + +branches: + except: + - /^bugfix\/.*$/ + - /^feature\/.*$/ + - /^optimization\/.*$/ + +matrix: + include: + - php: 5.4 + - php: 5.5 + - php: 5.6 + env: DEPENDENCIES='low' + - php: 5.6 + - php: 7.0 + - php: 7.1 + - php: 7.2 + - php: 7.3 + - php: 5.3 + dist: precise + fast_finish: true + +install: + - export COMPOSER_ROOT_VERSION=dev-master + - if [ "$DEPENDENCIES" != "low" ]; then composer update; fi; + - if [ "$DEPENDENCIES" == "low" ]; then composer update --prefer-lowest; fi; + +script: + - vendor/bin/phpspec run -fpretty -v + - vendor/bin/phpunit