IssetPassTest.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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\IssetPass;
  12. /**
  13. * Code cleaner to check for invalid isset() arguments.
  14. *
  15. * @group isolation-fail
  16. */
  17. class IssetPassTest extends CodeCleanerTestCase
  18. {
  19. /**
  20. * @before
  21. */
  22. public function getReady()
  23. {
  24. $this->setPass(new IssetPass());
  25. }
  26. /**
  27. * @dataProvider invalidStatements
  28. */
  29. public function testProcessStatementFails($code)
  30. {
  31. $this->expectException(\Psy\Exception\FatalErrorException::class);
  32. $this->expectExceptionMessage('Cannot use isset() on the result of an expression (you can use "null !== expression" instead)');
  33. $this->parseAndTraverse($code);
  34. $this->fail();
  35. }
  36. public function invalidStatements()
  37. {
  38. return [
  39. ['isset(1)'],
  40. ['isset(3.14)'],
  41. ['isset("a")'],
  42. ['isset([])'],
  43. ];
  44. }
  45. /**
  46. * @dataProvider validStatements
  47. */
  48. public function testValidStatements($code)
  49. {
  50. $this->parseAndTraverse($code);
  51. $this->assertTrue(true);
  52. }
  53. public function validStatements()
  54. {
  55. return [
  56. // Multiple scalar variables in a group
  57. ['isset($a, $b, $c)'],
  58. // Arrays and string offsets
  59. ['isset($var)'],
  60. ['isset($var[1])'],
  61. ['isset($var, $var[1])'],
  62. ['isset($var[1][2])'],
  63. ['isset($var["a"])'],
  64. ['isset($var[false])'],
  65. ['isset($var[0.6])'],
  66. ['isset($var[true])'],
  67. ['isset($var[null])'],
  68. ['isset($var[STDIN])'],
  69. ['isset($var[$key = "b"])'],
  70. ['isset($var[M_PI])'],
  71. ['isset($var[[]])'],
  72. ['isset($var[new stdClass()])'],
  73. // Objects
  74. ['isset($a->b)'],
  75. // $this
  76. ['isset($this)'],
  77. ['isset($this->foo)'],
  78. ['isset($this[0])'],
  79. // Variable variables, and other errata
  80. ['isset($$wat)'],
  81. ['isset($$$wat)'],
  82. ['isset(${"wat"})'],
  83. ];
  84. }
  85. /**
  86. * @dataProvider validFancyStatements
  87. */
  88. public function testValidFancyStatements($code)
  89. {
  90. $this->parseAndTraverse($code);
  91. $this->assertTrue(true);
  92. }
  93. public function validFancyStatements()
  94. {
  95. return [
  96. // isset() can be used on dereferences of temporary expressions
  97. // TODO: as of which version?
  98. ['isset([0, 1][0])'],
  99. ['isset(([0, 1] + [])[0])'],
  100. ['isset([[0, 1]][0][0])'],
  101. ['isset(([[0, 1]] + [])[0][0])'],
  102. ['isset(((object) ["a" => "b"])->a)'],
  103. ['isset(["a" => "b"]->a)'],
  104. ['isset("str"->a)'],
  105. ['isset((["a" => "b"] + [])->a)'],
  106. ['isset((["a" => "b"] + [])->a->b)'],
  107. // Nullsafe operator
  108. ['isset($foo?->bar)'],
  109. ['isset($foo?->bar->baz)'],
  110. ];
  111. }
  112. }