1var assert = require('assert'), 2 path = require('path'), 3 HTML = require('../../lib/common/html'), 4 parse5 = require('../../index'), 5 Parser = parse5.Parser, 6 Serializer = parse5.Serializer, 7 TestUtils = require('../test_utils'); 8 9 10TestUtils.generateTestsForEachTreeAdapter(module.exports, function (_test, treeAdapter) { 11 function getFullTestName(test) { 12 return ['Parser(', test.dirName, ') - ', test.idx, '.', test.setName, ' - ', test.input].join(''); 13 } 14 15 function getLocationFullTestName(test) { 16 return ['Parser(Location info) - ', test.name].join(''); 17 } 18 19 function walkTree(document, handler) { 20 for (var stack = treeAdapter.getChildNodes(document).slice(); stack.length;) { 21 var node = stack.shift(), 22 children = treeAdapter.getChildNodes(node); 23 24 handler(node); 25 26 if (children && children.length) 27 stack = children.concat(stack); 28 } 29 } 30 31 //Here we go.. 32 TestUtils.loadTreeConstructionTestData([ 33 path.join(__dirname, '../data/tree_construction'), 34 path.join(__dirname, '../data/tree_construction_regression'), 35 path.join(__dirname, '../data/tree_construction_options') 36 ], treeAdapter).forEach(function (test) { 37 _test[getFullTestName(test)] = function () { 38 var parser = new Parser(treeAdapter, { 39 decodeHtmlEntities: !test.disableEntitiesDecoding 40 }), 41 result = test.fragmentContext ? 42 parser.parseFragment(test.input, test.fragmentContext) : 43 parser.parse(test.input), 44 actual = TestUtils.serializeToTestDataFormat(result, treeAdapter), 45 msg = TestUtils.prettyPrintParserAssertionArgs(actual, test.expected); 46 47 assert.strictEqual(actual, test.expected, msg); 48 }; 49 }); 50 51 52 //Location info tests 53 TestUtils.loadSerializationTestData(path.join(__dirname, '../data/serialization')).forEach(function (test) { 54 //NOTE: the idea of this test is the following: we parse document with the location info. 55 //Then for each node in the tree we run serializer and compare results with the substring 56 //obtained via location info from the expected serialization results. 57 _test[getLocationFullTestName(test)] = function () { 58 var parser = new Parser(treeAdapter, { 59 locationInfo: true, 60 decodeHtmlEntities: false 61 }), 62 serializer = new Serializer(treeAdapter, { 63 encodeHtmlEntities: false 64 }), 65 html = test.expected, 66 document = parser.parse(html); 67 68 walkTree(document, function (node) { 69 if (node.__location !== null) { 70 var fragment = treeAdapter.createDocumentFragment(); 71 72 treeAdapter.appendChild(fragment, node); 73 74 var expected = serializer.serialize(fragment), 75 actual = html.substring(node.__location.start, node.__location.end); 76 77 expected = TestUtils.removeNewLines(expected); 78 actual = TestUtils.removeNewLines(actual); 79 80 //NOTE: use ok assertion, so output will not be polluted by the whole content of the strings 81 assert.ok(actual === expected, TestUtils.getStringDiffMsg(actual, expected)); 82 83 if (node.__location.startTag) { 84 //NOTE: Based on the idea that the serialized fragment starts with the startTag 85 var length = node.__location.startTag.end - node.__location.startTag.start, 86 expectedStartTag = serializer.serialize(fragment).substring(0, length), 87 actualStartTag = html.substring(node.__location.startTag.start, node.__location.startTag.end); 88 89 expectedStartTag = TestUtils.removeNewLines(expectedStartTag); 90 actualStartTag = TestUtils.removeNewLines(actualStartTag); 91 92 assert.ok(expectedStartTag === actualStartTag, TestUtils.getStringDiffMsg(actualStartTag, expectedStartTag)); 93 } 94 95 if (node.__location.endTag) { 96 //NOTE: Based on the idea that the serialized fragment ends with the endTag 97 var length = node.__location.endTag.end - node.__location.endTag.start, 98 expectedEndTag = serializer.serialize(fragment).slice(-length), 99 actualEndTag = html.substring(node.__location.endTag.start, node.__location.endTag.end); 100 101 expectedEndTag = TestUtils.removeNewLines(expectedEndTag); 102 actualEndTag = TestUtils.removeNewLines(actualEndTag); 103 104 assert.ok(expectedEndTag === actualEndTag, TestUtils.getStringDiffMsg(actualEndTag, expectedEndTag)); 105 } 106 } 107 }); 108 }; 109 }); 110 111 exports['Regression - location info for the implicitly generated <body>, <html> and <head> (GH-44)'] = function () { 112 var html = '</head><div class="test"></div></body></html>', 113 parser = new Parser(treeAdapter, { 114 locationInfo: true, 115 decodeHtmlEntities: false 116 }), 117 document = parser.parse(html); 118 119 //NOTE: location info for all implicitly generated elements should be null 120 walkTree(document, function (node) { 121 if (treeAdapter.getTagName(node) !== HTML.TAG_NAMES.DIV) 122 assert.strictEqual(node.__location, null); 123 }); 124 }; 125}); 126 127 128exports['Regression - HTML5 Legacy Doctype Misparsed with htmlparser2 tree adapter (GH-45)'] = function () { 129 var html = '<!DOCTYPE html SYSTEM "about:legacy-compat"><html><head></head><body>Hi there!</body></html>', 130 parser = new Parser(parse5.TreeAdapters.htmlparser2), 131 document = parser.parse(html); 132 133 assert.strictEqual(document.childNodes[0].data, '!DOCTYPE html SYSTEM "about:legacy-compat"'); 134}; 135 136 137