]+)>(.*?)<\/code>/s', '
', $dhtml);
62 |
63 | return $dhtml;
64 | }
65 |
66 | protected function parseParam($droot)
67 | {
68 | $param = self::$defaultParam;
69 | foreach ($droot as $element) {
70 | $class = $element->attributes()->class;
71 |
72 | $xml = $element->asXML();
73 | if ($element->getName() == 'code') {
74 | // Strip CDATA
75 | $xml = preg_replace('//', '$1', $xml);
76 | }
77 | $text = strip_tags($xml);
78 |
79 | if ($class == 'type') {
80 | $param['type'] = $text;
81 | } elseif ($class == 'parameter') {
82 | $param['name'] = $text;
83 | } elseif ($class == 'parameter reference') {
84 | $param['name'] = $text;
85 | $param['reference'] = true;
86 | } elseif ($class == 'initializer') {
87 | $param['optional'] = true; // FIXME: has default-value isn't meanning be optional
88 | $param['initializer'] = $text;
89 | } else {
90 | throw new \Exception('Unknown param defination class <'.$class.'>');
91 | }
92 | }
93 |
94 | return $param;
95 | }
96 |
97 | public function parseAll($wholehtml)
98 | {
99 | $list = [];
100 |
101 | preg_match_all('/.+?<\/div>/s', $wholehtml, $matches);
102 | if (!$matches[0]) {
103 | throw new \Exception('Invalid single document html');
104 | }
105 |
106 | foreach ($matches[0] as $desc) {
107 | try {
108 | $method = $this->parse($desc);
109 | $list[] = $method;
110 | } catch (\Exception $e) {
111 | continue;
112 | }
113 | }
114 |
115 | return $list;
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/Utils/Logging.php:
--------------------------------------------------------------------------------
1 | $method();
25 |
26 | case 1:
27 | return $logger->$method($args[0]);
28 |
29 | case 2:
30 | return $logger->$method($args[0], $args[1]);
31 |
32 | case 3:
33 | return $logger->$method($args[0], $args[1], $args[2]);
34 |
35 | case 4:
36 | return $logger->$method($args[0], $args[1], $args[2], $args[3]);
37 |
38 | default:
39 | return call_user_func_array([$logger, $method], $args);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Utils/Packager.php:
--------------------------------------------------------------------------------
1 | run();
108 |
109 | __HALT_COMPILER();
110 | EOC;
111 | $phar->setStub($code);
112 |
113 | // File
114 | foreach ($this->filelist as $file) {
115 | $phar->addFile($file);
116 | }
117 |
118 | // Vendor
119 | chdir(__DIR__.'/../../');
120 | $iterator = new \RecursiveIteratorIterator(
121 | new \RecursiveDirectoryIterator('vendor'),
122 | 0,
123 | \RecursiveIteratorIterator::CATCH_GET_CHILD
124 | );
125 | foreach ($iterator as $file) {
126 | if (!preg_match('/\/(\.|test\/)/i', $file)) {
127 | $phar->addFile($file);
128 | }
129 | }
130 |
131 | // Add execute permission
132 | chmod(self::NAME, 0755);
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/Utils/ParserHelper.php:
--------------------------------------------------------------------------------
1 | name);
20 | } elseif ($node instanceof Expr\StaticCall) {
21 | return !is_string($node->name) || !self::isConstName($node->class);
22 | } elseif ($node instanceof Expr\FuncCall) {
23 | return !($node->name instanceof Name);
24 | } else {
25 | throw new \Exception('Invalid function, method call node ('.get_class($node).')');
26 | }
27 | }
28 |
29 | /**
30 | * Test if given variable is a const name.
31 | */
32 | public static function isConstName($prop)
33 | {
34 | return is_string($prop) || method_exists($prop, '__toString');
35 | }
36 |
37 | public static function isSameFunc($name, $const)
38 | {
39 | if (!self::isConstName($name)) {
40 | return false;
41 | }
42 |
43 | return strcasecmp($name, $const) === 0;
44 | }
45 |
46 | public static function isSameClass($name, $const)
47 | {
48 | if (!self::isConstName($name)) {
49 | return false;
50 | }
51 |
52 | return strcasecmp($name, $const) === 0;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/tests/Changes/AbstractChangeTest.php:
--------------------------------------------------------------------------------
1 | change = new $chgname();
18 | }
19 |
20 | public function assertHasSpot($code)
21 | {
22 | $spots = TestHelper::runChange($this->change, $code);
23 | $this->assertNotEmpty($spots);
24 | }
25 |
26 | public function assertNotSpot($code)
27 | {
28 | $spots = TestHelper::runChange($this->change, $code);
29 | $this->assertEmpty($spots);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/Changes/AbstractIntroducedTest.php:
--------------------------------------------------------------------------------
1 | assertNotSpot($code);
14 |
15 | $table = TestHelper::fetchProperty($this->change, 'funcTable');
16 | if (is_null($table)) {
17 | return;
18 | }
19 | foreach ($table as $name => $dummy) {
20 | // Normal name
21 | $code = sprintf('function %s() {}', $name);
22 | $this->assertHasSpot($code);
23 |
24 | // Case Insensitive name
25 | $code = sprintf('function %s() {}', strtoupper($name));
26 | $this->assertHasSpot($code);
27 |
28 | // Namespaced
29 | $code = sprintf('namespace Dummy; function %s() {}', $name);
30 | $this->assertNotSpot($code);
31 |
32 | // Conditional name
33 | $code = sprintf("if (!function_exists('%s')) { function %s() {} }", $name, $name);
34 | $this->assertNotSpot($code);
35 | }
36 |
37 | // Error-conditional name
38 | $code = sprintf("if (!function_exists('nothing')) { function %s() {} }", $name);
39 | $this->assertHasSpot($code);
40 | }
41 |
42 | protected function genMethod($class, $method)
43 | {
44 | return sprintf('class Sample extends %s { public function %s() {} }', $class, $method);
45 | }
46 |
47 | public function testNewMethod()
48 | {
49 | $table = TestHelper::fetchProperty($this->change, 'methodTable');
50 | if (is_null($table)) {
51 | return;
52 | }
53 | foreach ($table as $name => $dummy) {
54 | list($class, $method) = explode('::', $name);
55 |
56 | // Normal name
57 | $code = $this->genMethod($class, $method);
58 | $this->assertHasSpot($code);
59 |
60 | // Case Insensitive name
61 | $code = $this->genMethod(strtoupper($class), strtoupper($method));
62 | $this->assertHasSpot($code);
63 |
64 | // Namespaced
65 | $code = 'namespace Dummy; '.$this->genMethod($class, $method);
66 | $this->assertNotSpot($code);
67 | }
68 | }
69 |
70 | public function testNewClass()
71 | {
72 | // Not-new
73 | $code = 'class not_new {}';
74 | $this->assertNotSpot($code);
75 |
76 | $table = TestHelper::fetchProperty($this->change, 'classTable');
77 | if (is_null($table)) {
78 | return;
79 | }
80 | foreach ($table as $name => $dummy) {
81 | // Normal name
82 | $code = sprintf('class %s {}', $name);
83 | $this->assertHasSpot($code);
84 |
85 | // Case Insensitive name
86 | $code = sprintf('class %s {}', strtoupper($name));
87 | $this->assertHasSpot($code);
88 |
89 | // Namespaced
90 | $code = sprintf('namespace Dummy; class %s {}', $name);
91 | $this->assertNotSpot($code);
92 |
93 | // Conditional name
94 | // Removed, because of autoload it's too rare to see
95 | // $code = sprintf("if (!class_exists('%s')) { class %s {} }", $name, $name);
96 | // $this->assertNotSpot($code);
97 | }
98 | }
99 |
100 | protected function genDefine($name)
101 | {
102 | return 'define("'.$name.'", 0);';
103 | }
104 |
105 | public function testNewConst()
106 | {
107 | // Not-new
108 | $code = $this->genDefine('NOTNEW');
109 | $this->assertNotSpot($code);
110 |
111 | $table = TestHelper::fetchProperty($this->change, 'constTable');
112 | foreach ($table as $name => $dummy) {
113 | // Normal name
114 | $code = $this->genDefine($name);
115 | $this->assertHasSpot($code);
116 |
117 | // Case Insensitive name
118 | $code = $this->genDefine(strtolower($name));
119 | $this->assertNotSpot($code);
120 | }
121 |
122 | // #Issue 7: First argument not a string
123 | $this->assertNotSpot('define(DUMMY, 0);');
124 | $this->assertNotSpot('define(123, 0);');
125 | $this->assertNotSpot('define($dummy, 0);');
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/tests/Changes/AbstractRemovedTest.php:
--------------------------------------------------------------------------------
1 | assertNotSpot($code);
14 |
15 | $table = TestHelper::fetchProperty($this->change, 'funcTable');
16 | if (is_null($table)) {
17 | return;
18 | }
19 | foreach ($table as $name => $dummy) {
20 | // Normal name
21 | $code = sprintf('%s();', $name);
22 | $this->assertHasSpot($code);
23 |
24 | // Case Insensitive name
25 | $code = sprintf('%s();', strtoupper($name));
26 | $this->assertHasSpot($code);
27 |
28 | // Namespaced
29 | $code = sprintf('use Dummy as %s; %s();', $name, $name);
30 | $this->assertHasSpot($code);
31 |
32 | $code = sprintf("dummy\%s();", $name, $name);
33 | $this->assertNotSpot($code);
34 | }
35 | }
36 |
37 | public function testConst()
38 | {
39 | // Not-new
40 | $code = 'NOT_REMOVED;';
41 | $this->assertNotSpot($code);
42 |
43 | $table = TestHelper::fetchProperty($this->change, 'constTable');
44 | if (is_null($table)) {
45 | return;
46 | }
47 | foreach ($table as $name => $dummy) {
48 | // Normal name
49 | $code = $name.';';
50 | $this->assertHasSpot($code);
51 |
52 | // Case Insensitive name
53 | $code = strtolower($name).';';
54 | $this->assertNotSpot($code);
55 | }
56 | }
57 |
58 | public function testVar()
59 | {
60 | // Not-new
61 | $code = '$not_removed;';
62 | $this->assertNotSpot($code);
63 |
64 | $table = TestHelper::fetchProperty($this->change, 'varTable');
65 | if (is_null($table)) {
66 | return;
67 | }
68 | foreach ($table as $name => $dummy) {
69 | $code = '$'.$name.';';
70 | $this->assertHasSpot($code);
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot3/DeprecatedTest.php:
--------------------------------------------------------------------------------
1 | assertNotSpot('not_new();');
14 |
15 | $table = TestHelper::fetchProperty($this->change, 'funcTable');
16 | foreach ($table as $name => $dummy) {
17 | // Normal name
18 | $this->assertHasSpot(sprintf('%s();', $name));
19 |
20 | // Case Insensitive name
21 | $this->assertHasSpot(sprintf('%s();', strtoupper($name)));
22 | }
23 | }
24 |
25 | public function testAssignNewByRef()
26 | {
27 | // Direct assign
28 | $this->assertNotSpot('$o = new Class_();');
29 |
30 | // By-reference
31 | $this->assertHasSpot('$o = &new Class_();');
32 | }
33 |
34 | public function testCallTimePassByRef()
35 | {
36 | $this->assertNotSpot('func($a, $b, "asdf");');
37 |
38 | // Call-time pass-by-reference
39 | $this->assertHasSpot('func($a, &$b, "asdf");');
40 |
41 | // Set skip
42 | $this->change->skipCallTimePassByRef(true);
43 | $this->assertNotSpot('func($a, &$b, "asdf");');
44 |
45 | // Cancle skip
46 | $this->change->skipCallTimePassByRef(false);
47 | $this->assertHasSpot('func($a, &$b, "asdf");');
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot3/IncompByReferenceTest.php:
--------------------------------------------------------------------------------
1 | assertNotSpot('function sample() {} sample();');
12 |
13 | $this->assertNotSpot('function sample() {} sample(1);');
14 |
15 | $this->assertNotSpot('function sample($a, $b) {} sample(1, 2);');
16 |
17 | $this->assertNotSpot('function sample($a, &$b) {} sample(1, $a);');
18 |
19 | $this->assertHasSpot('function sample($a, &$b) {} sample(1, 2);');
20 |
21 | $this->assertHasSpot('function sample($a, &$b) {} sample(1, "h");');
22 |
23 | $this->assertHasSpot('function sample($a, &$b) {} sample(1, array(1));');
24 |
25 | $this->assertHasSpot('function sample($a, &$b) {} sample(1, true);');
26 |
27 | // Case Insensitive
28 | $this->assertHasSpot('function SAMple($a, &$b) {} samPLE(1, "h");');
29 |
30 | // Built-in
31 | $this->assertNotSpot('array_shift($a);');
32 | $this->assertNotSpot('ksort($a);');
33 |
34 | $this->assertHasSpot('array_shift(1);');
35 | $this->assertHasSpot('ksort(1);');
36 | }
37 |
38 | public function testMehtod()
39 | {
40 | $code = 'class Sample {static function sample($a) {}} Sample::sample();';
41 | $this->assertNotSpot($code);
42 |
43 | $code = 'class Sample {static function sample($a, $b) {}} Sample::sample(1, 2);';
44 | $this->assertNotSpot($code);
45 |
46 | $code = 'class Sample {static function sample($a, &$b) {}} Sample::sample(1, 2);';
47 | $this->assertHasSpot($code);
48 |
49 | $code = 'class Sample {static function sample($a, &$b) {}} sAMPLE::saMPLe(1, 2);';
50 | $this->assertHasSpot($code);
51 |
52 | // #Issue 13: Call to undefined method PhpParser\Node\Expr\ArrayDimFetch::toString()
53 | $code = '$cb[0]::sample(1);';
54 | $this->assertNotSpot($code);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot3/IncompCallFromGlobalTest.php:
--------------------------------------------------------------------------------
1 | assertHasSpot('func_get_arg();');
12 |
13 | $this->assertNotSpot('function func() { func_get_arg(); }');
14 |
15 | $code = 'class Same { function func() { func_get_arg(); } }';
16 | $this->assertNotSpot($code);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot3/IncompMagicInvokedTest.php:
--------------------------------------------------------------------------------
1 | assertHasSpot($code);
18 |
19 | $code = <<<'EOC'
20 | class Sample {
21 | public function oh() {}
22 | public function __call() {}
23 | }
24 | EOC;
25 | $this->assertNotSpot($code);
26 |
27 | $code = <<<'EOC'
28 | class Sample {
29 | protected function oh() {}
30 | }
31 | EOC;
32 | $this->assertNotSpot($code);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot3/IncompMagicTest.php:
--------------------------------------------------------------------------------
1 | assertNotSpot($code);
13 |
14 | $code = 'class Sample{ function __toString($a){} }';
15 | $this->assertHasSpot($code);
16 | }
17 |
18 | public function testNonPub()
19 | {
20 | $code = 'class Sample{ function __get(){} }';
21 | $this->assertNotSpot($code);
22 |
23 | $code = 'class Sample{ public function __get(){} }';
24 | $this->assertNotSpot($code);
25 |
26 | $code = 'class Sample{ protected function __get($a){} }';
27 | $this->assertHasSpot($code);
28 |
29 | $code = 'class Sample{ private function __get($a){} }';
30 | $this->assertHasSpot($code);
31 |
32 | $code = 'class Sample{ public static function __get($a){} }';
33 | $this->assertHasSpot($code);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot3/IncompMiscTest.php:
--------------------------------------------------------------------------------
1 | assertNotSpot('never_emit_spot();');
13 |
14 | $this->assertHasSpot('clearstatcache();');
15 |
16 | $this->assertHasSpot('realpath();');
17 |
18 | $this->assertHasSpot('gd_info();');
19 |
20 | $table = TestHelper::fetchProperty($this->change, 'arrFuncTable');
21 | foreach ($table as $name => $dummy) {
22 | $this->assertHasSpot($name.'();');
23 | }
24 | }
25 |
26 | public function testCallFunc()
27 | {
28 | $this->assertNotSpot('call_user_func_array();');
29 |
30 | $this->assertNotSpot('call_user_func_array($a, array());');
31 |
32 | $this->assertHasSpot('call_user_func_array($a, $b);');
33 |
34 | $this->assertHasSpot('call_user_func_array($a, null);');
35 |
36 | $this->assertHasSpot('call_user_func_array($a, "str");');
37 |
38 | $this->assertHasSpot('call_user_func_array($a, 123);');
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot3/IntroducedTest.php:
--------------------------------------------------------------------------------
1 | assertHasSpot('mcrypt_generic_end();');
12 | $this->assertHasSpot('mysql_list_dbs();');
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot4/IncompBreakContinueTest.php:
--------------------------------------------------------------------------------
1 | assertNotSpot('break;');
13 | $this->assertNotSpot('break 1;');
14 | $this->assertNotSpot('break 100;');
15 |
16 | $this->assertHasSpot('break $a;');
17 | $this->assertHasSpot('break 0;');
18 | $this->assertHasSpot('break 1 + 1;');
19 |
20 | // Continue
21 | $this->assertNotSpot('continue;');
22 | $this->assertNotSpot('continue 1;');
23 | $this->assertNotSpot('continue 100;');
24 |
25 | $this->assertHasSpot('continue $a;');
26 | $this->assertHasSpot('continue 0;');
27 | $this->assertHasSpot('continue 1 + 1;');
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot4/IncompByReferenceTest.php:
--------------------------------------------------------------------------------
1 | assertNotSpot('func();');
12 | $this->assertNotSpot('func(1);');
13 | $this->assertNotSpot('func($a);');
14 |
15 | $this->assertHasSpot('func(&$a);');
16 | $this->assertHasSpot('$obj->func(&$a);');
17 | $this->assertHasSpot('Sample::func(&$a);');
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot4/IncompHashAlgoTest.php:
--------------------------------------------------------------------------------
1 | change, 'funcTable');
13 | foreach ($table as $name => $dummy) {
14 | $this->assertHasSpot($name.'("salsa10");');
15 | $this->assertHasSpot($name.'("salsa20");');
16 | $this->assertNotSpot($name.'("md5");');
17 |
18 | // Uncertain
19 | $this->assertHasSpot($name.'($a);');
20 |
21 | // Emtpy
22 | $this->assertNotSpot($name.'();');
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot4/IncompMiscTest.php:
--------------------------------------------------------------------------------
1 | assertNotSpot('never_emit_spot();');
12 |
13 | // array_combine
14 | $this->assertHasSpot('array_combine();');
15 |
16 | // ob_start
17 | $this->assertNotSpot('ob_start();');
18 | $this->assertNotSpot('ob_start(1, 2);');
19 | $this->assertHasSpot('ob_start(1, 2, 3);');
20 |
21 | // htmlentities, htmlspecialchars
22 | $this->assertHasSpot('htmlentities();');
23 | $this->assertHasSpot('htmlspecialchars();');
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot4/IncompParamNameTest.php:
--------------------------------------------------------------------------------
1 | change, 'autoGlobals');
14 | foreach ($table as $name => $dummy) {
15 | $this->assertHasSpot(sprintf('function f($%s) {}', $name));
16 | $this->assertHasSpot(sprintf('class Cl { function f($%s) {} }', $name));
17 |
18 | $this->assertHasSpot(sprintf('function f($a, $b, $c, $%s) {}', $name));
19 | $this->assertHasSpot(sprintf('class Cl { function f($a, $b, $c, $%s) {} }', $name));
20 | }
21 |
22 | // Method
23 | $this->assertHasSpot('class Cl { public function me($this) {} }');
24 | $this->assertNotSpot('class Cl { public static function me($this) {} }');
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot4/IncompRegisterTest.php:
--------------------------------------------------------------------------------
1 | assertHasSpot('$HTTP_POST_VARS;');
12 | $this->assertHasSpot('$HTTP_GET_VARS;');
13 | $this->assertHasSpot('$HTTP_ENV_VARS;');
14 | $this->assertHasSpot('$HTTP_SERVER_VARS;');
15 | $this->assertHasSpot('$HTTP_COOKIE_VARS;');
16 | $this->assertHasSpot('$HTTP_SESSION_VARS;');
17 | $this->assertHasSpot('$HTTP_POST_FILES;');
18 |
19 | // Case error
20 | $this->assertNotSpot('$HttP_POST_VARS;');
21 | $this->assertNotSpot('$HttP_GET_VARS;');
22 | $this->assertNotSpot('$HttP_ENV_VARS;');
23 | $this->assertNotSpot('$HttP_SERVER_VARS;');
24 | $this->assertNotSpot('$HttP_COOKIE_VARS;');
25 | $this->assertNotSpot('$HttP_SESSION_VARS;');
26 | $this->assertNotSpot('$HttP_POST_FILES;');
27 |
28 | $this->assertNotSpot('$HTTP_SHIT_VARS;');
29 |
30 | $this->assertNotSpot('$$name;');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot4/IntroducedTest.php:
--------------------------------------------------------------------------------
1 | change, 'funcTable');
13 | foreach ($table as $name => $dummy) {
14 | $this->assertHasSpot($name.'();');
15 | }
16 | }
17 |
18 | public function testMysqlFunc()
19 | {
20 | $table = TestHelper::fetchProperty($this->change, 'mysqlTable');
21 | foreach ($table as $name => $dummy) {
22 | $this->assertHasSpot($name.'();');
23 | }
24 | }
25 |
26 | public function testPregReplace()
27 | {
28 | $this->assertNotSpot('preg_replace();');
29 |
30 | $this->assertNotSpot('preg_replace("//i");');
31 | $this->assertNotSpot('preg_replace(""."//i");');
32 | $this->assertNotSpot('preg_replace("/{$part}$pattern/i");');
33 |
34 | $this->assertHasSpot('preg_replace("//e");');
35 | $this->assertHasSpot('preg_replace(""."//e");');
36 | $this->assertHasSpot('preg_replace("/{$part}$pattern/e");');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot5/IncompCaseInsensitiveTest.php:
--------------------------------------------------------------------------------
1 | assertNotSpot('self::call();');
13 | $this->assertNotSpot('parent::call();');
14 | $this->assertNotSpot('static::call();');
15 |
16 | $this->assertHasSpot('sElf::call();');
17 | $this->assertHasSpot('pArent::call();');
18 | $this->assertHasSpot('sTatic::call();');
19 |
20 | // Property
21 | $this->assertNotSpot('self::$fetch;');
22 | $this->assertNotSpot('parent::$fetch;');
23 | $this->assertNotSpot('static::$fetch;');
24 |
25 | $this->assertHasSpot('sElf::$fetch;');
26 | $this->assertHasSpot('pArent::$fetch;');
27 | $this->assertHasSpot('sTatic::$fetch;');
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot5/IncompPackTest.php:
--------------------------------------------------------------------------------
1 | assertNotSpot('unpack();');
12 | $this->assertNotSpot('unpack("x");');
13 |
14 | $this->assertHasSpot('unpack("a");');
15 | $this->assertHasSpot('unpack("A");');
16 | $this->assertHasSpot('unpack($a);');
17 | $this->assertHasSpot('unpack($a."");');
18 | $this->assertHasSpot('unpack("$b");');
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot5/IntroducedTest.php:
--------------------------------------------------------------------------------
1 | assertHasSpot('$HTTP_RAW_POST_DATA;');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot6/IncompMiscTest.php:
--------------------------------------------------------------------------------
1 | assertHasSpot('json_decode();');
13 | }
14 |
15 | public function testGmp()
16 | {
17 | $table = TestHelper::fetchProperty($this->change, 'gmpTable');
18 | foreach ($table as $name => $dummy) {
19 | $this->assertHasSpot($name.'();');
20 | }
21 | }
22 |
23 | public function testMcrypt()
24 | {
25 | $table = TestHelper::fetchProperty($this->change, 'mcryptTable');
26 | foreach ($table as $name => $dummy) {
27 | $this->assertHasSpot($name.'();');
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot6/IncompPropertyArrayTest.php:
--------------------------------------------------------------------------------
1 | assertNotSpot('class Sample { }');
13 |
14 | // Without default value, non-array type
15 | $this->assertNotSpot('class Sample { public $pro; protected $int = 5; private $str = "he";}');
16 |
17 | // Empty array
18 | $this->assertNotSpot('class Sample { public $arr = array(); }');
19 |
20 | // Class-const-key with null
21 | $code = <<<'EOC'
22 | class Sample
23 | {
24 | const CK = 'one';
25 | public $data = array(
26 | self::CK => 1,
27 | 2,
28 | );
29 | }
30 | EOC;
31 | $this->assertHasSpot($code);
32 |
33 | // Class-const-key unfetched
34 | $code = <<<'EOC'
35 | class Sample
36 | {
37 | public $data = array(
38 | self::CK => 1,
39 | 'two' => 2,
40 | );
41 | }
42 | EOC;
43 | $this->assertHasSpot($code);
44 |
45 | // Class-const-key fetched, but duplicated
46 | $code = <<<'EOC'
47 | class Sample
48 | {
49 | const CK = 'one';
50 | public $data = array(
51 | self::CK => 1,
52 | 'one' => 2,
53 | );
54 | }
55 | EOC;
56 | $this->assertHasSpot($code);
57 |
58 | // Global-const-key is always unfetched
59 | $code = <<<'EOC'
60 | class Sample
61 | {
62 | public $data = array(
63 | CK => 1,
64 | );
65 | }
66 | EOC;
67 | $this->assertHasSpot($code);
68 |
69 | // Class-const-key duplicated
70 | $code = <<<'EOC'
71 | class Sample
72 | {
73 | const CK = 'one';
74 | public $data = array(
75 | self::CK => 1,
76 | self::CK => 1,
77 | );
78 | }
79 | EOC;
80 | $this->assertHasSpot($code);
81 |
82 | // Exception, all const feteched, and no duplicated
83 | $code = <<<'EOC'
84 | class Sample
85 | {
86 | const CK1 = 'one';
87 | const CK2 = 'two';
88 | public $data = array(
89 | self::CK1 => 1,
90 | self::CK2 => 1,
91 | 'third' => 0,
92 | );
93 | }
94 | EOC;
95 | $this->assertNotSpot($code);
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/tests/Changes/v5dot6/IntroducedTest.php:
--------------------------------------------------------------------------------
1 | assertHasSpot('class OldClass { function OldClass() {} }');
12 |
13 | $this->assertHasSpot('namespace Dummy; class OldClass { function OldClass() {} }');
14 |
15 | $this->assertNotSpot('class OldClass { function setName() {} }');
16 |
17 | $this->assertNotSpot('class OldClass { function _construct() {} }');
18 | }
19 |
20 | public function testPasswordHash()
21 | {
22 | $this->assertHasSpot('password_hash($a, $b, $c);');
23 |
24 | $this->assertHasSpot('password_hash($a, $b, []);');
25 |
26 | $this->assertNotSpot('password_hash($a, $b);');
27 |
28 | $this->assertNotSpot('Dummy\password_hash($a, $b, []);');
29 | }
30 |
31 | public function testLdapSort()
32 | {
33 | $this->assertHasSpot('ldap_sort();');
34 |
35 | $this->assertNotSpot('Dummy\ldap_sort();');
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tests/Changes/v7dot0/ExceptionHandleTest.php:
--------------------------------------------------------------------------------
1 | assertNotSpot('set_exception_handler();');
12 |
13 | $this->assertHasSpot('set_exception_handler($handler);');
14 |
15 | $this->assertHasSpot('set_exception_handler([$this, "handler"]);');
16 |
17 | $this->assertNotSpot('set_exception_handler(function () {});');
18 |
19 | $this->assertNotSpot('set_exception_handler(function ($e) {});');
20 |
21 | $this->assertHasSpot('set_exception_handler(function (Exception $e) {});');
22 |
23 | $this->assertHasSpot('set_exception_handler(function (\Exception $e) {});');
24 |
25 | $this->assertHasSpot('use Dummy\Exception; set_exception_handler(function (Exception $e) {});');
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/tests/Changes/v7dot0/ForeachLoopTest.php:
--------------------------------------------------------------------------------
1 | assertHasSpot('foreach ($arr as &$i) { current(); }');
12 |
13 | $this->assertHasSpot('foreach ($arr as &$i) { key(); }');
14 |
15 | $this->assertNotSpot('foreach ($arr as &$i) { end(); }');
16 |
17 | $this->assertHasSpot('foreach ($arr as $key => &$i) { key(); }');
18 |
19 | $this->assertNotSpot('foreach ($arr as $key => $i) { key(); }');
20 |
21 | $this->assertNotSpot('foreach ($arr as $key => $i) {}');
22 |
23 | $this->assertHasSpot('foreach ($a as $b) {foreach ($c as &$i) { key(); }}');
24 |
25 | $this->assertHasSpot('foreach ($a as &$b) {foreach ($c as $i) { key(); }}');
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/tests/Changes/v7dot0/FuncListTest.php:
--------------------------------------------------------------------------------
1 | assertHasSpot('list($a[], $a[], $a[]) = [1, 2, 3];');
12 |
13 | $this->assertHasSpot('list($a[], $b, $a[]) = [1, 2, 3];');
14 |
15 | $this->assertNotSpot('list($a, $b) = [1, 2];');
16 | }
17 |
18 | public function testEmpty()
19 | {
20 | $this->assertHasSpot('list() = $a;');
21 |
22 | $this->assertHasSpot('list(,,) = $a;');
23 |
24 | $this->assertHasSpot('list($x, list(), $y) = $a;');
25 |
26 | $this->assertNotSpot('list(, , , , $b) = [1, 2, 2, 4,];');
27 |
28 | $this->assertNotSpot('list($x, list($l), $y) = $a;');
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Changes/v7dot0/FuncParametersTest.php:
--------------------------------------------------------------------------------
1 | assertHasSpot('function f($a, $a) {}');
12 |
13 | $this->assertHasSpot('class C { function f($a, $a) {} }');
14 |
15 | $this->assertHasSpot('$a = function ($a, $a) {};');
16 |
17 | $this->assertHasSpot('function f($a, $b, $a) {}');
18 |
19 | $this->assertHasSpot('class C { function f($a, $b, $a) {} }');
20 |
21 | $this->assertHasSpot('$a = function ($a, $b, $a) {};');
22 |
23 | $this->assertNotSpot('function f() {}');
24 |
25 | $this->assertNotSpot('function f($a, $b) {}');
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/tests/Changes/v7dot0/IntegerOperationTest.php:
--------------------------------------------------------------------------------
1 | assertHasSpot('1 >> -1;');
12 |
13 | $this->assertNotSpot('1 >> 1;');
14 |
15 | $this->assertHasSpot('$a >> -1;');
16 |
17 | $this->assertNotSpot('$a >> 1;');
18 |
19 | $this->assertHasSpot('1 << -1;');
20 |
21 | $this->assertNotSpot('1 << 1;');
22 |
23 | $this->assertHasSpot('1 << $a;');
24 |
25 | $this->assertNotSpot('1 << 0;');
26 | }
27 |
28 | public function testModulu()
29 | {
30 | $this->assertHasSpot('$a % 0;');
31 |
32 | $this->assertNotSpot('$a % 1;');
33 |
34 | $this->assertHasSpot('1 % 0;');
35 |
36 | $this->assertNotSpot('1 % 1;');
37 |
38 | $this->assertHasSpot('$a % $b;');
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/tests/Changes/v7dot0/IntroducedTest.php:
--------------------------------------------------------------------------------
1 | change, 'forbiddenTable');
15 | foreach ($table as $name => $dummy) {
16 | $words[] = $name;
17 | }
18 |
19 | $table = TestHelper::fetchProperty($this->change, 'reservedTable');
20 | foreach ($table as $name => $dummy) {
21 | $words[] = $name;
22 | }
23 |
24 | $this->assertNotSpot('class not_keyword {}');
25 |
26 | $this->assertNotSpot('trait not_keyword {}');
27 |
28 | $this->assertNotSpot('interface not_keyword {}');
29 |
30 | $this->assertNotSpot('$o = new class {};');
31 |
32 | foreach ($words as $word) {
33 | $this->assertHasSpot('class '.$word.' {}');
34 |
35 | $this->assertHasSpot('trait '.$word.' {}');
36 |
37 | $this->assertHasSpot('interface '.$word.' {}');
38 |
39 | $this->assertHasSpot('namespace Dummy; class '.$word.' {}');
40 |
41 | $this->assertHasSpot('namespace Dummy; trait '.$word.' {}');
42 |
43 | $this->assertHasSpot('namespace Dummy; interface '.$word.' {}');
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/tests/Changes/v7dot0/ParseDifferenceTest.php:
--------------------------------------------------------------------------------
1 | assertHasSpot('$$foo[\'bar\'][\'baz\'];');
17 | $this->assertHasSpot('$foo->$bar[\'baz\'];');
18 | $this->assertHasSpot('$foo->$bar[\'baz\']();');
19 | $this->assertHasSpot('Foo::$bar[\'baz\']();');
20 |
21 | $this->assertNotSpot('$foo[\'bar\'];');
22 | }
23 |
24 | /**
25 | * yield is now a right associative operator.
26 | *
27 | * @see http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.other.yield
28 | */
29 | public function testYield()
30 | {
31 | $this->assertHasSpot('echo yield -1;');
32 |
33 | $this->assertHasSpot('yield $foo or die;');
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/Changes/v7dot0/ParserTest.php:
--------------------------------------------------------------------------------
1 | parser = (new ParserFactory())->create(ParserFactory::ONLY_PHP7);
15 | }
16 |
17 | /**
18 | * global only accepts simple variables.
19 | *
20 | * @see http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.variable-handling.global
21 | * @expectedException PhpParser\Error
22 | */
23 | public function testInvalidGlobal()
24 | {
25 | // BC for PHPUnit 4.8
26 | if (method_exists($this, 'expectException')) {
27 | $this->expectException(Error::class);
28 | }
29 |
30 | $this->parser->parse('bar; }');
31 | }
32 |
33 | public function testValidGlobal()
34 | {
35 | $this->parser->parse('bar}; }');
36 | }
37 |
38 | /**
39 | * Invalid octal literals.
40 | *
41 | * @see http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.integers.invalid-octals
42 | * @expectedException PhpParser\Error
43 | */
44 | public function testInvalidOctal()
45 | {
46 | // BC for PHPUnit 4.8
47 | if (method_exists($this, 'expectException')) {
48 | $this->expectException(Error::class);
49 | }
50 |
51 | $this->parser->parse('parser->parse('assertHasSpot('1 + "0xab";');
12 |
13 | $this->assertHasSpot('1 + "0x01F";');
14 |
15 | $this->assertHasSpot('1 + "0XFFF";');
16 |
17 | $this->assertNotSpot('1 + "0xEOF";');
18 |
19 | $this->assertNotSpot('1 + "24";');
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tests/Changes/v7dot0/SwitchMultipleDefaultsTest.php:
--------------------------------------------------------------------------------
1 | assertHasSpot('switch ($a) { default: default: }');
12 |
13 | $this->assertNotSpot('switch ($a) { case 1: default: }');
14 |
15 | $this->assertHasSpot('switch ($a) { default: case 2: default: }');
16 |
17 | $this->assertHasSpot('switch ($a) { default: break; default: break; }');
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/SymbolTableTest.php:
--------------------------------------------------------------------------------
1 | 'CamelCase',
9 | ];
10 |
11 | protected $csEmptyTable;
12 |
13 | protected $icEmptyTable;
14 |
15 | protected $csFilledTable;
16 |
17 | protected $icFilledTable;
18 |
19 | protected function setUp()
20 | {
21 | $this->csEmptyTable = new SymbolTable([], SymbolTable::CS);
22 | $this->icEmptyTable = new SymbolTable([], SymbolTable::IC);
23 | $this->csFilledTable = new SymbolTable($this->fillData, SymbolTable::CS);
24 | $this->icFilledTable = new SymbolTable($this->fillData, SymbolTable::IC);
25 | }
26 |
27 | public function testHas()
28 | {
29 | // Varied param type
30 | $this->assertFalse($this->csFilledTable->has(false));
31 | $this->assertFalse($this->csFilledTable->has(null));
32 | $this->assertFalse($this->csFilledTable->has(1234));
33 | $this->assertFalse($this->csFilledTable->has(12.34));
34 | $this->assertFalse($this->csFilledTable->has(new \DateTime()));
35 |
36 | // Case Sensitive
37 | $this->assertTrue($this->csFilledTable->has('CamelCase'));
38 | $this->assertFalse($this->csFilledTable->has('camelcase'));
39 |
40 | // Case Insensitive
41 | $this->assertTrue($this->icFilledTable->has('CamelCase'));
42 | $this->assertTrue($this->icFilledTable->has('camelcase'));
43 | }
44 |
45 | public function testGet()
46 | {
47 | // Case Sensitive
48 | $this->assertEquals('CamelCase', $this->csFilledTable->get('CamelCase'));
49 | $this->assertEquals(null, $this->csFilledTable->get('cAMELcASE'));
50 |
51 | // Case Insensitive
52 | $this->assertEquals('CamelCase', $this->icFilledTable->get('CamelCase'));
53 | $this->assertEquals('CamelCase', $this->icFilledTable->get('cAMELcASE'));
54 | }
55 |
56 | public function testSet()
57 | {
58 | // Case Sensitive
59 | $this->csEmptyTable->set('KEY', 'Upper key');
60 | $this->assertTrue($this->csEmptyTable->has('KEY'));
61 | $this->assertFalse($this->csEmptyTable->has('key'));
62 | $this->assertEquals('Upper key', $this->csEmptyTable->get('KEY'));
63 | $this->assertEquals(null, $this->csEmptyTable->get('key'));
64 |
65 | // Case Insensitive
66 | $this->icEmptyTable->set('KEY', 'Upper key');
67 | $this->assertTrue($this->icEmptyTable->has('KEY'));
68 | $this->assertTrue($this->icEmptyTable->has('key'));
69 | $this->assertEquals('Upper key', $this->icEmptyTable->get('KEY'));
70 | $this->assertEquals('Upper key', $this->icEmptyTable->get('key'));
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/tests/Utils/TestHelper.php:
--------------------------------------------------------------------------------
1 | getProperty($name);
17 | $property->setAccessible(true);
18 |
19 | return $property->getValue($object);
20 | }
21 |
22 | public static function runChange($change, $code)
23 | {
24 | static $traverser_pre, $parser;
25 |
26 | $code = 'addVisitor($visitor);
32 |
33 | $visitor->prepare();
34 | $visitor->setCode($code);
35 |
36 | if (!isset($parser)) {
37 | $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
38 | }
39 | $stmts = $parser->parse($code);
40 |
41 | if (!isset($traverser_pre)) {
42 | $traverser_pre = new NodeTraverser();
43 | $traverser_pre->addVisitor(new NameResolver());
44 | $traverser_pre->addVisitor(new ReduceVisitor());
45 | }
46 | $stmts = $traverser_pre->traverse($stmts);
47 |
48 | $traverser->traverse($stmts);
49 |
50 | $visitor->finish();
51 |
52 | return $visitor->getSpots();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 | addPsr4('PhpMigration\\', __DIR__);
5 |
6 | $oldClass = '\PHPUnit\Framework\TestCase';
7 | $newClass = '\PHPUnit_Framework_TestCase';
8 | if (!class_exists($newClass) && class_exists($oldClass)) {
9 | class_alias($oldClass, $newClass);
10 | }
11 |
--------------------------------------------------------------------------------