Skip to content

Commit

Permalink
Add phpspecs as spec for better tests 🚀
Browse files Browse the repository at this point in the history
  • Loading branch information
akondas committed Dec 23, 2018
1 parent 0f42bca commit c38dc02
Show file tree
Hide file tree
Showing 170 changed files with 12,615 additions and 226 deletions.
3 changes: 1 addition & 2 deletions .php_cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ return PhpCsFixer\Config::create()
->setFinder(
PhpCsFixer\Finder::create()
->in(__DIR__ . '/src')
->in(__DIR__ . '/tests')
->in(__DIR__ . '/spec')
)
->setRiskyAllowed(true)
->setUsingCache(false)
;
;
5 changes: 2 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
},
"autoload-dev": {
"psr-4": {
"Proget\\Tests\\PHPStan\\PhpSpec\\": "tests/",
"spec\\Proget\\": "spec/Proget/"
"spec\\PhpSpec\\": "spec/PhpSpec/"
}
},
"license": "MIT",
Expand All @@ -37,7 +36,7 @@
"check-cs": "php-cs-fixer fix --dry-run --diff",
"fix-cs": "php-cs-fixer fix",
"tests": "phpspec run",
"stan": "phpstan analyse -l max -c ./phpstan.neon ./src ./tests ./spec",
"stan": "phpstan analyse -l max -c ./phpstan.neon ./src ./spec",
"check": [
"@check-cs",
"@stan",
Expand Down
6 changes: 6 additions & 0 deletions extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ services:
-
class: Proget\PHPStan\PhpSpec\Reflection\ObjectBehaviorMethodsClassReflectionExtension
tags: [phpstan.broker.methodsClassReflectionExtension]
-
class: Proget\PHPStan\PhpSpec\Reflection\ObjectBehaviorPropertiesClassReflectionExtension
tags: [phpstan.broker.propertiesClassReflectionExtension]
-
class: Proget\PHPStan\PhpSpec\Type\ObjectBehaviorDynamicMethodReturnTypeExtension
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]

extensions:
phpspec: Proget\PHPStan\PhpSpec\DependencyInjection\CollaboratorExtension
Expand Down
99 changes: 99 additions & 0 deletions spec/PhpSpec/CodeAnalysis/MagicAwareAccessInspectorSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

declare(strict_types=1);

namespace spec\PhpSpec\CodeAnalysis;

use PhpSpec\CodeAnalysis\AccessInspector;
use PhpSpec\ObjectBehavior;

class MagicAwareAccessInspectorSpec extends ObjectBehavior
{
public function let(AccessInspector $accessInspector)
{
$this->beConstructedWith($accessInspector);
}

public function it_should_be_an_access_inspector()
{
$this->shouldImplement('PhpSpec\CodeAnalysis\AccessInspector');
}

public function it_should_detect_a_magic_getter_if_no_value_is_given()
{
$this->isPropertyReadable(new ObjectWithMagicGet, 'property')->shouldReturn(true);
}

public function it_should_detect_a_magic_setter_if_a_value_is_given()
{
$this->isPropertyWritable(new ObjectWithMagicSet, 'property', true)->shouldReturn(true);
}

public function it_should_detect_a_magic_call_method()
{
$this->isMethodCallable(new ObjectWithMagicCall, 'method')->shouldreturn(true);
}

public function it_should_not_detect_a_getter_if_there_is_no_magic_getter_and_wrapped_inspector_finds_none(AccessInspector $accessInspector)
{
$accessInspector->isPropertyReadable(new \stdClass(), 'foo')->willReturn(false);

$this->isPropertyReadable(new \stdClass(), 'foo')->shouldReturn(false);
}

public function it_should_detect_a_getter_if_there_is_no_magic_getter_but_wrapped_inspector_finds_one(AccessInspector $accessInspector)
{
$accessInspector->isPropertyReadable(new \stdClass(), 'foo')->willReturn(true);

$this->isPropertyReadable(new \stdClass(), 'foo')->shouldReturn(true);
}

public function it_should_not_detect_a_setter_if_there_is_no_magic_setter_and_wrapped_inspector_finds_none(AccessInspector $accessInspector)
{
$accessInspector->isPropertyWritable(new \stdClass(), 'foo')->willReturn(false);

$this->isPropertyWritable(new \stdClass(), 'foo')->shouldReturn(false);
}

public function it_should_detect_a_setter_if_there_is_no_magic_setter_but_wrapped_inspector_finds_one(AccessInspector $accessInspector)
{
$accessInspector->isPropertyWritable(new \stdClass(), 'foo')->willReturn(true);

$this->isPropertyWritable(new \stdClass(), 'foo')->shouldReturn(true);
}

public function it_should_detect_a_method_if_there_is_no_magic_caller_and_wrapped_inspector_finds_none(AccessInspector $accessInspector)
{
$accessInspector->isMethodCallable(new \stdClass(), 'foo')->willReturn(false);

$this->isMethodCallable(new \stdClass(), 'foo')->shouldReturn(false);
}

public function it_should_detect_a_method_if_there_is_no_magic_caller_but_wrapped_inspector_finds_one(AccessInspector $accessInspector)
{
$accessInspector->isMethodCallable(new \stdClass(), 'foo')->willReturn(true);

$this->isMethodCallable(new \stdClass(), 'foo')->shouldReturn(true);
}
}

