AssertTest.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. <?php
  2. /*
  3. * This file is part of the webmozart/assert package.
  4. *
  5. * (c) Bernhard Schussek <bschussek@gmail.com>
  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 Webmozart\Assert\Tests;
  11. use ArrayIterator;
  12. use Exception;
  13. use Error;
  14. use LogicException;
  15. use PHPUnit_Framework_TestCase;
  16. use RuntimeException;
  17. use stdClass;
  18. use Webmozart\Assert\Assert;
  19. /**
  20. * @since 1.0
  21. *
  22. * @author Bernhard Schussek <bschussek@gmail.com>
  23. */
  24. class AssertTest extends PHPUnit_Framework_TestCase
  25. {
  26. private static $resource;
  27. public static function getResource()
  28. {
  29. if (!static::$resource) {
  30. static::$resource = fopen(__FILE__, 'r');
  31. }
  32. return static::$resource;
  33. }
  34. public static function tearDownAfterClass()
  35. {
  36. @fclose(self::$resource);
  37. }
  38. public function getTests()
  39. {
  40. $resource = self::getResource();
  41. return array(
  42. array('string', array('value'), true),
  43. array('string', array(''), true),
  44. array('string', array(1234), false),
  45. array('stringNotEmpty', array('value'), true),
  46. array('stringNotEmpty', array(''), false),
  47. array('stringNotEmpty', array(1234), false),
  48. array('integer', array(123), true),
  49. array('integer', array('123'), false),
  50. array('integer', array(1.0), false),
  51. array('integer', array(1.23), false),
  52. array('integerish', array(1.0), true),
  53. array('integerish', array(1.23), false),
  54. array('integerish', array(123), true),
  55. array('integerish', array('123'), true),
  56. array('float', array(1.0), true),
  57. array('float', array(1.23), true),
  58. array('float', array(123), false),
  59. array('float', array('123'), false),
  60. array('numeric', array(1.0), true),
  61. array('numeric', array(1.23), true),
  62. array('numeric', array(123), true),
  63. array('numeric', array('123'), true),
  64. array('numeric', array('foo'), false),
  65. array('boolean', array(true), true),
  66. array('boolean', array(false), true),
  67. array('boolean', array(1), false),
  68. array('boolean', array('1'), false),
  69. array('scalar', array('1'), true),
  70. array('scalar', array(123), true),
  71. array('scalar', array(true), true),
  72. array('scalar', array(null), false),
  73. array('scalar', array(array()), false),
  74. array('scalar', array(new stdClass()), false),
  75. array('object', array(new stdClass()), true),
  76. array('object', array(new RuntimeException()), true),
  77. array('object', array(null), false),
  78. array('object', array(true), false),
  79. array('object', array(1), false),
  80. array('object', array(array()), false),
  81. array('resource', array($resource), true),
  82. array('resource', array($resource, 'stream'), true),
  83. array('resource', array($resource, 'other'), false),
  84. array('resource', array(1), false),
  85. array('isCallable', array('strlen'), true),
  86. array('isCallable', array(array($this, 'getTests')), true),
  87. array('isCallable', array(function () {}), true),
  88. array('isCallable', array(1234), false),
  89. array('isCallable', array('foobar'), false),
  90. array('isArray', array(array()), true),
  91. array('isArray', array(array(1, 2, 3)), true),
  92. array('isArray', array(new ArrayIterator(array())), false),
  93. array('isArray', array(123), false),
  94. array('isArray', array(new stdClass()), false),
  95. array('isTraversable', array(array()), true),
  96. array('isTraversable', array(array(1, 2, 3)), true),
  97. array('isTraversable', array(new ArrayIterator(array())), true),
  98. array('isTraversable', array(123), false),
  99. array('isTraversable', array(new stdClass()), false),
  100. array('isInstanceOf', array(new stdClass(), 'stdClass'), true),
  101. array('isInstanceOf', array(new Exception(), 'stdClass'), false),
  102. array('isInstanceOf', array(123, 'stdClass'), false),
  103. array('isInstanceOf', array(array(), 'stdClass'), false),
  104. array('notInstanceOf', array(new stdClass(), 'stdClass'), false),
  105. array('notInstanceOf', array(new Exception(), 'stdClass'), true),
  106. array('notInstanceOf', array(123, 'stdClass'), true),
  107. array('notInstanceOf', array(array(), 'stdClass'), true),
  108. array('true', array(true), true),
  109. array('true', array(false), false),
  110. array('true', array(1), false),
  111. array('true', array(null), false),
  112. array('false', array(false), true),
  113. array('false', array(true), false),
  114. array('false', array(1), false),
  115. array('false', array(0), false),
  116. array('false', array(null), false),
  117. array('null', array(null), true),
  118. array('null', array(false), false),
  119. array('null', array(0), false),
  120. array('notNull', array(false), true),
  121. array('notNull', array(0), true),
  122. array('notNull', array(null), false),
  123. array('isEmpty', array(null), true),
  124. array('isEmpty', array(false), true),
  125. array('isEmpty', array(0), true),
  126. array('isEmpty', array(''), true),
  127. array('isEmpty', array(1), false),
  128. array('isEmpty', array('a'), false),
  129. array('notEmpty', array(1), true),
  130. array('notEmpty', array('a'), true),
  131. array('notEmpty', array(null), false),
  132. array('notEmpty', array(false), false),
  133. array('notEmpty', array(0), false),
  134. array('notEmpty', array(''), false),
  135. array('eq', array(1, 1), true),
  136. array('eq', array(1, '1'), true),
  137. array('eq', array(1, true), true),
  138. array('eq', array(1, 0), false),
  139. array('notEq', array(1, 0), true),
  140. array('notEq', array(1, 1), false),
  141. array('notEq', array(1, '1'), false),
  142. array('notEq', array(1, true), false),
  143. array('same', array(1, 1), true),
  144. array('same', array(1, '1'), false),
  145. array('same', array(1, true), false),
  146. array('same', array(1, 0), false),
  147. array('notSame', array(1, 0), true),
  148. array('notSame', array(1, 1), false),
  149. array('notSame', array(1, '1'), true),
  150. array('notSame', array(1, true), true),
  151. array('greaterThan', array(1, 0), true),
  152. array('greaterThan', array(0, 0), false),
  153. array('greaterThanEq', array(2, 1), true),
  154. array('greaterThanEq', array(1, 1), true),
  155. array('greaterThanEq', array(0, 1), false),
  156. array('lessThan', array(0, 1), true),
  157. array('lessThan', array(1, 1), false),
  158. array('lessThanEq', array(0, 1), true),
  159. array('lessThanEq', array(1, 1), true),
  160. array('lessThanEq', array(2, 1), false),
  161. array('range', array(1, 1, 2), true),
  162. array('range', array(2, 1, 2), true),
  163. array('range', array(0, 1, 2), false),
  164. array('range', array(3, 1, 2), false),
  165. array('oneOf', array(1, array(1, 2, 3)), true),
  166. array('oneOf', array(1, array('1', '2', '3')), false),
  167. array('contains', array('abcd', 'ab'), true),
  168. array('contains', array('abcd', 'bc'), true),
  169. array('contains', array('abcd', 'cd'), true),
  170. array('contains', array('abcd', 'de'), false),
  171. array('contains', array('', 'de'), false),
  172. array('startsWith', array('abcd', 'ab'), true),
  173. array('startsWith', array('abcd', 'bc'), false),
  174. array('startsWith', array('', 'bc'), false),
  175. array('startsWithLetter', array('abcd'), true),
  176. array('startsWithLetter', array('1abcd'), false),
  177. array('startsWithLetter', array(''), false),
  178. array('endsWith', array('abcd', 'cd'), true),
  179. array('endsWith', array('abcd', 'bc'), false),
  180. array('endsWith', array('', 'bc'), false),
  181. array('regex', array('abcd', '~^ab~'), true),
  182. array('regex', array('abcd', '~^bc~'), false),
  183. array('regex', array('', '~^bc~'), false),
  184. array('alpha', array('abcd'), true),
  185. array('alpha', array('ab1cd'), false),
  186. array('alpha', array(''), false),
  187. array('digits', array('1234'), true),
  188. array('digits', array('12a34'), false),
  189. array('digits', array(''), false),
  190. array('alnum', array('ab12'), true),
  191. array('alnum', array('ab12$'), false),
  192. array('alnum', array(''), false),
  193. array('lower', array('abcd'), true),
  194. array('lower', array('abCd'), false),
  195. array('lower', array('ab_d'), false),
  196. array('lower', array(''), false),
  197. array('upper', array('ABCD'), true),
  198. array('upper', array('ABcD'), false),
  199. array('upper', array('AB_D'), false),
  200. array('upper', array(''), false),
  201. array('length', array('abcd', 4), true),
  202. array('length', array('abc', 4), false),
  203. array('length', array('abcde', 4), false),
  204. array('length', array('äbcd', 4), true, true),
  205. array('length', array('äbc', 4), false, true),
  206. array('length', array('äbcde', 4), false, true),
  207. array('minLength', array('abcd', 4), true),
  208. array('minLength', array('abcde', 4), true),
  209. array('minLength', array('abc', 4), false),
  210. array('minLength', array('äbcd', 4), true, true),
  211. array('minLength', array('äbcde', 4), true, true),
  212. array('minLength', array('äbc', 4), false, true),
  213. array('maxLength', array('abcd', 4), true),
  214. array('maxLength', array('abc', 4), true),
  215. array('maxLength', array('abcde', 4), false),
  216. array('maxLength', array('äbcd', 4), true, true),
  217. array('maxLength', array('äbc', 4), true, true),
  218. array('maxLength', array('äbcde', 4), false, true),
  219. array('lengthBetween', array('abcd', 3, 5), true),
  220. array('lengthBetween', array('abc', 3, 5), true),
  221. array('lengthBetween', array('abcde', 3, 5), true),
  222. array('lengthBetween', array('ab', 3, 5), false),
  223. array('lengthBetween', array('abcdef', 3, 5), false),
  224. array('lengthBetween', array('äbcd', 3, 5), true, true),
  225. array('lengthBetween', array('äbc', 3, 5), true, true),
  226. array('lengthBetween', array('äbcde', 3, 5), true, true),
  227. array('lengthBetween', array('äb', 3, 5), false, true),
  228. array('lengthBetween', array('äbcdef', 3, 5), false, true),
  229. array('fileExists', array(__FILE__), true),
  230. array('fileExists', array(__DIR__), true),
  231. array('fileExists', array(__DIR__.'/foobar'), false),
  232. array('file', array(__FILE__), true),
  233. array('file', array(__DIR__), false),
  234. array('file', array(__DIR__.'/foobar'), false),
  235. array('directory', array(__DIR__), true),
  236. array('directory', array(__FILE__), false),
  237. array('directory', array(__DIR__.'/foobar'), false),
  238. // no tests for readable()/writable() for now
  239. array('classExists', array(__CLASS__), true),
  240. array('classExists', array(__NAMESPACE__.'\Foobar'), false),
  241. array('subclassOf', array(__CLASS__, 'PHPUnit_Framework_TestCase'), true),
  242. array('subclassOf', array(__CLASS__, 'stdClass'), false),
  243. array('implementsInterface', array('ArrayIterator', 'Traversable'), true),
  244. array('implementsInterface', array(__CLASS__, 'Traversable'), false),
  245. array('propertyExists', array((object) array('property' => 0), 'property'), true),
  246. array('propertyExists', array((object) array('property' => null), 'property'), true),
  247. array('propertyExists', array((object) array('property' => null), 'foo'), false),
  248. array('propertyNotExists', array((object) array('property' => 0), 'property'), false),
  249. array('propertyNotExists', array((object) array('property' => null), 'property'), false),
  250. array('propertyNotExists', array((object) array('property' => null), 'foo'), true),
  251. array('methodExists', array('RuntimeException', 'getMessage'), true),
  252. array('methodExists', array(new RuntimeException(), 'getMessage'), true),
  253. array('methodExists', array('stdClass', 'getMessage'), false),
  254. array('methodExists', array(new stdClass(), 'getMessage'), false),
  255. array('methodExists', array(null, 'getMessage'), false),
  256. array('methodExists', array(true, 'getMessage'), false),
  257. array('methodExists', array(1, 'getMessage'), false),
  258. array('methodNotExists', array('RuntimeException', 'getMessage'), false),
  259. array('methodNotExists', array(new RuntimeException(), 'getMessage'), false),
  260. array('methodNotExists', array('stdClass', 'getMessage'), true),
  261. array('methodNotExists', array(new stdClass(), 'getMessage'), true),
  262. array('methodNotExists', array(null, 'getMessage'), true),
  263. array('methodNotExists', array(true, 'getMessage'), true),
  264. array('methodNotExists', array(1, 'getMessage'), true),
  265. array('keyExists', array(array('key' => 0), 'key'), true),
  266. array('keyExists', array(array('key' => null), 'key'), true),
  267. array('keyExists', array(array('key' => null), 'foo'), false),
  268. array('keyNotExists', array(array('key' => 0), 'key'), false),
  269. array('keyNotExists', array(array('key' => null), 'key'), false),
  270. array('keyNotExists', array(array('key' => null), 'foo'), true),
  271. array('count', array(array(0, 1, 2), 3), true),
  272. array('count', array(array(0, 1, 2), 2), false),
  273. array('uuid', array('00000000-0000-0000-0000-000000000000'), true),
  274. array('uuid', array('ff6f8cb0-c57d-21e1-9b21-0800200c9a66'), true),
  275. array('uuid', array('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'), true),
  276. array('uuid', array('ff6f8cb0-c57d-31e1-9b21-0800200c9a66'), true),
  277. array('uuid', array('ff6f8cb0-c57d-41e1-9b21-0800200c9a66'), true),
  278. array('uuid', array('ff6f8cb0-c57d-51e1-9b21-0800200c9a66'), true),
  279. array('uuid', array('FF6F8CB0-C57D-11E1-9B21-0800200C9A66'), true),
  280. array('uuid', array('zf6f8cb0-c57d-11e1-9b21-0800200c9a66'), false),
  281. array('uuid', array('af6f8cb0c57d11e19b210800200c9a66'), false),
  282. array('uuid', array('ff6f8cb0-c57da-51e1-9b21-0800200c9a66'), false),
  283. array('uuid', array('af6f8cb-c57d-11e1-9b21-0800200c9a66'), false),
  284. array('uuid', array('3f6f8cb0-c57d-11e1-9b21-0800200c9a6'), false),
  285. array('throws', array(function() { throw new LogicException('test'); }, 'LogicException'), true),
  286. array('throws', array(function() { throw new LogicException('test'); }, 'IllogicException'), false),
  287. array('throws', array(function() { throw new Exception('test'); }), true),
  288. array('throws', array(function() { trigger_error('test'); }, 'Throwable'), true, false, 70000),
  289. array('throws', array(function() { trigger_error('test'); }, 'Unthrowable'), false, false, 70000),
  290. array('throws', array(function() { throw new Error(); }, 'Throwable'), true, true, 70000),
  291. );
  292. }
  293. public function getMethods()
  294. {
  295. $methods = array();
  296. foreach ($this->getTests() as $params) {
  297. $methods[$params[0]] = array($params[0]);
  298. }
  299. return array_values($methods);
  300. }
  301. /**
  302. * @dataProvider getTests
  303. */
  304. public function testAssert($method, $args, $success, $multibyte = false, $minVersion = null)
  305. {
  306. if ($minVersion && PHP_VERSION_ID < $minVersion) {
  307. $this->markTestSkipped(sprintf('This test requires php %s or upper.', $minVersion));
  308. return;
  309. }
  310. if ($multibyte && !function_exists('mb_strlen')) {
  311. $this->markTestSkipped('The function mb_strlen() is not available');
  312. return;
  313. }
  314. if (!$success) {
  315. $this->setExpectedException('\InvalidArgumentException');
  316. }
  317. call_user_func_array(array('Webmozart\Assert\Assert', $method), $args);
  318. }
  319. /**
  320. * @dataProvider getTests
  321. */
  322. public function testNullOr($method, $args, $success, $multibyte = false, $minVersion = null)
  323. {
  324. if ($minVersion && PHP_VERSION_ID < $minVersion) {
  325. $this->markTestSkipped(sprintf('This test requires php %s or upper.', $minVersion));
  326. return;
  327. }
  328. if ($multibyte && !function_exists('mb_strlen')) {
  329. $this->markTestSkipped('The function mb_strlen() is not available');
  330. return;
  331. }
  332. if (!$success && null !== reset($args)) {
  333. $this->setExpectedException('\InvalidArgumentException');
  334. }
  335. call_user_func_array(array('Webmozart\Assert\Assert', 'nullOr'.ucfirst($method)), $args);
  336. }
  337. /**
  338. * @dataProvider getMethods
  339. */
  340. public function testNullOrAcceptsNull($method)
  341. {
  342. call_user_func(array('Webmozart\Assert\Assert', 'nullOr'.ucfirst($method)), null);
  343. }
  344. /**
  345. * @dataProvider getTests
  346. */
  347. public function testAllArray($method, $args, $success, $multibyte = false, $minVersion = null)
  348. {
  349. if ($minVersion && PHP_VERSION_ID < $minVersion) {
  350. $this->markTestSkipped(sprintf('This test requires php %s or upper.', $minVersion));
  351. return;
  352. }
  353. if ($multibyte && !function_exists('mb_strlen')) {
  354. $this->markTestSkipped('The function mb_strlen() is not available');
  355. return;
  356. }
  357. if (!$success) {
  358. $this->setExpectedException('\InvalidArgumentException');
  359. }
  360. $arg = array_shift($args);
  361. array_unshift($args, array($arg));
  362. call_user_func_array(array('Webmozart\Assert\Assert', 'all'.ucfirst($method)), $args);
  363. }
  364. /**
  365. * @dataProvider getTests
  366. */
  367. public function testAllTraversable($method, $args, $success, $multibyte = false, $minVersion = null)
  368. {
  369. if ($minVersion && PHP_VERSION_ID < $minVersion) {
  370. $this->markTestSkipped(sprintf('This test requires php %s or upper.', $minVersion));
  371. return;
  372. }
  373. if ($multibyte && !function_exists('mb_strlen')) {
  374. $this->markTestSkipped('The function mb_strlen() is not available');
  375. return;
  376. }
  377. if (!$success) {
  378. $this->setExpectedException('\InvalidArgumentException');
  379. }
  380. $arg = array_shift($args);
  381. array_unshift($args, new ArrayIterator(array($arg)));
  382. call_user_func_array(array('Webmozart\Assert\Assert', 'all'.ucfirst($method)), $args);
  383. }
  384. public function getStringConversions()
  385. {
  386. return array(
  387. array('integer', array('foobar'), 'Expected an integer. Got: string'),
  388. array('string', array(1), 'Expected a string. Got: integer'),
  389. array('string', array(true), 'Expected a string. Got: boolean'),
  390. array('string', array(null), 'Expected a string. Got: NULL'),
  391. array('string', array(array()), 'Expected a string. Got: array'),
  392. array('string', array(new stdClass()), 'Expected a string. Got: stdClass'),
  393. array('string', array(self::getResource()), 'Expected a string. Got: resource'),
  394. array('eq', array('1', '2'), 'Expected a value equal to "2". Got: "1"'),
  395. array('eq', array(1, 2), 'Expected a value equal to 2. Got: 1'),
  396. array('eq', array(true, false), 'Expected a value equal to false. Got: true'),
  397. array('eq', array(true, null), 'Expected a value equal to null. Got: true'),
  398. array('eq', array(null, true), 'Expected a value equal to true. Got: null'),
  399. array('eq', array(array(1), array(2)), 'Expected a value equal to array. Got: array'),
  400. array('eq', array(new ArrayIterator(array()), new stdClass()), 'Expected a value equal to stdClass. Got: ArrayIterator'),
  401. array('eq', array(1, self::getResource()), 'Expected a value equal to resource. Got: 1'),
  402. );
  403. }
  404. /**
  405. * @dataProvider getStringConversions
  406. */
  407. public function testConvertValuesToStrings($method, $args, $exceptionMessage)
  408. {
  409. $this->setExpectedException('\InvalidArgumentException', $exceptionMessage);
  410. call_user_func_array(array('Webmozart\Assert\Assert', $method), $args);
  411. }
  412. }