visual_test.php 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. <?php
  2. // $Id: visual_test.php 1787 2008-04-26 20:35:39Z pp11 $
  3. // NOTE:
  4. // Some of these tests are designed to fail! Do not be alarmed.
  5. // ----------------
  6. // The following tests are a bit hacky. Whilst Kent Beck tried to
  7. // build a unit tester with a unit tester, I am not that brave.
  8. // Instead I have just hacked together odd test scripts until
  9. // I have enough of a tester to procede more formally.
  10. //
  11. // The proper tests start in all_tests.php
  12. require_once('../unit_tester.php');
  13. require_once('../shell_tester.php');
  14. require_once('../mock_objects.php');
  15. require_once('../reporter.php');
  16. require_once('../xml.php');
  17. class TestDisplayClass {
  18. private $a;
  19. function TestDisplayClass($a) {
  20. $this->a = $a;
  21. }
  22. }
  23. class PassingUnitTestCaseOutput extends UnitTestCase {
  24. function testOfResults() {
  25. $this->pass('Pass');
  26. }
  27. function testTrue() {
  28. $this->assertTrue(true);
  29. }
  30. function testFalse() {
  31. $this->assertFalse(false);
  32. }
  33. function testExpectation() {
  34. $expectation = &new EqualExpectation(25, 'My expectation message: %s');
  35. $this->assert($expectation, 25, 'My assert message : %s');
  36. }
  37. function testNull() {
  38. $this->assertNull(null, "%s -> Pass");
  39. $this->assertNotNull(false, "%s -> Pass");
  40. }
  41. function testType() {
  42. $this->assertIsA("hello", "string", "%s -> Pass");
  43. $this->assertIsA($this, "PassingUnitTestCaseOutput", "%s -> Pass");
  44. $this->assertIsA($this, "UnitTestCase", "%s -> Pass");
  45. }
  46. function testTypeEquality() {
  47. $this->assertEqual("0", 0, "%s -> Pass");
  48. }
  49. function testNullEquality() {
  50. $this->assertNotEqual(null, 1, "%s -> Pass");
  51. $this->assertNotEqual(1, null, "%s -> Pass");
  52. }
  53. function testIntegerEquality() {
  54. $this->assertNotEqual(1, 2, "%s -> Pass");
  55. }
  56. function testStringEquality() {
  57. $this->assertEqual("a", "a", "%s -> Pass");
  58. $this->assertNotEqual("aa", "ab", "%s -> Pass");
  59. }
  60. function testHashEquality() {
  61. $this->assertEqual(array("a" => "A", "b" => "B"), array("b" => "B", "a" => "A"), "%s -> Pass");
  62. }
  63. function testWithin() {
  64. $this->assertWithinMargin(5, 5.4, 0.5, "%s -> Pass");
  65. }
  66. function testOutside() {
  67. $this->assertOutsideMargin(5, 5.6, 0.5, "%s -> Pass");
  68. }
  69. function testStringIdentity() {
  70. $a = "fred";
  71. $b = $a;
  72. $this->assertIdentical($a, $b, "%s -> Pass");
  73. }
  74. function testTypeIdentity() {
  75. $a = "0";
  76. $b = 0;
  77. $this->assertNotIdentical($a, $b, "%s -> Pass");
  78. }
  79. function testNullIdentity() {
  80. $this->assertNotIdentical(null, 1, "%s -> Pass");
  81. $this->assertNotIdentical(1, null, "%s -> Pass");
  82. }
  83. function testHashIdentity() {
  84. }
  85. function testObjectEquality() {
  86. $this->assertEqual(new TestDisplayClass(4), new TestDisplayClass(4), "%s -> Pass");
  87. $this->assertNotEqual(new TestDisplayClass(4), new TestDisplayClass(5), "%s -> Pass");
  88. }
  89. function testObjectIndentity() {
  90. $this->assertIdentical(new TestDisplayClass(false), new TestDisplayClass(false), "%s -> Pass");
  91. $this->assertNotIdentical(new TestDisplayClass(false), new TestDisplayClass(0), "%s -> Pass");
  92. }
  93. function testReference() {
  94. $a = "fred";
  95. $b = &$a;
  96. $this->assertReference($a, $b, "%s -> Pass");
  97. }
  98. function testCloneOnDifferentObjects() {
  99. $a = "fred";
  100. $b = $a;
  101. $c = "Hello";
  102. $this->assertClone($a, $b, "%s -> Pass");
  103. }
  104. function testPatterns() {
  105. $this->assertPattern('/hello/i', "Hello there", "%s -> Pass");
  106. $this->assertNoPattern('/hello/', "Hello there", "%s -> Pass");
  107. }
  108. function testLongStrings() {
  109. $text = "";
  110. for ($i = 0; $i < 10; $i++) {
  111. $text .= "0123456789";
  112. }
  113. $this->assertEqual($text, $text);
  114. }
  115. }
  116. class FailingUnitTestCaseOutput extends UnitTestCase {
  117. function testOfResults() {
  118. $this->fail('Fail'); // Fail.
  119. }
  120. function testTrue() {
  121. $this->assertTrue(false); // Fail.
  122. }
  123. function testFalse() {
  124. $this->assertFalse(true); // Fail.
  125. }
  126. function testExpectation() {
  127. $expectation = &new EqualExpectation(25, 'My expectation message: %s');
  128. $this->assert($expectation, 24, 'My assert message : %s'); // Fail.
  129. }
  130. function testNull() {
  131. $this->assertNull(false, "%s -> Fail"); // Fail.
  132. $this->assertNotNull(null, "%s -> Fail"); // Fail.
  133. }
  134. function testType() {
  135. $this->assertIsA(14, "string", "%s -> Fail"); // Fail.
  136. $this->assertIsA(14, "TestOfUnitTestCaseOutput", "%s -> Fail"); // Fail.
  137. $this->assertIsA($this, "TestReporter", "%s -> Fail"); // Fail.
  138. }
  139. function testTypeEquality() {
  140. $this->assertNotEqual("0", 0, "%s -> Fail"); // Fail.
  141. }
  142. function testNullEquality() {
  143. $this->assertEqual(null, 1, "%s -> Fail"); // Fail.
  144. $this->assertEqual(1, null, "%s -> Fail"); // Fail.
  145. }
  146. function testIntegerEquality() {
  147. $this->assertEqual(1, 2, "%s -> Fail"); // Fail.
  148. }
  149. function testStringEquality() {
  150. $this->assertNotEqual("a", "a", "%s -> Fail"); // Fail.
  151. $this->assertEqual("aa", "ab", "%s -> Fail"); // Fail.
  152. }
  153. function testHashEquality() {
  154. $this->assertEqual(array("a" => "A", "b" => "B"), array("b" => "B", "a" => "Z"), "%s -> Fail");
  155. }
  156. function testWithin() {
  157. $this->assertWithinMargin(5, 5.6, 0.5, "%s -> Fail"); // Fail.
  158. }
  159. function testOutside() {
  160. $this->assertOutsideMargin(5, 5.4, 0.5, "%s -> Fail"); // Fail.
  161. }
  162. function testStringIdentity() {
  163. $a = "fred";
  164. $b = $a;
  165. $this->assertNotIdentical($a, $b, "%s -> Fail"); // Fail.
  166. }
  167. function testTypeIdentity() {
  168. $a = "0";
  169. $b = 0;
  170. $this->assertIdentical($a, $b, "%s -> Fail"); // Fail.
  171. }
  172. function testNullIdentity() {
  173. $this->assertIdentical(null, 1, "%s -> Fail"); // Fail.
  174. $this->assertIdentical(1, null, "%s -> Fail"); // Fail.
  175. }
  176. function testHashIdentity() {
  177. $this->assertIdentical(array("a" => "A", "b" => "B"), array("b" => "B", "a" => "A"), "%s -> fail"); // Fail.
  178. }
  179. function testObjectEquality() {
  180. $this->assertNotEqual(new TestDisplayClass(4), new TestDisplayClass(4), "%s -> Fail"); // Fail.
  181. $this->assertEqual(new TestDisplayClass(4), new TestDisplayClass(5), "%s -> Fail"); // Fail.
  182. }
  183. function testObjectIndentity() {
  184. $this->assertNotIdentical(new TestDisplayClass(false), new TestDisplayClass(false), "%s -> Fail"); // Fail.
  185. $this->assertIdentical(new TestDisplayClass(false), new TestDisplayClass(0), "%s -> Fail"); // Fail.
  186. }
  187. function testReference() {
  188. $a = "fred";
  189. $b = &$a;
  190. $this->assertClone($a, $b, "%s -> Fail"); // Fail.
  191. }
  192. function testCloneOnDifferentObjects() {
  193. $a = "fred";
  194. $b = $a;
  195. $c = "Hello";
  196. $this->assertClone($a, $c, "%s -> Fail"); // Fail.
  197. }
  198. function testPatterns() {
  199. $this->assertPattern('/hello/', "Hello there", "%s -> Fail"); // Fail.
  200. $this->assertNoPattern('/hello/i', "Hello there", "%s -> Fail"); // Fail.
  201. }
  202. function testLongStrings() {
  203. $text = "";
  204. for ($i = 0; $i < 10; $i++) {
  205. $text .= "0123456789";
  206. }
  207. $this->assertEqual($text . $text, $text . "a" . $text); // Fail.
  208. }
  209. }
  210. class Dummy {
  211. function Dummy() {
  212. }
  213. function a() {
  214. }
  215. }
  216. Mock::generate('Dummy');
  217. class TestOfMockObjectsOutput extends UnitTestCase {
  218. function testCallCounts() {
  219. $dummy = &new MockDummy();
  220. $dummy->expectCallCount('a', 1, 'My message: %s');
  221. $dummy->a();
  222. $dummy->a();
  223. }
  224. function testMinimumCallCounts() {
  225. $dummy = &new MockDummy();
  226. $dummy->expectMinimumCallCount('a', 2, 'My message: %s');
  227. $dummy->a();
  228. $dummy->a();
  229. }
  230. function testEmptyMatching() {
  231. $dummy = &new MockDummy();
  232. $dummy->expect('a', array());
  233. $dummy->a();
  234. $dummy->a(null); // Fail.
  235. }
  236. function testEmptyMatchingWithCustomMessage() {
  237. $dummy = &new MockDummy();
  238. $dummy->expect('a', array(), 'My expectation message: %s');
  239. $dummy->a();
  240. $dummy->a(null); // Fail.
  241. }
  242. function testNullMatching() {
  243. $dummy = &new MockDummy();
  244. $dummy->expect('a', array(null));
  245. $dummy->a(null);
  246. $dummy->a(); // Fail.
  247. }
  248. function testBooleanMatching() {
  249. $dummy = &new MockDummy();
  250. $dummy->expect('a', array(true, false));
  251. $dummy->a(true, false);
  252. $dummy->a(true, true); // Fail.
  253. }
  254. function testIntegerMatching() {
  255. $dummy = &new MockDummy();
  256. $dummy->expect('a', array(32, 33));
  257. $dummy->a(32, 33);
  258. $dummy->a(32, 34); // Fail.
  259. }
  260. function testFloatMatching() {
  261. $dummy = &new MockDummy();
  262. $dummy->expect('a', array(3.2, 3.3));
  263. $dummy->a(3.2, 3.3);
  264. $dummy->a(3.2, 3.4); // Fail.
  265. }
  266. function testStringMatching() {
  267. $dummy = &new MockDummy();
  268. $dummy->expect('a', array('32', '33'));
  269. $dummy->a('32', '33');
  270. $dummy->a('32', '34'); // Fail.
  271. }
  272. function testEmptyMatchingWithCustomExpectationMessage() {
  273. $dummy = &new MockDummy();
  274. $dummy->expect(
  275. 'a',
  276. array(new EqualExpectation('A', 'My part expectation message: %s')),
  277. 'My expectation message: %s');
  278. $dummy->a('A');
  279. $dummy->a('B'); // Fail.
  280. }
  281. function testArrayMatching() {
  282. $dummy = &new MockDummy();
  283. $dummy->expect('a', array(array(32), array(33)));
  284. $dummy->a(array(32), array(33));
  285. $dummy->a(array(32), array('33')); // Fail.
  286. }
  287. function testObjectMatching() {
  288. $a = new Dummy();
  289. $a->a = 'a';
  290. $b = new Dummy();
  291. $b->b = 'b';
  292. $dummy = &new MockDummy();
  293. $dummy->expect('a', array($a, $b));
  294. $dummy->a($a, $b);
  295. $dummy->a($a, $a); // Fail.
  296. }
  297. function testBigList() {
  298. $dummy = &new MockDummy();
  299. $dummy->expect('a', array(false, 0, 1, 1.0));
  300. $dummy->a(false, 0, 1, 1.0);
  301. $dummy->a(true, false, 2, 2.0); // Fail.
  302. }
  303. }
  304. class TestOfPastBugs extends UnitTestCase {
  305. function testMixedTypes() {
  306. $this->assertEqual(array(), null, "%s -> Pass");
  307. $this->assertIdentical(array(), null, "%s -> Fail"); // Fail.
  308. }
  309. function testMockWildcards() {
  310. $dummy = &new MockDummy();
  311. $dummy->expect('a', array('*', array(33)));
  312. $dummy->a(array(32), array(33));
  313. $dummy->a(array(32), array('33')); // Fail.
  314. }
  315. }
  316. class TestOfVisualShell extends ShellTestCase {
  317. function testDump() {
  318. $this->execute('ls');
  319. $this->dumpOutput();
  320. $this->execute('dir');
  321. $this->dumpOutput();
  322. }
  323. function testDumpOfList() {
  324. $this->execute('ls');
  325. $this->dump($this->getOutputAsList());
  326. }
  327. }
  328. class PassesAsWellReporter extends HtmlReporter {
  329. protected function getCss() {
  330. return parent::getCss() . ' .pass { color: darkgreen; }';
  331. }
  332. function paintPass($message) {
  333. parent::paintPass($message);
  334. print "<span class=\"pass\">Pass</span>: ";
  335. $breadcrumb = $this->getTestList();
  336. array_shift($breadcrumb);
  337. print implode(" -&gt; ", $breadcrumb);
  338. print " -&gt; " . htmlentities($message) . "<br />\n";
  339. }
  340. function paintSignal($type, &$payload) {
  341. print "<span class=\"fail\">$type</span>: ";
  342. $breadcrumb = $this->getTestList();
  343. array_shift($breadcrumb);
  344. print implode(" -&gt; ", $breadcrumb);
  345. print " -&gt; " . htmlentities(serialize($payload)) . "<br />\n";
  346. }
  347. }
  348. class TestOfSkippingNoMatterWhat extends UnitTestCase {
  349. function skip() {
  350. $this->skipIf(true, 'Always skipped -> %s');
  351. }
  352. function testFail() {
  353. $this->fail('This really shouldn\'t have happened');
  354. }
  355. }
  356. class TestOfSkippingOrElse extends UnitTestCase {
  357. function skip() {
  358. $this->skipUnless(false, 'Always skipped -> %s');
  359. }
  360. function testFail() {
  361. $this->fail('This really shouldn\'t have happened');
  362. }
  363. }
  364. class TestOfSkippingTwiceOver extends UnitTestCase {
  365. function skip() {
  366. $this->skipIf(true, 'First reason -> %s');
  367. $this->skipIf(true, 'Second reason -> %s');
  368. }
  369. function testFail() {
  370. $this->fail('This really shouldn\'t have happened');
  371. }
  372. }
  373. class TestThatShouldNotBeSkipped extends UnitTestCase {
  374. function skip() {
  375. $this->skipIf(false);
  376. $this->skipUnless(true);
  377. }
  378. function testFail() {
  379. $this->fail('We should see this message');
  380. }
  381. function testPass() {
  382. $this->pass('We should see this message');
  383. }
  384. }
  385. $test = &new TestSuite('Visual test with 46 passes, 47 fails and 0 exceptions');
  386. $test->add(new PassingUnitTestCaseOutput());
  387. $test->add(new FailingUnitTestCaseOutput());
  388. $test->add(new TestOfMockObjectsOutput());
  389. $test->add(new TestOfPastBugs());
  390. $test->add(new TestOfVisualShell());
  391. $test->add(new TestOfSkippingNoMatterWhat());
  392. $test->add(new TestOfSkippingOrElse());
  393. $test->add(new TestOfSkippingTwiceOver());
  394. $test->add(new TestThatShouldNotBeSkipped());
  395. if (isset($_GET['xml']) || in_array('xml', (isset($argv) ? $argv : array()))) {
  396. $reporter = new XmlReporter();
  397. } elseif (TextReporter::inCli()) {
  398. $reporter = new TextReporter();
  399. } else {
  400. $reporter = new PassesAsWellReporter();
  401. }
  402. if (isset($_GET['dry']) || in_array('dry', (isset($argv) ? $argv : array()))) {
  403. $reporter->makeDry();
  404. }
  405. exit ($test->run($reporter) ? 0 : 1);
  406. ?>