PostfixAdmin - web based virtual user administration interface for Postfix mail servers https://postfixadmin.github.io/postfixadmin/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

519 lines
24 KiB

  1. <?php
  2. // $Id: parser_test.php,v 1.58 2006/01/04 04:35:36 lastcraft Exp $
  3. require_once(dirname(__FILE__) . '/../parser.php');
  4. Mock::generate('SimpleHtmlSaxParser');
  5. Mock::generate('SimpleSaxListener');
  6. class TestOfParallelRegex extends UnitTestCase {
  7. function testNoPatterns() {
  8. $regex = &new ParallelRegex(false);
  9. $this->assertFalse($regex->match("Hello", $match));
  10. $this->assertEqual($match, "");
  11. }
  12. function testNoSubject() {
  13. $regex = &new ParallelRegex(false);
  14. $regex->addPattern(".*");
  15. $this->assertTrue($regex->match("", $match));
  16. $this->assertEqual($match, "");
  17. }
  18. function testMatchAll() {
  19. $regex = &new ParallelRegex(false);
  20. $regex->addPattern(".*");
  21. $this->assertTrue($regex->match("Hello", $match));
  22. $this->assertEqual($match, "Hello");
  23. }
  24. function testCaseSensitive() {
  25. $regex = &new ParallelRegex(true);
  26. $regex->addPattern("abc");
  27. $this->assertTrue($regex->match("abcdef", $match));
  28. $this->assertEqual($match, "abc");
  29. $this->assertTrue($regex->match("AAABCabcdef", $match));
  30. $this->assertEqual($match, "abc");
  31. }
  32. function testCaseInsensitive() {
  33. $regex = &new ParallelRegex(false);
  34. $regex->addPattern("abc");
  35. $this->assertTrue($regex->match("abcdef", $match));
  36. $this->assertEqual($match, "abc");
  37. $this->assertTrue($regex->match("AAABCabcdef", $match));
  38. $this->assertEqual($match, "ABC");
  39. }
  40. function testMatchMultiple() {
  41. $regex = &new ParallelRegex(true);
  42. $regex->addPattern("abc");
  43. $regex->addPattern("ABC");
  44. $this->assertTrue($regex->match("abcdef", $match));
  45. $this->assertEqual($match, "abc");
  46. $this->assertTrue($regex->match("AAABCabcdef", $match));
  47. $this->assertEqual($match, "ABC");
  48. $this->assertFalse($regex->match("Hello", $match));
  49. }
  50. function testPatternLabels() {
  51. $regex = &new ParallelRegex(false);
  52. $regex->addPattern("abc", "letter");
  53. $regex->addPattern("123", "number");
  54. $this->assertIdentical($regex->match("abcdef", $match), "letter");
  55. $this->assertEqual($match, "abc");
  56. $this->assertIdentical($regex->match("0123456789", $match), "number");
  57. $this->assertEqual($match, "123");
  58. }
  59. }
  60. class TestOfStateStack extends UnitTestCase {
  61. function testStartState() {
  62. $stack = &new SimpleStateStack("one");
  63. $this->assertEqual($stack->getCurrent(), "one");
  64. }
  65. function testExhaustion() {
  66. $stack = &new SimpleStateStack("one");
  67. $this->assertFalse($stack->leave());
  68. }
  69. function testStateMoves() {
  70. $stack = &new SimpleStateStack("one");
  71. $stack->enter("two");
  72. $this->assertEqual($stack->getCurrent(), "two");
  73. $stack->enter("three");
  74. $this->assertEqual($stack->getCurrent(), "three");
  75. $this->assertTrue($stack->leave());
  76. $this->assertEqual($stack->getCurrent(), "two");
  77. $stack->enter("third");
  78. $this->assertEqual($stack->getCurrent(), "third");
  79. $this->assertTrue($stack->leave());
  80. $this->assertTrue($stack->leave());
  81. $this->assertEqual($stack->getCurrent(), "one");
  82. }
  83. }
  84. class TestParser {
  85. function accept() {
  86. }
  87. function a() {
  88. }
  89. function b() {
  90. }
  91. }
  92. Mock::generate('TestParser');
  93. class TestOfLexer extends UnitTestCase {
  94. function testEmptyPage() {
  95. $handler = &new MockTestParser();
  96. $handler->expectNever("accept");
  97. $handler->setReturnValue("accept", true);
  98. $handler->expectNever("accept");
  99. $handler->setReturnValue("accept", true);
  100. $lexer = &new SimpleLexer($handler);
  101. $lexer->addPattern("a+");
  102. $this->assertTrue($lexer->parse(""));
  103. }
  104. function testSinglePattern() {
  105. $handler = &new MockTestParser();
  106. $handler->expectArgumentsAt(0, "accept", array("aaa", LEXER_MATCHED));
  107. $handler->expectArgumentsAt(1, "accept", array("x", LEXER_UNMATCHED));
  108. $handler->expectArgumentsAt(2, "accept", array("a", LEXER_MATCHED));
  109. $handler->expectArgumentsAt(3, "accept", array("yyy", LEXER_UNMATCHED));
  110. $handler->expectArgumentsAt(4, "accept", array("a", LEXER_MATCHED));
  111. $handler->expectArgumentsAt(5, "accept", array("x", LEXER_UNMATCHED));
  112. $handler->expectArgumentsAt(6, "accept", array("aaa", LEXER_MATCHED));
  113. $handler->expectArgumentsAt(7, "accept", array("z", LEXER_UNMATCHED));
  114. $handler->expectCallCount("accept", 8);
  115. $handler->setReturnValue("accept", true);
  116. $lexer = &new SimpleLexer($handler);
  117. $lexer->addPattern("a+");
  118. $this->assertTrue($lexer->parse("aaaxayyyaxaaaz"));
  119. }
  120. function testMultiplePattern() {
  121. $handler = &new MockTestParser();
  122. $target = array("a", "b", "a", "bb", "x", "b", "a", "xxxxxx", "a", "x");
  123. for ($i = 0; $i < count($target); $i++) {
  124. $handler->expectArgumentsAt($i, "accept", array($target[$i], '*'));
  125. }
  126. $handler->expectCallCount("accept", count($target));
  127. $handler->setReturnValue("accept", true);
  128. $lexer = &new SimpleLexer($handler);
  129. $lexer->addPattern("a+");
  130. $lexer->addPattern("b+");
  131. $this->assertTrue($lexer->parse("ababbxbaxxxxxxax"));
  132. }
  133. }
  134. class TestOfLexerModes extends UnitTestCase {
  135. function testIsolatedPattern() {
  136. $handler = &new MockTestParser();
  137. $handler->expectArgumentsAt(0, "a", array("a", LEXER_MATCHED));
  138. $handler->expectArgumentsAt(1, "a", array("b", LEXER_UNMATCHED));
  139. $handler->expectArgumentsAt(2, "a", array("aa", LEXER_MATCHED));
  140. $handler->expectArgumentsAt(3, "a", array("bxb", LEXER_UNMATCHED));
  141. $handler->expectArgumentsAt(4, "a", array("aaa", LEXER_MATCHED));
  142. $handler->expectArgumentsAt(5, "a", array("x", LEXER_UNMATCHED));
  143. $handler->expectArgumentsAt(6, "a", array("aaaa", LEXER_MATCHED));
  144. $handler->expectArgumentsAt(7, "a", array("x", LEXER_UNMATCHED));
  145. $handler->expectCallCount("a", 8);
  146. $handler->setReturnValue("a", true);
  147. $lexer = &new SimpleLexer($handler, "a");
  148. $lexer->addPattern("a+", "a");
  149. $lexer->addPattern("b+", "b");
  150. $this->assertTrue($lexer->parse("abaabxbaaaxaaaax"));
  151. }
  152. function testModeChange() {
  153. $handler = &new MockTestParser();
  154. $handler->expectArgumentsAt(0, "a", array("a", LEXER_MATCHED));
  155. $handler->expectArgumentsAt(1, "a", array("b", LEXER_UNMATCHED));
  156. $handler->expectArgumentsAt(2, "a", array("aa", LEXER_MATCHED));
  157. $handler->expectArgumentsAt(3, "a", array("b", LEXER_UNMATCHED));
  158. $handler->expectArgumentsAt(4, "a", array("aaa", LEXER_MATCHED));
  159. $handler->expectArgumentsAt(0, "b", array(":", LEXER_ENTER));
  160. $handler->expectArgumentsAt(1, "b", array("a", LEXER_UNMATCHED));
  161. $handler->expectArgumentsAt(2, "b", array("b", LEXER_MATCHED));
  162. $handler->expectArgumentsAt(3, "b", array("a", LEXER_UNMATCHED));
  163. $handler->expectArgumentsAt(4, "b", array("bb", LEXER_MATCHED));
  164. $handler->expectArgumentsAt(5, "b", array("a", LEXER_UNMATCHED));
  165. $handler->expectArgumentsAt(6, "b", array("bbb", LEXER_MATCHED));
  166. $handler->expectArgumentsAt(7, "b", array("a", LEXER_UNMATCHED));
  167. $handler->expectCallCount("a", 5);
  168. $handler->expectCallCount("b", 8);
  169. $handler->setReturnValue("a", true);
  170. $handler->setReturnValue("b", true);
  171. $lexer = &new SimpleLexer($handler, "a");
  172. $lexer->addPattern("a+", "a");
  173. $lexer->addEntryPattern(":", "a", "b");
  174. $lexer->addPattern("b+", "b");
  175. $this->assertTrue($lexer->parse("abaabaaa:ababbabbba"));
  176. }
  177. function testNesting() {
  178. $handler = &new MockTestParser();
  179. $handler->setReturnValue("a", true);
  180. $handler->setReturnValue("b", true);
  181. $handler->expectArgumentsAt(0, "a", array("aa", LEXER_MATCHED));
  182. $handler->expectArgumentsAt(1, "a", array("b", LEXER_UNMATCHED));
  183. $handler->expectArgumentsAt(2, "a", array("aa", LEXER_MATCHED));
  184. $handler->expectArgumentsAt(3, "a", array("b", LEXER_UNMATCHED));
  185. $handler->expectArgumentsAt(0, "b", array("(", LEXER_ENTER));
  186. $handler->expectArgumentsAt(1, "b", array("bb", LEXER_MATCHED));
  187. $handler->expectArgumentsAt(2, "b", array("a", LEXER_UNMATCHED));
  188. $handler->expectArgumentsAt(3, "b", array("bb", LEXER_MATCHED));
  189. $handler->expectArgumentsAt(4, "b", array(")", LEXER_EXIT));
  190. $handler->expectArgumentsAt(4, "a", array("aa", LEXER_MATCHED));
  191. $handler->expectArgumentsAt(5, "a", array("b", LEXER_UNMATCHED));
  192. $handler->expectCallCount("a", 6);
  193. $handler->expectCallCount("b", 5);
  194. $lexer = &new SimpleLexer($handler, "a");
  195. $lexer->addPattern("a+", "a");
  196. $lexer->addEntryPattern("(", "a", "b");
  197. $lexer->addPattern("b+", "b");
  198. $lexer->addExitPattern(")", "b");
  199. $this->assertTrue($lexer->parse("aabaab(bbabb)aab"));
  200. }
  201. function testSingular() {
  202. $handler = &new MockTestParser();
  203. $handler->setReturnValue("a", true);
  204. $handler->setReturnValue("b", true);
  205. $handler->expectArgumentsAt(0, "a", array("aa", LEXER_MATCHED));
  206. $handler->expectArgumentsAt(1, "a", array("aa", LEXER_MATCHED));
  207. $handler->expectArgumentsAt(2, "a", array("xx", LEXER_UNMATCHED));
  208. $handler->expectArgumentsAt(3, "a", array("xx", LEXER_UNMATCHED));
  209. $handler->expectArgumentsAt(0, "b", array("b", LEXER_SPECIAL));
  210. $handler->expectArgumentsAt(1, "b", array("bbb", LEXER_SPECIAL));
  211. $handler->expectCallCount("a", 4);
  212. $handler->expectCallCount("b", 2);
  213. $lexer = &new SimpleLexer($handler, "a");
  214. $lexer->addPattern("a+", "a");
  215. $lexer->addSpecialPattern("b+", "a", "b");
  216. $this->assertTrue($lexer->parse("aabaaxxbbbxx"));
  217. }
  218. function testUnwindTooFar() {
  219. $handler = &new MockTestParser();
  220. $handler->setReturnValue("a", true);
  221. $handler->expectArgumentsAt(0, "a", array("aa", LEXER_MATCHED));
  222. $handler->expectArgumentsAt(1, "a", array(")", LEXER_EXIT));
  223. $handler->expectCallCount("a", 2);
  224. $lexer = &new SimpleLexer($handler, "a");
  225. $lexer->addPattern("a+", "a");
  226. $lexer->addExitPattern(")", "a");
  227. $this->assertFalse($lexer->parse("aa)aa"));
  228. }
  229. }
  230. class TestOfLexerHandlers extends UnitTestCase {
  231. function testModeMapping() {
  232. $handler = &new MockTestParser();
  233. $handler->setReturnValue("a", true);
  234. $handler->expectArgumentsAt(0, "a", array("aa", LEXER_MATCHED));
  235. $handler->expectArgumentsAt(1, "a", array("(", LEXER_ENTER));
  236. $handler->expectArgumentsAt(2, "a", array("bb", LEXER_MATCHED));
  237. $handler->expectArgumentsAt(3, "a", array("a", LEXER_UNMATCHED));
  238. $handler->expectArgumentsAt(4, "a", array("bb", LEXER_MATCHED));
  239. $handler->expectArgumentsAt(5, "a", array(")", LEXER_EXIT));
  240. $handler->expectArgumentsAt(6, "a", array("b", LEXER_UNMATCHED));
  241. $handler->expectCallCount("a", 7);
  242. $lexer = &new SimpleLexer($handler, "mode_a");
  243. $lexer->addPattern("a+", "mode_a");
  244. $lexer->addEntryPattern("(", "mode_a", "mode_b");
  245. $lexer->addPattern("b+", "mode_b");
  246. $lexer->addExitPattern(")", "mode_b");
  247. $lexer->mapHandler("mode_a", "a");
  248. $lexer->mapHandler("mode_b", "a");
  249. $this->assertTrue($lexer->parse("aa(bbabb)b"));
  250. }
  251. }
  252. class TestOfSimpleHtmlLexer extends UnitTestCase {
  253. function &createParser() {
  254. $parser = &new MockSimpleHtmlSaxParser();
  255. $parser->setReturnValue('acceptStartToken', true);
  256. $parser->setReturnValue('acceptEndToken', true);
  257. $parser->setReturnValue('acceptAttributeToken', true);
  258. $parser->setReturnValue('acceptEntityToken', true);
  259. $parser->setReturnValue('acceptTextToken', true);
  260. $parser->setReturnValue('ignore', true);
  261. return $parser;
  262. }
  263. function testNoContent() {
  264. $parser = &$this->createParser();
  265. $parser->expectNever('acceptStartToken');
  266. $parser->expectNever('acceptEndToken');
  267. $parser->expectNever('acceptAttributeToken');
  268. $parser->expectNever('acceptEntityToken');
  269. $parser->expectNever('acceptTextToken');
  270. $lexer = &new SimpleHtmlLexer($parser);
  271. $this->assertTrue($lexer->parse(''));
  272. }
  273. function testUninteresting() {
  274. $parser = &$this->createParser();
  275. $parser->expectOnce('acceptTextToken', array('<html></html>', '*'));
  276. $lexer = &new SimpleHtmlLexer($parser);
  277. $this->assertTrue($lexer->parse('<html></html>'));
  278. }
  279. function testSkipCss() {
  280. $parser = &$this->createParser();
  281. $parser->expectNever('acceptTextToken');
  282. $parser->expectAtLeastOnce('ignore');
  283. $lexer = &new SimpleHtmlLexer($parser);
  284. $this->assertTrue($lexer->parse("<style>Lot's of styles</style>"));
  285. }
  286. function testSkipJavaScript() {
  287. $parser = &$this->createParser();
  288. $parser->expectNever('acceptTextToken');
  289. $parser->expectAtLeastOnce('ignore');
  290. $lexer = &new SimpleHtmlLexer($parser);
  291. $this->assertTrue($lexer->parse("<SCRIPT>Javascript code {';:^%^%�$'@\"*(}</SCRIPT>"));
  292. }
  293. function testSkipHtmlComments() {
  294. $parser = &$this->createParser();
  295. $parser->expectNever('acceptTextToken');
  296. $parser->expectAtLeastOnce('ignore');
  297. $lexer = &new SimpleHtmlLexer($parser);
  298. $this->assertTrue($lexer->parse("<!-- <title>title</title><style>styles</style> -->"));
  299. }
  300. function testTagWithNoAttributes() {
  301. $parser = &$this->createParser();
  302. $parser->expectAt(0, 'acceptStartToken', array('<title', '*'));
  303. $parser->expectAt(1, 'acceptStartToken', array('>', '*'));
  304. $parser->expectCallCount('acceptStartToken', 2);
  305. $parser->expectOnce('acceptTextToken', array('Hello', '*'));
  306. $parser->expectOnce('acceptEndToken', array('</title>', '*'));
  307. $lexer = &new SimpleHtmlLexer($parser);
  308. $this->assertTrue($lexer->parse('<title>Hello</title>'));
  309. }
  310. function testTagWithAttributes() {
  311. $parser = &$this->createParser();
  312. $parser->expectOnce('acceptTextToken', array('label', '*'));
  313. $parser->expectAt(0, 'acceptStartToken', array('<a', '*'));
  314. $parser->expectAt(1, 'acceptStartToken', array('href', '*'));
  315. $parser->expectAt(2, 'acceptStartToken', array('>', '*'));
  316. $parser->expectCallCount('acceptStartToken', 3);
  317. $parser->expectAt(0, 'acceptAttributeToken', array('= "', '*'));
  318. $parser->expectAt(1, 'acceptAttributeToken', array('here.html', '*'));
  319. $parser->expectAt(2, 'acceptAttributeToken', array('"', '*'));
  320. $parser->expectCallCount('acceptAttributeToken', 3);
  321. $parser->expectOnce('acceptEndToken', array('</a>', '*'));
  322. $lexer = &new SimpleHtmlLexer($parser);
  323. $this->assertTrue($lexer->parse('<a href = "here.html">label</a>'));
  324. }
  325. }
  326. class TestOfHtmlSaxParser extends UnitTestCase {
  327. function &createListener() {
  328. $listener = &new MockSimpleSaxListener();
  329. $listener->setReturnValue('startElement', true);
  330. $listener->setReturnValue('addContent', true);
  331. $listener->setReturnValue('endElement', true);
  332. return $listener;
  333. }
  334. function testFramesetTag() {
  335. $listener = &$this->createListener();
  336. $listener->expectOnce('startElement', array('frameset', array()));
  337. $listener->expectOnce('addContent', array('Frames'));
  338. $listener->expectOnce('endElement', array('frameset'));
  339. $parser = &new SimpleHtmlSaxParser($listener);
  340. $this->assertTrue($parser->parse('<frameset>Frames</frameset>'));
  341. }
  342. function testTagWithUnquotedAttributes() {
  343. $listener = &$this->createListener();
  344. $listener->expectOnce(
  345. 'startElement',
  346. array('input', array('name' => 'a.b.c', 'value' => 'd')));
  347. $parser = &new SimpleHtmlSaxParser($listener);
  348. $this->assertTrue($parser->parse('<input name=a.b.c value = d>'));
  349. }
  350. function testTagInsideContent() {
  351. $listener = &$this->createListener();
  352. $listener->expectOnce('startElement', array('a', array()));
  353. $listener->expectAt(0, 'addContent', array('<html>'));
  354. $listener->expectAt(1, 'addContent', array('</html>'));
  355. $parser = &new SimpleHtmlSaxParser($listener);
  356. $this->assertTrue($parser->parse('<html><a></a></html>'));
  357. }
  358. function testTagWithInternalContent() {
  359. $listener = &$this->createListener();
  360. $listener->expectOnce('startElement', array('a', array()));
  361. $listener->expectOnce('addContent', array('label'));
  362. $listener->expectOnce('endElement', array('a'));
  363. $parser = &new SimpleHtmlSaxParser($listener);
  364. $this->assertTrue($parser->parse('<a>label</a>'));
  365. }
  366. function testLinkAddress() {
  367. $listener = &$this->createListener();
  368. $listener->expectOnce('startElement', array('a', array('href' => 'here.html')));
  369. $listener->expectOnce('addContent', array('label'));
  370. $listener->expectOnce('endElement', array('a'));
  371. $parser = &new SimpleHtmlSaxParser($listener);
  372. $this->assertTrue($parser->parse("<a href = 'here.html'>label</a>"));
  373. }
  374. function testEncodedAttribute() {
  375. $listener = &$this->createListener();
  376. $listener->expectOnce('startElement', array('a', array('href' => 'here&there.html')));
  377. $listener->expectOnce('addContent', array('label'));
  378. $listener->expectOnce('endElement', array('a'));
  379. $parser = &new SimpleHtmlSaxParser($listener);
  380. $this->assertTrue($parser->parse("<a href = 'here&amp;there.html'>label</a>"));
  381. }
  382. function testTagWithId() {
  383. $listener = &$this->createListener();
  384. $listener->expectOnce('startElement', array('a', array('id' => '0')));
  385. $listener->expectOnce('addContent', array('label'));
  386. $listener->expectOnce('endElement', array('a'));
  387. $parser = &new SimpleHtmlSaxParser($listener);
  388. $this->assertTrue($parser->parse('<a id="0">label</a>'));
  389. }
  390. function testTagWithEmptyAttributes() {
  391. $listener = &$this->createListener();
  392. $listener->expectOnce(
  393. 'startElement',
  394. array('option', array('value' => '', 'selected' => '')));
  395. $listener->expectOnce('addContent', array('label'));
  396. $listener->expectOnce('endElement', array('option'));
  397. $parser = &new SimpleHtmlSaxParser($listener);
  398. $this->assertTrue($parser->parse('<option value="" selected>label</option>'));
  399. }
  400. function testComplexTagWithLotsOfCaseVariations() {
  401. $listener = &$this->createListener();
  402. $listener->expectOnce(
  403. 'startElement',
  404. array('a', array('href' => 'here.html', 'style' => "'cool'")));
  405. $listener->expectOnce('addContent', array('label'));
  406. $listener->expectOnce('endElement', array('a'));
  407. $parser = &new SimpleHtmlSaxParser($listener);
  408. $this->assertTrue($parser->parse('<A HREF = \'here.html\' Style="\'cool\'">label</A>'));
  409. }
  410. function testXhtmlSelfClosingTag() {
  411. $listener = &$this->createListener();
  412. $listener->expectOnce(
  413. 'startElement',
  414. array('input', array('type' => 'submit', 'name' => 'N', 'value' => 'V')));
  415. $parser = &new SimpleHtmlSaxParser($listener);
  416. $this->assertTrue($parser->parse('<input type="submit" name="N" value="V" />'));
  417. }
  418. function testNestedFrameInFrameset() {
  419. $listener = &$this->createListener();
  420. $listener->expectAt(0, 'startElement', array('frameset', array()));
  421. $listener->expectAt(1, 'startElement', array('frame', array('src' => 'frame.html')));
  422. $listener->expectCallCount('startElement', 2);
  423. $listener->expectOnce('addContent', array('<noframes>Hello</noframes>'));
  424. $listener->expectOnce('endElement', array('frameset'));
  425. $parser = &new SimpleHtmlSaxParser($listener);
  426. $this->assertTrue($parser->parse(
  427. '<frameset><frame src="frame.html"><noframes>Hello</noframes></frameset>'));
  428. }
  429. }
  430. class TestOfTextExtraction extends UnitTestCase {
  431. function testSpaceNormalisation() {
  432. $this->assertEqual(
  433. SimpleHtmlSaxParser::normalise("\nOne\tTwo \nThree\t"),
  434. 'One Two Three');
  435. }
  436. function testTagSuppression() {
  437. $this->assertEqual(
  438. SimpleHtmlSaxParser::normalise('<b>Hello</b>'),
  439. 'Hello');
  440. }
  441. function testAdjoiningTagSuppression() {
  442. $this->assertEqual(
  443. SimpleHtmlSaxParser::normalise('<b>Hello</b><em>Goodbye</em>'),
  444. 'HelloGoodbye');
  445. }
  446. function testExtractImageAltTextWithDifferentQuotes() {
  447. $this->assertEqual(
  448. SimpleHtmlSaxParser::normalise('<img alt="One"><img alt=\'Two\'><img alt=Three>'),
  449. 'One Two Three');
  450. }
  451. function testExtractImageAltTextMultipleTimes() {
  452. $this->assertEqual(
  453. SimpleHtmlSaxParser::normalise('<img alt="One"><img alt="Two"><img alt="Three">'),
  454. 'One Two Three');
  455. }
  456. function testHtmlEntityTranslation() {
  457. $this->assertEqual(
  458. SimpleHtmlSaxParser::normalise('&lt;&gt;&quot;&amp;'),
  459. '<>"&');
  460. }
  461. }
  462. ?>