mirror of
https://github.com/rectorphp/rector.git
synced 2024-05-31 00:10:51 +00:00
[PhpSpecToPHPUnit] Deprecate historical set, mostly for experimental in early days (#1901)
This commit is contained in:
parent
320cdcd8de
commit
e2cc867255
|
@ -1,4 +1,4 @@
|
|||
# 512 Rules Overview
|
||||
# 505 Rules Overview
|
||||
|
||||
<br>
|
||||
|
||||
|
@ -74,8 +74,6 @@
|
|||
|
||||
- [Php81](#php81) (9)
|
||||
|
||||
- [PhpSpecToPHPUnit](#phpspectophpunit) (7)
|
||||
|
||||
- [PostRector](#postrector) (7)
|
||||
|
||||
- [Privatization](#privatization) (10)
|
||||
|
@ -8550,225 +8548,6 @@ Refactor Spatie enum class to native Enum
|
|||
|
||||
<br>
|
||||
|
||||
## PhpSpecToPHPUnit
|
||||
|
||||
### AddMockPropertiesRector
|
||||
|
||||
Migrate PhpSpec behavior to PHPUnit test
|
||||
|
||||
- class: [`Rector\PhpSpecToPHPUnit\Rector\Class_\AddMockPropertiesRector`](../rules/PhpSpecToPHPUnit/Rector/Class_/AddMockPropertiesRector.php)
|
||||
|
||||
```diff
|
||||
namespace spec\SomeNamespaceForThisTest;
|
||||
|
||||
-use PhpSpec\ObjectBehavior;
|
||||
-
|
||||
class OrderSpec extends ObjectBehavior
|
||||
{
|
||||
- public function let(OrderFactory $factory, ShippingMethod $shippingMethod): void
|
||||
+ /**
|
||||
+ * @var \SomeNamespaceForThisTest\Order
|
||||
+ */
|
||||
+ private $order;
|
||||
+ protected function setUp()
|
||||
{
|
||||
- $factory->createShippingMethodFor(Argument::any())->shouldBeCalled()->willReturn($shippingMethod);
|
||||
+ /** @var OrderFactory|\PHPUnit\Framework\MockObject\MockObject $factory */
|
||||
+ $factory = $this->createMock(OrderFactory::class);
|
||||
+
|
||||
+ /** @var ShippingMethod|\PHPUnit\Framework\MockObject\MockObject $shippingMethod */
|
||||
+ $shippingMethod = $this->createMock(ShippingMethod::class);
|
||||
+
|
||||
+ $factory->expects($this->once())->method('createShippingMethodFor')->willReturn($shippingMethod);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### MockVariableToPropertyFetchRector
|
||||
|
||||
Migrate PhpSpec behavior to PHPUnit test
|
||||
|
||||
- class: [`Rector\PhpSpecToPHPUnit\Rector\Variable\MockVariableToPropertyFetchRector`](../rules/PhpSpecToPHPUnit/Rector/Variable/MockVariableToPropertyFetchRector.php)
|
||||
|
||||
```diff
|
||||
namespace spec\SomeNamespaceForThisTest;
|
||||
|
||||
-use PhpSpec\ObjectBehavior;
|
||||
-
|
||||
class OrderSpec extends ObjectBehavior
|
||||
{
|
||||
- public function let(OrderFactory $factory, ShippingMethod $shippingMethod): void
|
||||
+ /**
|
||||
+ * @var \SomeNamespaceForThisTest\Order
|
||||
+ */
|
||||
+ private $order;
|
||||
+ protected function setUp()
|
||||
{
|
||||
- $factory->createShippingMethodFor(Argument::any())->shouldBeCalled()->willReturn($shippingMethod);
|
||||
+ /** @var OrderFactory|\PHPUnit\Framework\MockObject\MockObject $factory */
|
||||
+ $factory = $this->createMock(OrderFactory::class);
|
||||
+
|
||||
+ /** @var ShippingMethod|\PHPUnit\Framework\MockObject\MockObject $shippingMethod */
|
||||
+ $shippingMethod = $this->createMock(ShippingMethod::class);
|
||||
+
|
||||
+ $factory->expects($this->once())->method('createShippingMethodFor')->willReturn($shippingMethod);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### PhpSpecClassToPHPUnitClassRector
|
||||
|
||||
Migrate PhpSpec behavior to PHPUnit test
|
||||
|
||||
- class: [`Rector\PhpSpecToPHPUnit\Rector\Class_\PhpSpecClassToPHPUnitClassRector`](../rules/PhpSpecToPHPUnit/Rector/Class_/PhpSpecClassToPHPUnitClassRector.php)
|
||||
|
||||
```diff
|
||||
namespace spec\SomeNamespaceForThisTest;
|
||||
|
||||
-use PhpSpec\ObjectBehavior;
|
||||
-
|
||||
class OrderSpec extends ObjectBehavior
|
||||
{
|
||||
- public function let(OrderFactory $factory, ShippingMethod $shippingMethod): void
|
||||
+ /**
|
||||
+ * @var \SomeNamespaceForThisTest\Order
|
||||
+ */
|
||||
+ private $order;
|
||||
+ protected function setUp()
|
||||
{
|
||||
- $factory->createShippingMethodFor(Argument::any())->shouldBeCalled()->willReturn($shippingMethod);
|
||||
+ /** @var OrderFactory|\PHPUnit\Framework\MockObject\MockObject $factory */
|
||||
+ $factory = $this->createMock(OrderFactory::class);
|
||||
+
|
||||
+ /** @var ShippingMethod|\PHPUnit\Framework\MockObject\MockObject $shippingMethod */
|
||||
+ $shippingMethod = $this->createMock(ShippingMethod::class);
|
||||
+
|
||||
+ $factory->expects($this->once())->method('createShippingMethodFor')->willReturn($shippingMethod);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### PhpSpecMethodToPHPUnitMethodRector
|
||||
|
||||
Migrate PhpSpec behavior to PHPUnit test
|
||||
|
||||
- class: [`Rector\PhpSpecToPHPUnit\Rector\ClassMethod\PhpSpecMethodToPHPUnitMethodRector`](../rules/PhpSpecToPHPUnit/Rector/ClassMethod/PhpSpecMethodToPHPUnitMethodRector.php)
|
||||
|
||||
```diff
|
||||
namespace spec\SomeNamespaceForThisTest;
|
||||
|
||||
-use PhpSpec\ObjectBehavior;
|
||||
-
|
||||
class OrderSpec extends ObjectBehavior
|
||||
{
|
||||
- public function let(OrderFactory $factory, ShippingMethod $shippingMethod): void
|
||||
+ /**
|
||||
+ * @var \SomeNamespaceForThisTest\Order
|
||||
+ */
|
||||
+ private $order;
|
||||
+ protected function setUp()
|
||||
{
|
||||
- $factory->createShippingMethodFor(Argument::any())->shouldBeCalled()->willReturn($shippingMethod);
|
||||
+ /** @var OrderFactory|\PHPUnit\Framework\MockObject\MockObject $factory */
|
||||
+ $factory = $this->createMock(OrderFactory::class);
|
||||
+
|
||||
+ /** @var ShippingMethod|\PHPUnit\Framework\MockObject\MockObject $shippingMethod */
|
||||
+ $shippingMethod = $this->createMock(ShippingMethod::class);
|
||||
+
|
||||
+ $factory->expects($this->once())->method('createShippingMethodFor')->willReturn($shippingMethod);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### PhpSpecMocksToPHPUnitMocksRector
|
||||
|
||||
Migrate PhpSpec behavior to PHPUnit test
|
||||
|
||||
- class: [`Rector\PhpSpecToPHPUnit\Rector\MethodCall\PhpSpecMocksToPHPUnitMocksRector`](../rules/PhpSpecToPHPUnit/Rector/MethodCall/PhpSpecMocksToPHPUnitMocksRector.php)
|
||||
|
||||
```diff
|
||||
namespace spec\SomeNamespaceForThisTest;
|
||||
|
||||
-use PhpSpec\ObjectBehavior;
|
||||
-
|
||||
class OrderSpec extends ObjectBehavior
|
||||
{
|
||||
- public function let(OrderFactory $factory, ShippingMethod $shippingMethod): void
|
||||
+ /**
|
||||
+ * @var \SomeNamespaceForThisTest\Order
|
||||
+ */
|
||||
+ private $order;
|
||||
+ protected function setUp()
|
||||
{
|
||||
- $factory->createShippingMethodFor(Argument::any())->shouldBeCalled()->willReturn($shippingMethod);
|
||||
+ /** @var OrderFactory|\PHPUnit\Framework\MockObject\MockObject $factory */
|
||||
+ $factory = $this->createMock(OrderFactory::class);
|
||||
+
|
||||
+ /** @var ShippingMethod|\PHPUnit\Framework\MockObject\MockObject $shippingMethod */
|
||||
+ $shippingMethod = $this->createMock(ShippingMethod::class);
|
||||
+
|
||||
+ $factory->expects($this->once())->method('createShippingMethodFor')->willReturn($shippingMethod);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### PhpSpecPromisesToPHPUnitAssertRector
|
||||
|
||||
Migrate PhpSpec behavior to PHPUnit test
|
||||
|
||||
- class: [`Rector\PhpSpecToPHPUnit\Rector\MethodCall\PhpSpecPromisesToPHPUnitAssertRector`](../rules/PhpSpecToPHPUnit/Rector/MethodCall/PhpSpecPromisesToPHPUnitAssertRector.php)
|
||||
|
||||
```diff
|
||||
namespace spec\SomeNamespaceForThisTest;
|
||||
|
||||
-use PhpSpec\ObjectBehavior;
|
||||
-
|
||||
class OrderSpec extends ObjectBehavior
|
||||
{
|
||||
- public function let(OrderFactory $factory, ShippingMethod $shippingMethod): void
|
||||
+ /**
|
||||
+ * @var \SomeNamespaceForThisTest\Order
|
||||
+ */
|
||||
+ private $order;
|
||||
+ protected function setUp()
|
||||
{
|
||||
- $factory->createShippingMethodFor(Argument::any())->shouldBeCalled()->willReturn($shippingMethod);
|
||||
+ /** @var OrderFactory|\PHPUnit\Framework\MockObject\MockObject $factory */
|
||||
+ $factory = $this->createMock(OrderFactory::class);
|
||||
+
|
||||
+ /** @var ShippingMethod|\PHPUnit\Framework\MockObject\MockObject $shippingMethod */
|
||||
+ $shippingMethod = $this->createMock(ShippingMethod::class);
|
||||
+
|
||||
+ $factory->expects($this->once())->method('createShippingMethodFor')->willReturn($shippingMethod);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### RenameSpecFileToTestFileRector
|
||||
|
||||
Rename "*Spec.php" file to "*Test.php" file
|
||||
|
||||
- class: [`Rector\PhpSpecToPHPUnit\Rector\Class_\RenameSpecFileToTestFileRector`](../rules/PhpSpecToPHPUnit/Rector/Class_/RenameSpecFileToTestFileRector.php)
|
||||
|
||||
```diff
|
||||
-// tests/SomeSpec.php
|
||||
+// tests/SomeTest.php
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## PostRector
|
||||
|
||||
### ClassRenamingPostRector
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
"phpstan/phpstan-strict-rules": "^1.1",
|
||||
"phpstan/phpstan-webmozart-assert": "^1.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"rector/phpstan-rules": "^0.4.20",
|
||||
"rector/phpstan-rules": "^0.4.21",
|
||||
"spatie/enum": "^3.12",
|
||||
"symplify/coding-standard": "^10.1",
|
||||
"symplify/easy-ci": "^10.1",
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\PhpSpecToPHPUnit\Rector\Class_\AddMockPropertiesRector;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\Class_\PhpSpecClassToPHPUnitClassRector;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\Class_\RenameSpecFileToTestFileRector;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\ClassMethod\PhpSpecMethodToPHPUnitMethodRector;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\MethodCall\PhpSpecMocksToPHPUnitMocksRector;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\MethodCall\PhpSpecPromisesToPHPUnitAssertRector;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\Variable\MockVariableToPropertyFetchRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
# see: https://gnugat.github.io/2015/09/23/phpunit-with-phpspec.html
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
# 1. first convert mocks
|
||||
$services->set(PhpSpecMocksToPHPUnitMocksRector::class);
|
||||
|
||||
$services->set(PhpSpecPromisesToPHPUnitAssertRector::class);
|
||||
|
||||
# 2. then methods
|
||||
$services->set(PhpSpecMethodToPHPUnitMethodRector::class);
|
||||
|
||||
# 3. then the class itself
|
||||
$services->set(PhpSpecClassToPHPUnitClassRector::class);
|
||||
|
||||
$services->set(AddMockPropertiesRector::class);
|
||||
$services->set(MockVariableToPropertyFetchRector::class);
|
||||
$services->set(RenameSpecFileToTestFileRector::class);
|
||||
};
|
|
@ -83,11 +83,6 @@ final class SetList implements SetListInterface
|
|||
*/
|
||||
public const PHPSPEC_40 = __DIR__ . '/../../../config/set/phpspec40.php';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const PHPSPEC_TO_PHPUNIT = __DIR__ . '/../../../config/set/phpspec-to-phpunit.php';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
|
15
phpstan.neon
15
phpstan.neon
|
@ -7,7 +7,6 @@ includes:
|
|||
- vendor/symplify/phpstan-rules/config/regex-rules.neon
|
||||
- vendor/symplify/phpstan-rules/config/services-rules.neon
|
||||
- vendor/symplify/phpstan-rules/config/static-rules.neon
|
||||
- vendor/symplify/phpstan-rules/config/size-rules.neon
|
||||
- vendor/symplify/phpstan-rules/config/string-to-constant-rules.neon
|
||||
- vendor/symplify/phpstan-rules/config/symfony-rules.neon
|
||||
- vendor/symplify/phpstan-rules/config/test-rules.neon
|
||||
|
@ -84,10 +83,6 @@ parameters:
|
|||
|
||||
- '#Cognitive complexity for "Rector\\Php80\\NodeResolver\\SwitchExprsResolver\:\:resolve\(\)" is (.*?), keep it under 10#'
|
||||
|
||||
-
|
||||
message: "#^Cognitive complexity for \"Rector\\\\PhpSpecToPHPUnit\\\\Rector\\\\MethodCall\\\\PhpSpecPromisesToPHPUnitAssertRector\\:\\:refactor\\(\\)\" is (.*?), keep it under 10$#"
|
||||
path: rules/PhpSpecToPHPUnit/Rector/MethodCall/PhpSpecPromisesToPHPUnitAssertRector.php
|
||||
|
||||
-
|
||||
message: '#Class cognitive complexity is \d+, keep it under \d+#'
|
||||
paths:
|
||||
|
@ -150,11 +145,6 @@ parameters:
|
|||
# for config class reflection
|
||||
- packages/NodeTypeResolver/DependencyInjection/PHPStanServicesFactory.php
|
||||
|
||||
# known values from other methods
|
||||
-
|
||||
message: '#Negated boolean expression is always true#'
|
||||
path: rules/PhpSpecToPHPUnit/NodeFactory/AssertMethodCallFactory.php
|
||||
|
||||
- '#PhpParser\\Node\\Expr\\Error\|PhpParser\\Node\\Expr\\Variable given#'
|
||||
|
||||
- '#Method Rector\\CodeQuality\\Rector\\Foreach_\\SimplifyForeachToCoalescingRector\:\:matchReturnOrAssignNode\(\) should return PhpParser\\Node\\Expr\\Assign\|PhpParser\\Node\\Stmt\\Return_\|null but returns PhpParser\\Node\|null#'
|
||||
|
@ -341,7 +331,6 @@ parameters:
|
|||
paths:
|
||||
- packages/BetterPhpDocParser/ValueObject/PhpDoc/DoctrineAnnotation/AbstractValuesAwareNode.php
|
||||
- packages/PostRector/Rector/AbstractPostRector.php
|
||||
- rules/PhpSpecToPHPUnit/Rector/AbstractPhpSpecToPHPUnitRector.php
|
||||
- src/Rector/AbstractRector.php
|
||||
|
||||
-
|
||||
|
@ -601,3 +590,7 @@ parameters:
|
|||
-
|
||||
path: src/PhpParser/Node/BetterNodeFinder.php
|
||||
message: '#Method Rector\\Core\\PhpParser\\Node\\BetterNodeFinder\:\:findParentByTypes\(\) should return T of PhpParser\\Node\|null but returns PhpParser\\Node#'
|
||||
|
||||
-
|
||||
message: '#Make callable type explicit#'
|
||||
path: src/NodeManipulator/BinaryOpManipulator.php
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Class_\RenameSpecFileToTestFileRector\Fixture;
|
||||
|
||||
class SomeFileSpec
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Class_\RenameSpecFileToTestFileRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class RenameSpecFileToTestFileRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
|
||||
// test file is moved
|
||||
$isFileRemoved = $this->removedAndAddedFilesCollector->isFileRemoved($this->originalTempFileInfo);
|
||||
$this->assertTrue($isFileRemoved);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator<SmartFileInfo>
|
||||
*/
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture', '*.php');
|
||||
}
|
||||
|
||||
public function provideConfigFilePath(): string
|
||||
{
|
||||
return __DIR__ . '/config/configured_rule.php';
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\PhpSpecToPHPUnit\Rector\Class_\RenameSpecFileToTestFileRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(RenameSpecFileToTestFileRector::class);
|
||||
};
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
final class Blabla
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
final class CreateMe
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
final class Currency
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
final class Delivery
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
final class Exception
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
final class ItIsMe
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
final class MockProperties
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
final class MockPropertiesNonLocal
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
final class Order
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
final class Rates
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
final class Result
|
||||
{
|
||||
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class RatesSpec extends ObjectBehavior
|
||||
{
|
||||
public function let(Provider $provider)
|
||||
{
|
||||
$provider->get()->shouldBeCalled()->willReturn(
|
||||
'08.12.2017 #237
|
||||
země|měna|množství|kód|kurz
|
||||
Austrálie|dolar|1|AUD|16,362
|
||||
Velká Británie|libra|1|GBP|29,194'
|
||||
);
|
||||
$this->beConstructedWith($provider);
|
||||
}
|
||||
|
||||
public function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType(Rates::class);
|
||||
}
|
||||
|
||||
public function it_should_load_current_rates(Provider $provider)
|
||||
{
|
||||
$provider->get()->shouldBeCalled()->willReturn(
|
||||
'08.12.2017 #237
|
||||
země|měna|množství|kód|kurz
|
||||
Austrálie|dolar|1|AUD|16,362
|
||||
Velká Británie|libra|1|GBP|29,194'
|
||||
);
|
||||
|
||||
$this->load()->shouldReturnRates(new ArrayCollection([
|
||||
new Rate('AUD', '16.362'),
|
||||
new Rate('GBP', '29.194'),
|
||||
]));
|
||||
}
|
||||
|
||||
public function getMatchers(): array
|
||||
{
|
||||
return [
|
||||
'returnRates' => function (ArrayCollection $rates, ArrayCollection $expectedRates) {
|
||||
foreach ($rates as $index => $rate) {
|
||||
if ($rate->rate !== $expectedRates[$index]->rate || $rate->currency !== $expectedRates[$index]->currency) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Tests\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class RatesTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Rates $rates;
|
||||
private \PHPUnit\Framework\MockObject\MockObject|\spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Provider $provider;
|
||||
protected function setUp()
|
||||
{
|
||||
$this->provider = $this->createMock(Provider::class);
|
||||
$this->provider->expects($this->atLeastOnce())->method('get')->willReturn(
|
||||
'08.12.2017 #237
|
||||
země|měna|množství|kód|kurz
|
||||
Austrálie|dolar|1|AUD|16,362
|
||||
Velká Británie|libra|1|GBP|29,194'
|
||||
);
|
||||
$this->rates = new \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Rates($this->provider);
|
||||
}
|
||||
|
||||
public function testInitializable()
|
||||
{
|
||||
$this->assertInstanceOf(Rates::class, $this->rates);
|
||||
}
|
||||
|
||||
public function testLoadCurrentRates()
|
||||
{
|
||||
$this->provider->expects($this->atLeastOnce())->method('get')->willReturn(
|
||||
'08.12.2017 #237
|
||||
země|měna|množství|kód|kurz
|
||||
Austrálie|dolar|1|AUD|16,362
|
||||
Velká Británie|libra|1|GBP|29,194'
|
||||
);
|
||||
$matcherCallable = $this->getMatchers()['returnRates'];
|
||||
$matcherCallable(new ArrayCollection([
|
||||
new Rate('AUD', '16.362'),
|
||||
new Rate('GBP', '29.194'),
|
||||
]), $this->rates->load());
|
||||
}
|
||||
|
||||
public function getMatchers(): array
|
||||
{
|
||||
return [
|
||||
'returnRates' => function (ArrayCollection $rates, ArrayCollection $expectedRates) {
|
||||
foreach ($rates as $index => $rate) {
|
||||
if ($rate->rate !== $expectedRates[$index]->rate || $rate->currency !== $expectedRates[$index]->currency) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class ExceptionSpec extends ObjectBehavior
|
||||
{
|
||||
public function it_should_throw_exceptions_where_rates_are_not_loaded()
|
||||
{
|
||||
$this->beConstructedWith('https://non-existent-rates.example.com/denni_kurz.txt');
|
||||
|
||||
$this->shouldThrow(RatesNotLoadedException::class)->during('get');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Tests\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class ExceptionTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Exception $exception;
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->exception = new \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Exception();
|
||||
}
|
||||
public function testThrowExceptionsWhereRatesAreNotLoaded()
|
||||
{
|
||||
$this->exception = new \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Exception('https://non-existent-rates.example.com/denni_kurz.txt');
|
||||
|
||||
$this->expectException(RatesNotLoadedException::class);
|
||||
$this->exception->get();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,97 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source\Address;
|
||||
use Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source\Cart;
|
||||
|
||||
class CreateMeSpec extends ObjectBehavior
|
||||
{
|
||||
public function let()
|
||||
{
|
||||
$this->beConstructedWith(5);
|
||||
}
|
||||
|
||||
public function it_returns_id()
|
||||
{
|
||||
$this->id()->shouldReturn(5);
|
||||
}
|
||||
|
||||
public function it_blows()
|
||||
{
|
||||
$this->shouldThrow('SomeException')->during('item', [5]);
|
||||
}
|
||||
|
||||
public function it_should_be_called(Cart $cart)
|
||||
{
|
||||
$cart->price()->shouldBeCalled()->willReturn(5);
|
||||
$cart->shippingAddress(Argument::type(Address::class))->shouldBeCalled();
|
||||
$cart->shippingAddress(Argument::type('DateTime'))->shouldBeCalled();
|
||||
$cart->shippingAddress(Argument::type('string'))->shouldBeCalled();
|
||||
}
|
||||
|
||||
public function is_bool_check()
|
||||
{
|
||||
$this->hasFailed()->shouldBe(false);
|
||||
$this->hasFailed()->shouldNotBe(false);
|
||||
}
|
||||
|
||||
public function is_array_type()
|
||||
{
|
||||
$this->shippingAddresses()->shouldBeArray();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Tests\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source\Address;
|
||||
use Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source\Cart;
|
||||
|
||||
class CreateMeTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\CreateMe $createMe;
|
||||
protected function setUp()
|
||||
{
|
||||
$this->createMe = new \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\CreateMe(5);
|
||||
}
|
||||
|
||||
public function testReturnsId()
|
||||
{
|
||||
$this->assertSame(5, $this->createMe->id());
|
||||
}
|
||||
|
||||
public function testBlows()
|
||||
{
|
||||
$this->expectException('SomeException');
|
||||
$this->createMe->item(5);
|
||||
}
|
||||
|
||||
public function testCalled()
|
||||
{
|
||||
/** @var Cart|\PHPUnit\Framework\MockObject\MockObject $cart */
|
||||
$cart = $this->createMock(Cart::class);
|
||||
$cart->expects($this->atLeastOnce())->method('price')->willReturn(5);
|
||||
$cart->expects($this->atLeastOnce())->method('shippingAddress')->with($this->isInstanceOf(Address::class));
|
||||
$cart->expects($this->atLeastOnce())->method('shippingAddress')->with($this->isInstanceOf('DateTime'));
|
||||
$cart->expects($this->atLeastOnce())->method('shippingAddress')->with($this->isType('string'));
|
||||
}
|
||||
|
||||
public function testBoolCheck()
|
||||
{
|
||||
$this->assertFalse($this->createMe->hasFailed());
|
||||
$this->assertNotFalse($this->createMe->hasFailed());
|
||||
}
|
||||
|
||||
public function testArrayType()
|
||||
{
|
||||
$this->assertIsIterable($this->createMe->shippingAddresses());
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,352 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use Ecommerce\Cart\Cart;
|
||||
use Ecommerce\Cart\Exception\NotFoundException;
|
||||
use Ecommerce\Component\Factory\EntityFactory;
|
||||
use Ecommerce\Pricing\Currency\DefaultCurrency;
|
||||
use Ecommerce\Pricing\Currency\DummyDefaultCurrencyProvider;
|
||||
use Ecommerce\Pricing\Price\CalculatedPrice;
|
||||
use Ecommerce\Pricing\Price\Price;
|
||||
use Ecommerce\Taxing\PriceType;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class CartSpec extends ObjectBehavior
|
||||
{
|
||||
public function let()
|
||||
{
|
||||
DefaultCurrency::setProvider(new DummyDefaultCurrencyProvider());
|
||||
|
||||
$this->beConstructedWith(Uuid::uuid1());
|
||||
}
|
||||
|
||||
public function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType(Cart::class);
|
||||
}
|
||||
|
||||
public function it_should_add_new_item()
|
||||
{
|
||||
$id = Uuid::uuid1();
|
||||
$taxRate = EntityFactory::make('tax_rate_21');
|
||||
$currency = EntityFactory::make('currency_czk');
|
||||
|
||||
$this->add(new \Ecommerce\Cart\Item($id, 'Lorem ipsum', 4, new Price(671, $taxRate, $currency)));
|
||||
|
||||
$item = $this->item($id);
|
||||
|
||||
$item->id()->shouldReturn($id);
|
||||
$item->quantity()->shouldReturn(4);
|
||||
}
|
||||
|
||||
public function it_should_provide_item_by_its_identifier()
|
||||
{
|
||||
$id = Uuid::uuid1();
|
||||
$taxRate = EntityFactory::make('tax_rate_21');
|
||||
$currency = EntityFactory::make('currency_czk');
|
||||
|
||||
$this->add(new \Ecommerce\Cart\Item($id, 'Lorem ipsum', 3, new Price(671, $taxRate, $currency)));
|
||||
|
||||
$this->item($id)->shouldBeAnInstanceOf(\Ecommerce\Cart\Contract\Item::class);
|
||||
}
|
||||
|
||||
public function it_should_throw_an_exception_when_item_is_not_in_cart()
|
||||
{
|
||||
$id = Uuid::uuid1();
|
||||
|
||||
$this->shouldThrow(NotFoundException::class)->during('item', [$id]);
|
||||
}
|
||||
|
||||
public function it_should_summ_up_quantities_when_adding_same_item_multiple_times()
|
||||
{
|
||||
PriceType::set(PriceType::WITH_VAT);
|
||||
|
||||
$id = Uuid::uuid1();
|
||||
$taxRate = EntityFactory::make('tax_rate_21');
|
||||
$currency = EntityFactory::make('currency_czk');
|
||||
|
||||
$this->add(new \Ecommerce\Cart\Item($id, 'Lorem ipsum', 3, new Price(671, $taxRate, $currency)));
|
||||
$this->add(new \Ecommerce\Cart\Item($id, 'Dolor sit amet', 7, new Price(671, $taxRate, $currency)));
|
||||
|
||||
$item = $this->item($id);
|
||||
|
||||
$item->quantity()->shouldReturn(10);
|
||||
}
|
||||
|
||||
public function it_should_remove_item()
|
||||
{
|
||||
PriceType::set(PriceType::WITH_VAT);
|
||||
|
||||
$id = Uuid::uuid1();
|
||||
$taxRate = EntityFactory::make('tax_rate_21');
|
||||
$currency = EntityFactory::make('currency_czk');
|
||||
|
||||
$this->add(new \Ecommerce\Cart\Item($id, 'Lorem ipsum', 3, new Price(671, $taxRate, $currency)));
|
||||
$this->remove($id);
|
||||
|
||||
$this->shouldThrow(NotFoundException::class)->during('item', [$id]);
|
||||
}
|
||||
|
||||
public function it_should_calculate_zero_price_when_cart_is_empty()
|
||||
{
|
||||
$price = $this->price();
|
||||
|
||||
$price->shouldBeAnInstanceOf(CalculatedPrice::class);
|
||||
$price->withVat()->shouldReturn(0.0);
|
||||
$price->withoutVat()->shouldReturn(0.0);
|
||||
$price->vat()->shouldReturn(0.0);
|
||||
}
|
||||
|
||||
public function it_should_calculate_total_price_of_all_items_when_not_empty()
|
||||
{
|
||||
PriceType::set(PriceType::WITH_VAT);
|
||||
|
||||
$taxRate = EntityFactory::make('tax_rate_21');
|
||||
$currency = EntityFactory::make('currency_czk');
|
||||
|
||||
$this->add(new \Ecommerce\Cart\Item(Uuid::uuid1(), 'Lorem ipsum', 3, new Price(671, $taxRate, $currency)));
|
||||
|
||||
$price = $this->price();
|
||||
|
||||
$price->shouldReturnAnInstanceOf(CalculatedPrice::class);
|
||||
|
||||
$price->withVat()->shouldReturn(2013.00);
|
||||
$price->withoutVat()->shouldReturn(1663.54);
|
||||
$price->vat()->shouldReturn(349.46);
|
||||
}
|
||||
|
||||
public function it_should_contain_old_items_when_merged_with_empty_cart()
|
||||
{
|
||||
PriceType::set(PriceType::WITH_VAT);
|
||||
|
||||
$taxRate = EntityFactory::make('tax_rate_21');
|
||||
$currency = EntityFactory::make('currency_czk');
|
||||
|
||||
$cart = new Cart(Uuid::uuid1());
|
||||
|
||||
$item1 = new \Ecommerce\Cart\Item(Uuid::fromString('3cf9f49c-af76-11e8-8981-529269fb1459'), 'Lorem ipsum', 2, new Price(671, $taxRate, $currency));
|
||||
$item2 = new \Ecommerce\Cart\Item(Uuid::fromString('3cf9f80c-af76-11e8-8981-529269fb1459'), 'Dolor sit amet', 3, new Price(475, $taxRate, $currency));
|
||||
|
||||
$this->add($item1);
|
||||
$this->add($item2);
|
||||
|
||||
$this->merge($cart);
|
||||
|
||||
$items = $this->items();
|
||||
$items->shouldHaveCount(2);
|
||||
|
||||
$this->item($item1->key())->quantity()->shouldBe(2);
|
||||
$this->item($item2->key())->quantity()->shouldBe(3);
|
||||
}
|
||||
|
||||
public function it_should_contain_only_items_from_second_cart_when_merged_with_not_empty_cart()
|
||||
{
|
||||
PriceType::set(PriceType::WITH_VAT);
|
||||
|
||||
$taxRate = EntityFactory::make('tax_rate_21');
|
||||
$currency = EntityFactory::make('currency_czk');
|
||||
|
||||
$cart = new Cart(Uuid::uuid1());
|
||||
|
||||
$item1 = new \Ecommerce\Cart\Item(Uuid::fromString('3cf9f49c-af76-11e8-8981-529269fb1459'), 'Lorem ipsum', 2, new Price(671, $taxRate, $currency));
|
||||
$item2 = new \Ecommerce\Cart\Item(Uuid::fromString('3cf9f80c-af76-11e8-8981-529269fb1459'), 'Dolor sit amet', 3, new Price(475, $taxRate, $currency));
|
||||
$item3 = new \Ecommerce\Cart\Item(Uuid::fromString('3cf9f49c-af76-11e8-8981-529269fb1459'), 'Lorem ipsum', 4, new Price(671, $taxRate, $currency));
|
||||
$item4 = new \Ecommerce\Cart\Item(Uuid::fromString('3cf9fa0a-af76-11e8-8981-529269fb1459'), 'Lorem ipsum', 5, new Price(671, $taxRate, $currency));
|
||||
|
||||
$cart->add($item1);
|
||||
$cart->add($item2);
|
||||
|
||||
$this->add($item3);
|
||||
$this->add($item4);
|
||||
|
||||
$this->merge($cart);
|
||||
|
||||
$items = $this->items();
|
||||
$items->shouldHaveCount(2);
|
||||
|
||||
$this->item($item1->key())->quantity()->shouldBe(2);
|
||||
$this->item($item2->key())->quantity()->shouldBe(3);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Tests\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use Ecommerce\Cart\Cart;
|
||||
use Ecommerce\Cart\Exception\NotFoundException;
|
||||
use Ecommerce\Component\Factory\EntityFactory;
|
||||
use Ecommerce\Pricing\Currency\DefaultCurrency;
|
||||
use Ecommerce\Pricing\Currency\DummyDefaultCurrencyProvider;
|
||||
use Ecommerce\Pricing\Price\CalculatedPrice;
|
||||
use Ecommerce\Pricing\Price\Price;
|
||||
use Ecommerce\Taxing\PriceType;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class CartTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Cart $cart;
|
||||
protected function setUp()
|
||||
{
|
||||
DefaultCurrency::setProvider(new DummyDefaultCurrencyProvider());
|
||||
|
||||
$this->cart = new \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Cart(Uuid::uuid1());
|
||||
}
|
||||
|
||||
public function testInitializable()
|
||||
{
|
||||
$this->assertInstanceOf(Cart::class, $this->cart);
|
||||
}
|
||||
|
||||
public function testAddNewItem()
|
||||
{
|
||||
$id = Uuid::uuid1();
|
||||
$taxRate = EntityFactory::make('tax_rate_21');
|
||||
$currency = EntityFactory::make('currency_czk');
|
||||
|
||||
$this->cart->add(new \Ecommerce\Cart\Item($id, 'Lorem ipsum', 4, new Price(671, $taxRate, $currency)));
|
||||
|
||||
$item = $this->cart->item($id);
|
||||
|
||||
$this->assertSame($id, $item->id());
|
||||
$this->assertSame(4, $item->quantity());
|
||||
}
|
||||
|
||||
public function testProvideItemByItsIdentifier()
|
||||
{
|
||||
$id = Uuid::uuid1();
|
||||
$taxRate = EntityFactory::make('tax_rate_21');
|
||||
$currency = EntityFactory::make('currency_czk');
|
||||
|
||||
$this->cart->add(new \Ecommerce\Cart\Item($id, 'Lorem ipsum', 3, new Price(671, $taxRate, $currency)));
|
||||
|
||||
$this->assertInstanceOf(\Ecommerce\Cart\Contract\Item::class, $this->cart->item($id));
|
||||
}
|
||||
|
||||
public function testThrowAnExceptionWhenItemIsNotInCart()
|
||||
{
|
||||
$id = Uuid::uuid1();
|
||||
|
||||
$this->expectException(NotFoundException::class);
|
||||
$this->cart->item($id);
|
||||
}
|
||||
|
||||
public function testSummUpQuantitiesWhenAddingSameItemMultipleTimes()
|
||||
{
|
||||
PriceType::set(PriceType::WITH_VAT);
|
||||
|
||||
$id = Uuid::uuid1();
|
||||
$taxRate = EntityFactory::make('tax_rate_21');
|
||||
$currency = EntityFactory::make('currency_czk');
|
||||
|
||||
$this->cart->add(new \Ecommerce\Cart\Item($id, 'Lorem ipsum', 3, new Price(671, $taxRate, $currency)));
|
||||
$this->cart->add(new \Ecommerce\Cart\Item($id, 'Dolor sit amet', 7, new Price(671, $taxRate, $currency)));
|
||||
|
||||
$item = $this->cart->item($id);
|
||||
|
||||
$this->assertSame(10, $item->quantity());
|
||||
}
|
||||
|
||||
public function testRemoveItem()
|
||||
{
|
||||
PriceType::set(PriceType::WITH_VAT);
|
||||
|
||||
$id = Uuid::uuid1();
|
||||
$taxRate = EntityFactory::make('tax_rate_21');
|
||||
$currency = EntityFactory::make('currency_czk');
|
||||
|
||||
$this->cart->add(new \Ecommerce\Cart\Item($id, 'Lorem ipsum', 3, new Price(671, $taxRate, $currency)));
|
||||
$this->cart->remove($id);
|
||||
|
||||
$this->expectException(NotFoundException::class);
|
||||
$this->cart->item($id);
|
||||
}
|
||||
|
||||
public function testCalculateZeroPriceWhenCartIsEmpty()
|
||||
{
|
||||
$price = $this->cart->price();
|
||||
|
||||
$this->assertInstanceOf(CalculatedPrice::class, $price);
|
||||
$this->assertSame(0.0, $price->withVat());
|
||||
$this->assertSame(0.0, $price->withoutVat());
|
||||
$this->assertSame(0.0, $price->vat());
|
||||
}
|
||||
|
||||
public function testCalculateTotalPriceOfAllItemsWhenNotEmpty()
|
||||
{
|
||||
PriceType::set(PriceType::WITH_VAT);
|
||||
|
||||
$taxRate = EntityFactory::make('tax_rate_21');
|
||||
$currency = EntityFactory::make('currency_czk');
|
||||
|
||||
$this->cart->add(new \Ecommerce\Cart\Item(Uuid::uuid1(), 'Lorem ipsum', 3, new Price(671, $taxRate, $currency)));
|
||||
|
||||
$price = $this->cart->price();
|
||||
|
||||
$this->assertInstanceOf(CalculatedPrice::class, $price);
|
||||
|
||||
$this->assertSame(2013.00, $price->withVat());
|
||||
$this->assertSame(1663.54, $price->withoutVat());
|
||||
$this->assertSame(349.46, $price->vat());
|
||||
}
|
||||
|
||||
public function testContainOldItemsWhenMergedWithEmptyCart()
|
||||
{
|
||||
PriceType::set(PriceType::WITH_VAT);
|
||||
|
||||
$taxRate = EntityFactory::make('tax_rate_21');
|
||||
$currency = EntityFactory::make('currency_czk');
|
||||
|
||||
$cart = new Cart(Uuid::uuid1());
|
||||
|
||||
$item1 = new \Ecommerce\Cart\Item(Uuid::fromString('3cf9f49c-af76-11e8-8981-529269fb1459'), 'Lorem ipsum', 2, new Price(671, $taxRate, $currency));
|
||||
$item2 = new \Ecommerce\Cart\Item(Uuid::fromString('3cf9f80c-af76-11e8-8981-529269fb1459'), 'Dolor sit amet', 3, new Price(475, $taxRate, $currency));
|
||||
|
||||
$this->cart->add($item1);
|
||||
$this->cart->add($item2);
|
||||
|
||||
$this->cart->merge($cart);
|
||||
|
||||
$items = $this->cart->items();
|
||||
$this->assertCount(2, $items);
|
||||
|
||||
$this->assertSame(2, $this->cart->item($item1->key())->quantity());
|
||||
$this->assertSame(3, $this->cart->item($item2->key())->quantity());
|
||||
}
|
||||
|
||||
public function testContainOnlyItemsFromSecondCartWhenMergedWithNotEmptyCart()
|
||||
{
|
||||
PriceType::set(PriceType::WITH_VAT);
|
||||
|
||||
$taxRate = EntityFactory::make('tax_rate_21');
|
||||
$currency = EntityFactory::make('currency_czk');
|
||||
|
||||
$cart = new Cart(Uuid::uuid1());
|
||||
|
||||
$item1 = new \Ecommerce\Cart\Item(Uuid::fromString('3cf9f49c-af76-11e8-8981-529269fb1459'), 'Lorem ipsum', 2, new Price(671, $taxRate, $currency));
|
||||
$item2 = new \Ecommerce\Cart\Item(Uuid::fromString('3cf9f80c-af76-11e8-8981-529269fb1459'), 'Dolor sit amet', 3, new Price(475, $taxRate, $currency));
|
||||
$item3 = new \Ecommerce\Cart\Item(Uuid::fromString('3cf9f49c-af76-11e8-8981-529269fb1459'), 'Lorem ipsum', 4, new Price(671, $taxRate, $currency));
|
||||
$item4 = new \Ecommerce\Cart\Item(Uuid::fromString('3cf9fa0a-af76-11e8-8981-529269fb1459'), 'Lorem ipsum', 5, new Price(671, $taxRate, $currency));
|
||||
|
||||
$cart->add($item1);
|
||||
$cart->add($item2);
|
||||
|
||||
$this->cart->add($item3);
|
||||
$this->cart->add($item4);
|
||||
|
||||
$this->cart->merge($cart);
|
||||
|
||||
$items = $this->cart->items();
|
||||
$this->assertCount(2, $items);
|
||||
|
||||
$this->assertSame(2, $this->cart->item($item1->key())->quantity());
|
||||
$this->assertSame(3, $this->cart->item($item2->key())->quantity());
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class BlablaSpec extends ObjectBehavior
|
||||
{
|
||||
public function it_is_me(SomeType $someType)
|
||||
{
|
||||
$assignMe = $someType->getWrappedObject();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Tests\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class BlablaTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Blabla $blabla;
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->blabla = new \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Blabla();
|
||||
}
|
||||
public function testMe()
|
||||
{
|
||||
/** @var SomeType|\PHPUnit\Framework\MockObject\MockObject $someType */
|
||||
$someType = $this->createMock(SomeType::class);
|
||||
$assignMe = $someType;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,103 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use JsonApiBundle\Paging\PageLinksGenerator;
|
||||
use JsonApiBundle\Paging\Paginator;
|
||||
use Neomerx\JsonApi\Document\Link;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Symfony\Bundle\FrameworkBundle\Routing\Router;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
|
||||
/**
|
||||
* Class PageLinksGeneratorSpec
|
||||
*/
|
||||
class PageLinksGeneratorSpec extends ObjectBehavior
|
||||
{
|
||||
public function it_is_initializable()
|
||||
{
|
||||
$this->shouldHaveType(PageLinksGenerator::class);
|
||||
}
|
||||
|
||||
public function let(Router $router)
|
||||
{
|
||||
$this->beConstructedWith($router);
|
||||
}
|
||||
|
||||
public function it_should_return_only_self_link_when_no_results(Router $router)
|
||||
{
|
||||
$paginator = new Paginator(
|
||||
10,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
'route_name'
|
||||
);
|
||||
|
||||
$router->generate($paginator->getRouteName(), [], UrlGeneratorInterface::ABSOLUTE_URL)
|
||||
->shouldBeCalled()->willReturn('http://api.foo.loc/bar/1.0.0/');
|
||||
|
||||
$expectations = [
|
||||
'self' => new Link('http://api.foo.loc/bar/1.0.0/'),
|
||||
'first' => null,
|
||||
'prev' => null,
|
||||
'next' => null,
|
||||
'last' => null,
|
||||
];
|
||||
|
||||
$this->generateLinks($paginator)->shouldBeLike($expectations);
|
||||
}
|
||||
}
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Tests\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use JsonApiBundle\Paging\PageLinksGenerator;
|
||||
use JsonApiBundle\Paging\Paginator;
|
||||
use Neomerx\JsonApi\Document\Link;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Symfony\Bundle\FrameworkBundle\Routing\Router;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
|
||||
/**
|
||||
* Class PageLinksGeneratorSpec
|
||||
*/
|
||||
class PageLinksGeneratorTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\PageLinksGenerator $pageLinksGenerator;
|
||||
private \PHPUnit\Framework\MockObject\MockObject|\Symfony\Bundle\FrameworkBundle\Routing\Router $router;
|
||||
public function testInitializable()
|
||||
{
|
||||
$this->assertInstanceOf(PageLinksGenerator::class, $this->pageLinksGenerator);
|
||||
}
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->router = $this->createMock(Router::class);
|
||||
$this->pageLinksGenerator = new \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\PageLinksGenerator($this->router);
|
||||
}
|
||||
|
||||
public function testReturnOnlySelfLinkWhenNoResults()
|
||||
{
|
||||
$paginator = new Paginator(
|
||||
10,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
'route_name'
|
||||
);
|
||||
$this->router->expects($this->atLeastOnce())
|
||||
->method('generate')->with($this->equalTo($paginator->getRouteName()))->willReturn('http://api.foo.loc/bar/1.0.0/');
|
||||
$expectations = [
|
||||
'self' => new Link('http://api.foo.loc/bar/1.0.0/'),
|
||||
'first' => null,
|
||||
'prev' => null,
|
||||
'next' => null,
|
||||
'last' => null,
|
||||
];
|
||||
$this->pageLinksGenerator->generateLinks($paginator)->shouldBeLike($expectations);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
final class KeepMethod
|
||||
{
|
||||
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class CurrencySpec extends ObjectBehavior
|
||||
{
|
||||
public function let(CurrencyData $data)
|
||||
{
|
||||
$data->code = 'CZK';
|
||||
|
||||
$this->beConstructedThrough('create', [$data]);
|
||||
}
|
||||
|
||||
public function it_should_not_be_constructed_without_code(CurrencyData $data)
|
||||
{
|
||||
$data->code = '';
|
||||
|
||||
$this->beConstructedThrough('create', [$data]);
|
||||
$this->shouldThrow(ValidationException::class)->duringInstantiation();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Tests\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class CurrencyTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Currency $currency;
|
||||
private \PHPUnit\Framework\MockObject\MockObject|\spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\CurrencyData $data;
|
||||
protected function setUp()
|
||||
{
|
||||
$this->data = $this->createMock(CurrencyData::class);
|
||||
$this->data->code = 'CZK';
|
||||
$this->currency = \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Currency::create($this->data);
|
||||
}
|
||||
|
||||
public function testNotBeConstructedWithoutCode()
|
||||
{
|
||||
$this->data->code = '';
|
||||
$this->expectException(ValidationException::class);
|
||||
$this->currency = \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Currency::create($this->data);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class KeepMethodSpec extends ObjectBehavior
|
||||
{
|
||||
public function let()
|
||||
{
|
||||
$this->beConstructedWith(5);
|
||||
|
||||
$result = $this->getSomeNumbers();
|
||||
}
|
||||
|
||||
private function getSomeNumbers()
|
||||
{
|
||||
return [1, 2, 3];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Tests\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class KeepMethodTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\KeepMethod $keepMethod;
|
||||
protected function setUp()
|
||||
{
|
||||
$this->keepMethod = new \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\KeepMethod(5);
|
||||
|
||||
$result = $this->getSomeNumbers();
|
||||
}
|
||||
|
||||
private function getSomeNumbers()
|
||||
{
|
||||
return [1, 2, 3];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source\DeliveryFactory;
|
||||
use Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source\ShippingMethod;
|
||||
|
||||
class DeliverySpec extends ObjectBehavior
|
||||
{
|
||||
public function let(DeliveryFactory $factory, ShippingMethod $shippingMethod)
|
||||
{
|
||||
$factory->createShippingMethodFor(5)
|
||||
->shouldBeCalled()
|
||||
->willReturn($shippingMethod);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Tests\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source\DeliveryFactory;
|
||||
use Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source\ShippingMethod;
|
||||
|
||||
class DeliveryTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Delivery $delivery;
|
||||
protected function setUp()
|
||||
{
|
||||
/** @var DeliveryFactory|\PHPUnit\Framework\MockObject\MockObject $factory */
|
||||
$factory = $this->createMock(DeliveryFactory::class);
|
||||
/** @var ShippingMethod|\PHPUnit\Framework\MockObject\MockObject $shippingMethod */
|
||||
$shippingMethod = $this->createMock(ShippingMethod::class);
|
||||
$factory->expects($this->atLeastOnce())
|
||||
->method('createShippingMethodFor')->with($this->equalTo(5))
|
||||
->willReturn($shippingMethod);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source\OrderFactory;
|
||||
|
||||
class MockPropertiesSpec extends ObjectBehavior
|
||||
{
|
||||
public function let(OrderFactory $factory)
|
||||
{
|
||||
$this->beConstructedWith($factory);
|
||||
}
|
||||
|
||||
public function let_it_go(OrderFactory $factory)
|
||||
{
|
||||
$factory->someMethod()->shouldBeCalled();
|
||||
$this->run();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Tests\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source\OrderFactory;
|
||||
|
||||
class MockPropertiesTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\MockProperties $mockProperties;
|
||||
private \PHPUnit\Framework\MockObject\MockObject|\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source\OrderFactory $factory;
|
||||
protected function setUp()
|
||||
{
|
||||
$this->factory = $this->createMock(OrderFactory::class);
|
||||
$this->mockProperties = new \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\MockProperties($this->factory);
|
||||
}
|
||||
|
||||
public function testLetItGo()
|
||||
{
|
||||
$this->factory->expects($this->atLeastOnce())->method('someMethod');
|
||||
$this->mockProperties->run();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,64 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source\AnotherMock;
|
||||
|
||||
class MockPropertiesNonLocalSpec extends ObjectBehavior
|
||||
{
|
||||
public function let(OrderFactory $factory)
|
||||
{
|
||||
$this->beConstructedWith($factory);
|
||||
}
|
||||
|
||||
public function let_it_go(AnotherMock $anotherMock)
|
||||
{
|
||||
$anotherMock->setName('Nummy');
|
||||
$this->addAnotherMock($anotherMock);
|
||||
}
|
||||
|
||||
public function let_it_go_again(AnotherMock $anotherMock)
|
||||
{
|
||||
$anotherMock->setName('Nummy2');
|
||||
$this->addAnotherMock($anotherMock);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Tests\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source\AnotherMock;
|
||||
|
||||
class MockPropertiesNonLocalTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\MockPropertiesNonLocal $mockPropertiesNonLocal;
|
||||
protected function setUp()
|
||||
{
|
||||
/** @var OrderFactory|\PHPUnit\Framework\MockObject\MockObject $factory */
|
||||
$factory = $this->createMock(OrderFactory::class);
|
||||
$this->mockPropertiesNonLocal = new \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\MockPropertiesNonLocal($factory);
|
||||
}
|
||||
|
||||
public function testLetItGo()
|
||||
{
|
||||
/** @var AnotherMock|\PHPUnit\Framework\MockObject\MockObject $anotherMock */
|
||||
$anotherMock = $this->createMock(AnotherMock::class);
|
||||
$anotherMock->setName('Nummy');
|
||||
$this->mockPropertiesNonLocal->addAnotherMock($anotherMock);
|
||||
}
|
||||
|
||||
public function testLetItGoAgain()
|
||||
{
|
||||
/** @var AnotherMock|\PHPUnit\Framework\MockObject\MockObject $anotherMock */
|
||||
$anotherMock = $this->createMock(AnotherMock::class);
|
||||
$anotherMock->setName('Nummy2');
|
||||
$this->mockPropertiesNonLocal->addAnotherMock($anotherMock);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class OrderSpec extends ObjectBehavior
|
||||
{
|
||||
public function let(OrderFactory $factory, ShippingMethod $shippingMethod)
|
||||
{
|
||||
$factory->createShippingMethodFor(Argument::any())->shouldBeCalled()->willReturn($shippingMethod);
|
||||
$factory->anotherMethod(25)->shouldBeCalled()->willReturn($shippingMethod);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Tests\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class OrderTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Order $order;
|
||||
protected function setUp()
|
||||
{
|
||||
/** @var OrderFactory|\PHPUnit\Framework\MockObject\MockObject $factory */
|
||||
$factory = $this->createMock(OrderFactory::class);
|
||||
/** @var ShippingMethod|\PHPUnit\Framework\MockObject\MockObject $shippingMethod */
|
||||
$shippingMethod = $this->createMock(ShippingMethod::class);
|
||||
$factory->expects($this->atLeastOnce())->method('createShippingMethodFor')->willReturn($shippingMethod);
|
||||
$factory->expects($this->atLeastOnce())->method('anotherMethod')->with($this->equalTo(25))->willReturn($shippingMethod);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\ItIsMe;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class ItIsMeSpec extends ObjectBehavior
|
||||
{
|
||||
public function it_is_me()
|
||||
{
|
||||
$this->shouldHaveType(ItIsMe::class);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Tests\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\ItIsMe;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class ItIsMeTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\ItIsMe $itIsMe;
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->itIsMe = new \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\ItIsMe();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace spec\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class ResultSpec extends ObjectBehavior
|
||||
{
|
||||
public function it_is_initializable()
|
||||
{
|
||||
$this->beConstructedThrough('success');
|
||||
$this->shouldHaveType(Result::class);
|
||||
}
|
||||
|
||||
public function it_should_succeed()
|
||||
{
|
||||
$this->beConstructedThrough('fail');
|
||||
$this->hasFailed()->shouldReturn(false);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Tests\Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class ResultTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
private \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Result $result;
|
||||
public function testInitializable()
|
||||
{
|
||||
$this->result = \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Result::success();
|
||||
$this->assertInstanceOf(Result::class, $this->result);
|
||||
}
|
||||
|
||||
public function testSucceed()
|
||||
{
|
||||
$this->result = \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Fixture\Result::fail();
|
||||
$this->assertFalse($this->result->hasFailed());
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\EasyTesting\DataProvider\StaticFixtureFinder;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class PhpSpecToPHPUnitRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator<SmartFileInfo>
|
||||
*/
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return StaticFixtureFinder::yieldDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
public function provideConfigFilePath(): string
|
||||
{
|
||||
return __DIR__ . '/config/configured_rule.php';
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source;
|
||||
|
||||
final class Address
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source;
|
||||
|
||||
final class AnotherMock
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source;
|
||||
|
||||
final class Cart
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source;
|
||||
|
||||
final class DeliveryFactory
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source;
|
||||
|
||||
final class OrderFactory
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\Source;
|
||||
|
||||
final class ShippingMethod
|
||||
{
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\PhpSpecToPHPUnit\Rector\Class_\AddMockPropertiesRector;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\Class_\PhpSpecClassToPHPUnitClassRector;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\ClassMethod\PhpSpecMethodToPHPUnitMethodRector;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\MethodCall\PhpSpecMocksToPHPUnitMocksRector;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\MethodCall\PhpSpecPromisesToPHPUnitAssertRector;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\Variable\MockVariableToPropertyFetchRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(PhpSpecMocksToPHPUnitMocksRector::class);
|
||||
$services->set(PhpSpecPromisesToPHPUnitAssertRector::class);
|
||||
$services->set(PhpSpecMethodToPHPUnitMethodRector::class);
|
||||
$services->set(PhpSpecClassToPHPUnitClassRector::class);
|
||||
$services->set(AddMockPropertiesRector::class);
|
||||
$services->set(MockVariableToPropertyFetchRector::class);
|
||||
};
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
|
||||
final class LetManipulator
|
||||
{
|
||||
public function __construct(
|
||||
private readonly BetterNodeFinder $betterNodeFinder,
|
||||
private readonly NodeNameResolver $nodeNameResolver
|
||||
) {
|
||||
}
|
||||
|
||||
public function isLetNeededInClass(Class_ $class): bool
|
||||
{
|
||||
foreach ($class->getMethods() as $classMethod) {
|
||||
// new test
|
||||
if ($this->nodeNameResolver->isName($classMethod, 'test*')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$hasBeConstructedThrough = (bool) $this->betterNodeFinder->find(
|
||||
(array) $classMethod->stmts,
|
||||
function (Node $node): bool {
|
||||
if (! $node instanceof MethodCall) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->nodeNameResolver->isName($node->name, 'beConstructedThrough');
|
||||
}
|
||||
);
|
||||
|
||||
if ($hasBeConstructedThrough) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit;
|
||||
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
|
||||
final class MatchersManipulator
|
||||
{
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function resolveMatcherNamesFromClass(Class_ $class): array
|
||||
{
|
||||
$classMethod = $class->getMethod('getMatchers');
|
||||
if (! $classMethod instanceof ClassMethod) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (! isset($classMethod->stmts[0])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (! $classMethod->stmts[0] instanceof Return_) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/** @var Return_ $return */
|
||||
$return = $classMethod->stmts[0];
|
||||
if (! $return->expr instanceof Array_) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$keys = [];
|
||||
foreach ($return->expr->items as $arrayItem) {
|
||||
if ($arrayItem === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($arrayItem->key instanceof String_) {
|
||||
$keys[] = $arrayItem->key->value;
|
||||
}
|
||||
}
|
||||
|
||||
return $keys;
|
||||
}
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit\Naming;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Namespace_;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Core\Util\StaticRectorStrings;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Symplify\PackageBuilder\Strings\StringFormatConverter;
|
||||
|
||||
final class PhpSpecRenaming
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const SPEC = 'Spec';
|
||||
|
||||
public function __construct(
|
||||
private readonly NodeNameResolver $nodeNameResolver,
|
||||
private readonly StringFormatConverter $stringFormatConverter,
|
||||
private readonly BetterNodeFinder $betterNodeFinder
|
||||
) {
|
||||
}
|
||||
|
||||
public function renameMethod(ClassMethod $classMethod): void
|
||||
{
|
||||
if ($classMethod->isPrivate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$classMethodName = $this->nodeNameResolver->getName($classMethod);
|
||||
$classMethodName = $this->removeNamePrefixes($classMethodName);
|
||||
|
||||
// from PhpSpec to PHPUnit method naming convention
|
||||
$classMethodName = $this->stringFormatConverter->underscoreAndHyphenToCamelCase($classMethodName);
|
||||
|
||||
// add "test", so PHPUnit runs the method
|
||||
if (! \str_starts_with($classMethodName, 'test')) {
|
||||
$classMethodName = 'test' . ucfirst($classMethodName);
|
||||
}
|
||||
|
||||
$classMethod->name = new Identifier($classMethodName);
|
||||
}
|
||||
|
||||
public function renameExtends(Class_ $class): void
|
||||
{
|
||||
$class->extends = new FullyQualified('PHPUnit\Framework\TestCase');
|
||||
}
|
||||
|
||||
public function renameNamespace(Class_ $class): void
|
||||
{
|
||||
$namespace = $this->betterNodeFinder->findParentType($class, Namespace_::class);
|
||||
if (! $namespace instanceof Namespace_) {
|
||||
return;
|
||||
}
|
||||
|
||||
$namespaceName = $this->nodeNameResolver->getName($namespace);
|
||||
if ($namespaceName === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$newNamespaceName = StaticRectorStrings::removePrefixes($namespaceName, ['spec\\']);
|
||||
|
||||
$namespace->name = new Name('Tests\\' . $newNamespaceName);
|
||||
}
|
||||
|
||||
public function renameClass(Class_ $class): void
|
||||
{
|
||||
$classShortName = $this->nodeNameResolver->getShortName($class);
|
||||
|
||||
// anonymous class?
|
||||
if ($classShortName === '') {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
// 2. change class name
|
||||
$newClassName = StaticRectorStrings::removeSuffixes($classShortName, [self::SPEC]);
|
||||
$newTestClassName = $newClassName . 'Test';
|
||||
|
||||
$class->name = new Identifier($newTestClassName);
|
||||
}
|
||||
|
||||
public function resolveObjectPropertyName(Class_ $class): string
|
||||
{
|
||||
// anonymous class?
|
||||
if ($class->name === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$shortClassName = $this->nodeNameResolver->getShortName($class);
|
||||
$bareClassName = StaticRectorStrings::removeSuffixes($shortClassName, [self::SPEC, 'Test']);
|
||||
|
||||
return lcfirst($bareClassName);
|
||||
}
|
||||
|
||||
public function resolveTestedClass(Node $node): string
|
||||
{
|
||||
if ($node instanceof ClassLike) {
|
||||
$className = (string) $this->nodeNameResolver->getName($node);
|
||||
} else {
|
||||
$classLike = $this->betterNodeFinder->findParentType($node, ClassLike::class);
|
||||
if (! $classLike instanceof ClassLike) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$className = (string) $this->nodeNameResolver->getName($classLike);
|
||||
}
|
||||
|
||||
$newClassName = StaticRectorStrings::removePrefixes($className, ['spec\\']);
|
||||
return StaticRectorStrings::removeSuffixes($newClassName, [self::SPEC]);
|
||||
}
|
||||
|
||||
private function removeNamePrefixes(string $name): string
|
||||
{
|
||||
$originalName = $name;
|
||||
|
||||
$name = StaticRectorStrings::removePrefixes(
|
||||
$name,
|
||||
['it_should_have_', 'it_should_be', 'it_should_', 'it_is_', 'it_', 'is_']
|
||||
);
|
||||
|
||||
if ($name === '') {
|
||||
return $originalName;
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit\NodeFactory;
|
||||
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use Rector\Core\PhpParser\Node\NodeFactory;
|
||||
use Rector\Core\PhpParser\Node\Value\ValueResolver;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
|
||||
final class AssertMethodCallFactory
|
||||
{
|
||||
private bool $isBoolAssert = false;
|
||||
|
||||
public function __construct(
|
||||
private readonly NodeFactory $nodeFactory,
|
||||
private readonly NodeNameResolver $nodeNameResolver,
|
||||
private readonly ValueResolver $valueResolver
|
||||
) {
|
||||
}
|
||||
|
||||
public function createAssertMethod(
|
||||
string $name,
|
||||
Expr $value,
|
||||
?Expr $expected,
|
||||
PropertyFetch $testedObjectPropertyFetch
|
||||
): MethodCall {
|
||||
$this->isBoolAssert = false;
|
||||
|
||||
// special case with bool!
|
||||
if ($expected instanceof Expr) {
|
||||
$name = $this->resolveBoolMethodName($name, $expected);
|
||||
}
|
||||
|
||||
$assetMethodCall = $this->nodeFactory->createMethodCall('this', $name);
|
||||
|
||||
if (! $this->isBoolAssert && $expected instanceof Expr) {
|
||||
$assetMethodCall->args[] = new Arg($this->thisToTestedObjectPropertyFetch(
|
||||
$expected,
|
||||
$testedObjectPropertyFetch
|
||||
));
|
||||
}
|
||||
|
||||
$assetMethodCall->args[] = new Arg($this->thisToTestedObjectPropertyFetch($value, $testedObjectPropertyFetch));
|
||||
|
||||
return $assetMethodCall;
|
||||
}
|
||||
|
||||
private function resolveBoolMethodName(string $name, Expr $expr): string
|
||||
{
|
||||
if (! $this->valueResolver->isTrueOrFalse($expr)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
$isFalse = $this->valueResolver->isFalse($expr);
|
||||
if ($name === 'assertSame') {
|
||||
$this->isBoolAssert = true;
|
||||
return $isFalse ? 'assertFalse' : 'assertTrue';
|
||||
}
|
||||
|
||||
if ($name === 'assertNotSame') {
|
||||
$this->isBoolAssert = true;
|
||||
return $isFalse ? 'assertNotFalse' : 'assertNotTrue';
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
private function thisToTestedObjectPropertyFetch(Expr $expr, PropertyFetch $propertyFetch): Expr
|
||||
{
|
||||
if (! $expr instanceof Variable) {
|
||||
return $expr;
|
||||
}
|
||||
|
||||
if (! $this->nodeNameResolver->isName($expr, 'this')) {
|
||||
return $expr;
|
||||
}
|
||||
|
||||
return $propertyFetch;
|
||||
}
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit\NodeFactory;
|
||||
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Expr\ArrayItem;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use Rector\Core\PhpParser\Node\NodeFactory;
|
||||
use Rector\Core\PhpParser\Node\Value\ValueResolver;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
|
||||
final class BeConstructedWithAssignFactory
|
||||
{
|
||||
public function __construct(
|
||||
private readonly NodeNameResolver $nodeNameResolver,
|
||||
private readonly ValueResolver $valueResolver,
|
||||
private readonly NodeFactory $nodeFactory
|
||||
) {
|
||||
}
|
||||
|
||||
public function create(MethodCall $methodCall, string $testedClass, PropertyFetch $propertyFetch): ?Assign
|
||||
{
|
||||
if ($this->nodeNameResolver->isName($methodCall->name, 'beConstructedWith')) {
|
||||
$new = new New_(new FullyQualified($testedClass));
|
||||
$new->args = $methodCall->args;
|
||||
|
||||
return new Assign($propertyFetch, $new);
|
||||
}
|
||||
|
||||
if ($this->nodeNameResolver->isName($methodCall->name, 'beConstructedThrough')) {
|
||||
if (! isset($methodCall->args[0])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $methodCall->args[0] instanceof Arg) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$methodName = $this->valueResolver->getValue($methodCall->args[0]->value);
|
||||
$staticCall = $this->nodeFactory->createStaticCall($testedClass, $methodName);
|
||||
|
||||
$this->moveConstructorArguments($methodCall, $staticCall);
|
||||
|
||||
return new Assign($propertyFetch, $staticCall);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function moveConstructorArguments(MethodCall $methodCall, StaticCall $staticCall): void
|
||||
{
|
||||
if (! isset($methodCall->args[1])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $methodCall->args[1] instanceof Arg) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $methodCall->args[1]->value instanceof Array_) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var Array_ $array */
|
||||
$array = $methodCall->args[1]->value;
|
||||
foreach ($array->items as $arrayItem) {
|
||||
if (! $arrayItem instanceof ArrayItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$staticCall->args[] = new Arg($arrayItem->value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit\NodeFactory;
|
||||
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Identifier;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\PhpParser\Node\Value\ValueResolver;
|
||||
use Rector\PostRector\Collector\NodesToAddCollector;
|
||||
|
||||
final class DuringMethodCallFactory
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ValueResolver $valueResolver,
|
||||
private readonly NodesToAddCollector $nodesToAddCollector
|
||||
) {
|
||||
}
|
||||
|
||||
public function create(MethodCall $methodCall, PropertyFetch $propertyFetch): MethodCall
|
||||
{
|
||||
if (! isset($methodCall->args[0])) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
if (! $methodCall->args[0] instanceof Arg) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$name = $this->valueResolver->getValue($methodCall->args[0]->value);
|
||||
$thisObjectPropertyMethodCall = new MethodCall($propertyFetch, $name);
|
||||
|
||||
if (isset($methodCall->args[1]) && $methodCall->args[1] instanceof Arg && $methodCall->args[1]->value instanceof Array_) {
|
||||
/** @var Array_ $array */
|
||||
$array = $methodCall->args[1]->value;
|
||||
|
||||
if (isset($array->items[0])) {
|
||||
$thisObjectPropertyMethodCall->args[] = new Arg($array->items[0]->value);
|
||||
}
|
||||
}
|
||||
|
||||
/** @var MethodCall $parentMethodCall */
|
||||
$parentMethodCall = $methodCall->var;
|
||||
$parentMethodCall->name = new Identifier('expectException');
|
||||
|
||||
// add $this->object->someCall($withArgs)
|
||||
$this->nodesToAddCollector->addNodeAfterNode($thisObjectPropertyMethodCall, $methodCall);
|
||||
|
||||
return $parentMethodCall;
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit;
|
||||
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Core\PhpParser\AstResolver;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
use Rector\Testing\PHPUnit\StaticPHPUnitEnvironment;
|
||||
|
||||
/**
|
||||
* Decorate setUp() and tearDown() with "void" when local TestClass class uses them
|
||||
*/
|
||||
final class PHPUnitTypeDeclarationDecorator
|
||||
{
|
||||
public function __construct(
|
||||
private readonly AstResolver $astResolver
|
||||
) {
|
||||
}
|
||||
|
||||
public function decorate(ClassMethod $classMethod): void
|
||||
{
|
||||
// skip test run
|
||||
if (StaticPHPUnitEnvironment::isPHPUnitRun()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$setUpClassMethod = $this->astResolver->resolveClassMethod('PHPUnit\Framework\TestCase', MethodName::SET_UP);
|
||||
if (! $setUpClassMethod instanceof ClassMethod) {
|
||||
return;
|
||||
}
|
||||
|
||||
$classMethod->returnType = $setUpClassMethod->returnType;
|
||||
}
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
|
||||
|
||||
final class PhpSpecMockCollector
|
||||
{
|
||||
/**
|
||||
* @var mixed[]
|
||||
*/
|
||||
private array $mocks = [];
|
||||
|
||||
/**
|
||||
* @var mixed[]
|
||||
*/
|
||||
private array $mocksWithsTypes = [];
|
||||
|
||||
/**
|
||||
* @var mixed[]
|
||||
*/
|
||||
private array $propertyMocksByClass = [];
|
||||
|
||||
public function __construct(
|
||||
private readonly SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
|
||||
private readonly NodeNameResolver $nodeNameResolver,
|
||||
private readonly BetterNodeFinder $betterNodeFinder,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function resolveClassMocksFromParam(Class_ $class): array
|
||||
{
|
||||
$className = (string) $this->nodeNameResolver->getName($class);
|
||||
|
||||
if (isset($this->mocks[$className]) && $this->mocks[$className] !== []) {
|
||||
return $this->mocks[$className];
|
||||
}
|
||||
|
||||
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($class, function (Node $node) use ($class) {
|
||||
if (! $node instanceof ClassMethod) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $node->isPublic()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($node->params as $param) {
|
||||
$this->addMockFromParam($class, $param);
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
// set default value if none was found
|
||||
if (! isset($this->mocks[$className])) {
|
||||
$this->mocks[$className] = [];
|
||||
}
|
||||
|
||||
return $this->mocks[$className];
|
||||
}
|
||||
|
||||
public function isVariableMockInProperty(Class_ $class, Variable $variable): bool
|
||||
{
|
||||
$variableName = $this->nodeNameResolver->getName($variable);
|
||||
$className = (string) $this->nodeNameResolver->getName($class);
|
||||
|
||||
return in_array($variableName, $this->propertyMocksByClass[$className] ?? [], true);
|
||||
}
|
||||
|
||||
public function getTypeForClassAndVariable(Class_ $class, string $variable): string
|
||||
{
|
||||
$className = (string) $this->nodeNameResolver->getName($class);
|
||||
|
||||
if (! isset($this->mocksWithsTypes[$className][$variable])) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
return $this->mocksWithsTypes[$className][$variable];
|
||||
}
|
||||
|
||||
public function addPropertyMock(string $class, string $property): void
|
||||
{
|
||||
$this->propertyMocksByClass[$class][] = $property;
|
||||
}
|
||||
|
||||
private function addMockFromParam(Class_ $class, Param $param): void
|
||||
{
|
||||
$variable = $this->nodeNameResolver->getName($param->var);
|
||||
|
||||
$className = (string) $this->nodeNameResolver->getName($class);
|
||||
|
||||
$classMethod = $this->betterNodeFinder->findParentType($param, ClassMethod::class);
|
||||
if (! $classMethod instanceof ClassMethod) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$methodName = $this->nodeNameResolver->getName($classMethod);
|
||||
$this->mocks[$className][$variable][] = $methodName;
|
||||
|
||||
if ($param->type === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$paramType = (string) ($param->type ?? $param->type->getAttribute(AttributeKey::ORIGINAL_NAME));
|
||||
$this->mocksWithsTypes[$className][$variable] = $paramType;
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit\Rector;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* @changelog https://gnugat.github.io/2015/09/23/phpunit-with-phpspec.html
|
||||
* @changelog http://www.phpspec.net/en/stable/cookbook/construction.html
|
||||
*/
|
||||
abstract class AbstractPhpSpecToPHPUnitRector extends AbstractRector
|
||||
{
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Migrate PhpSpec behavior to PHPUnit test', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
namespace spec\SomeNamespaceForThisTest;
|
||||
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
||||
class OrderSpec extends ObjectBehavior
|
||||
{
|
||||
public function let(OrderFactory $factory, ShippingMethod $shippingMethod): void
|
||||
{
|
||||
$factory->createShippingMethodFor(Argument::any())->shouldBeCalled()->willReturn($shippingMethod);
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
namespace spec\SomeNamespaceForThisTest;
|
||||
|
||||
class OrderSpec extends ObjectBehavior
|
||||
{
|
||||
/**
|
||||
* @var \SomeNamespaceForThisTest\Order
|
||||
*/
|
||||
private $order;
|
||||
protected function setUp()
|
||||
{
|
||||
/** @var OrderFactory|\PHPUnit\Framework\MockObject\MockObject $factory */
|
||||
$factory = $this->createMock(OrderFactory::class);
|
||||
|
||||
/** @var ShippingMethod|\PHPUnit\Framework\MockObject\MockObject $shippingMethod */
|
||||
$shippingMethod = $this->createMock(ShippingMethod::class);
|
||||
|
||||
$factory->expects($this->once())->method('createShippingMethodFor')->willReturn($shippingMethod);
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
protected function isInPhpSpecBehavior(Node $node): bool
|
||||
{
|
||||
if ($node instanceof ClassLike) {
|
||||
return $this->isObjectType($node, new ObjectType('PhpSpec\ObjectBehavior'));
|
||||
}
|
||||
|
||||
$classLike = $this->betterNodeFinder->findParentType($node, ClassLike::class);
|
||||
if (! $classLike instanceof ClassLike) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->isInPhpSpecBehavior($classLike);
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit\Rector\ClassMethod;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
use Rector\PhpSpecToPHPUnit\Naming\PhpSpecRenaming;
|
||||
use Rector\PhpSpecToPHPUnit\PHPUnitTypeDeclarationDecorator;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\AbstractPhpSpecToPHPUnitRector;
|
||||
use Rector\Privatization\NodeManipulator\VisibilityManipulator;
|
||||
|
||||
/**
|
||||
* @see \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\PhpSpecToPHPUnitRectorTest
|
||||
*/
|
||||
final class PhpSpecMethodToPHPUnitMethodRector extends AbstractPhpSpecToPHPUnitRector
|
||||
{
|
||||
public function __construct(
|
||||
private readonly PHPUnitTypeDeclarationDecorator $phpUnitTypeDeclarationDecorator,
|
||||
private readonly PhpSpecRenaming $phpSpecRenaming,
|
||||
private readonly VisibilityManipulator $visibilityManipulator,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [ClassMethod::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMethod $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isInPhpSpecBehavior($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->isName($node, 'letGo')) {
|
||||
$node->name = new Identifier(MethodName::TEAR_DOWN);
|
||||
$this->visibilityManipulator->makeProtected($node);
|
||||
$this->phpUnitTypeDeclarationDecorator->decorate($node);
|
||||
} elseif ($this->isName($node, 'let')) {
|
||||
$node->name = new Identifier(MethodName::SET_UP);
|
||||
$this->visibilityManipulator->makeProtected($node);
|
||||
$this->phpUnitTypeDeclarationDecorator->decorate($node);
|
||||
} elseif ($node->isPublic()) {
|
||||
$this->processTestMethod($node);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
private function processTestMethod(ClassMethod $classMethod): void
|
||||
{
|
||||
// special case, @see https://johannespichler.com/writing-custom-phpspec-matchers/
|
||||
if ($this->isName($classMethod, 'getMatchers')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// change name to phpunit test case format
|
||||
$this->phpSpecRenaming->renameMethod($classMethod);
|
||||
|
||||
// reorder instantiation + expected exception
|
||||
$previousStmt = null;
|
||||
foreach ((array) $classMethod->stmts as $key => $stmt) {
|
||||
$printedStmtContent = $this->print($stmt);
|
||||
|
||||
if (\str_contains($printedStmtContent, 'duringInstantiation') && $previousStmt instanceof Stmt) {
|
||||
$printedPreviousStmt = $this->print($previousStmt);
|
||||
if (\str_contains($printedPreviousStmt, 'beConstructedThrough')) {
|
||||
$classMethod->stmts[$key - 1] = $stmt;
|
||||
$classMethod->stmts[$key] = $previousStmt;
|
||||
}
|
||||
}
|
||||
|
||||
$previousStmt = $stmt;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\Core\NodeManipulator\ClassInsertManipulator;
|
||||
use Rector\PhpSpecToPHPUnit\PhpSpecMockCollector;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\AbstractPhpSpecToPHPUnitRector;
|
||||
|
||||
/**
|
||||
* @see \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\PhpSpecToPHPUnitRectorTest
|
||||
*/
|
||||
final class AddMockPropertiesRector extends AbstractPhpSpecToPHPUnitRector
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ClassInsertManipulator $classInsertManipulator,
|
||||
private readonly PhpSpecMockCollector $phpSpecMockCollector
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isInPhpSpecBehavior($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classMocks = $this->phpSpecMockCollector->resolveClassMocksFromParam($node);
|
||||
|
||||
$className = $this->getName($node);
|
||||
if (! is_string($className)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($classMocks as $name => $methods) {
|
||||
if ((is_countable($methods) ? count($methods) : 0) <= 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// non-ctor used mocks are probably local only
|
||||
if (! in_array('let', $methods, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->phpSpecMockCollector->addPropertyMock($className, $name);
|
||||
|
||||
$variableType = $this->phpSpecMockCollector->getTypeForClassAndVariable($node, $name);
|
||||
|
||||
$unionType = new UnionType([
|
||||
new ObjectType($variableType),
|
||||
new ObjectType('PHPUnit\Framework\MockObject\MockObject'),
|
||||
]);
|
||||
|
||||
$this->classInsertManipulator->addPropertyToClass($node, $name, $unionType);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\NodeManipulator\ClassInsertManipulator;
|
||||
use Rector\PhpSpecToPHPUnit\LetManipulator;
|
||||
use Rector\PhpSpecToPHPUnit\Naming\PhpSpecRenaming;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\AbstractPhpSpecToPHPUnitRector;
|
||||
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
|
||||
use Rector\PHPUnit\NodeFactory\SetUpClassMethodFactory;
|
||||
|
||||
/**
|
||||
* @see \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\PhpSpecToPHPUnitRectorTest
|
||||
*/
|
||||
final class PhpSpecClassToPHPUnitClassRector extends AbstractPhpSpecToPHPUnitRector
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ClassInsertManipulator $classInsertManipulator,
|
||||
private readonly LetManipulator $letManipulator,
|
||||
private readonly PhpSpecRenaming $phpSpecRenaming,
|
||||
private readonly SetUpClassMethodFactory $setUpClassMethodFactory
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isInPhpSpecBehavior($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 1. change namespace name to PHPUnit-like
|
||||
$this->phpSpecRenaming->renameNamespace($node);
|
||||
|
||||
$propertyName = $this->phpSpecRenaming->resolveObjectPropertyName($node);
|
||||
|
||||
$this->phpSpecRenaming->renameClass($node);
|
||||
$this->phpSpecRenaming->renameExtends($node);
|
||||
|
||||
$testedClass = $this->phpSpecRenaming->resolveTestedClass($node);
|
||||
|
||||
$testedObjectType = new ObjectType($testedClass);
|
||||
$this->classInsertManipulator->addPropertyToClass($node, $propertyName, $testedObjectType);
|
||||
$classMethod = $node->getMethod('let');
|
||||
|
||||
// add let if missing
|
||||
if (! $classMethod instanceof ClassMethod) {
|
||||
if (! $this->letManipulator->isLetNeededInClass($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$letClassMethod = $this->createLetClassMethod($propertyName, $testedObjectType);
|
||||
$this->classInsertManipulator->addAsFirstMethod($node, $letClassMethod);
|
||||
}
|
||||
|
||||
return $this->removeSelfTypeMethod($node, $testedObjectType);
|
||||
}
|
||||
|
||||
private function createLetClassMethod(string $propertyName, ObjectType $testedObjectType): ClassMethod
|
||||
{
|
||||
$propertyFetch = new PropertyFetch(new Variable('this'), $propertyName);
|
||||
|
||||
$testedObjectType = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode(
|
||||
$testedObjectType,
|
||||
TypeKind::RETURN()
|
||||
);
|
||||
if (! $testedObjectType instanceof Name) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$new = new New_($testedObjectType);
|
||||
$assign = new Assign($propertyFetch, $new);
|
||||
|
||||
return $this->setUpClassMethodFactory->createSetUpMethod([$assign]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is already checked on construction of object
|
||||
*/
|
||||
private function removeSelfTypeMethod(Class_ $class, ObjectType $testedObjectType): Class_
|
||||
{
|
||||
foreach ($class->getMethods() as $classMethod) {
|
||||
$classMethodStmts = (array) $classMethod->stmts;
|
||||
if (count($classMethodStmts) !== 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$innerClassMethodStmt = $this->resolveFirstNonExpressionStmt($classMethodStmts);
|
||||
if (! $innerClassMethodStmt instanceof MethodCall) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $this->isName($innerClassMethodStmt->name, 'shouldHaveType')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! isset($innerClassMethodStmt->args[0])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $innerClassMethodStmt->args[0] instanceof Arg) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// not the tested type
|
||||
if (! $this->valueResolver->isValue(
|
||||
$innerClassMethodStmt->args[0]->value,
|
||||
$testedObjectType->getClassName()
|
||||
)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// remove it
|
||||
$this->removeNodeFromStatements($class, $classMethod);
|
||||
}
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Stmt[] $stmts
|
||||
*/
|
||||
private function resolveFirstNonExpressionStmt(array $stmts): ?Node
|
||||
{
|
||||
if (! isset($stmts[0])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$firstStmt = $stmts[0];
|
||||
if ($firstStmt instanceof Expression) {
|
||||
return $firstStmt->expr;
|
||||
}
|
||||
|
||||
return $firstStmt;
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit\Rector\Class_;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\Util\StringUtils;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* @changelog https://gnugat.github.io/2015/09/23/phpunit-with-phpspec.html
|
||||
*
|
||||
* @see \Rector\Tests\PhpSpecToPHPUnit\Rector\Class_\RenameSpecFileToTestFileRector\RenameSpecFileToTestFileRectorTest
|
||||
*/
|
||||
final class RenameSpecFileToTestFileRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @see https://regex101.com/r/r1VkPt/1
|
||||
*/
|
||||
private const SPEC_REGEX = '#\/spec\/#';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @see https://regex101.com/r/WD4U43/1
|
||||
*/
|
||||
private const SPEC_SUFFIX_REGEX = '#Spec\.php$#';
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition(
|
||||
'Rename "*Spec.php" file to "*Test.php" file',
|
||||
[
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
// tests/SomeSpec.php
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
// tests/SomeTest.php
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$smartFileInfo = $this->file->getSmartFileInfo();
|
||||
$oldPathname = $smartFileInfo->getPathname();
|
||||
|
||||
// ends with Spec.php
|
||||
if (! StringUtils::isMatch($oldPathname, self::SPEC_SUFFIX_REGEX)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$newPathName = $this->createPathName($oldPathname);
|
||||
$this->removedAndAddedFilesCollector->addMovedFile($this->file, $newPathName);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function createPathName(string $oldRealPath): string
|
||||
{
|
||||
// suffix
|
||||
$newRealPath = Strings::replace($oldRealPath, self::SPEC_SUFFIX_REGEX, 'Test.php');
|
||||
|
||||
// directory
|
||||
return Strings::replace($newRealPath, self::SPEC_REGEX, '/tests/');
|
||||
}
|
||||
}
|
|
@ -1,251 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit\Rector\MethodCall;
|
||||
|
||||
use PhpParser\Comment\Doc;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\Error;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\Php\TypeAnalyzer;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\PhpSpecToPHPUnit\PhpSpecMockCollector;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\AbstractPhpSpecToPHPUnitRector;
|
||||
|
||||
/**
|
||||
* @see \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\PhpSpecToPHPUnitRectorTest
|
||||
*/
|
||||
final class PhpSpecMocksToPHPUnitMocksRector extends AbstractPhpSpecToPHPUnitRector
|
||||
{
|
||||
public function __construct(
|
||||
private readonly PhpSpecMockCollector $phpSpecMockCollector,
|
||||
private readonly TypeAnalyzer $typeAnalyzer
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [ClassMethod::class, MethodCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMethod|MethodCall $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isInPhpSpecBehavior($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($node instanceof ClassMethod) {
|
||||
// public = tests, protected = internal, private = own (no framework magic)
|
||||
if ($node->isPrivate()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->processMethodParamsToMocks($node);
|
||||
return $node;
|
||||
}
|
||||
|
||||
return $this->processMethodCall($node);
|
||||
}
|
||||
|
||||
private function processMethodParamsToMocks(ClassMethod $classMethod): void
|
||||
{
|
||||
// remove params and turn them to instances
|
||||
$assigns = [];
|
||||
foreach ($classMethod->params as $param) {
|
||||
if (! $param->type instanceof Name) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$createMockCall = $this->createCreateMockCall($param, $param->type);
|
||||
if ($createMockCall !== null) {
|
||||
$assigns[] = $createMockCall;
|
||||
}
|
||||
}
|
||||
|
||||
// remove all params
|
||||
$classMethod->params = [];
|
||||
|
||||
$classMethod->stmts = array_merge($assigns, (array) $classMethod->stmts);
|
||||
}
|
||||
|
||||
private function processMethodCall(MethodCall $methodCall): ?MethodCall
|
||||
{
|
||||
if (! $this->isName($methodCall->name, 'shouldBeCalled')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $methodCall->var instanceof MethodCall) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$mockMethodName = $this->getName($methodCall->var->name);
|
||||
if ($mockMethodName === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$arg = $methodCall->var->args[0] ?? null;
|
||||
|
||||
$expectedArg = $arg instanceof Arg ? $arg->value : null;
|
||||
|
||||
$methodCall->var->name = new Identifier('expects');
|
||||
$thisOnceMethodCall = $this->nodeFactory->createLocalMethodCall('atLeastOnce');
|
||||
$methodCall->var->args = [new Arg($thisOnceMethodCall)];
|
||||
|
||||
$methodCall->name = new Identifier('method');
|
||||
$methodCall->args = [new Arg(new String_($mockMethodName))];
|
||||
|
||||
if ($expectedArg !== null) {
|
||||
return $this->appendWithMethodCall($methodCall, $expectedArg);
|
||||
}
|
||||
|
||||
return $methodCall;
|
||||
}
|
||||
|
||||
/**
|
||||
* Variable or property fetch, based on number of present params in whole class
|
||||
*/
|
||||
private function createCreateMockCall(Param $param, Name $name): ?Expression
|
||||
{
|
||||
$class = $this->betterNodeFinder->findParentType($param, Class_::class);
|
||||
if (! $class instanceof Class_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classMocks = $this->phpSpecMockCollector->resolveClassMocksFromParam($class);
|
||||
|
||||
$variable = $this->getName($param->var);
|
||||
|
||||
$classMethod = $this->betterNodeFinder->findParentType($param, ClassMethod::class);
|
||||
if (! $classMethod instanceof ClassMethod) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$methodName = $this->nodeNameResolver->getName($classMethod);
|
||||
$methodsWithWThisMock = $classMocks[$variable];
|
||||
|
||||
if ($param->var instanceof Error) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// single use: "$mock = $this->createMock()"
|
||||
if (! $this->phpSpecMockCollector->isVariableMockInProperty($class, $param->var)) {
|
||||
return $this->createNewMockVariableAssign($param, $name);
|
||||
}
|
||||
|
||||
$reversedMethodsWithThisMock = array_flip($methodsWithWThisMock);
|
||||
|
||||
// first use of many: "$this->mock = $this->createMock()"
|
||||
if ($reversedMethodsWithThisMock[$methodName] === 0) {
|
||||
return $this->createPropertyFetchMockVariableAssign($param, $name);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function appendWithMethodCall(MethodCall $methodCall, Expr $expr): MethodCall
|
||||
{
|
||||
$withMethodCall = new MethodCall($methodCall, 'with');
|
||||
|
||||
if ($expr instanceof StaticCall) {
|
||||
if ($this->isName($expr->class, '*Argument')) {
|
||||
if ($this->isName($expr->name, 'any')) {
|
||||
// no added value having this method
|
||||
return $methodCall;
|
||||
}
|
||||
|
||||
if ($this->isName($expr->name, 'type')) {
|
||||
$expr = $this->createIsTypeOrIsInstanceOf($expr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$newExpr = $this->nodeFactory->createLocalMethodCall('equalTo');
|
||||
$newExpr->args = [new Arg($expr)];
|
||||
$expr = $newExpr;
|
||||
}
|
||||
|
||||
$withMethodCall->args = [new Arg($expr)];
|
||||
|
||||
return $withMethodCall;
|
||||
}
|
||||
|
||||
private function createNewMockVariableAssign(Param $param, Name $name): Expression
|
||||
{
|
||||
$methodCall = $this->nodeFactory->createLocalMethodCall('createMock');
|
||||
$methodCall->args[] = new Arg(new ClassConstFetch($name, 'class'));
|
||||
|
||||
$assign = new Assign($param->var, $methodCall);
|
||||
$assignExpression = new Expression($assign);
|
||||
|
||||
// add @var doc comment
|
||||
$varDoc = $this->createMockVarDoc($param, $name);
|
||||
$assignExpression->setDocComment(new Doc($varDoc));
|
||||
|
||||
return $assignExpression;
|
||||
}
|
||||
|
||||
private function createPropertyFetchMockVariableAssign(Param $param, Name $name): Expression
|
||||
{
|
||||
$variable = $this->getName($param->var);
|
||||
if ($variable === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$propertyFetch = new PropertyFetch(new Variable('this'), $variable);
|
||||
|
||||
$methodCall = $this->nodeFactory->createLocalMethodCall('createMock');
|
||||
$methodCall->args[] = new Arg(new ClassConstFetch($name, 'class'));
|
||||
|
||||
$assign = new Assign($propertyFetch, $methodCall);
|
||||
|
||||
return new Expression($assign);
|
||||
}
|
||||
|
||||
private function createIsTypeOrIsInstanceOf(StaticCall $staticCall): MethodCall
|
||||
{
|
||||
$args = $staticCall->args;
|
||||
$type = $this->valueResolver->getValue($args[0]->value);
|
||||
|
||||
$name = $this->typeAnalyzer->isPhpReservedType($type) ? 'isType' : 'isInstanceOf';
|
||||
|
||||
return $this->nodeFactory->createLocalMethodCall($name, $args);
|
||||
}
|
||||
|
||||
private function createMockVarDoc(Param $param, Name $name): string
|
||||
{
|
||||
$paramType = (string) $name->getAttribute(AttributeKey::ORIGINAL_NAME, $name);
|
||||
$variableName = $this->getName($param->var);
|
||||
|
||||
if ($variableName === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'/** @var %s|\%s $%s */',
|
||||
$paramType,
|
||||
'PHPUnit\Framework\MockObject\MockObject',
|
||||
$variableName
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,300 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit\Rector\MethodCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\ArrayDimFetch;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\Clone_;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\PhpSpecToPHPUnit\MatchersManipulator;
|
||||
use Rector\PhpSpecToPHPUnit\Naming\PhpSpecRenaming;
|
||||
use Rector\PhpSpecToPHPUnit\NodeFactory\AssertMethodCallFactory;
|
||||
use Rector\PhpSpecToPHPUnit\NodeFactory\BeConstructedWithAssignFactory;
|
||||
use Rector\PhpSpecToPHPUnit\NodeFactory\DuringMethodCallFactory;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\AbstractPhpSpecToPHPUnitRector;
|
||||
|
||||
/**
|
||||
* @see \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\PhpSpecToPHPUnitRectorTest
|
||||
*/
|
||||
final class PhpSpecPromisesToPHPUnitAssertRector extends AbstractPhpSpecToPHPUnitRector
|
||||
{
|
||||
/**
|
||||
* @changelog https://github.com/phpspec/phpspec/blob/master/src/PhpSpec/Wrapper/Subject.php
|
||||
* ↓
|
||||
* @changelog https://phpunit.readthedocs.io/en/8.0/assertions.html
|
||||
* @var array<string, string[]>
|
||||
*/
|
||||
private const NEW_METHOD_TO_OLD_METHODS = [
|
||||
'assertInstanceOf' => ['shouldBeAnInstanceOf', 'shouldHaveType', 'shouldReturnAnInstanceOf'],
|
||||
'assertSame' => ['shouldBe', 'shouldReturn'],
|
||||
'assertNotSame' => ['shouldNotBe', 'shouldNotReturn'],
|
||||
'assertCount' => ['shouldHaveCount'],
|
||||
'assertEquals' => ['shouldBeEqualTo', 'shouldEqual'],
|
||||
'assertNotEquals' => ['shouldNotBeEqualTo'],
|
||||
'assertContains' => ['shouldContain'],
|
||||
'assertNotContains' => ['shouldNotContain'],
|
||||
// types
|
||||
'assertIsIterable' => ['shouldBeArray'],
|
||||
'assertIsNotIterable' => ['shouldNotBeArray'],
|
||||
'assertIsString' => ['shouldBeString'],
|
||||
'assertIsNotString' => ['shouldNotBeString'],
|
||||
'assertIsBool' => ['shouldBeBool', 'shouldBeBoolean'],
|
||||
'assertIsNotBool' => ['shouldNotBeBool', 'shouldNotBeBoolean'],
|
||||
'assertIsCallable' => ['shouldBeCallable'],
|
||||
'assertIsNotCallable' => ['shouldNotBeCallable'],
|
||||
'assertIsFloat' => ['shouldBeDouble', 'shouldBeFloat'],
|
||||
'assertIsNotFloat' => ['shouldNotBeDouble', 'shouldNotBeFloat'],
|
||||
'assertIsInt' => ['shouldBeInt', 'shouldBeInteger'],
|
||||
'assertIsNotInt' => ['shouldNotBeInt', 'shouldNotBeInteger'],
|
||||
'assertIsNull' => ['shouldBeNull'],
|
||||
'assertIsNotNull' => ['shouldNotBeNull'],
|
||||
'assertIsNumeric' => ['shouldBeNumeric'],
|
||||
'assertIsNotNumeric' => ['shouldNotBeNumeric'],
|
||||
'assertIsObject' => ['shouldBeObject'],
|
||||
'assertIsNotObject' => ['shouldNotBeObject'],
|
||||
'assertIsResource' => ['shouldBeResource'],
|
||||
'assertIsNotResource' => ['shouldNotBeResource'],
|
||||
'assertIsScalar' => ['shouldBeScalar'],
|
||||
'assertIsNotScalar' => ['shouldNotBeScalar'],
|
||||
'assertNan' => ['shouldBeNan'],
|
||||
'assertFinite' => ['shouldBeFinite', 'shouldNotBeFinite'],
|
||||
'assertInfinite' => ['shouldBeInfinite', 'shouldNotBeInfinite'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const THIS = 'this';
|
||||
|
||||
private ?string $testedClass = null;
|
||||
|
||||
private bool $isPrepared = false;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private array $matchersKeys = [];
|
||||
|
||||
private ?PropertyFetch $testedObjectPropertyFetch = null;
|
||||
|
||||
public function __construct(
|
||||
private readonly MatchersManipulator $matchersManipulator,
|
||||
private readonly PhpSpecRenaming $phpSpecRenaming,
|
||||
private readonly AssertMethodCallFactory $assertMethodCallFactory,
|
||||
private readonly BeConstructedWithAssignFactory $beConstructedWithAssignFactory,
|
||||
private readonly DuringMethodCallFactory $duringMethodCallFactory
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [MethodCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MethodCall $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$this->isPrepared = false;
|
||||
$this->matchersKeys = [];
|
||||
|
||||
if (! $this->isInPhpSpecBehavior($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->isName($node->name, 'getWrappedObject')) {
|
||||
return $node->var;
|
||||
}
|
||||
|
||||
if ($this->isName($node->name, 'during')) {
|
||||
return $this->duringMethodCallFactory->create($node, $this->getTestedObjectPropertyFetch());
|
||||
}
|
||||
|
||||
if ($this->isName($node->name, 'duringInstantiation')) {
|
||||
return $this->processDuringInstantiation($node);
|
||||
}
|
||||
|
||||
// skip reserved names
|
||||
if ($this->isNames($node->name, ['getMatchers', 'expectException', 'assert*'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->prepareMethodCall($node);
|
||||
|
||||
if ($this->isName($node->name, 'beConstructed*')) {
|
||||
return $this->beConstructedWithAssignFactory->create(
|
||||
$node,
|
||||
$this->getTestedClass(),
|
||||
$this->getTestedObjectPropertyFetch()
|
||||
);
|
||||
}
|
||||
|
||||
$this->processMatchersKeys($node);
|
||||
|
||||
$args = $node->args;
|
||||
foreach (self::NEW_METHOD_TO_OLD_METHODS as $newMethod => $oldMethods) {
|
||||
if (! $this->isNames($node->name, $oldMethods)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $this->assertMethodCallFactory->createAssertMethod(
|
||||
$newMethod,
|
||||
$node->var,
|
||||
$args[0]->value ?? null,
|
||||
$this->getTestedObjectPropertyFetch()
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->shouldSkip($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->isName($node->name, 'clone')) {
|
||||
return new Clone_($this->getTestedObjectPropertyFetch());
|
||||
}
|
||||
|
||||
$methodName = $this->getName($node->name);
|
||||
if ($methodName === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var Class_ $classLike */
|
||||
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
|
||||
$classMethod = $classLike->getMethod($methodName);
|
||||
// it's a method call, skip
|
||||
if ($classMethod !== null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// direct PHPUnit method calls, no need to call on property
|
||||
if (in_array($methodName, ['atLeastOnce', 'equalTo', 'isInstanceOf', 'isType'], true)) {
|
||||
return $node;
|
||||
}
|
||||
|
||||
$node->var = $this->getTestedObjectPropertyFetch();
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
private function processDuringInstantiation(MethodCall $methodCall): MethodCall
|
||||
{
|
||||
/** @var MethodCall $parentMethodCall */
|
||||
$parentMethodCall = $methodCall->var;
|
||||
$parentMethodCall->name = new Identifier('expectException');
|
||||
|
||||
return $parentMethodCall;
|
||||
}
|
||||
|
||||
private function prepareMethodCall(MethodCall $methodCall): void
|
||||
{
|
||||
if ($this->isPrepared) {
|
||||
return;
|
||||
}
|
||||
|
||||
$class = $this->betterNodeFinder->findParentType($methodCall, Class_::class);
|
||||
if (! $class instanceof Class_) {
|
||||
return;
|
||||
}
|
||||
|
||||
$className = $this->getName($class);
|
||||
if (! is_string($className)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->matchersKeys = $this->matchersManipulator->resolveMatcherNamesFromClass($class);
|
||||
$this->testedClass = $this->phpSpecRenaming->resolveTestedClass($class);
|
||||
$this->testedObjectPropertyFetch = $this->createTestedObjectPropertyFetch($class);
|
||||
|
||||
$this->isPrepared = true;
|
||||
}
|
||||
|
||||
private function getTestedObjectPropertyFetch(): PropertyFetch
|
||||
{
|
||||
if ($this->testedObjectPropertyFetch === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
return $this->testedObjectPropertyFetch;
|
||||
}
|
||||
|
||||
private function getTestedClass(): string
|
||||
{
|
||||
if ($this->testedClass === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
return $this->testedClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @changelog https://johannespichler.com/writing-custom-phpspec-matchers/
|
||||
*/
|
||||
private function processMatchersKeys(MethodCall $methodCall): void
|
||||
{
|
||||
foreach ($this->matchersKeys as $matcherKey) {
|
||||
if (! $this->isName($methodCall->name, 'should' . ucfirst($matcherKey))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $methodCall->var instanceof MethodCall) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 1. assign callable to variable
|
||||
$thisGetMatchers = $this->nodeFactory->createMethodCall(self::THIS, 'getMatchers');
|
||||
$arrayDimFetch = new ArrayDimFetch($thisGetMatchers, new String_($matcherKey));
|
||||
$matcherCallableVariable = new Variable('matcherCallable');
|
||||
$assign = new Assign($matcherCallableVariable, $arrayDimFetch);
|
||||
|
||||
// 2. call it on result
|
||||
$funcCall = new FuncCall($matcherCallableVariable);
|
||||
$funcCall->args = $methodCall->args;
|
||||
|
||||
$methodCall->name = $methodCall->var->name;
|
||||
$methodCall->var = $this->getTestedObjectPropertyFetch();
|
||||
$methodCall->args = [];
|
||||
$funcCall->args[] = new Arg($methodCall);
|
||||
|
||||
$this->nodesToAddCollector->addNodesAfterNode([$assign, $funcCall], $methodCall);
|
||||
|
||||
$this->removeNode($methodCall);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private function shouldSkip(MethodCall $methodCall): bool
|
||||
{
|
||||
if (! $methodCall->var instanceof Variable) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (! $this->nodeNameResolver->isName($methodCall->var, self::THIS)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// skip "createMock" method
|
||||
return $this->isName($methodCall->name, 'createMock');
|
||||
}
|
||||
|
||||
private function createTestedObjectPropertyFetch(Class_ $class): PropertyFetch
|
||||
{
|
||||
$propertyName = $this->phpSpecRenaming->resolveObjectPropertyName($class);
|
||||
return new PropertyFetch(new Variable(self::THIS), $propertyName);
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PhpSpecToPHPUnit\Rector\Variable;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\PhpSpecToPHPUnit\PhpSpecMockCollector;
|
||||
use Rector\PhpSpecToPHPUnit\Rector\AbstractPhpSpecToPHPUnitRector;
|
||||
|
||||
/**
|
||||
* $mock->call()
|
||||
* ↓
|
||||
* $this->mock->call()
|
||||
*
|
||||
* @see \Rector\Tests\PhpSpecToPHPUnit\Rector\Variable\PhpSpecToPHPUnitRector\PhpSpecToPHPUnitRectorTest
|
||||
*/
|
||||
final class MockVariableToPropertyFetchRector extends AbstractPhpSpecToPHPUnitRector
|
||||
{
|
||||
public function __construct(
|
||||
private readonly PhpSpecMockCollector $phpSpecMockCollector
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Variable::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Variable $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$class = $this->betterNodeFinder->findParentType($node, Class_::class);
|
||||
if (! $class instanceof Class_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isInPhpSpecBehavior($class)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->phpSpecMockCollector->isVariableMockInProperty($class, $node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var string $variableName */
|
||||
$variableName = $this->getName($node);
|
||||
|
||||
return new PropertyFetch(new Variable('this'), $variableName);
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\Php;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
|
||||
final class TypeAnalyzer
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private const EXTRA_TYPES = ['object'];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @see https://regex101.com/r/57HGpC/1
|
||||
*/
|
||||
private const SQUARE_BRACKET_REGEX = '#(\[\])+$#';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private array $phpSupportedTypes = [
|
||||
'string',
|
||||
'bool',
|
||||
'int',
|
||||
'null',
|
||||
'array',
|
||||
'false',
|
||||
'true',
|
||||
'mixed',
|
||||
'iterable',
|
||||
'float',
|
||||
'self',
|
||||
'parent',
|
||||
'callable',
|
||||
'void',
|
||||
];
|
||||
|
||||
public function __construct(PhpVersionProvider $phpVersionProvider)
|
||||
{
|
||||
if ($phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::OBJECT_TYPE)) {
|
||||
$this->phpSupportedTypes[] = 'object';
|
||||
}
|
||||
}
|
||||
|
||||
public function isPhpReservedType(string $type): bool
|
||||
{
|
||||
$types = explode('|', $type);
|
||||
|
||||
$reservedTypes = array_merge($this->phpSupportedTypes, self::EXTRA_TYPES);
|
||||
|
||||
foreach ($types as $type) {
|
||||
$type = strtolower($type);
|
||||
|
||||
// remove [] from arrays
|
||||
$type = Strings::replace($type, self::SQUARE_BRACKET_REGEX, '');
|
||||
|
||||
if (in_array($type, $reservedTypes, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user