// This library supports HTML5lib-style test cases. // // The HTMLlib test case format describes an actual DOM tree. For testing, and // particular for testing of DOM parsers and DOM parser-related functionality, // this has the advantage of being able to represent edge cases. // // Example: If `.replaceWithChildren` is called on the `` element as a // result of parsing `"

HelloWorld

"`, then this results in // a tree with two adjacent text nodes. This behaviour will affect subsequent // DOM operations and should thus be tested. The HTML5lib format makes it easy // to describe the expected result unambiguously. // // References: // - HTML5lib: https://github.com/html5lib // - HTML5lib testcases: https://github.com/html5lib/html5lib-tests/tree/master/tree-construction // - test case format description: // https://github.com/html5lib/html5lib-tests/blob/master/tree-construction/README.md // // The main "API" is: // // - parse_html5lib_testcases(string) // This returns an array of dictionaries, where the dictionary contains the // the text of the test file, keyed by the lines starting with a hashtag. // // E.g. #data\nbla results in [{data: "bla"}]. // // - html5lib_testcases_from_script() // Wrapper for parse_html5lib_testcases that gets the test data from a script // element with type "html5lib-tests". This allows to specify the test data // in the test file, but requires working around closing script tags. // // - html5lib_testcases_from_response(response_promise) // Wrapper for parse_html5lib_testcases that gets the data from a Response // Promise, as is returned from `fetch()`, and returns a Promise for the array // of testcases. This allows getting the test dat from a text resource. // // - build_node_tree(node, documentstr) // This builds a node tree from the "#document" string from a testcase, and // appends it to the node argument. Returns node. // // - assert_subtree_equals(node1, node2) // Asserts that the child trees of node1 and node2 are equals. This // recursively descends the trees. // // - assert_testcase(node, testcase) // Wrapper for build_node_tree and assert_subtree_equals, for use with a // result of parse_html5lib_testcases. // function html5lib_testcases_from_script() { return parse_html5lib_testcases( document.querySelector("script[type='html5lib-tests']").textContent); } function html5lib_testcases_from_response(response_promise) { return response_promise .then(response => response.text()) .then(parse_html5lib_testcases); } function add_html5lib_testcase(testcases, current) { for (const item in current) { current[item] = current[item].join("\n"); } if (Object.entries(current).length) { testcases.push(current); } } function parse_html5lib_testcases(content) { const testcases = []; var state = undefined; var current = {}; for (const line of content.split("\n")) { if (!line) { add_html5lib_testcase(testcases, current); state = undefined; current = {}; } else if (line[0] == "#") { state = line.substring(1); current[state] = []; } else if (state) { current[state].push(line); } else { // Error handling is for another day. } } return testcases; } function get_child_at(node, level) { for (i = 0; i < level; i++) { if (is_html_template(node)) { // For