Skip to content

Commit

Permalink
Atomize namespace processing; Install full Sylius library to use as c…
Browse files Browse the repository at this point in the history
…andidates.
  • Loading branch information
adamelso committed Jun 10, 2024
1 parent 8251fdf commit 873f9ba
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 54 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
# transunit
Transunit
===

Convert PhpSpec tests to PHPUnit

Dependencies
---

- nikic/php-parser
- symfony/finder
- symfony/filesystem
6 changes: 2 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
"require-dev": {
"phpspec/phpspec": "*",
"phpunit/phpunit": "*",
"sylius/addressing": "*",
"sylius/sylius": "^1.0",
"phpspec/prophecy-phpunit": "^2.2"
},
"require": {
"nikic/php-parser": "*",
"symfony/finder": "*",
"symfony/filesystem": "^7.0"
"nikic/php-parser": "*"
},
"autoload": {
"psr-4": {
Expand Down
29 changes: 22 additions & 7 deletions lib/Transunit/Pass/GlobalTestSubjectInstancePass.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,29 @@ private function instantiateTestSubject(Node\Stmt\ClassMethod $node, string $sub

foreach ($node->stmts as $stmt) {
// Check if expression is a property assignment
if ($stmt instanceof Node\Stmt\Expression
&& $stmt->expr instanceof Node\Expr\Assign
&& $stmt->expr->var instanceof Node\Expr\PropertyFetch
&& $stmt->expr->var->var instanceof Node\Expr\Variable
&& $stmt->expr->var->var->name === 'this'
) {
$collaboratorNames[$stmt->expr->var->name->name] = true;
if (! $stmt instanceof Node\Stmt\Expression) {
continue;
}

if (! $stmt->expr instanceof Node\Expr\Assign) {
continue;
}

if (! $stmt->expr->var instanceof Node\Expr\PropertyFetch) {
continue;
}

if (! $stmt->expr->var->var instanceof Node\Expr\Variable) {
continue;
}

$collaboratorVariableName = $stmt->expr->var->var->name;

if ($collaboratorVariableName === 'this') {
continue;
}

$collaboratorNames[$collaboratorVariableName] = true;
}

$globalCollaborators = [];
Expand Down
48 changes: 48 additions & 0 deletions lib/Transunit/Pass/ImportMockingLibraryPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Transunit\Pass;

use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Namespace_;
use PhpParser\NodeFinder;
use Transunit\Pass;

/**
* ```
* + use Prophecy\Prophecy\ObjectProphecy;
* + use Prophecy\PhpUnit\ProphecyTrait;
* + use PHPUnit\Framework\TestCase;
* ```
*/
class ImportMockingLibraryPass implements Pass
{
public function find(NodeFinder $nodeFinder, $ast): array
{
return [$nodeFinder->findFirstInstanceOf($ast, Namespace_::class)];
}

public function rewrite(Node $node): void
{
if (!$node instanceof Namespace_) {
return;
}

$this->importMockingLibraryClasses($node);
}

private function importMockingLibraryClasses(Namespace_ $node): void
{
array_unshift($node->stmts, new Node\Stmt\Use_([
new Node\Stmt\UseUse(new Name('Prophecy\Prophecy\ObjectProphecy')),
]));

array_unshift($node->stmts, new Node\Stmt\Use_([
new Node\Stmt\UseUse(new Name('Prophecy\PhpUnit\ProphecyTrait')),
]));

array_unshift($node->stmts, new Node\Stmt\Use_([
new Node\Stmt\UseUse(new Name('PHPUnit\Framework\TestCase')),
]));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,17 @@
use PhpParser\NodeFinder;
use Transunit\Pass;

class NamespacePass implements Pass
/**
* ```
* namespace test\unit\Foo\Bar;
*
* + use Foo\Bar\TestSubject;
*
* class TestSubjectSpec extends ObjectBehaviour
* {
* ```
*/
class ImportSubjectClassPass implements Pass
{
public function find(NodeFinder $nodeFinder, $ast): array
{
Expand All @@ -21,24 +31,7 @@ public function rewrite(Node $node): void
return;
}

$this->moveToNamespace($node);
$this->importSubjectClass($node);
$this->importMockingLibraryClasses($node);
}

/**
* namespace tests\unit\Foo\Bar;
*/
private function moveToNamespace(Namespace_ $node): void
{
$ns = $node->name->getParts();

if ($ns[0] === 'spec') {
array_shift($ns);
$ns = array_merge(['tests', 'unit'], $ns);
}

$node->name = new Name($ns);
}

/**
Expand Down Expand Up @@ -81,19 +74,4 @@ private function importSubjectClass(Namespace_ $node): void

array_unshift($node->stmts, $use);
}

private function importMockingLibraryClasses(Namespace_ $node): void
{
array_unshift($node->stmts, new Node\Stmt\Use_([
new Node\Stmt\UseUse(new Name('Prophecy\Prophecy\ObjectProphecy')),
]));

array_unshift($node->stmts, new Node\Stmt\Use_([
new Node\Stmt\UseUse(new Name('Prophecy\PhpUnit\ProphecyTrait')),
]));

array_unshift($node->stmts, new Node\Stmt\Use_([
new Node\Stmt\UseUse(new Name('PHPUnit\Framework\TestCase')),
]));
}
}
44 changes: 44 additions & 0 deletions lib/Transunit/Pass/MoveNamespacePass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Transunit\Pass;

use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Namespace_;
use PhpParser\NodeFinder;
use Transunit\Pass;

/**
* ```
* - namespace spec\Foo\Bar;
* + namespace tests\unit\Foo\Bar;
* ```
*/
class MoveNamespacePass implements Pass
{
public function find(NodeFinder $nodeFinder, $ast): array
{
return [$nodeFinder->findFirstInstanceOf($ast, Namespace_::class)];
}

public function rewrite(Node $node): void
{
if (!$node instanceof Namespace_) {
return;
}

$this->moveToNamespace($node);
}

private function moveToNamespace(Namespace_ $node): void
{
$ns = $node->name->getParts();

if ($ns[0] === 'spec') {
array_shift($ns);
$ns = array_merge(['tests', 'unit'], $ns);
}

$node->name = new Name($ns);
}
}
25 changes: 16 additions & 9 deletions lib/Transunit/Transunit.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,27 @@

class Transunit
{
public static function run(string $path): void
public static function run(string $path, string $destination = 'var'): void
{
$f = new Filesystem();
$fs = new Filesystem();
$specs = (new Finder())->files()->in($path)->name('*Spec.php');

$root = dirname(__DIR__, 2);
$exportDir = "{$root}/var";
$f->remove($exportDir);
$f->mkdir($exportDir);
$exportDir = "{$root}/{$destination}";

$fs->remove($exportDir);
$fs->mkdir($exportDir);

foreach ($specs as $file) {
$relative = trim($fs->makePathRelative($file->getPath(), $path), DIRECTORY_SEPARATOR);
$newFilename = substr($file->getBasename(), 0, -8) . 'Test.php';
$fullPathToNewTestFile = "{$exportDir}/{$relative}/{$newFilename}";

$modifiedCode = self::processFile($file->getRealPath());
$fullPathToNewTestFile = "{$exportDir}/{$newFilename}";
$f->touch($fullPathToNewTestFile);
file_put_contents($fullPathToNewTestFile, $modifiedCode);

$fs->mkdir("{$exportDir}/{$relative}");
$fs->touch($fullPathToNewTestFile);
$fs->dumpFile($fullPathToNewTestFile, $modifiedCode);
}
}

Expand All @@ -49,7 +54,9 @@ private static function processFile(string $path): string

$nodeFinder = new NodeFinder();
$passes = [
new Pass\NamespacePass(),
new Pass\MoveNamespacePass(),
new Pass\ImportSubjectClassPass(),
new Pass\ImportMockingLibraryPass(),
new Pass\ClassnamePass(),
new Pass\GlobalCollaboratorPass(),
new Pass\GlobalTestSubjectInstancePass(),
Expand Down
1 change: 1 addition & 0 deletions transunit.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@

$args = $argv;
array_shift($args);
$args[0] = getcwd().'/'.$args[0];

\Transunit\Transunit::run(...$args);

0 comments on commit 873f9ba

Please sign in to comment.