LoopContextPassTest.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <?php
  2. /*
  3. * This file is part of Psy Shell.
  4. *
  5. * (c) 2012-2023 Justin Hileman
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Psy\Test\CodeCleaner;
  11. use Psy\CodeCleaner\LoopContextPass;
  12. /**
  13. * @group isolation-fail
  14. */
  15. class LoopContextPassTest extends CodeCleanerTestCase
  16. {
  17. /**
  18. * @before
  19. */
  20. public function getReady()
  21. {
  22. $this->setPass(new LoopContextPass());
  23. }
  24. /**
  25. * @dataProvider invalidStatements
  26. */
  27. public function testProcessStatementFails($code)
  28. {
  29. $this->expectException(\Psy\Exception\FatalErrorException::class);
  30. $this->parseAndTraverse($code);
  31. $this->fail();
  32. }
  33. public function invalidStatements()
  34. {
  35. return [
  36. ['continue'],
  37. ['break'],
  38. ['if (true) { continue; }'],
  39. ['if (true) { break; }'],
  40. ['if (false) { continue; }'],
  41. ['if (false) { break; }'],
  42. ['function foo() { break; }'],
  43. ['function foo() { continue; }'],
  44. // actually enforce break/continue depth argument
  45. ['do { break 2; } while (true)'],
  46. ['do { continue 2; } while (true)'],
  47. ['for ($a; $b; $c) { break 2; }'],
  48. ['for ($a; $b; $c) { continue 2; }'],
  49. ['foreach ($a as $b) { break 2; }'],
  50. ['foreach ($a as $b) { continue 2; }'],
  51. ['switch (true) { default: break 2; }'],
  52. ['switch (true) { default: continue 2; }'],
  53. ['while (true) { break 2; }'],
  54. ['while (true) { continue 2; }'],
  55. // In PHP 5.4+, only positive literal integers are allowed
  56. ['while (true) { break $n; }'],
  57. ['while (true) { continue $n; }'],
  58. ['while (true) { break N; }'],
  59. ['while (true) { continue N; }'],
  60. ['while (true) { break 0; }'],
  61. ['while (true) { continue 0; }'],
  62. ['while (true) { break -1; }'],
  63. ['while (true) { continue -1; }'],
  64. ['while (true) { break 1.0; }'],
  65. ['while (true) { continue 1.0; }'],
  66. ['while (true) { break 2.0; }'],
  67. ['while (true) { continue 2.0; }'],
  68. // and once with nested loops, just for good measure
  69. ['while (true) { while (true) { break 3; } }'],
  70. ['while (true) { while (true) { continue 3; } }'],
  71. ];
  72. }
  73. /**
  74. * @dataProvider validStatements
  75. */
  76. public function testProcessStatementPasses($code)
  77. {
  78. $this->parseAndTraverse($code);
  79. $this->assertTrue(true);
  80. }
  81. public function validStatements()
  82. {
  83. return [
  84. ['do { break; } while (true)'],
  85. ['do { continue; } while (true)'],
  86. ['for ($a; $b; $c) { break; }'],
  87. ['for ($a; $b; $c) { continue; }'],
  88. ['foreach ($a as $b) { break; }'],
  89. ['foreach ($a as $b) { continue; }'],
  90. ['switch (true) { default: break; }'],
  91. ['switch (true) { default: continue; }'],
  92. ['while (true) { break; }'],
  93. ['while (true) { continue; }'],
  94. // `break 1` is redundant, but not invalid
  95. ['while (true) { break 1; }'],
  96. ['while (true) { continue 1; }'],
  97. // and once with nested loops just for good measure
  98. ['while (true) { while (true) { break 2; } }'],
  99. ['while (true) { while (true) { continue 2; } }'],
  100. ];
  101. }
  102. }