ContextTest.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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;
  11. use Psy\Context;
  12. use Psy\Shell;
  13. class ContextTest extends TestCase
  14. {
  15. public function testGet()
  16. {
  17. $this->assertTrue(true);
  18. }
  19. public function testGetAll()
  20. {
  21. $this->assertTrue(true);
  22. }
  23. public function testGetSpecialVariables()
  24. {
  25. $context = new Context();
  26. $this->assertNull($context->get('_'));
  27. $this->assertNull($context->getReturnValue());
  28. $this->assertSame(['_' => null], $context->getAll());
  29. $e = new \Exception('eeeeeee');
  30. $obj = new \stdClass();
  31. $context->setLastException($e);
  32. $context->setLastStdout('out');
  33. $context->setBoundObject($obj);
  34. $context->setCommandScopeVariables([
  35. '__function' => 'function',
  36. '__method' => 'method',
  37. '__class' => 'class',
  38. '__namespace' => 'namespace',
  39. '__file' => 'file',
  40. '__line' => 'line',
  41. '__dir' => 'dir',
  42. ]);
  43. $expected = [
  44. '_' => null,
  45. '_e' => $e,
  46. '__out' => 'out',
  47. 'this' => $obj,
  48. '__function' => 'function',
  49. '__method' => 'method',
  50. '__class' => 'class',
  51. '__namespace' => 'namespace',
  52. '__file' => 'file',
  53. '__line' => 'line',
  54. '__dir' => 'dir',
  55. ];
  56. $this->assertSame($expected, $context->getAll());
  57. }
  58. public function testSetAll()
  59. {
  60. $context = new Context();
  61. $baz = new \stdClass();
  62. $vars = [
  63. 'foo' => 'Foo',
  64. 'bar' => 123,
  65. 'baz' => $baz,
  66. '_' => 'fail',
  67. '_e' => 'fail',
  68. '__out' => 'fail',
  69. 'this' => 'fail',
  70. '__psysh__' => 'fail',
  71. '__function' => 'fail',
  72. '__method' => 'fail',
  73. '__class' => 'fail',
  74. '__namespace' => 'fail',
  75. '__file' => 'fail',
  76. '__line' => 'fail',
  77. '__dir' => 'fail',
  78. ];
  79. $context->setAll($vars);
  80. $this->assertSame('Foo', $context->get('foo'));
  81. $this->assertSame(123, $context->get('bar'));
  82. $this->assertSame($baz, $context->get('baz'));
  83. $this->assertSame(['foo' => 'Foo', 'bar' => 123, 'baz' => $baz, '_' => null], $context->getAll());
  84. }
  85. /**
  86. * @dataProvider specialNames
  87. */
  88. public function testSetAllDoesNotSetSpecial($name)
  89. {
  90. $this->expectException(\InvalidArgumentException::class);
  91. $this->expectExceptionMessageMatches('/Unknown variable: \$\w+/');
  92. $context = new Context();
  93. $context->setAll([$name => 'fail']);
  94. $context->get($name);
  95. $this->fail();
  96. }
  97. public function specialNames()
  98. {
  99. return [
  100. ['_e'],
  101. ['__out'],
  102. ['this'],
  103. ['__psysh__'],
  104. ['__function'],
  105. ['__method'],
  106. ['__class'],
  107. ['__namespace'],
  108. ['__file'],
  109. ['__line'],
  110. ['__dir'],
  111. ];
  112. }
  113. public function testReturnValue()
  114. {
  115. $context = new Context();
  116. $this->assertNull($context->getReturnValue());
  117. $val = 'some string';
  118. $context->setReturnValue($val);
  119. $this->assertSame($val, $context->getReturnValue());
  120. $this->assertSame($val, $context->get('_'));
  121. $obj = new \stdClass();
  122. $context->setReturnValue($obj);
  123. $this->assertSame($obj, $context->getReturnValue());
  124. $this->assertSame($obj, $context->get('_'));
  125. $context->setReturnValue(null);
  126. $this->assertNull($context->getReturnValue());
  127. }
  128. public function testLastException()
  129. {
  130. $context = new Context();
  131. $e = new \Exception('wat');
  132. $context->setLastException($e);
  133. $this->assertSame($e, $context->getLastException());
  134. $this->assertSame($e, $context->get('_e'));
  135. }
  136. public function testLastExceptionThrowsSometimes()
  137. {
  138. $this->expectException(\InvalidArgumentException::class);
  139. $this->expectExceptionMessage('No most-recent exception');
  140. $context = new Context();
  141. $context->getLastException();
  142. $this->fail();
  143. }
  144. public function testLastStdout()
  145. {
  146. $context = new Context();
  147. $context->setLastStdout('ouuuuut');
  148. $this->assertSame('ouuuuut', $context->getLastStdout());
  149. $this->assertSame('ouuuuut', $context->get('__out'));
  150. }
  151. public function testLastStdoutThrowsSometimes()
  152. {
  153. $this->expectException(\InvalidArgumentException::class);
  154. $this->expectExceptionMessage('No most-recent output');
  155. $context = new Context();
  156. $context->getLastStdout();
  157. $this->fail();
  158. }
  159. public function testBoundObject()
  160. {
  161. $context = new Context();
  162. $this->assertNull($context->getBoundObject());
  163. $obj = new \stdClass();
  164. $context->setBoundObject($obj);
  165. $this->assertSame($obj, $context->getBoundObject());
  166. $this->assertSame($obj, $context->get('this'));
  167. $context->setBoundObject(null);
  168. $this->assertNull($context->getBoundObject());
  169. }
  170. public function testBoundObjectThrowsSometimes()
  171. {
  172. $this->expectException(\InvalidArgumentException::class);
  173. $this->expectExceptionMessage('Unknown variable: $this');
  174. $context = new Context();
  175. $context->get('this');
  176. $this->fail();
  177. }
  178. public function testBoundClass()
  179. {
  180. $context = new Context();
  181. $this->assertNull($context->getBoundClass());
  182. $context->setBoundClass('');
  183. $this->assertNull($context->getBoundClass());
  184. $context->setBoundClass(Shell::class);
  185. $this->assertSame(Shell::class, $context->getBoundClass());
  186. $context->setBoundObject(new \stdClass());
  187. $this->assertNotNull($context->getBoundObject());
  188. $this->assertNull($context->getBoundClass());
  189. $context->setBoundClass(Shell::class);
  190. $this->assertSame(Shell::class, $context->getBoundClass());
  191. $this->assertNull($context->getBoundObject());
  192. $context->setBoundClass(null);
  193. $this->assertNull($context->getBoundClass());
  194. $this->assertNull($context->getBoundObject());
  195. }
  196. public function testCommandScopeVariables()
  197. {
  198. $__function = 'donkey';
  199. $__method = 'diddy';
  200. $__class = 'cranky';
  201. $__namespace = 'funky';
  202. $__file = 'candy';
  203. $__line = 'dixie';
  204. $__dir = 'wrinkly';
  205. $vars = \compact('__function', '__method', '__class', '__namespace', '__file', '__line', '__dir');
  206. $context = new Context();
  207. $context->setCommandScopeVariables($vars);
  208. $this->assertSame($vars, $context->getCommandScopeVariables());
  209. $this->assertSame($__function, $context->get('__function'));
  210. $this->assertSame($__method, $context->get('__method'));
  211. $this->assertSame($__class, $context->get('__class'));
  212. $this->assertSame($__namespace, $context->get('__namespace'));
  213. $this->assertSame($__file, $context->get('__file'));
  214. $this->assertSame($__line, $context->get('__line'));
  215. $this->assertSame($__dir, $context->get('__dir'));
  216. $someVars = \compact('__function', '__namespace', '__file', '__line', '__dir');
  217. $context->setCommandScopeVariables($someVars);
  218. }
  219. public function testGetUnusedCommandScopeVariableNames()
  220. {
  221. $context = new Context();
  222. $this->assertSame(
  223. ['__function', '__method', '__class', '__namespace', '__file', '__line', '__dir'],
  224. $context->getUnusedCommandScopeVariableNames()
  225. );
  226. $context->setCommandScopeVariables([
  227. '__function' => 'foo',
  228. '__namespace' => 'bar',
  229. '__file' => 'baz',
  230. '__line' => 123,
  231. '__dir' => 'qux',
  232. ]);
  233. $this->assertSame(
  234. ['__method', '__class'],
  235. \array_values($context->getUnusedCommandScopeVariableNames())
  236. );
  237. }
  238. /**
  239. * @dataProvider specialAndNotSpecialVariableNames
  240. */
  241. public function testIsSpecialVariableName($name, $isSpecial)
  242. {
  243. $context = new Context();
  244. if ($isSpecial) {
  245. $this->assertTrue($context->isSpecialVariableName($name));
  246. } else {
  247. $this->assertFalse($context->isSpecialVariableName($name));
  248. }
  249. }
  250. public function specialAndNotSpecialVariableNames()
  251. {
  252. return [
  253. ['foo', false],
  254. ['psysh', false],
  255. ['__psysh', false],
  256. ['_', true],
  257. ['_e', true],
  258. ['__out', true],
  259. ['this', true],
  260. ['__psysh__', true],
  261. ['__function', true],
  262. ['__method', true],
  263. ['__class', true],
  264. ['__namespace', true],
  265. ['__file', true],
  266. ['__line', true],
  267. ['__dir', true],
  268. ];
  269. }
  270. }