class ObjectWithMagicGet
{
public function __get($name)
{
}
}

class ObjectWithMagicSet
{
public function __set($name, $value)
{
}
}

class ObjectWithMagicCall
{
public function __call($name, $args)
{
}
}
45 changes: 45 additions & 0 deletions spec/PhpSpec/CodeAnalysis/StaticRejectingNamespaceResolverSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace spec\PhpSpec\CodeAnalysis;

use PhpSpec\CodeAnalysis\DisallowedNonObjectTypehintException;
use PhpSpec\CodeAnalysis\NamespaceResolver;
use PhpSpec\ObjectBehavior;

class StaticRejectingNamespaceResolverSpec extends ObjectBehavior
{
public function let(NamespaceResolver $namespaceResolver)
{
$this->beConstructedWith($namespaceResolver);
}

public function it_is_initializable()
{
$this->shouldHaveType('PhpSpec\CodeAnalysis\NamespaceResolver');
}

public function it_delegates_analysis_to_wrapped_resolver(NamespaceResolver $namespaceResolver)
{
$this->analyse('foo');

$namespaceResolver->analyse('foo')->shouldhaveBeenCalled();
}

public function it_delegates_resolution_to_wrapped_resolver(NamespaceResolver $namespaceResolver)
{
$namespaceResolver->resolve('Bar')->willReturn('Foo\Bar');

$this->resolve('Bar')->shouldReturn('Foo\Bar');
}

public function it_does_not_allow_resolution_of_non_object_types()
{
$this->shouldThrow(DisallowedNonObjectTypehintException::class)->duringResolve('int');
$this->shouldThrow(DisallowedNonObjectTypehintException::class)->duringResolve('float');
$this->shouldThrow(DisallowedNonObjectTypehintException::class)->duringResolve('string');
$this->shouldThrow(DisallowedNonObjectTypehintException::class)->duringResolve('bool');
$this->shouldThrow(DisallowedNonObjectTypehintException::class)->duringResolve('iterable');
}
}
128 changes: 128 additions & 0 deletions spec/PhpSpec/CodeAnalysis/TokenizedNamespaceResolverSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php

declare(strict_types=1);

namespace spec\PhpSpec\CodeAnalysis;

use PhpSpec\ObjectBehavior;

class TokenizedNamespaceResolverSpec extends ObjectBehavior
{
public function it_is_initializable()
{
$this->shouldHaveType('PhpSpec\CodeAnalysis\NamespaceResolver');
}

public function it_resolves_types_outside_of_namespaces()
{
$this->analyse('
<?php
class Foo
{
}
');

$this->resolve('Bar')->shouldReturn('Bar');
$this->resolve('Bar')->shouldReturn('Bar');
}

public function it_resolves_types_from_current_namespace()
{
$this->analyse('
<?php
namespace Baz;
class Foo
{
}
');

$this->resolve('Foo')->shouldReturn('Baz\Foo');
$this->resolve('Bar')->shouldReturn('Baz\Bar');
}

public function it_resolves_types_with_use_statements()
{
$this->analyse('
<?php
namespace Baz;
use Boz\Bar;
class Foo
{
}
');

$this->resolve('Foo')->shouldReturn('Baz\Foo');
$this->resolve('Bar')->shouldReturn('Boz\Bar');
}

public function it_resolves_types_with_use_aliases()
{
$this->analyse('
<?php
namespace Baz;
use Boz\Bar as Biz;
class Foo
{
}
');

$this->resolve('Foo')->shouldReturn('Baz\Foo');
$this->resolve('Biz')->shouldReturn('Boz\Bar');
}

public function it_resolves_types_with_partial_use_statements()
{
$this->analyse('
<?php
namespace Baz;
use Boz\Bar;
class Foo
{
function it_something(Bar\Baz $boz)
{
}
}
');

$this->resolve('Foo')->shouldReturn('Baz\Foo');
$this->resolve('Bar\Baz')->shouldReturn('Boz\Bar\Baz');
}

public 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');
}
}
Loading

0 comments on commit c38dc02

Please sign in to comment.