update v 1.0.7.5
This commit is contained in:
2
vendor/phpspec/phpspec/.scrutinizer.yml
vendored
2
vendor/phpspec/phpspec/.scrutinizer.yml
vendored
@@ -18,7 +18,7 @@ tools:
|
||||
excluded-paths: [ spec/*, integration/* ]
|
||||
|
||||
build_failure_conditions:
|
||||
- 'issues.label("coding-style").exists'
|
||||
- 'issues.label("coding-style").new.exists'
|
||||
|
||||
filter:
|
||||
excluded_paths:
|
||||
|
||||
1
vendor/phpspec/phpspec/.travis.yml
vendored
1
vendor/phpspec/phpspec/.travis.yml
vendored
@@ -24,6 +24,7 @@ matrix:
|
||||
|
||||
before_install:
|
||||
- composer selfupdate
|
||||
- if [ "$DEPENDENCIES" == "low" ]; then composer config disable-tls true; fi;
|
||||
|
||||
install:
|
||||
- export COMPOSER_ROOT_VERSION=dev-master
|
||||
|
||||
29
vendor/phpspec/phpspec/CHANGES.md
vendored
29
vendor/phpspec/phpspec/CHANGES.md
vendored
@@ -1,4 +1,27 @@
|
||||
2.4.1 / 2016/01/01
|
||||
2.5.0 / 2016-03-20
|
||||
==================
|
||||
|
||||
* No changes from RC1
|
||||
|
||||
|
||||
2.5.0-rc1 / 2016-03-12
|
||||
======================
|
||||
|
||||
* Fixed bug with typehints in classes defined in spec file
|
||||
|
||||
2.5.0-beta / 2016-02-16
|
||||
=======================
|
||||
|
||||
* Supports grouped Use statements
|
||||
* Now shows path in error message when spec file doesn't contain a class
|
||||
* Supports catching PHP 7 Errors in shouldThrow
|
||||
* No longer attempts to generate methods with reserved names
|
||||
* Fixed bug where bootstrapped classes could not be loaded after class generation
|
||||
* Fixed bug where line numbers were incorrectly reported on PHP 7
|
||||
* Fixed new methods being inserted incorrectly when strings included closing brace
|
||||
* Dot formatter now shows spec count on last line
|
||||
|
||||
2.4.1 / 2016-01-01
|
||||
==================
|
||||
|
||||
* Correctly handle nested class definitions
|
||||
@@ -9,12 +32,12 @@
|
||||
* Handle underscores correctly when using PSR-4
|
||||
* Fixed HTML formatter
|
||||
|
||||
2.4.0 / 2015/11/28
|
||||
2.4.0 / 2015-11-28
|
||||
==================
|
||||
|
||||
* Improved docblock for beConstructedThrough()
|
||||
|
||||
2.4.0-rc1 / 2015/11/20
|
||||
2.4.0-rc1 / 2015-11-20
|
||||
======================
|
||||
|
||||
* No changes from RC1
|
||||
|
||||
6
vendor/phpspec/phpspec/README.rst
vendored
6
vendor/phpspec/phpspec/README.rst
vendored
@@ -11,6 +11,12 @@ The main website with documentation is at `http://www.phpspec.net <http://www.ph
|
||||
:target: https://scrutinizer-ci.com/g/phpspec/phpspec/build-status/master
|
||||
:alt: Master Scrutinizer Quality Score
|
||||
|
||||
.. image:: https://ci.appveyor.com/api/projects/status/wce4nun9re76ocp6/branch/master?svg=true
|
||||
:target: https://ci.appveyor.com/project/ciaranmcnulty/phpspec/branch/master
|
||||
:alt: AppVeyor build status
|
||||
|
||||
|
||||
|
||||
Installing Dependencies
|
||||
-----------------------
|
||||
|
||||
|
||||
7
vendor/phpspec/phpspec/appveyor.yml
vendored
7
vendor/phpspec/phpspec/appveyor.yml
vendored
@@ -7,17 +7,12 @@ environment:
|
||||
matrix:
|
||||
- PHP_DOWNLOAD_FILE: php-5.6.14-nts-Win32-VC11-x86.zip
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- PHP_DOWNLOAD_FILE: php-5.6.14-nts-Win32-VC11-x86.zip
|
||||
|
||||
skip_commits:
|
||||
message: /\[ci skip\]/
|
||||
|
||||
cache:
|
||||
- c:\php -> appveyor.yml
|
||||
- '%LOCALAPPDATA%\Composer'
|
||||
- vendor
|
||||
|
||||
init:
|
||||
- SET PATH=c:\php;%PATH%
|
||||
@@ -48,4 +43,4 @@ test_script:
|
||||
- cd c:\projects\phpspec
|
||||
- php bin\phpspec run --format=pretty
|
||||
- php vendor\phpunit\phpunit\phpunit --testdox
|
||||
- php vendor\behat\behat\bin\behat --format=pretty --tags="~@php-version,@php5.4"
|
||||
- php vendor\behat\behat\bin\behat --format=pretty --tags="~@php-version,@php5.4&&~@hhvm"
|
||||
|
||||
2
vendor/phpspec/phpspec/bin/phpspec
vendored
2
vendor/phpspec/phpspec/bin/phpspec
vendored
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
define('PHPSPEC_VERSION', '2.4.1');
|
||||
define('PHPSPEC_VERSION', '2.5.0');
|
||||
|
||||
if (is_file($autoload = getcwd() . '/vendor/autoload.php')) {
|
||||
require $autoload;
|
||||
|
||||
@@ -108,7 +108,10 @@ class ApplicationContext implements Context, MatchersProviderInterface
|
||||
|
||||
$this->addOptionToArguments($option, $arguments);
|
||||
|
||||
$this->lastExitCode = $this->tester->run($arguments, array('interactive' => (bool)$interactive));
|
||||
$this->lastExitCode = $this->tester->run($arguments, array(
|
||||
'interactive' => (bool)$interactive,
|
||||
'decorated' => false,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,7 @@ use Behat\Gherkin\Node\TableNode;
|
||||
use Matcher\FileExistsMatcher;
|
||||
use Matcher\FileHasContentsMatcher;
|
||||
use PhpSpec\Matcher\MatchersProviderInterface;
|
||||
use Symfony\Component\Filesystem\Exception\IOException;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
/**
|
||||
@@ -51,7 +52,11 @@ class FilesystemContext implements Context, MatchersProviderInterface
|
||||
*/
|
||||
public function removeWorkingDirectory()
|
||||
{
|
||||
$this->filesystem->remove($this->workingDirectory);
|
||||
try {
|
||||
$this->filesystem->remove($this->workingDirectory);
|
||||
} catch (IOException $e) {
|
||||
//ignoring exception
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,8 +40,8 @@ class IsolatedProcessContext implements Context, SnippetAcceptingContext
|
||||
$command = sprintf('%s %s', $this->buildPhpSpecCmd(), 'run');
|
||||
$env = array(
|
||||
'SHELL_INTERACTIVE' => true,
|
||||
'HOME' => $_SERVER['HOME'],
|
||||
'PATH' => $_SERVER['PATH']
|
||||
'HOME' => getenv('HOME'),
|
||||
'PATH' => getenv('PATH'),
|
||||
);
|
||||
|
||||
$this->process = $process = new Process($command);
|
||||
@@ -56,7 +56,13 @@ class IsolatedProcessContext implements Context, SnippetAcceptingContext
|
||||
*/
|
||||
protected function buildPhpSpecCmd()
|
||||
{
|
||||
return escapeshellcmd(__DIR__ . '/../../bin/phpspec');
|
||||
$isWindows = DIRECTORY_SEPARATOR === '\\';
|
||||
$cmd = escapeshellcmd('' . __DIR__ . '/../../bin/phpspec');
|
||||
if ($isWindows) {
|
||||
$cmd = 'php ' . $cmd;
|
||||
}
|
||||
|
||||
return $cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,7 +33,7 @@ class ApplicationOutputMatcher implements MatcherInterface
|
||||
public function positiveMatch($name, $subject, array $arguments)
|
||||
{
|
||||
$expected = $this->normalize($arguments[0]);
|
||||
$actual = $this->normalize($subject->getDisplay());
|
||||
$actual = $this->normalize($subject->getDisplay(true));
|
||||
if (strpos($actual, $expected) === false) {
|
||||
throw new FailureException(sprintf(
|
||||
"Application output did not contain expected '%s'. Actual output:\n'%s'" ,
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
@php-version @php7
|
||||
Feature: Developer generates a collaborator
|
||||
As a Developer
|
||||
I want to automate creating collaborators
|
||||
In order to avoid disrupting my workflow
|
||||
|
||||
Scenario: Being prompted but not generating a collaborator
|
||||
Given the spec file "spec/CodeGeneration/CollaboratorExample1/Markdown1Spec.php" contains:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace spec\CodeGeneration\CollaboratorExample1;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
use CodeGeneration\CollaboratorExample1\{Tokenizer, Parser};
|
||||
|
||||
class Markdown1Spec extends ObjectBehavior
|
||||
{
|
||||
function it_interacts_with_a_collaborator(Parser $parser)
|
||||
{
|
||||
$parser->willReturn(true);
|
||||
}
|
||||
}
|
||||
|
||||
"""
|
||||
And the class file "src/CodeGeneration/CollaboratorExample1/Markdown1.php" contains:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace CodeGeneration\CollaboratorExample1;
|
||||
|
||||
class Markdown1
|
||||
{
|
||||
}
|
||||
|
||||
"""
|
||||
When I run phpspec and answer "n" when asked if I want to generate the code
|
||||
Then I should be prompted with:
|
||||
"""
|
||||
Would you like me to generate an interface
|
||||
`CodeGeneration\CollaboratorExample1\Parser` for you?
|
||||
[Y/n]
|
||||
"""
|
||||
|
||||
Scenario: Asking for interface to be generated for second collaborator in group
|
||||
Given the spec file "spec/CodeGeneration/CollaboratorExample2/Markdown1Spec.php" contains:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace spec\CodeGeneration\CollaboratorExample2;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
use CodeGeneration\CollaboratorExample2\{Tokenizer, Parser};
|
||||
|
||||
class Markdown1Spec extends ObjectBehavior
|
||||
{
|
||||
function it_interacts_with_a_collaborator(Parser $parser)
|
||||
{
|
||||
$parser->willReturn(true);
|
||||
}
|
||||
}
|
||||
|
||||
"""
|
||||
And the class file "src/CodeGeneration/CollaboratorExample2/Markdown1.php" contains:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace CodeGeneration\CollaboratorExample2;
|
||||
|
||||
class Markdown1
|
||||
{
|
||||
}
|
||||
|
||||
"""
|
||||
When I run phpspec and answer "y" when asked if I want to generate the code
|
||||
Then the class in "src/CodeGeneration/CollaboratorExample2/Parser.php" should contain:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace CodeGeneration\CollaboratorExample2;
|
||||
|
||||
interface Parser
|
||||
{
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
Scenario: Asking for interface to be generated for the first collaborator in group
|
||||
Given the spec file "spec/CodeGeneration/CollaboratorExample3/Markdown1Spec.php" contains:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace spec\CodeGeneration\CollaboratorExample3;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
use CodeGeneration\CollaboratorExample3\{Tokenizer, Parser};
|
||||
|
||||
class Markdown1Spec extends ObjectBehavior
|
||||
{
|
||||
function it_interacts_with_a_collaborator(Tokenizer $tokenizer)
|
||||
{
|
||||
$tokenizer->willReturn(true);
|
||||
}
|
||||
}
|
||||
|
||||
"""
|
||||
And the class file "src/CodeGeneration/CollaboratorExample3/Markdown1.php" contains:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace CodeGeneration\CollaboratorExample3;
|
||||
|
||||
class Markdown1
|
||||
{
|
||||
}
|
||||
"""
|
||||
When I run phpspec and answer "y" when asked if I want to generate the code
|
||||
Then the class in "src/CodeGeneration/CollaboratorExample3/Tokenizer.php" should contain:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace CodeGeneration\CollaboratorExample3;
|
||||
|
||||
interface Tokenizer
|
||||
{
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -264,3 +264,48 @@ Feature: Developer generates a collaborator's method
|
||||
"""
|
||||
When I run phpspec and answer "n" when asked if I want to generate the code
|
||||
Then I should not be prompted for code generation
|
||||
|
||||
Scenario: Being warned when a collaborator method is a restricted word
|
||||
Given the spec file "spec/CodeGeneration/CollaboratorMethodExample6/MarkdownSpec.php" contains:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace spec\CodeGeneration\CollaboratorMethodExample6;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
use CodeGeneration\CollaboratorMethodExample1\Parser;
|
||||
|
||||
class MarkdownSpec extends ObjectBehavior
|
||||
{
|
||||
function it_interacts_with_a_collaborator(Parser $parser)
|
||||
{
|
||||
$parser->throw()->willReturn(true);
|
||||
}
|
||||
}
|
||||
|
||||
"""
|
||||
And the class file "src/CodeGeneration/CollaboratorMethodExample6/Markdown.php" contains:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace CodeGeneration\CollaboratorMethodExample6;
|
||||
|
||||
class Markdown
|
||||
{
|
||||
}
|
||||
|
||||
"""
|
||||
And the class file "src/CodeGeneration/CollaboratorMethodExample6/Parser.php" contains:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace CodeGeneration\CollaboratorMethodExample6;
|
||||
|
||||
interface Parser
|
||||
{
|
||||
}
|
||||
|
||||
"""
|
||||
When I run phpspec and answer "n" when asked if I want to generate the code
|
||||
Then I should see "I cannot generate the method 'throw' for you"
|
||||
|
||||
@@ -371,3 +371,47 @@ Feature: Developer generates a method
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
Scenario: Generating a method named with a restricted keyword
|
||||
Given the spec file "spec/MyNamespace/RestrictedSpec.php" contains:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace spec\MyNamespace;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
|
||||
class RestrictedSpec extends ObjectBehavior
|
||||
{
|
||||
function it_tries_to_call_wrong_method()
|
||||
{
|
||||
$this->throw()->shouldReturn();
|
||||
}
|
||||
}
|
||||
|
||||
"""
|
||||
And the class file "src/MyNamespace/Restricted.php" contains:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace MyNamespace;
|
||||
|
||||
class Restricted
|
||||
{
|
||||
}
|
||||
|
||||
"""
|
||||
When I run phpspec interactively
|
||||
Then I should see "I cannot generate the method 'throw' for you"
|
||||
And the class in "src/MyNamespace/Restricted.php" should contain:
|
||||
"""
|
||||
<?php
|
||||
|
||||
namespace MyNamespace;
|
||||
|
||||
class Restricted
|
||||
{
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
@@ -396,7 +396,7 @@ Feature: Developer is shown diffs
|
||||
"""
|
||||
method call:
|
||||
- methodTwo("value")
|
||||
on Double\Diffs\DiffExample7\ClassBeingMocked\P13 was not expected, expected calls were:
|
||||
on Double\Diffs\DiffExample7\ClassBeingMocked\P14 was not expected, expected calls were:
|
||||
- methodOne(exact("value"))
|
||||
"""
|
||||
|
||||
@@ -460,7 +460,7 @@ Feature: Developer is shown diffs
|
||||
"""
|
||||
method call:
|
||||
- methodTwo("another value")
|
||||
on Double\Diffs\DiffExample8\ClassBeingMocked\P14 was not expected, expected calls were:
|
||||
on Double\Diffs\DiffExample8\ClassBeingMocked\P15 was not expected, expected calls were:
|
||||
- methodTwo(exact("value"))
|
||||
- methodOne(exact("another value"))
|
||||
"""
|
||||
|
||||
@@ -102,4 +102,27 @@ class TokenizedNamespaceResolverSpec extends ObjectBehavior
|
||||
$this->resolve('Foo')->shouldReturn('Baz\Foo');
|
||||
$this->resolve('Bar\Baz')->shouldReturn('Boz\Bar\Baz');
|
||||
}
|
||||
|
||||
|
||||
function it_resolves_types_from_grouped_use_statements()
|
||||
{
|
||||
$this->analyse('
|
||||
<?php
|
||||
|
||||
namespace Baz;
|
||||
|
||||
use Boz\{Fiz, Buz};
|
||||
|
||||
class Foo
|
||||
{
|
||||
function it_something(Fiz $fiz, Buz $buz)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
');
|
||||
|
||||
$this->resolve('Fiz')->shouldReturn('Boz\Fiz');
|
||||
$this->resolve('Buz')->shouldReturn('Boz\Buz');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ class TokenizedTypeHintRewriterSpec extends ObjectBehavior
|
||||
$this->rewrite('
|
||||
<?php
|
||||
|
||||
class Foo
|
||||
class FooSpec
|
||||
{
|
||||
public function bar()
|
||||
{
|
||||
@@ -35,7 +35,7 @@ class TokenizedTypeHintRewriterSpec extends ObjectBehavior
|
||||
')->shouldReturn('
|
||||
<?php
|
||||
|
||||
class Foo
|
||||
class FooSpec
|
||||
{
|
||||
public function bar()
|
||||
{
|
||||
@@ -50,7 +50,7 @@ class TokenizedTypeHintRewriterSpec extends ObjectBehavior
|
||||
$this->rewrite('
|
||||
<?php
|
||||
|
||||
class Foo
|
||||
class FooSpec
|
||||
{
|
||||
public function bar(\Foo\Bar $bar)
|
||||
{
|
||||
@@ -60,9 +60,9 @@ class TokenizedTypeHintRewriterSpec extends ObjectBehavior
|
||||
')->shouldReturn('
|
||||
<?php
|
||||
|
||||
class Foo
|
||||
class FooSpec
|
||||
{
|
||||
public function bar($bar)
|
||||
public function bar( $bar)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ class TokenizedTypeHintRewriterSpec extends ObjectBehavior
|
||||
$this->rewrite('
|
||||
<?php
|
||||
|
||||
class Foo
|
||||
class FooSpec
|
||||
{
|
||||
public function bar(\Foo\Bar $bar)
|
||||
{
|
||||
@@ -89,9 +89,9 @@ class TokenizedTypeHintRewriterSpec extends ObjectBehavior
|
||||
')->shouldReturn('
|
||||
<?php
|
||||
|
||||
class Foo
|
||||
class FooSpec
|
||||
{
|
||||
public function bar($bar)
|
||||
public function bar( $bar)
|
||||
{
|
||||
new class($argument) implements InterfaceName
|
||||
{
|
||||
@@ -108,7 +108,7 @@ class TokenizedTypeHintRewriterSpec extends ObjectBehavior
|
||||
$this->rewrite('
|
||||
<?php
|
||||
|
||||
class Foo
|
||||
class FooSpec
|
||||
{
|
||||
public function bar(Bar $bar, Baz $baz)
|
||||
{
|
||||
@@ -118,9 +118,9 @@ class TokenizedTypeHintRewriterSpec extends ObjectBehavior
|
||||
')->shouldReturn('
|
||||
<?php
|
||||
|
||||
class Foo
|
||||
class FooSpec
|
||||
{
|
||||
public function bar($bar,$baz)
|
||||
public function bar( $bar, $baz)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -132,14 +132,14 @@ class TokenizedTypeHintRewriterSpec extends ObjectBehavior
|
||||
{
|
||||
$namespaceResolver->analyse(Argument::any())->shouldBeCalled();
|
||||
|
||||
$namespaceResolver->resolve('Foo')->willReturn('Foo');
|
||||
$namespaceResolver->resolve('FooSpec')->willReturn('FooSpec');
|
||||
$namespaceResolver->resolve('Foo\Bar')->willReturn('Foo\Bar');
|
||||
$namespaceResolver->resolve('Baz')->willReturn('Baz');
|
||||
|
||||
$this->rewrite('
|
||||
<?php
|
||||
|
||||
class Foo
|
||||
class FooSpec
|
||||
{
|
||||
public function bar(Foo\Bar $bar, Baz $baz)
|
||||
{
|
||||
@@ -148,8 +148,8 @@ class TokenizedTypeHintRewriterSpec extends ObjectBehavior
|
||||
|
||||
');
|
||||
|
||||
$typeHintIndex->add('Foo', 'bar', '$bar', 'Foo\Bar')->shouldHaveBeenCalled();
|
||||
$typeHintIndex->add('Foo', 'bar', '$baz', 'Baz')->shouldHaveBeenCalled();
|
||||
$typeHintIndex->add('FooSpec', 'bar', '$bar', 'Foo\Bar')->shouldHaveBeenCalled();
|
||||
$typeHintIndex->add('FooSpec', 'bar', '$baz', 'Baz')->shouldHaveBeenCalled();
|
||||
}
|
||||
|
||||
function it_indexes_invalid_typehints(
|
||||
@@ -159,13 +159,13 @@ class TokenizedTypeHintRewriterSpec extends ObjectBehavior
|
||||
$e = new DisallowedScalarTypehintException();
|
||||
$namespaceResolver->analyse(Argument::any())->shouldBeCalled();
|
||||
|
||||
$namespaceResolver->resolve('Foo')->willReturn('Foo');
|
||||
$namespaceResolver->resolve('FooSpec')->willReturn('FooSpec');
|
||||
$namespaceResolver->resolve('int')->willThrow($e);
|
||||
|
||||
$this->rewrite('
|
||||
<?php
|
||||
|
||||
class Foo
|
||||
class FooSpec
|
||||
{
|
||||
public function bar(int $bar)
|
||||
{
|
||||
@@ -174,7 +174,79 @@ class TokenizedTypeHintRewriterSpec extends ObjectBehavior
|
||||
|
||||
');
|
||||
|
||||
$typeHintIndex->addInvalid('Foo', 'bar', '$bar', $e)->shouldHaveBeenCalled();
|
||||
$typeHintIndex->add('Foo', 'bar', '$bar', Argument::any())->shouldNotHaveBeenCalled();
|
||||
$typeHintIndex->addInvalid('FooSpec', 'bar', '$bar', $e)->shouldHaveBeenCalled();
|
||||
$typeHintIndex->add('FooSpec', 'bar', '$bar', Argument::any())->shouldNotHaveBeenCalled();
|
||||
}
|
||||
|
||||
function it_preserves_line_numbers()
|
||||
{
|
||||
$this->rewrite('
|
||||
<?php
|
||||
|
||||
class FooSpec
|
||||
{
|
||||
public function(
|
||||
$foo,
|
||||
array $bar,
|
||||
Foo\Bar $arg3,
|
||||
$arg4
|
||||
)
|
||||
{
|
||||
}
|
||||
}
|
||||
')->shouldReturn('
|
||||
<?php
|
||||
|
||||
class FooSpec
|
||||
{
|
||||
public function(
|
||||
$foo,
|
||||
array $bar,
|
||||
$arg3,
|
||||
$arg4
|
||||
)
|
||||
{
|
||||
}
|
||||
}
|
||||
');
|
||||
}
|
||||
|
||||
function it_do_not_remove_typehints_of_non_spec_classes()
|
||||
{
|
||||
$this->rewrite('
|
||||
<?php
|
||||
|
||||
class FooSpec
|
||||
{
|
||||
public function bar(Bar $bar, Baz $baz)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class Bar
|
||||
{
|
||||
public function foo(Baz $baz)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
')->shouldReturn('
|
||||
<?php
|
||||
|
||||
class FooSpec
|
||||
{
|
||||
public function bar( $bar, $baz)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class Bar
|
||||
{
|
||||
public function foo(Baz $baz)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,15 @@ class TokenizedCodeWriterSpec extends ObjectBehavior
|
||||
$this->shouldThrow($exception)->during('insertAfterMethod', array($class, 'methodOne', ''));
|
||||
}
|
||||
|
||||
function it_should_generate_a_method_in_a_class_with_a_string_containing_braces()
|
||||
{
|
||||
$class = $this->getClassWithBraceText();
|
||||
$method = $this->getMethod();
|
||||
$result = $this->getClassWithBraceTextAndNewMethod();
|
||||
|
||||
$this->insertMethodLastInClass($class, $method)->shouldReturn($result);
|
||||
}
|
||||
|
||||
private function getSingleMethodClass()
|
||||
{
|
||||
return <<<SINGLE_METHOD_CLASS
|
||||
@@ -232,4 +241,43 @@ final class MyClass
|
||||
}
|
||||
ONLY_NEW_METHOD_CLASS;
|
||||
}
|
||||
|
||||
private function getClassWithBraceText()
|
||||
{
|
||||
return <<<'BRACE_TEXT_CLASS'
|
||||
<?php
|
||||
|
||||
namespace MyNamespace;
|
||||
|
||||
final class MyClass
|
||||
{
|
||||
public function braceMethod()
|
||||
{
|
||||
return "{$foo}";
|
||||
}
|
||||
}
|
||||
BRACE_TEXT_CLASS;
|
||||
}
|
||||
|
||||
private function getClassWithBraceTextAndNewMethod()
|
||||
{
|
||||
return <<<'BRACE_TEXT_RESULT_CLASS'
|
||||
<?php
|
||||
|
||||
namespace MyNamespace;
|
||||
|
||||
final class MyClass
|
||||
{
|
||||
public function braceMethod()
|
||||
{
|
||||
return "{$foo}";
|
||||
}
|
||||
|
||||
public function newMethod()
|
||||
{
|
||||
return 'newSomething';
|
||||
}
|
||||
}
|
||||
BRACE_TEXT_RESULT_CLASS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,4 +180,36 @@ class IOSpec extends ObjectBehavior
|
||||
|
||||
$this->getBlockWidth()->shouldReturn(65);
|
||||
}
|
||||
|
||||
function it_writes_a_message_about_broken_code(OutputInterface $output)
|
||||
{
|
||||
$message = 'Error message';
|
||||
$output->writeln('<broken-bg> </broken-bg>')->shouldBeCalledTimes(2);
|
||||
$output->writeln('<broken-bg>Error message </broken-bg>')->shouldBeCalled();
|
||||
$output->writeln('')->shouldBeCalled();
|
||||
|
||||
$this->writeBrokenCodeBlock($message);
|
||||
}
|
||||
|
||||
function it_wraps_long_broken_message(OutputInterface $output)
|
||||
{
|
||||
$message = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pro maximus nulla eget libero rhoncus lacinia.';
|
||||
$output->writeln('<broken-bg> </broken-bg>')->shouldBeCalledTimes(2);
|
||||
$output->writeln('<broken-bg>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pro</broken-bg>')->shouldBeCalled();
|
||||
$output->writeln('<broken-bg>maximus nulla eget libero rhoncus lacinia. </broken-bg>')->shouldBeCalled();
|
||||
$output->writeln('')->shouldBeCalled();
|
||||
|
||||
$this->writeBrokenCodeBlock($message);
|
||||
}
|
||||
|
||||
function it_indents_and_wraps_long_broken_message(OutputInterface $output)
|
||||
{
|
||||
$message = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin maximus nulla eget libero rhoncus lacinia.';
|
||||
$output->writeln('<broken-bg> </broken-bg>')->shouldBeCalledTimes(2);
|
||||
$output->writeln('<broken-bg> Lorem ipsum dolor sit amet, consectetur adipiscing elit. </broken-bg>')->shouldBeCalled();
|
||||
$output->writeln('<broken-bg> Proin maximus nulla eget libero rhoncus lacinia. </broken-bg>')->shouldBeCalled();
|
||||
$output->writeln('')->shouldBeCalled();
|
||||
|
||||
$this->writeBrokenCodeBlock($message, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,4 +45,12 @@ class SuiteEventSpec extends ObjectBehavior
|
||||
$this->markAsWorthRerunning();
|
||||
$this->isWorthRerunning()->shouldReturn(true);
|
||||
}
|
||||
|
||||
function it_can_be_told_that_the_suite_is_no_longer_worth_rerunning()
|
||||
{
|
||||
$this->markAsWorthRerunning();
|
||||
$this->markAsNotWorthRerunning();
|
||||
|
||||
$this->isWorthRerunning()->shouldReturn(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,6 @@ class StringEngineSpec extends ObjectBehavior
|
||||
</code>
|
||||
DIFF;
|
||||
|
||||
$this->compare('string1', 'string2')->shouldReturn(str_replace("\n", PHP_EOL, $expected));
|
||||
$this->compare('string1', 'string2')->shouldReturn($expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,19 +11,19 @@ use PhpSpec\Locator\ResourceInterface;
|
||||
use PhpSpec\Locator\ResourceManager;
|
||||
use PhpSpec\Locator\ResourceManagerInterface;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use PhpSpec\Util\NameCheckerInterface;
|
||||
use Prophecy\Argument;
|
||||
use Prophecy\Doubler\DoubleInterface;
|
||||
use Prophecy\Exception\Doubler\MethodNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
class CollaboratorMethodNotFoundListenerSpec extends ObjectBehavior
|
||||
{
|
||||
function let(
|
||||
IO $io, ResourceManagerInterface $resources, ExampleEvent $event,
|
||||
MethodNotFoundException $exception, ResourceInterface $resource, GeneratorManager $generator
|
||||
)
|
||||
{
|
||||
$this->beConstructedWith($io, $resources, $generator);
|
||||
MethodNotFoundException $exception, ResourceInterface $resource, GeneratorManager $generator,
|
||||
NameCheckerInterface $nameChecker
|
||||
) {
|
||||
$this->beConstructedWith($io, $resources, $generator, $nameChecker);
|
||||
$event->getException()->willReturn($exception);
|
||||
|
||||
$io->isCodeGenerationEnabled()->willReturn(true);
|
||||
@@ -32,6 +32,7 @@ class CollaboratorMethodNotFoundListenerSpec extends ObjectBehavior
|
||||
$resources->createResource(Argument::any())->willReturn($resource);
|
||||
|
||||
$exception->getArguments()->willReturn(array());
|
||||
$nameChecker->isNameValid('aMethod')->willReturn(true);
|
||||
}
|
||||
|
||||
function it_is_an_event_subscriber()
|
||||
@@ -72,7 +73,7 @@ class CollaboratorMethodNotFoundListenerSpec extends ObjectBehavior
|
||||
|
||||
function it_does_not_prompt_when_wrong_exception_is_thrown(IO $io, ExampleEvent $event, SuiteEvent $suiteEvent)
|
||||
{
|
||||
$event->getException()->willReturn(new RuntimeException());
|
||||
$event->getException()->willReturn(new \RuntimeException());
|
||||
|
||||
$this->afterExample($event);
|
||||
$this->afterSuite($suiteEvent);
|
||||
@@ -153,6 +154,49 @@ class CollaboratorMethodNotFoundListenerSpec extends ObjectBehavior
|
||||
|
||||
$suiteEvent->markAsWorthRerunning()->shouldHaveBeenCalled();
|
||||
}
|
||||
|
||||
function it_warns_if_a_method_name_is_wrong(
|
||||
ExampleEvent $event,
|
||||
SuiteEvent $suiteEvent,
|
||||
IO $io,
|
||||
NameCheckerInterface $nameChecker
|
||||
) {
|
||||
$exception = new MethodNotFoundException('Error', new DoubleOfInterface(), 'throw');
|
||||
|
||||
$event->getException()->willReturn($exception);
|
||||
$nameChecker->isNameValid('throw')->willReturn(false);
|
||||
|
||||
$io->writeBrokenCodeBlock("I cannot generate the method 'throw' for you because it is a reserved keyword", 2)->shouldBeCalled();
|
||||
$io->askConfirmation(Argument::any())->shouldNotBeCalled();
|
||||
|
||||
$this->afterExample($event);
|
||||
$this->afterSuite($suiteEvent);
|
||||
}
|
||||
|
||||
function it_prompts_and_warns_when_one_method_name_is_correct_but_other_reserved(
|
||||
ExampleEvent $event,
|
||||
SuiteEvent $suiteEvent,
|
||||
IO $io,
|
||||
NameCheckerInterface $nameChecker
|
||||
) {
|
||||
$this->callAfterExample($event, $nameChecker, 'throw', false);
|
||||
$this->callAfterExample($event, $nameChecker, 'foo');
|
||||
|
||||
$io->writeBrokenCodeBlock("I cannot generate the method 'throw' for you because it is a reserved keyword", 2)->shouldBeCalled();
|
||||
$io->askConfirmation(Argument::any())->shouldBeCalled();
|
||||
$suiteEvent->markAsNotWorthRerunning()->shouldBeCalled();
|
||||
|
||||
$this->afterSuite($suiteEvent);
|
||||
}
|
||||
|
||||
private function callAfterExample($event, $nameChecker, $method, $isNameValid = true)
|
||||
{
|
||||
$exception = new MethodNotFoundException('Error', new DoubleOfInterface(), $method);
|
||||
$event->getException()->willReturn($exception);
|
||||
$nameChecker->isNameValid($method)->willReturn($isNameValid);
|
||||
|
||||
$this->afterExample($event);
|
||||
}
|
||||
}
|
||||
|
||||
interface ExampleInterface {}
|
||||
|
||||
@@ -11,22 +11,27 @@ use PhpSpec\CodeGenerator\GeneratorManager;
|
||||
use PhpSpec\Event\ExampleEvent;
|
||||
use PhpSpec\Event\SuiteEvent;
|
||||
use PhpSpec\Exception\Fracture\MethodNotFoundException;
|
||||
use PhpSpec\Util\NameCheckerInterface;
|
||||
|
||||
class MethodNotFoundListenerSpec extends ObjectBehavior
|
||||
{
|
||||
function let(IO $io, ResourceManager $resourceManager, GeneratorManager $generatorManager,
|
||||
SuiteEvent $suiteEvent, ExampleEvent $exampleEvent)
|
||||
{
|
||||
function let(
|
||||
IO $io,
|
||||
ResourceManager $resourceManager,
|
||||
GeneratorManager $generatorManager,
|
||||
SuiteEvent $suiteEvent,
|
||||
ExampleEvent $exampleEvent,
|
||||
NameCheckerInterface $nameChecker
|
||||
) {
|
||||
$io->writeln(Argument::any())->willReturn();
|
||||
$io->askConfirmation(Argument::any())->willReturn();
|
||||
|
||||
$this->beConstructedWith($io, $resourceManager, $generatorManager);
|
||||
$this->beConstructedWith($io, $resourceManager, $generatorManager, $nameChecker);
|
||||
$io->isCodeGenerationEnabled()->willReturn(true);
|
||||
}
|
||||
|
||||
function it_does_not_prompt_for_method_generation_if_no_exception_was_thrown($exampleEvent, $suiteEvent, $io)
|
||||
{
|
||||
$io->isCodeGenerationEnabled()->willReturn(true);
|
||||
|
||||
$this->afterExample($exampleEvent);
|
||||
$this->afterSuite($suiteEvent);
|
||||
|
||||
@@ -36,7 +41,6 @@ class MethodNotFoundListenerSpec extends ObjectBehavior
|
||||
function it_does_not_prompt_for_method_generation_if_non_methodnotfoundexception_was_thrown($exampleEvent, $suiteEvent, $io, \InvalidArgumentException $exception)
|
||||
{
|
||||
$exampleEvent->getException()->willReturn($exception);
|
||||
$io->isCodeGenerationEnabled()->willReturn(true);
|
||||
|
||||
$this->afterExample($exampleEvent);
|
||||
$this->afterSuite($suiteEvent);
|
||||
@@ -44,10 +48,16 @@ class MethodNotFoundListenerSpec extends ObjectBehavior
|
||||
$io->askConfirmation(Argument::any())->shouldNotBeenCalled();
|
||||
}
|
||||
|
||||
function it_prompts_for_method_generation_if_methodnotfoundexception_was_thrown_and_input_is_interactive($exampleEvent, $suiteEvent, $io, MethodNotFoundException $exception)
|
||||
{
|
||||
function it_prompts_for_method_generation_if_methodnotfoundexception_was_thrown_and_input_is_interactive(
|
||||
$exampleEvent,
|
||||
$suiteEvent,
|
||||
$io,
|
||||
NameCheckerInterface $nameChecker
|
||||
) {
|
||||
$exception = new MethodNotFoundException('Error', new \stdClass(), 'bar');
|
||||
|
||||
$exampleEvent->getException()->willReturn($exception);
|
||||
$io->isCodeGenerationEnabled()->willReturn(true);
|
||||
$nameChecker->isNameValid('bar')->willReturn(true);
|
||||
|
||||
$this->afterExample($exampleEvent);
|
||||
$this->afterSuite($suiteEvent);
|
||||
@@ -65,4 +75,42 @@ class MethodNotFoundListenerSpec extends ObjectBehavior
|
||||
|
||||
$io->askConfirmation(Argument::any())->shouldNotBeenCalled();
|
||||
}
|
||||
|
||||
function it_warns_when_method_name_is_reserved(
|
||||
$exampleEvent,
|
||||
$suiteEvent,
|
||||
IO $io,
|
||||
NameCheckerInterface $nameChecker
|
||||
) {
|
||||
$this->callAfterExample($exampleEvent, $nameChecker, 'throw', false);
|
||||
|
||||
$io->writeBrokenCodeBlock("I cannot generate the method 'throw' for you because it is a reserved keyword", 2)->shouldBeCalled();
|
||||
|
||||
$this->afterSuite($suiteEvent);
|
||||
}
|
||||
|
||||
function it_prompts_and_warns_when_one_method_name_is_correct_but_other_reserved(
|
||||
$exampleEvent,
|
||||
SuiteEvent $suiteEvent,
|
||||
IO $io,
|
||||
NameCheckerInterface $nameChecker
|
||||
) {
|
||||
$this->callAfterExample($exampleEvent, $nameChecker, 'throw', false);
|
||||
$this->callAfterExample($exampleEvent, $nameChecker, 'foo');
|
||||
|
||||
$io->writeBrokenCodeBlock("I cannot generate the method 'throw' for you because it is a reserved keyword", 2)->shouldBeCalled();
|
||||
$io->askConfirmation('Do you want me to create `stdClass::foo()` for you?')->shouldBeCalled();
|
||||
$suiteEvent->markAsNotWorthRerunning()->shouldBeCalled();
|
||||
|
||||
$this->afterSuite($suiteEvent);
|
||||
}
|
||||
|
||||
private function callAfterExample($exampleEvent, $nameChecker, $method, $isNameValid = true)
|
||||
{
|
||||
$exception = new MethodNotFoundException('Error', new \stdClass(), $method);
|
||||
$exampleEvent->getException()->willReturn($exception);
|
||||
$nameChecker->isNameValid($method)->willReturn($isNameValid);
|
||||
|
||||
$this->afterExample($exampleEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ class PSR0LocatorSpec extends ObjectBehavior
|
||||
$fs->getFileContents($filePath)->willReturn('no class definition');
|
||||
$file->getRealPath()->willReturn($filePath);
|
||||
|
||||
$exception = new \RuntimeException('Spec file does not contains any class definition.');
|
||||
$exception = new \RuntimeException(sprintf('Spec file "%s" does not contains any class definition.', $filePath));
|
||||
|
||||
$this->shouldThrow($exception)->duringFindResources($this->srcPath);
|
||||
}
|
||||
|
||||
@@ -99,11 +99,21 @@ class PSR0ResourceSpec extends ObjectBehavior
|
||||
{
|
||||
$this->beConstructedWith(array('usr', 'lib', 'config_test'), $locator);
|
||||
|
||||
$locator->getFullSrcPath()->willReturn('/local/');
|
||||
$locator->getFullSpecPath()->willReturn('/local/spec/');
|
||||
$locator->getFullSrcPath()->willReturn($this->convert_to_path('/local/'));
|
||||
$locator->getFullSpecPath()->willReturn($this->convert_to_path('/local/spec/'));
|
||||
$locator->isPSR4()->willReturn(true);
|
||||
|
||||
$this->getSrcFilename()->shouldReturn('/local/usr/lib/config_test.php');
|
||||
$this->getSpecFilename()->shouldReturn('/local/spec/usr/lib/config_testSpec.php');
|
||||
$this->getSrcFilename()->shouldReturn($this->convert_to_path('/local/usr/lib/config_test.php'));
|
||||
$this->getSpecFilename()->shouldReturn($this->convert_to_path('/local/spec/usr/lib/config_testSpec.php'));
|
||||
}
|
||||
|
||||
private function convert_to_path($path)
|
||||
{
|
||||
if ('/' === DIRECTORY_SEPARATOR) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
return str_replace('/', DIRECTORY_SEPARATOR, $path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ use Prophecy\Argument;
|
||||
|
||||
use PhpSpec\Wrapper\Unwrapper;
|
||||
use PhpSpec\Formatter\Presenter\PresenterInterface;
|
||||
use PhpSpec\Exception\Example\SkippingException;
|
||||
|
||||
use ArrayObject;
|
||||
|
||||
@@ -32,8 +33,28 @@ class ThrowMatcherSpec extends ObjectBehavior
|
||||
$this->positiveMatch('throw', $arr, array('\Exception'))->during('ksort', array());
|
||||
}
|
||||
|
||||
function it_accepts_a_method_during_which_an_error_should_be_thrown(ArrayObject $arr)
|
||||
{
|
||||
if (!class_exists('\Error')) {
|
||||
throw new SkippingException('The class Error, introduced in PHP 7, does not exist');
|
||||
}
|
||||
|
||||
$arr->ksort()->willThrow('\Error');
|
||||
|
||||
$this->positiveMatch('throw', $arr, array('\Error'))->during('ksort', array());
|
||||
}
|
||||
|
||||
function it_accepts_a_method_during_which_an_exception_should_not_be_thrown(ArrayObject $arr)
|
||||
{
|
||||
$this->negativeMatch('throw', $arr, array('\Exception'))->during('ksort', array());
|
||||
}
|
||||
|
||||
function it_accepts_a_method_during_which_an_error_should_not_be_thrown(ArrayObject $arr)
|
||||
{
|
||||
if (!class_exists('\Error')) {
|
||||
throw new SkippingException('The class Error, introduced in PHP 7, does not exist');
|
||||
}
|
||||
|
||||
$this->negativeMatch('throw', $arr, array('\Error'))->during('ksort', array());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,14 +15,12 @@ class CurrentExampleTrackerSpec extends ObjectBehavior
|
||||
|
||||
function it_should_set_a_message()
|
||||
{
|
||||
$currentExample = new CurrentExampleTracker();
|
||||
$currentExample->setCurrentExample('test');
|
||||
expect($currentExample->getCurrentExample())->toBe('test');
|
||||
$this->setCurrentExample('test');
|
||||
$this->getCurrentExample()->shouldBe('test');
|
||||
}
|
||||
|
||||
function it_should_be_null_on_construction()
|
||||
{
|
||||
$currentExample = new CurrentExampleTracker();
|
||||
expect($currentExample->getCurrentExample())->toBe(null);
|
||||
$this->getCurrentExample()->shouldBe(null);
|
||||
}
|
||||
}
|
||||
|
||||
35
vendor/phpspec/phpspec/spec/PhpSpec/Util/ReservedWordsMethodNameCheckerSpec.php
vendored
Normal file
35
vendor/phpspec/phpspec/spec/PhpSpec/Util/ReservedWordsMethodNameCheckerSpec.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace spec\PhpSpec\Util;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Prophecy\Argument;
|
||||
|
||||
class ReservedWordsMethodNameCheckerSpec extends ObjectBehavior
|
||||
{
|
||||
function it_is_restriction_provider()
|
||||
{
|
||||
$this->shouldHaveType('PhpSpec\Util\NameCheckerInterface');
|
||||
}
|
||||
|
||||
function it_returns_true_for_not_php_restricted_name()
|
||||
{
|
||||
$this->isNameValid('foo')->shouldReturn(true);
|
||||
}
|
||||
|
||||
function it_returns_false_for_php_restricted_name()
|
||||
{
|
||||
$this->isNameValid('function')->shouldReturn(false);
|
||||
}
|
||||
|
||||
function it_returns_false_for_php_predefined_constant()
|
||||
{
|
||||
$this->isNameValid('__CLASS__')->shouldReturn(false);
|
||||
}
|
||||
|
||||
function it_returns_false_for_php_restricted_name_case_insensitive()
|
||||
{
|
||||
$this->isNameValid('instanceof')->shouldReturn(false);
|
||||
$this->isNameValid('instanceOf')->shouldReturn(false);
|
||||
}
|
||||
}
|
||||
@@ -18,10 +18,12 @@ final class TokenizedNamespaceResolver implements NamespaceResolver
|
||||
const STATE_DEFAULT = 0;
|
||||
const STATE_READING_NAMESPACE = 1;
|
||||
const STATE_READING_USE = 2;
|
||||
const STATE_READING_USE_GROUP = 3;
|
||||
|
||||
private $state = self::STATE_DEFAULT;
|
||||
|
||||
private $currentNamespace;
|
||||
private $currentUseGroup;
|
||||
private $currentUse;
|
||||
private $uses = array();
|
||||
|
||||
@@ -32,6 +34,7 @@ final class TokenizedNamespaceResolver implements NamespaceResolver
|
||||
{
|
||||
$this->state = self::STATE_DEFAULT;
|
||||
$this->currentUse = null;
|
||||
$this->currentUseGroup = null;
|
||||
$this->uses = array();
|
||||
|
||||
$tokens = token_get_all($code);
|
||||
@@ -48,12 +51,29 @@ final class TokenizedNamespaceResolver implements NamespaceResolver
|
||||
$this->currentNamespace .= $token[1];
|
||||
}
|
||||
break;
|
||||
case self::STATE_READING_USE_GROUP:
|
||||
if ('}' == $token) {
|
||||
$this->state = self::STATE_READING_USE;
|
||||
$this->currentUseGroup = null;
|
||||
}
|
||||
elseif (',' == $token) {
|
||||
$this->storeCurrentUse();
|
||||
}
|
||||
elseif (is_array($token)) {
|
||||
$this->currentUse = $this->currentUseGroup . trim($token[1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case self::STATE_READING_USE:
|
||||
if (';' == $token) {
|
||||
$this->storeCurrentUse();
|
||||
$this->state = self::STATE_DEFAULT;
|
||||
}
|
||||
if (',' == $token) {
|
||||
if ('{' == $token) {
|
||||
$this->currentUseGroup = trim($this->currentUse);
|
||||
$this->state = self::STATE_READING_USE_GROUP;
|
||||
}
|
||||
elseif (',' == $token) {
|
||||
$this->storeCurrentUse();
|
||||
}
|
||||
elseif (is_array($token)) {
|
||||
|
||||
@@ -74,6 +74,7 @@ final class TokenizedTypeHintRewriter implements TypeHintRewriter
|
||||
$this->currentClass = '';
|
||||
$this->currentFunction = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $tokens
|
||||
* @return array $tokens
|
||||
@@ -81,6 +82,13 @@ final class TokenizedTypeHintRewriter implements TypeHintRewriter
|
||||
private function stripTypeHints($tokens)
|
||||
{
|
||||
foreach ($tokens as $index => $token) {
|
||||
if ($this->isToken($token, '{')) {
|
||||
$this->currentBodyLevel++;
|
||||
}
|
||||
elseif ($this->isToken($token, '}')) {
|
||||
$this->currentBodyLevel--;
|
||||
}
|
||||
|
||||
switch ($this->state) {
|
||||
case self::STATE_READING_ARGUMENTS:
|
||||
if (')' == $token) {
|
||||
@@ -103,24 +111,21 @@ final class TokenizedTypeHintRewriter implements TypeHintRewriter
|
||||
$this->state = self::STATE_READING_FUNCTION_BODY;
|
||||
$this->currentBodyLevel = 1;
|
||||
}
|
||||
elseif ($this->tokenHasType($token, T_STRING) && !$this->currentClass) {
|
||||
elseif ('}' == $token && $this->currentClass) {
|
||||
$this->state = self::STATE_DEFAULT;
|
||||
$this->currentClass = null;
|
||||
}
|
||||
elseif ($this->tokenHasType($token, T_STRING) && !$this->currentClass && $this->shouldExtractTokensOfClass($token[1])) {
|
||||
$this->currentClass = $token[1];
|
||||
}
|
||||
elseif($this->tokenHasType($token, T_FUNCTION)) {
|
||||
elseif ($this->tokenHasType($token, T_FUNCTION) && $this->currentClass) {
|
||||
$this->state = self::STATE_READING_FUNCTION;
|
||||
}
|
||||
break;
|
||||
case self::STATE_READING_FUNCTION_BODY:
|
||||
if ('{' == $token) {
|
||||
$this->currentBodyLevel++;
|
||||
}
|
||||
elseif ('}' == $token) {
|
||||
$this->currentBodyLevel--;
|
||||
|
||||
if ($this->currentBodyLevel === 0) {
|
||||
$this->currentFunction = '';
|
||||
$this->state = self::STATE_READING_CLASS;
|
||||
}
|
||||
if ('}' == $token && $this->currentBodyLevel === 0) {
|
||||
$this->currentFunction = '';
|
||||
$this->state = self::STATE_READING_CLASS;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -155,7 +160,10 @@ final class TokenizedTypeHintRewriter implements TypeHintRewriter
|
||||
$typehint = '';
|
||||
for ($i = $index - 1; in_array($tokens[$i][0], $this->typehintTokens); $i--) {
|
||||
$typehint = $tokens[$i][1] . $typehint;
|
||||
unset($tokens[$i]);
|
||||
|
||||
if (T_WHITESPACE !== $tokens[$i][0]) {
|
||||
unset($tokens[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($typehint = trim($typehint)) {
|
||||
@@ -189,4 +197,25 @@ final class TokenizedTypeHintRewriter implements TypeHintRewriter
|
||||
{
|
||||
return is_array($token) && $type == $token[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function shouldExtractTokensOfClass($className)
|
||||
{
|
||||
return substr($className, -4) == 'Spec';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $token
|
||||
* @param string $string
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isToken($token, $string)
|
||||
{
|
||||
return $token == $string || (is_array($token) && $token[1] == $string);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,11 +87,12 @@ final class TokenizedCodeWriter implements CodeWriter
|
||||
$lastLines = array_slice($lines, $line);
|
||||
$toInsert = trim($toInsert, "\n\r");
|
||||
if ($leadingNewline) {
|
||||
$toInsert = PHP_EOL . $toInsert;
|
||||
$toInsert = "\n" . $toInsert;
|
||||
}
|
||||
array_unshift($lastLines, $toInsert);
|
||||
array_splice($lines, $line, count($lines), $lastLines);
|
||||
return implode(PHP_EOL, $lines);
|
||||
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,9 +106,10 @@ final class TokenizedCodeWriter implements CodeWriter
|
||||
$line--;
|
||||
$lines = explode("\n", $target);
|
||||
$lastLines = array_slice($lines, $line);
|
||||
array_unshift($lastLines, trim($toInsert, "\n\r") . PHP_EOL);
|
||||
array_unshift($lastLines, trim($toInsert, "\n\r") . "\n");
|
||||
array_splice($lines, $line, count($lines), $lastLines);
|
||||
return implode(PHP_EOL, $lines);
|
||||
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,12 +122,13 @@ final class TokenizedCodeWriter implements CodeWriter
|
||||
{
|
||||
$tokens = token_get_all($class);
|
||||
$searching = false;
|
||||
$inString = false;
|
||||
$searchPattern = array();
|
||||
|
||||
for ($i = count($tokens) - 1; $i >= 0; $i--) {
|
||||
$token = $tokens[$i];
|
||||
|
||||
if ($token === '}') {
|
||||
if ($token === '}' && !$inString) {
|
||||
$searching = true;
|
||||
continue;
|
||||
}
|
||||
@@ -134,6 +137,11 @@ final class TokenizedCodeWriter implements CodeWriter
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($token === '"') {
|
||||
$inString = !$inString;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->isWritePoint($token)) {
|
||||
$line = $token[2];
|
||||
return $this->insertStringAfterLine($class, $method, $line, $token[0] === T_COMMENT ?: $prependNewLine);
|
||||
@@ -144,7 +152,8 @@ final class TokenizedCodeWriter implements CodeWriter
|
||||
if ($token === '{') {
|
||||
$search = implode('', $searchPattern);
|
||||
$position = strpos($class, $search) + strlen($search) - 1;
|
||||
return substr_replace($class, PHP_EOL . $method . PHP_EOL, $position, 0);
|
||||
|
||||
return substr_replace($class, "\n" . $method . "\n", $position, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,6 +164,6 @@ final class TokenizedCodeWriter implements CodeWriter
|
||||
*/
|
||||
private function isWritePoint($token)
|
||||
{
|
||||
return is_array($token) && ($token[1] === PHP_EOL || $token[0] === T_COMMENT);
|
||||
return is_array($token) && ($token[1] === "\n" || $token[0] === T_COMMENT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ use PhpSpec\CodeAnalysis\TokenizedTypeHintRewriter;
|
||||
use PhpSpec\CodeAnalysis\VisibilityAccessInspector;
|
||||
use PhpSpec\Console\Assembler\PresenterAssembler;
|
||||
use PhpSpec\Process\Prerequisites\SuitePrerequisites;
|
||||
use SebastianBergmann\Exporter\Exporter;
|
||||
use PhpSpec\Util\ReservedWordsMethodNameChecker;
|
||||
use PhpSpec\Process\ReRunner;
|
||||
use PhpSpec\Util\MethodAnalyser;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
@@ -151,7 +151,8 @@ class ContainerAssembler
|
||||
return new Listener\CollaboratorMethodNotFoundListener(
|
||||
$c->get('console.io'),
|
||||
$c->get('locator.resource_manager'),
|
||||
$c->get('code_generator')
|
||||
$c->get('code_generator'),
|
||||
$c->get('util.reserved_words_checker')
|
||||
);
|
||||
});
|
||||
$container->setShared('event_dispatcher.listeners.named_constructor_not_found', function (ServiceContainer $c) {
|
||||
@@ -165,7 +166,8 @@ class ContainerAssembler
|
||||
return new Listener\MethodNotFoundListener(
|
||||
$c->get('console.io'),
|
||||
$c->get('locator.resource_manager'),
|
||||
$c->get('code_generator')
|
||||
$c->get('code_generator'),
|
||||
$c->get('util.reserved_words_checker')
|
||||
);
|
||||
});
|
||||
$container->setShared('event_dispatcher.listeners.stop_on_failure', function (ServiceContainer $c) {
|
||||
@@ -195,6 +197,9 @@ class ContainerAssembler
|
||||
$container->setShared('util.method_analyser', function () {
|
||||
return new MethodAnalyser();
|
||||
});
|
||||
$container->setShared('util.reserved_words_checker', function () {
|
||||
return new ReservedWordsMethodNameChecker();
|
||||
});
|
||||
$container->setShared('event_dispatcher.listeners.bootstrap', function (ServiceContainer $c) {
|
||||
return new Listener\BootstrapListener(
|
||||
$c->get('console.io')
|
||||
|
||||
@@ -342,4 +342,26 @@ class IO implements IOInterface
|
||||
}
|
||||
return $width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param int $indent
|
||||
*/
|
||||
public function writeBrokenCodeBlock($message, $indent = 0)
|
||||
{
|
||||
$message = wordwrap($message, $this->getBlockWidth() - ($indent * 2), "\n", true);
|
||||
|
||||
if ($indent) {
|
||||
$message = $this->indentText($message, $indent);
|
||||
}
|
||||
|
||||
$this->output->writeln("<broken-bg>".str_repeat(" ", $this->getBlockWidth())."</broken-bg>");
|
||||
|
||||
foreach (explode("\n", $message) as $line) {
|
||||
$this->output->writeln("<broken-bg>".str_pad($line, $this->getBlockWidth(), ' ')."</broken-bg>");
|
||||
}
|
||||
|
||||
$this->output->writeln("<broken-bg>".str_repeat(" ", $this->getBlockWidth())."</broken-bg>");
|
||||
$this->output->writeln('');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,4 +89,9 @@ class SuiteEvent extends Event implements EventInterface
|
||||
{
|
||||
$this->worthRerunning = true;
|
||||
}
|
||||
|
||||
public function markAsNotWorthRerunning()
|
||||
{
|
||||
$this->worthRerunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,13 +61,21 @@ class DotFormatter extends ConsoleFormatter
|
||||
break;
|
||||
}
|
||||
|
||||
if ($eventsCount % 50 === 0) {
|
||||
$remainder = $eventsCount % 50;
|
||||
$lastRow = $eventsCount === $this->examplesCount;
|
||||
|
||||
if ($remainder === 0 || $lastRow) {
|
||||
$length = strlen((string) $this->examplesCount);
|
||||
$format = sprintf(' %%%dd / %%%dd', $length, $length);
|
||||
|
||||
if ($lastRow) {
|
||||
$io->write(str_repeat(' ', 50 - $remainder));
|
||||
}
|
||||
|
||||
$io->write(sprintf($format, $eventsCount, $this->examplesCount));
|
||||
|
||||
if ($eventsCount !== $this->examplesCount) {
|
||||
$io->writeLn();
|
||||
$io->writeln();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ class StringEngine implements EngineInterface
|
||||
|
||||
public function compare($expected, $actual)
|
||||
{
|
||||
$expected = explode(PHP_EOL, (string) $expected);
|
||||
$actual = explode(PHP_EOL, (string) $actual);
|
||||
$expected = explode("\n", (string) $expected);
|
||||
$actual = explode("\n", (string) $actual);
|
||||
|
||||
$diff = new \Diff($expected, $actual, array());
|
||||
|
||||
@@ -41,6 +41,6 @@ class StringEngine implements EngineInterface
|
||||
}
|
||||
}
|
||||
|
||||
return sprintf("<code>%s%s</code>", PHP_EOL, implode(PHP_EOL, $lines));
|
||||
return sprintf("<code>%s%s</code>", "\n", implode("\n", $lines));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class BootstrapListener implements EventSubscriberInterface
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array('beforeSuite' => 'beforeSuite');
|
||||
return array('beforeSuite' => array('beforeSuite', 1100));
|
||||
}
|
||||
|
||||
public function beforeSuite()
|
||||
|
||||
@@ -19,6 +19,8 @@ use PhpSpec\Event\ExampleEvent;
|
||||
use PhpSpec\Event\SuiteEvent;
|
||||
use PhpSpec\Exception\Locator\ResourceCreationException;
|
||||
use PhpSpec\Locator\ResourceManagerInterface;
|
||||
use PhpSpec\Util\NameCheckerInterface;
|
||||
use PhpSpec\Util\ReservedWordsMethodNameChecker;
|
||||
use Prophecy\Argument\ArgumentsWildcard;
|
||||
use Prophecy\Exception\Doubler\MethodNotFoundException;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
@@ -47,16 +49,32 @@ class CollaboratorMethodNotFoundListener implements EventSubscriberInterface
|
||||
*/
|
||||
private $generator;
|
||||
|
||||
/**
|
||||
* @var NameCheckerInterface
|
||||
*/
|
||||
private $nameChecker;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $wrongMethodNames = array();
|
||||
|
||||
/**
|
||||
* @param IO $io
|
||||
* @param ResourceManagerInterface $resources
|
||||
* @param GeneratorManager $generator
|
||||
* @param NameCheckerInterface $nameChecker
|
||||
*/
|
||||
public function __construct(IO $io, ResourceManagerInterface $resources, GeneratorManager $generator)
|
||||
{
|
||||
public function __construct(
|
||||
IO $io,
|
||||
ResourceManagerInterface $resources,
|
||||
GeneratorManager $generator,
|
||||
NameCheckerInterface $nameChecker = null
|
||||
) {
|
||||
$this->io = $io;
|
||||
$this->resources = $resources;
|
||||
$this->generator = $generator;
|
||||
$this->nameChecker = $nameChecker ?: new ReservedWordsMethodNameChecker();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,7 +105,9 @@ class CollaboratorMethodNotFoundListener implements EventSubscriberInterface
|
||||
$this->interfaces[$interface] = array();
|
||||
}
|
||||
|
||||
$this->interfaces[$interface][$exception->getMethodName()] = $exception->getArguments();
|
||||
$methodName = $exception->getMethodName();
|
||||
$this->interfaces[$interface][$methodName] = $exception->getArguments();
|
||||
$this->checkIfMethodNameAllowed($methodName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,7 +139,6 @@ class CollaboratorMethodNotFoundListener implements EventSubscriberInterface
|
||||
public function afterSuite(SuiteEvent $event)
|
||||
{
|
||||
foreach ($this->interfaces as $interface => $methods) {
|
||||
|
||||
try {
|
||||
$resource = $this->resources->createResource($interface);
|
||||
} catch (ResourceCreationException $e) {
|
||||
@@ -127,6 +146,10 @@ class CollaboratorMethodNotFoundListener implements EventSubscriberInterface
|
||||
}
|
||||
|
||||
foreach ($methods as $method => $arguments) {
|
||||
if (in_array($method, $this->wrongMethodNames)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->io->askConfirmation(sprintf(self::PROMPT, $interface, $method))) {
|
||||
$this->generator->generate(
|
||||
$resource,
|
||||
@@ -140,6 +163,11 @@ class CollaboratorMethodNotFoundListener implements EventSubscriberInterface
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->wrongMethodNames) {
|
||||
$this->writeErrorMessage();
|
||||
$event->markAsNotWorthRerunning();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,4 +195,19 @@ class CollaboratorMethodNotFoundListener implements EventSubscriberInterface
|
||||
return $exception;
|
||||
}
|
||||
}
|
||||
|
||||
private function checkIfMethodNameAllowed($methodName)
|
||||
{
|
||||
if (!$this->nameChecker->isNameValid($methodName)) {
|
||||
$this->wrongMethodNames[] = $methodName;
|
||||
}
|
||||
}
|
||||
|
||||
private function writeErrorMessage()
|
||||
{
|
||||
foreach ($this->wrongMethodNames as $methodName) {
|
||||
$message = sprintf("I cannot generate the method '%s' for you because it is a reserved keyword", $methodName);
|
||||
$this->io->writeBrokenCodeBlock($message, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
namespace PhpSpec\Listener;
|
||||
|
||||
use PhpSpec\Util\ReservedWordsMethodNameChecker;
|
||||
use PhpSpec\Util\NameCheckerInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use PhpSpec\Console\IO;
|
||||
use PhpSpec\Locator\ResourceManagerInterface;
|
||||
@@ -27,12 +29,28 @@ class MethodNotFoundListener implements EventSubscriberInterface
|
||||
private $resources;
|
||||
private $generator;
|
||||
private $methods = array();
|
||||
private $wrongMethodNames = array();
|
||||
/**
|
||||
* @var NameCheckerInterface
|
||||
*/
|
||||
private $nameChecker;
|
||||
|
||||
public function __construct(IO $io, ResourceManagerInterface $resources, GeneratorManager $generator)
|
||||
{
|
||||
/**
|
||||
* @param IO $io
|
||||
* @param ResourceManagerInterface $resources
|
||||
* @param GeneratorManager $generator
|
||||
* @param NameCheckerInterface $nameChecker
|
||||
*/
|
||||
public function __construct(
|
||||
IO $io,
|
||||
ResourceManagerInterface $resources,
|
||||
GeneratorManager $generator,
|
||||
NameCheckerInterface $nameChecker = null
|
||||
) {
|
||||
$this->io = $io;
|
||||
$this->resources = $resources;
|
||||
$this->generator = $generator;
|
||||
$this->nameChecker = $nameChecker ?: new ReservedWordsMethodNameChecker();
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
@@ -54,7 +72,9 @@ class MethodNotFoundListener implements EventSubscriberInterface
|
||||
}
|
||||
|
||||
$classname = get_class($exception->getSubject());
|
||||
$this->methods[$classname .'::'.$exception->getMethodName()] = $exception->getArguments();
|
||||
$methodName = $exception->getMethodName();
|
||||
$this->methods[$classname .'::'.$methodName] = $exception->getArguments();
|
||||
$this->checkIfMethodNameAllowed($methodName);
|
||||
}
|
||||
|
||||
public function afterSuite(SuiteEvent $event)
|
||||
@@ -65,6 +85,11 @@ class MethodNotFoundListener implements EventSubscriberInterface
|
||||
|
||||
foreach ($this->methods as $call => $arguments) {
|
||||
list($classname, $method) = explode('::', $call);
|
||||
|
||||
if (in_array($method, $this->wrongMethodNames)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$message = sprintf('Do you want me to create `%s()` for you?', $call);
|
||||
|
||||
try {
|
||||
@@ -81,5 +106,25 @@ class MethodNotFoundListener implements EventSubscriberInterface
|
||||
$event->markAsWorthRerunning();
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->wrongMethodNames) {
|
||||
$this->writeWrongMethodNameMessage();
|
||||
$event->markAsNotWorthRerunning();
|
||||
}
|
||||
}
|
||||
|
||||
private function checkIfMethodNameAllowed($methodName)
|
||||
{
|
||||
if (!$this->nameChecker->isNameValid($methodName)) {
|
||||
$this->wrongMethodNames[] = $methodName;
|
||||
}
|
||||
}
|
||||
|
||||
private function writeWrongMethodNameMessage()
|
||||
{
|
||||
foreach ($this->wrongMethodNames as $methodName) {
|
||||
$message = sprintf("I cannot generate the method '%s' for you because it is a reserved keyword", $methodName);
|
||||
$this->io->writeBrokenCodeBlock($message, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,7 +282,7 @@ class PSR0Locator implements ResourceLocatorInterface
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
*
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
private function findSpecClassname($path)
|
||||
@@ -327,7 +327,7 @@ class PSR0Locator implements ResourceLocatorInterface
|
||||
$classname = $this->findSpecClassname($path);
|
||||
|
||||
if (null === $classname) {
|
||||
throw new \RuntimeException('Spec file does not contains any class definition.');
|
||||
throw new \RuntimeException(sprintf('Spec file "%s" does not contains any class definition.', $path));
|
||||
}
|
||||
|
||||
// Remove spec namespace from the begining of the classname.
|
||||
|
||||
@@ -28,10 +28,12 @@ class ThrowMatcher implements MatcherInterface
|
||||
* @var array
|
||||
*/
|
||||
private static $ignoredProperties = array('file', 'line', 'string', 'trace', 'previous');
|
||||
|
||||
/**
|
||||
* @var Unwrapper
|
||||
*/
|
||||
private $unwrapper;
|
||||
|
||||
/**
|
||||
* @var PresenterInterface
|
||||
*/
|
||||
@@ -43,9 +45,9 @@ class ThrowMatcher implements MatcherInterface
|
||||
private $factory;
|
||||
|
||||
/**
|
||||
* @param Unwrapper $unwrapper
|
||||
* @param PresenterInterface $presenter
|
||||
* @param ReflectionFactory $factory
|
||||
* @param Unwrapper $unwrapper
|
||||
* @param PresenterInterface $presenter
|
||||
* @param ReflectionFactory|null $factory
|
||||
*/
|
||||
public function __construct(Unwrapper $unwrapper, PresenterInterface $presenter, ReflectionFactory $factory = null)
|
||||
{
|
||||
@@ -91,114 +93,134 @@ class ThrowMatcher implements MatcherInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $callable
|
||||
* @param array $arguments
|
||||
* @param null $exception
|
||||
* @param callable $callable
|
||||
* @param array $arguments
|
||||
* @param null|object|string $exception
|
||||
*
|
||||
* @throws \PhpSpec\Exception\Example\FailureException
|
||||
* @throws \PhpSpec\Exception\Example\NotEqualException
|
||||
*/
|
||||
public function verifyPositive($callable, array $arguments, $exception = null)
|
||||
{
|
||||
$exceptionThrown = null;
|
||||
|
||||
try {
|
||||
call_user_func_array($callable, $arguments);
|
||||
} catch (\Exception $e) {
|
||||
if (null === $exception) {
|
||||
return;
|
||||
}
|
||||
$exceptionThrown = $e;
|
||||
} catch (\Throwable $e) {
|
||||
$exceptionThrown = $e;
|
||||
}
|
||||
|
||||
if (!$e instanceof $exception) {
|
||||
throw new FailureException(sprintf(
|
||||
if (!$exceptionThrown) {
|
||||
throw new FailureException('Expected to get exception / throwable, none got.');
|
||||
}
|
||||
|
||||
if (null === $exception) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$exceptionThrown instanceof $exception) {
|
||||
throw new FailureException(
|
||||
sprintf(
|
||||
'Expected exception of class %s, but got %s.',
|
||||
$this->presenter->presentValue($exception),
|
||||
$this->presenter->presentValue($e)
|
||||
));
|
||||
}
|
||||
$this->presenter->presentValue($exceptionThrown)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (is_object($exception)) {
|
||||
$exceptionRefl = $this->factory->create($exception);
|
||||
foreach ($exceptionRefl->getProperties() as $property) {
|
||||
if (in_array($property->getName(), self::$ignoredProperties)) {
|
||||
continue;
|
||||
}
|
||||
if (is_object($exception)) {
|
||||
$exceptionRefl = $this->factory->create($exception);
|
||||
foreach ($exceptionRefl->getProperties() as $property) {
|
||||
if (in_array($property->getName(), self::$ignoredProperties, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$property->setAccessible(true);
|
||||
$expected = $property->getValue($exception);
|
||||
$actual = $property->getValue($e);
|
||||
$property->setAccessible(true);
|
||||
$expected = $property->getValue($exception);
|
||||
$actual = $property->getValue($exceptionThrown);
|
||||
|
||||
if (null !== $expected && $actual !== $expected) {
|
||||
throw new NotEqualException(sprintf(
|
||||
if (null !== $expected && $actual !== $expected) {
|
||||
throw new NotEqualException(
|
||||
sprintf(
|
||||
'Expected exception `%s` to be %s, but it is %s.',
|
||||
$property->getName(),
|
||||
$this->presenter->presentValue($expected),
|
||||
$this->presenter->presentValue($actual)
|
||||
), $expected, $actual);
|
||||
}
|
||||
), $expected, $actual
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
throw new FailureException('Expected to get exception, none got.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $callable
|
||||
* @param array $arguments
|
||||
* @param string|null $exception
|
||||
* @param callable $callable
|
||||
* @param array $arguments
|
||||
* @param string|null|object $exception
|
||||
*
|
||||
* @throws \PhpSpec\Exception\Example\FailureException
|
||||
*/
|
||||
public function verifyNegative($callable, array $arguments, $exception = null)
|
||||
{
|
||||
$exceptionThrown = null;
|
||||
|
||||
try {
|
||||
call_user_func_array($callable, $arguments);
|
||||
} catch (\Exception $e) {
|
||||
if (null === $exception) {
|
||||
throw new FailureException(sprintf(
|
||||
$exceptionThrown = $e;
|
||||
} catch (\Throwable $e) {
|
||||
$exceptionThrown = $e;
|
||||
}
|
||||
|
||||
if ($exceptionThrown && null === $exception) {
|
||||
throw new FailureException(
|
||||
sprintf(
|
||||
'Expected to not throw any exceptions, but got %s.',
|
||||
$this->presenter->presentValue($e)
|
||||
));
|
||||
}
|
||||
$this->presenter->presentValue($exceptionThrown)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($e instanceof $exception) {
|
||||
$invalidProperties = array();
|
||||
if (is_object($exception)) {
|
||||
$exceptionRefl = $this->factory->create($exception);
|
||||
foreach ($exceptionRefl->getProperties() as $property) {
|
||||
if (in_array($property->getName(), self::$ignoredProperties)) {
|
||||
continue;
|
||||
}
|
||||
if ($exceptionThrown && $exceptionThrown instanceof $exception) {
|
||||
$invalidProperties = array();
|
||||
if (is_object($exception)) {
|
||||
$exceptionRefl = $this->factory->create($exception);
|
||||
foreach ($exceptionRefl->getProperties() as $property) {
|
||||
if (in_array($property->getName(), self::$ignoredProperties, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$property->setAccessible(true);
|
||||
$expected = $property->getValue($exception);
|
||||
$actual = $property->getValue($e);
|
||||
$property->setAccessible(true);
|
||||
$expected = $property->getValue($exception);
|
||||
$actual = $property->getValue($exceptionThrown);
|
||||
|
||||
if (null !== $expected && $actual === $expected) {
|
||||
$invalidProperties[] = sprintf(
|
||||
' `%s`=%s',
|
||||
$property->getName(),
|
||||
$this->presenter->presentValue($expected)
|
||||
);
|
||||
}
|
||||
if (null !== $expected && $actual === $expected) {
|
||||
$invalidProperties[] = sprintf(
|
||||
' `%s`=%s',
|
||||
$property->getName(),
|
||||
$this->presenter->presentValue($expected)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$withProperties = '';
|
||||
if (count($invalidProperties) > 0) {
|
||||
$withProperties = sprintf(
|
||||
' with'.PHP_EOL.'%s,'.PHP_EOL,
|
||||
implode(",\n", $invalidProperties)
|
||||
);
|
||||
}
|
||||
$withProperties = '';
|
||||
if (count($invalidProperties) > 0) {
|
||||
$withProperties = sprintf(
|
||||
' with'.PHP_EOL.'%s,'.PHP_EOL,
|
||||
implode(",\n", $invalidProperties)
|
||||
);
|
||||
}
|
||||
|
||||
throw new FailureException(sprintf(
|
||||
throw new FailureException(
|
||||
sprintf(
|
||||
'Expected to not throw %s exception%s but got it.',
|
||||
$this->presenter->presentValue($exception),
|
||||
$withProperties
|
||||
));
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +248,7 @@ class ThrowMatcher implements MatcherInterface
|
||||
function ($method, $arguments) use ($check, $subject, $exception, $unwrapper) {
|
||||
$arguments = $unwrapper->unwrapAll($arguments);
|
||||
|
||||
$methodName = $arguments[0];
|
||||
$methodName = $arguments[0];
|
||||
$arguments = isset($arguments[1]) ? $arguments[1] : array();
|
||||
$callable = array($subject, $methodName);
|
||||
|
||||
@@ -253,7 +275,7 @@ class ThrowMatcher implements MatcherInterface
|
||||
*/
|
||||
private function getException(array $arguments)
|
||||
{
|
||||
if (0 == count($arguments)) {
|
||||
if (0 === count($arguments)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -261,15 +283,21 @@ class ThrowMatcher implements MatcherInterface
|
||||
return $arguments[0];
|
||||
}
|
||||
|
||||
if (is_object($arguments[0]) && $arguments[0] instanceof \Exception) {
|
||||
return $arguments[0];
|
||||
if (is_object($arguments[0])) {
|
||||
if (class_exists('\Throwable') && $arguments[0] instanceof \Throwable) {
|
||||
return $arguments[0];
|
||||
} elseif ($arguments[0] instanceof \Exception) {
|
||||
return $arguments[0];
|
||||
}
|
||||
}
|
||||
|
||||
throw new MatcherException(sprintf(
|
||||
"Wrong argument provided in throw matcher.\n".
|
||||
"Fully qualified classname or exception instance expected,\n".
|
||||
"Got %s.",
|
||||
$this->presenter->presentValue($arguments[0])
|
||||
));
|
||||
throw new MatcherException(
|
||||
sprintf(
|
||||
"Wrong argument provided in throw matcher.\n".
|
||||
"Fully qualified classname or exception instance expected,\n".
|
||||
"Got %s.",
|
||||
$this->presenter->presentValue($arguments[0])
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ use ArrayAccess;
|
||||
* @method void beConstructedThrough($factoryMethod, array $constructorArguments = array())
|
||||
* @method void beAnInstanceOf($class)
|
||||
* @method void shouldHaveType($type)
|
||||
* @method void shouldImplement($interface)
|
||||
* @method Subject\Expectation\DuringCall shouldThrow($exception = null)
|
||||
*/
|
||||
class ObjectBehavior implements
|
||||
|
||||
@@ -198,7 +198,7 @@ final class ClassFileAnalyser
|
||||
for ($i = $index, $max = count($tokens); $i < $max; $i++) {
|
||||
$token = $tokens[$i];
|
||||
|
||||
if ('{' === $token) {
|
||||
if ('{' === $token || $this->isSpecialBraceToken($token)) {
|
||||
$braceCount++;
|
||||
continue;
|
||||
}
|
||||
@@ -212,6 +212,15 @@ final class ClassFileAnalyser
|
||||
}
|
||||
}
|
||||
|
||||
private function isSpecialBraceToken($token)
|
||||
{
|
||||
if (!is_array($token)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $token[1] === "{";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $token
|
||||
* @return bool
|
||||
|
||||
24
vendor/phpspec/phpspec/src/PhpSpec/Util/NameCheckerInterface.php
vendored
Normal file
24
vendor/phpspec/phpspec/src/PhpSpec/Util/NameCheckerInterface.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of PhpSpec, A php toolset to drive emergent
|
||||
* design by specification.
|
||||
*
|
||||
* (c) Marcello Duarte <marcello.duarte@gmail.com>
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace PhpSpec\Util;
|
||||
|
||||
interface NameCheckerInterface
|
||||
{
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNameValid($name);
|
||||
}
|
||||
101
vendor/phpspec/phpspec/src/PhpSpec/Util/ReservedWordsMethodNameChecker.php
vendored
Normal file
101
vendor/phpspec/phpspec/src/PhpSpec/Util/ReservedWordsMethodNameChecker.php
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of PhpSpec, A php toolset to drive emergent
|
||||
* design by specification.
|
||||
*
|
||||
* (c) Marcello Duarte <marcello.duarte@gmail.com>
|
||||
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace PhpSpec\Util;
|
||||
|
||||
final class ReservedWordsMethodNameChecker implements NameCheckerInterface
|
||||
{
|
||||
private $reservedWords = array(
|
||||
'__halt_compiler',
|
||||
'abstract',
|
||||
'and',
|
||||
'array',
|
||||
'as',
|
||||
'break',
|
||||
'callable',
|
||||
'case',
|
||||
'catch',
|
||||
'class',
|
||||
'clone',
|
||||
'const',
|
||||
'continue',
|
||||
'declare',
|
||||
'default',
|
||||
'die',
|
||||
'do',
|
||||
'echo',
|
||||
'else',
|
||||
'elseif',
|
||||
'empty',
|
||||
'enddeclare',
|
||||
'endfor',
|
||||
'endforeach',
|
||||
'endif',
|
||||
'endswitch',
|
||||
'endwhile',
|
||||
'eval',
|
||||
'exit',
|
||||
'extends',
|
||||
'final',
|
||||
'for',
|
||||
'foreach',
|
||||
'function',
|
||||
'global',
|
||||
'goto',
|
||||
'if',
|
||||
'implements',
|
||||
'include',
|
||||
'include_once',
|
||||
'instanceof',
|
||||
'insteadof',
|
||||
'interface',
|
||||
'isset',
|
||||
'list',
|
||||
'namespace',
|
||||
'new',
|
||||
'or',
|
||||
'print',
|
||||
'private',
|
||||
'protected',
|
||||
'public',
|
||||
'require',
|
||||
'require_once',
|
||||
'return',
|
||||
'static',
|
||||
'switch',
|
||||
'throw',
|
||||
'trait',
|
||||
'try',
|
||||
'unset',
|
||||
'use',
|
||||
'var',
|
||||
'while',
|
||||
'xor',
|
||||
'__class__',
|
||||
'__dir__',
|
||||
'__file__',
|
||||
'__function__',
|
||||
'__line__',
|
||||
'__method__',
|
||||
'__namespace__',
|
||||
'__trait__',
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isNameValid($name)
|
||||
{
|
||||
return !in_array(strtolower($name), $this->reservedWords);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user