ArgumentTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. <?php
  2. namespace League\CLImate\Tests;
  3. use League\CLImate\Argument\Argument;
  4. class ArgumentTest extends TestBase
  5. {
  6. /** @test */
  7. public function it_throws_an_exception_when_setting_an_unknown_cast_type()
  8. {
  9. $this->setExpectedException(
  10. 'Exception',
  11. "An argument may only be cast to the data type 'string', 'int', 'float', or 'bool'."
  12. );
  13. Argument::createFromArray('invalid-cast-type', [
  14. 'castTo' => 'invalid',
  15. ]);
  16. }
  17. /** @test */
  18. public function it_throws_an_exception_when_building_arguments_from_an_unknown_type()
  19. {
  20. $this->setExpectedException(
  21. 'Exception',
  22. 'Please provide an argument name or object.'
  23. );
  24. $this->cli->arguments->add(new \stdClass);
  25. }
  26. public function provide_cast_types_and_values()
  27. {
  28. return [
  29. 'to string' => ['string', 'a string',],
  30. 'to int' => ['int', '1234',],
  31. 'to float' => ['float', '12.34',],
  32. 'to boolean' => ['bool', '1'],
  33. ];
  34. }
  35. protected function getFullArguments()
  36. {
  37. return [
  38. 'only-short-prefix' => [
  39. 'prefix' => 's',
  40. 'description' => 'Only short prefix',
  41. ],
  42. 'only-long-prefix' => [
  43. 'longPrefix' => 'long',
  44. 'description' => 'Only long prefix',
  45. ],
  46. 'both-prefixes' => [
  47. 'prefix' => 'b',
  48. 'longPrefix' => 'both',
  49. 'description' => 'Both short and long prefixes',
  50. ],
  51. 'no-prefix' => [
  52. 'description' => 'Not defined by a prefix',
  53. ],
  54. 'defined-only' => [
  55. 'prefix' => 'd',
  56. 'longPrefix' => 'defined',
  57. 'description' => 'True when defined',
  58. 'noValue' => true,
  59. ],
  60. 'required' => [
  61. 'prefix' => 'r',
  62. 'description' => 'Required',
  63. 'required' => true,
  64. ],
  65. 'default-value' => [
  66. 'prefix' => 'v',
  67. 'description' => 'Has a default value',
  68. 'defaultValue' => 'test',
  69. ],
  70. ];
  71. }
  72. /**
  73. * @test
  74. * @dataProvider provide_cast_types_and_values
  75. * @param string $castTo
  76. * @param string $value
  77. */
  78. public function it_can_cast_different_value_data_types($castTo, $value)
  79. {
  80. $argument = Argument::createFromArray('test', [
  81. 'castTo' => $castTo,
  82. ]);
  83. $argument->setValue($value);
  84. $this->assertInternalType($castTo, $argument->value());
  85. }
  86. /** @test */
  87. public function it_casts_to_bool_when_defined_only()
  88. {
  89. $argument = Argument::createFromArray('invalid-cast-type', [
  90. 'noValue' => true,
  91. ]);
  92. $this->assertEquals('bool', $argument->castTo());
  93. }
  94. /** @test */
  95. public function it_builds_arguments_from_a_single_array()
  96. {
  97. // Test Description
  98. //
  99. // Usage: test-script [-b both-prefixes, --both both-prefixes] [-d, --defined] [--long only-long-prefix] [-r required] [-s only-short-prefix] [-v default-value (default: test)] [no-prefix]
  100. //
  101. // Required Arguments:
  102. // -r required
  103. // Required
  104. //
  105. // Optional Arguments:
  106. // -b both-prefixes, --both both-prefixes
  107. // Both short and long prefixes
  108. // -d, --defined
  109. // True when defined
  110. // -s only-short-prefix
  111. // Only short prefix
  112. // --long only-long-prefix
  113. // Only long prefix
  114. // -v default-value (default: test)
  115. // Has a default value
  116. // no-prefix
  117. // Not defined by a prefix
  118. $this->output->shouldReceive("sameLine");
  119. $this->shouldWrite("\e[mTest Description\e[0m");
  120. $this->shouldWrite("\e[m\e[0m");
  121. $this->shouldWrite("\e[mUsage: test-script "
  122. . "[-b both-prefixes, --both both-prefixes] [-d, --defined] "
  123. . "[--long only-long-prefix] [-r required] [-s only-short-prefix] "
  124. . "[-v default-value (default: test)] [no-prefix]\e[0m");
  125. $this->shouldWrite("\e[m\e[0m");
  126. $this->shouldWrite("\e[mRequired Arguments:\e[0m");
  127. $this->shouldWrite("\e[m\t\e[0m");
  128. $this->shouldWrite("\e[m-r required\e[0m");
  129. $this->shouldWrite("\e[m\t\t\e[0m");
  130. $this->shouldWrite("\e[mRequired\e[0m");
  131. $this->shouldWrite("\e[m\e[0m");
  132. $this->shouldWrite("\e[mOptional Arguments:\e[0m");
  133. $this->shouldWrite("\e[m\t\e[0m");
  134. $this->shouldWrite("\e[m-b both-prefixes, --both both-prefixes\e[0m");
  135. $this->shouldWrite("\e[m\t\t\e[0m");
  136. $this->shouldWrite("\e[mBoth short and long prefixes\e[0m");
  137. $this->shouldWrite("\e[m\t\e[0m");
  138. $this->shouldWrite("\e[m-d, --defined\e[0m");
  139. $this->shouldWrite("\e[m\t\t\e[0m");
  140. $this->shouldWrite("\e[mTrue when defined\e[0m");
  141. $this->shouldWrite("\e[m\t\e[0m");
  142. $this->shouldWrite("\e[m--long only-long-prefix\e[0m");
  143. $this->shouldWrite("\e[m\t\t\e[0m");
  144. $this->shouldWrite("\e[mOnly long prefix\e[0m");
  145. $this->shouldWrite("\e[m\t\e[0m");
  146. $this->shouldWrite("\e[m-s only-short-prefix\e[0m");
  147. $this->shouldWrite("\e[m\t\t\e[0m");
  148. $this->shouldWrite("\e[mOnly short prefix\e[0m");
  149. $this->shouldWrite("\e[m\t\e[0m");
  150. $this->shouldWrite("\e[m-v default-value (default: test)\e[0m");
  151. $this->shouldWrite("\e[m\t\t\e[0m");
  152. $this->shouldWrite("\e[mHas a default value\e[0m");
  153. $this->shouldWrite("\e[m\t\e[0m");
  154. $this->shouldWrite("\e[mno-prefix\e[0m");
  155. $this->shouldWrite("\e[m\t\t\e[0m");
  156. $this->shouldWrite("\e[mNot defined by a prefix\e[0m");
  157. $this->shouldHavePersisted(35);
  158. $this->cli->description('Test Description');
  159. $this->cli->arguments->add($this->getFullArguments());
  160. $command = 'test-script';
  161. $this->cli->usage([$command]);
  162. }
  163. /** @test */
  164. public function it_can_parse_arguments()
  165. {
  166. $this->cli->arguments->add([
  167. 'only-short-prefix' => [
  168. 'prefix' => 's',
  169. ],
  170. 'only-long-prefix' => [
  171. 'longPrefix' => 'long',
  172. ],
  173. 'both-prefixes' => [
  174. 'prefix' => 'b',
  175. 'longPrefix' => 'both',
  176. ],
  177. 'both-equals' => [
  178. 'longPrefix' => 'both-equals',
  179. ],
  180. 'no-prefix' => [],
  181. 'defined-only' => [
  182. 'prefix' => 'd',
  183. 'longPrefix' => 'defined',
  184. 'noValue' => true,
  185. ],
  186. ]);
  187. $argv = [
  188. 'test-script',
  189. '-s',
  190. 'foo',
  191. '--long',
  192. 'bar',
  193. '-b=both',
  194. '-d',
  195. '--both-equals=both_equals',
  196. 'no_prefix_value',
  197. '-unknown',
  198. 'after_non_prefixed'
  199. ];
  200. $this->cli->arguments->parse($argv);
  201. $processed = $this->cli->arguments->toArray();
  202. $this->assertCount(6, $processed);
  203. $this->assertEquals('foo', $processed['only-short-prefix']);
  204. $this->assertEquals('bar', $processed['only-long-prefix']);
  205. $this->assertEquals('both', $processed['both-prefixes']);
  206. $this->assertEquals('both_equals', $processed['both-equals']);
  207. $this->assertEquals('no_prefix_value', $processed['no-prefix']);
  208. $this->assertTrue($processed['defined-only']);
  209. $this->assertEquals('foo', $this->cli->arguments->get('only-short-prefix'));
  210. }
  211. /** @test */
  212. public function it_will_get_a_default_value_for_a_long_prefix_with_no_value()
  213. {
  214. $this->cli->arguments->add([
  215. 'only-long-prefix' => [
  216. 'longPrefix' => 'long',
  217. 'defaultValue' => 'HEY',
  218. ],
  219. ]);
  220. $argv = [
  221. 'test-script',
  222. '--long',
  223. ];
  224. $this->cli->arguments->parse($argv);
  225. $processed = $this->cli->arguments->toArray();
  226. $this->assertEquals('HEY', $this->cli->arguments->get('only-long-prefix'));
  227. }
  228. /** @test */
  229. public function it_throws_an_exception_when_required_arguments_are_not_defined()
  230. {
  231. $this->setExpectedException(
  232. 'Exception',
  233. 'The following arguments are required: [-r required-value] [-r1 required-value-1].'
  234. );
  235. $this->cli->arguments->add([
  236. 'required-value' => [
  237. 'prefix' => 'r',
  238. 'required' => true,
  239. ],
  240. 'required-value-1' => [
  241. 'prefix' => 'r1',
  242. 'required' => true,
  243. ],
  244. 'optional-value' => [
  245. 'prefix' => 'o',
  246. ],
  247. ]);
  248. $argv = ['test-script', '-o', 'foo'];
  249. $this->cli->arguments->parse($argv);
  250. }
  251. /** @test */
  252. public function it_can_detect_when_arguments_are_defined()
  253. {
  254. $this->cli->arguments->add([
  255. 'argument' => [
  256. 'prefix' => 'a',
  257. ],
  258. 'another-argument' => [
  259. 'prefix' => 'b',
  260. ],
  261. 'long-argument' => [
  262. 'longPrefix' => 'c',
  263. ],
  264. ]);
  265. $argv = ['test-script', '-a', 'foo', '--c=bar'];
  266. $this->assertTrue($this->cli->arguments->defined('argument', $argv));
  267. $this->assertTrue($this->cli->arguments->defined('long-argument', $argv));
  268. $this->assertFalse($this->cli->arguments->defined('another-argument', $argv));
  269. $this->assertFalse($this->cli->arguments->defined('nonexistent', $argv));
  270. }
  271. /** @test */
  272. public function it_can_grab_the_trailing_arguments()
  273. {
  274. $this->cli->arguments->add([
  275. 'argument' => [
  276. 'prefix' => 'a',
  277. ],
  278. 'another-argument' => [
  279. 'prefix' => 'b',
  280. ],
  281. 'long-argument' => [
  282. 'longPrefix' => 'c',
  283. ],
  284. ]);
  285. $argv = ['test-script', '-a', 'foo', '--c=bar', '--', '-the', 'trailing', '--arguments=here'];
  286. $this->cli->arguments->parse($argv);
  287. $this->assertTrue($this->cli->arguments->defined('argument', $argv));
  288. $this->assertTrue($this->cli->arguments->defined('long-argument', $argv));
  289. $this->assertFalse($this->cli->arguments->defined('another-argument', $argv));
  290. $this->assertFalse($this->cli->arguments->defined('nonexistent', $argv));
  291. $this->assertSame($this->cli->arguments->trailing(), '-the trailing --arguments=here');
  292. }
  293. }