ParserTest.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <?php
  2. /**
  3. * Lithium: the most rad php framework
  4. *
  5. * @copyright Copyright 2013, Union of RAD (http://union-of-rad.org)
  6. * @license http://opensource.org/licenses/bsd-license.php The BSD License
  7. */
  8. namespace lithium\tests\cases\analysis;
  9. use lithium\core\Libraries;
  10. use lithium\analysis\Parser;
  11. class ParserTest extends \lithium\test\Unit {
  12. /**
  13. * Tests that PHP code snippets properly resolve to their corresponding tokens.
  14. *
  15. * @return void
  16. */
  17. public function testSingleTokenization() {
  18. $result = Parser::token('static');
  19. $this->assertEqual('T_STATIC', $result);
  20. $result = Parser::token('=>');
  21. $this->assertEqual('T_DOUBLE_ARROW', $result);
  22. $result = Parser::token(' =>');
  23. $this->assertEqual('T_WHITESPACE', $result);
  24. $result = Parser::token('static =>');
  25. $this->assertEqual('T_STATIC', $result);
  26. $result = Parser::token("\nstatic =>");
  27. $this->assertEqual('T_WHITESPACE', $result);
  28. $this->assertFalse(Parser::token(''));
  29. $result = Parser::token(';');
  30. $this->assertEqual(';', $result);
  31. $result = Parser::token('"string"');
  32. $this->assertEqual('T_CONSTANT_ENCAPSED_STRING', $result);
  33. $result = Parser::token('1');
  34. $this->assertEqual('T_LNUMBER', $result);
  35. $result = Parser::token('0');
  36. $this->assertEqual('T_LNUMBER', $result);
  37. $result = Parser::token('0');
  38. $this->assertEqual('T_LNUMBER', $result);
  39. }
  40. public function testFullTokenization() {
  41. $result = Parser::tokenize('$foo = function() {};');
  42. $this->assertEqual(11, count($result));
  43. $expected = array(
  44. 'id' => T_VARIABLE,
  45. 'name' => 'T_VARIABLE',
  46. 'content' => '$foo',
  47. 'line' => 1
  48. );
  49. $this->assertEqual($expected, $result[0]);
  50. $expected = array('id' => null, 'name' => ';', 'content' => ';', 'line' => 1);
  51. $this->assertEqual($expected, $result[10]);
  52. $code = '$defaults = array("id" => "foo", "name" => "bar", \'count\' => 5);';
  53. $result = Parser::tokenize($code);
  54. $this->assertEqual(27, count($result));
  55. $this->assertEqual('T_VARIABLE', $result[0]['name']);
  56. $this->assertEqual('$defaults', $result[0]['content']);
  57. }
  58. public function testTokenPatternMatching() {
  59. $code = '$defaults = array("id" => "foo", "name" => "bar", \'count\' => 5);';
  60. $result = Parser::match($code, array('"string"'), array('return' => 'content'));
  61. $expected = array('"id"', '"foo"', '"name"', '"bar"', '\'count\'');
  62. $this->assertEqual($expected, $result);
  63. $result = Parser::match(
  64. $code,
  65. array('"string"' => array('before' => '=>'), '1' => array('before' => '=>')),
  66. array('return' => 'content')
  67. );
  68. $expected = array('"foo"', '"bar"', '5');
  69. $this->assertEqual($expected, $result);
  70. $result = Parser::match($code, array('"string"' => array('after' => '=>')), array(
  71. 'return' => 'content'
  72. ));
  73. $expected = array ('"id"', '"name"', '\'count\'');
  74. $this->assertEqual($expected, $result);
  75. }
  76. public function testFilteredTokenization() {
  77. $code = 'while (isset($countRugen)) { if ($inigoMontoya->is("alive")) { ' . "\n";
  78. $code .= '$inigoMontoya->say(array("hello", "name", "accusation", "die")); ' . "\n";
  79. $code .= 'try { $inigoMontoya->kill($countRugen); } catch (Exception $e) { continue; } } }';
  80. $result = Parser::tokenize($code, array('include' => array('T_IF', 'T_WHILE', 'T_CATCH')));
  81. $expected = array(
  82. array('id' => T_WHILE, 'name' => 'T_WHILE', 'content' => 'while', 'line' => 1),
  83. array('id' => T_IF, 'name' => 'T_IF', 'content' => 'if', 'line' => 1),
  84. array('id' => T_CATCH, 'name' => 'T_CATCH', 'content' => 'catch', 'line' => 3)
  85. );
  86. $this->assertEqual($expected, $result);
  87. }
  88. public function testFindingTokenPatterns() {
  89. $code = file_get_contents(Libraries::path('lithium\analysis\Parser'));
  90. $expected = array('tokenize', 'matchToken', '_prepareMatchParams', 'token');
  91. $results = array_values(array_unique(array_map(function($i) { return $i[0]; }, Parser::find(
  92. $code, 'static::_(*)', array('capture' => array('T_STRING'), 'return' => 'content')
  93. ))));
  94. $this->assertEqual($expected, $results);
  95. $expected = array('lithium\util\Set', 'lithium\util\Collection');
  96. $results = array_map(
  97. function ($i) { return join('', $i); },
  98. $results = Parser::find($code, 'use *;', array(
  99. 'return' => 'content',
  100. 'lineBreaks' => true,
  101. 'startOfLine' => true,
  102. 'capture' => array('T_STRING', 'T_NS_SEPARATOR')
  103. ))
  104. );
  105. $this->assertEqual($expected, $results);
  106. $code = 'function test($options) { return function($foo) use ($options) {';
  107. $code .= ' ClassName::method($options); ' . "\n" . ' $foo->method($options); }; }';
  108. list($results) = Parser::find($code, '_::_(', array(
  109. 'capture' => array('T_STRING'), 'return' => 'content'
  110. ));
  111. $expected = array('ClassName', 'method');
  112. $this->assertEqual($expected, $results);
  113. }
  114. public function testParserGuessesLineBleed() {
  115. $code = <<<EOD
  116. if (false) {
  117. return true;
  118. }
  119. EOD;
  120. $tokens = Parser::tokenize($code);
  121. $this->assertIdentical('}', $tokens[13]['content']);
  122. $this->assertIdentical(3, $tokens[13]['line']);
  123. }
  124. public function testParserGuessesLineBleedWithNonWhitespace() {
  125. $code = <<<EOD
  126. if (false) {
  127. // hello world
  128. }
  129. EOD;
  130. $tokens = Parser::tokenize($code);
  131. $this->assertIdentical('}', $tokens[9]['content']);
  132. $this->assertIdentical(3, $tokens[9]['line']);
  133. }
  134. }
  135. ?>