<?php namespace Kahlan\Spec\Suite\Jit\Patcher; use Kahlan\Jit\Parser; use Kahlan\Jit\Patcher\Rebase; describe("Rebase", function () { beforeEach(function () { $this->path = 'spec/Fixture/Jit/Patcher/Rebase'; $this->patcher = new Rebase(); }); describe("->process()", function () { it("patches class's methods", function () { $nodes = Parser::parse(file_get_contents($this->path . '/Rebase.php')); $expected = file_get_contents($this->path . '/RebaseProcessed.php'); $actual = Parser::unparse($this->patcher->process($nodes, '/the/original/path/Rebase.php')); expect($actual)->toBe($expected); }); }); describe("->patchable()", function () { it("return `true`", function () { expect($this->patcher->patchable('SomeClass'))->toBe(true); }); }); });
/** * Runs file patchers. * * @param string $code The source code to process. * @param string $path The file path of the source code. * @return string The patched source code. */ public function process($code, $path = null) { if (!$code) { return ''; } $nodes = Parser::parse($code); foreach ($this->_patchers as $patcher) { $patcher->process($nodes, $path); } return Parser::unparse($nodes); }
{ }class InspectorKLAYER extends \\Kahlan\\Analysis\\Inspector { public static function inspect(\$class) {\$__KPOINTCUT_ARGS__ = func_get_args(); \$__KPOINTCUT_SELF__ = isset(\$this) ? \$this : get_called_class(); if (\$__KPOINTCUT__ = \\Kahlan\\Plugin\\Pointcut::before(__METHOD__, \$__KPOINTCUT_SELF__, \$__KPOINTCUT_ARGS__)) { \$r = \$__KPOINTCUT__(\$__KPOINTCUT_SELF__, \$__KPOINTCUT_ARGS__); return \$r; }return parent::inspect(\$class);} public static function parameters(\$class, \$method, \$data = NULL) {\$__KPOINTCUT_ARGS__ = func_get_args(); \$__KPOINTCUT_SELF__ = isset(\$this) ? \$this : get_called_class(); if (\$__KPOINTCUT__ = \\Kahlan\\Plugin\\Pointcut::before(__METHOD__, \$__KPOINTCUT_SELF__, \$__KPOINTCUT_ARGS__)) { \$r = \$__KPOINTCUT__(\$__KPOINTCUT_SELF__, \$__KPOINTCUT_ARGS__); return \$r; }return parent::parameters(\$class, \$method, \$data);} public static function typehint(\$parameter) {\$__KPOINTCUT_ARGS__ = func_get_args(); \$__KPOINTCUT_SELF__ = isset(\$this) ? \$this : get_called_class(); if (\$__KPOINTCUT__ = \\Kahlan\\Plugin\\Pointcut::before(__METHOD__, \$__KPOINTCUT_SELF__, \$__KPOINTCUT_ARGS__)) { \$r = \$__KPOINTCUT__(\$__KPOINTCUT_SELF__, \$__KPOINTCUT_ARGS__); return \$r; }return parent::typehint(\$parameter);}} EOD; expect($actual)->toBe($expected); }); it("bails out when `'override'` is empty", function () { $this->patcher = new Layer([]); $nodes = Parser::parse(file_get_contents($this->path . '/Layer.php')); $actual = Parser::unparse($this->patcher->process($nodes)); expect($actual)->toBe(""); }); it("doesn't patch classes which are not present in the `'override'` option", function () { $this->patcher = new Layer(['override' => ['Kahlan\\Analysis\\Debugger']]); $nodes = Parser::parse(file_get_contents($this->path . '/Layer.php')); $actual = Parser::unparse($this->patcher->process($nodes)); $expected = <<<EOD <?php namespace Kahlan\\Spec\\Fixture\\Jit\\Patcher\\Layer; class Inspector extends \\Kahlan\\Analysis\\Inspector { } EOD; expect($actual)->toBe($expected); }); }); });
namespace Kahlan\Spec\Suite\Jit\Patcher; use Kahlan\Jit\Parser; use Kahlan\Jit\Patcher\Monkey; describe("Monkey", function () { describe("->process()", function () { beforeEach(function () { $this->path = 'spec/Fixture/Jit/Patcher/Monkey'; $this->patcher = new Monkey(); }); it("patches class's methods", function () { $nodes = Parser::parse(file_get_contents($this->path . '/Class.php')); $expected = file_get_contents($this->path . '/ClassProcessed.php'); $actual = Parser::unparse($this->patcher->process($nodes)); expect($actual)->toBe($expected); }); it("patches trait's methods", function () { $nodes = Parser::parse(file_get_contents($this->path . '/Trait.php')); $expected = file_get_contents($this->path . '/TraitProcessed.php'); $actual = Parser::unparse($this->patcher->process($nodes)); expect($actual)->toBe($expected); }); it("patches plain php file", function () { $nodes = Parser::parse(file_get_contents($this->path . '/Plain.php')); $expected = file_get_contents($this->path . '/PlainProcessed.php'); $actual = Parser::unparse($this->patcher->process($nodes)); expect($actual)->toBe($expected); }); }); });
} if ($node->name === 'C') { expect($node->extends)->toBe('\\Test\\ParentC'); $check++; } if ($node->name === 'D') { expect($node->extends)->toBe(''); $check++; } } } expect($check)->toBe(4); }); it("parses implements", function () { $sample = file_get_contents('spec/Fixture/Jit/Parser/Implements.php'); $root = Parser::parse($sample); $check = 0; foreach ($root->tree as $node) { if ($node->type !== 'namespace') { continue; } expect($node->name)->toBe('Test'); foreach ($node->tree as $node) { if ($node->type !== 'class') { continue; } if ($node->name === 'A') { expect($node->implements)->toBe(['\\Space\\ParentA']); $check++; } if ($node->name === 'B') {
expect($actual)->toBe($expected); }); it("patches trait's methods", function () { $nodes = Parser::parse(file_get_contents($this->path . '/Trait.php')); $expected = file_get_contents($this->path . '/TraitProcessed.php'); $actual = Parser::unparse($this->patcher->process($nodes)); expect($actual)->toBe($expected); }); it("patches plain php file", function () { $nodes = Parser::parse(file_get_contents($this->path . '/Plain.php')); $expected = file_get_contents($this->path . '/PlainProcessed.php'); $actual = Parser::unparse($this->patcher->process($nodes)); expect($actual)->toBe($expected); }); it("patches errored php file", function () { $nodes = Parser::parse(file_get_contents($this->path . '/Errored.php')); $expected = file_get_contents($this->path . '/ErroredProcessed.php'); $actual = Parser::unparse($this->patcher->process($nodes)); expect($actual)->toBe($expected); }); }); describe("->patchable()", function () { it("return `true`", function () { expect($this->patcher->patchable('SomeClass'))->toBe(true); }); }); describe("::blacklisted()", function () { it("checks that blacklisted function returns `false`", function () { foreach (Monkey::blacklisted() as $name) { expect(Monkey::blacklisted($name))->toBe(true); }
} } } expect($check)->toBe(5); }); it("parses declare", function () { $filename = 'spec/Fixture/Jit/Parser/Declare'; $content = file_get_contents($filename . '.php'); $parsed = Parser::debug($content); expect($parsed)->toBe(file_get_contents($filename . '.txt')); $parsed = Parser::parse($content); expect(Parser::unparse($parsed))->toBe($content); }); it("parses declare as block", function () { $filename = 'spec/Fixture/Jit/Parser/DeclareAsBlock'; $content = file_get_contents($filename . '.php'); $parsed = Parser::debug($content); expect($parsed)->toBe(file_get_contents($filename . '.txt')); $parsed = Parser::parse($content); expect(Parser::unparse($parsed))->toBe($content); }); it("parses interfaces", function () { $filename = 'spec/Fixture/Jit/Parser/Interface'; $content = file_get_contents($filename . '.php'); $parsed = Parser::debug($content); expect($parsed)->toBe(file_get_contents($filename . '.txt')); $parsed = Parser::parse($content); expect(Parser::unparse($parsed))->toBe($content); }); }); });
use Kahlan\Jit\Parser; use Kahlan\Jit\Patcher\Pointcut; describe("Pointcut", function () { beforeEach(function () { $this->path = 'spec/Fixture/Jit/Patcher/Pointcut'; $this->patcher = new Pointcut(); }); describe("->process()", function () { it("adds an entry point to methods and wrap function call for classes", function () { $nodes = Parser::parse(file_get_contents($this->path . '/Simple.php')); if (version_compare(phpversion(), '5.5', '<')) { $expected = file_get_contents($this->path . '/SimpleProcessed_5.4.php'); } else { $expected = file_get_contents($this->path . '/SimpleProcessed.php'); } $actual = Parser::unparse($this->patcher->process($nodes)); expect($actual)->toBe($expected); }); it("adds an entry point to methods and wrap function call for traits", function () { $nodes = Parser::parse(file_get_contents($this->path . '/SimpleTrait.php')); $expected = file_get_contents($this->path . '/SimpleTraitProcessed.php'); $actual = Parser::unparse($this->patcher->process($nodes)); expect($actual)->toBe($expected); }); }); describe("->patchable()", function () { it("return `true`", function () { expect($this->patcher->patchable('SomeClass'))->toBe(true); }); }); });