OLD | NEW |
(Empty) | |
| 1 var namespaces = { |
| 2 "html":"http://www.w3.org/1999/xhtml", |
| 3 "mathml":"http://www.w3.org/1998/Math/MathML", |
| 4 "svg":"http://www.w3.org/2000/svg", |
| 5 "xlink":"http://www.w3.org/1999/xlink", |
| 6 "xml":"http://www.w3.org/XML/1998/namespace", |
| 7 "xmlns":"http://www.w3.org/2000/xmlns/" |
| 8 }; |
| 9 |
| 10 var prefixes = {}; |
| 11 for (var prefix in namespaces) { |
| 12 if (namespaces.hasOwnProperty(prefix)) { |
| 13 prefixes[namespaces[prefix]] = prefix; |
| 14 } |
| 15 } |
| 16 prefixes[namespaces["mathml"]] = "math"; |
| 17 |
| 18 function format(format_string) { |
| 19 var insertions = Array.prototype.slice.call(arguments, 1); |
| 20 var regexp = /%s/g; |
| 21 var match_count = 0; |
| 22 var rv = format_string.replace(regexp, function(match) { |
| 23 var rv = insertions[match_count]; |
| 24 match_count++; |
| 25 return rv; |
| 26 }); |
| 27 return rv; |
| 28 } |
| 29 |
| 30 function test_serializer(element) { |
| 31 element.normalize(); |
| 32 var lines = []; |
| 33 function serialize_element(element, indent) { |
| 34 var indent_spaces = (new Array(indent)).join(" "); |
| 35 switch(element.nodeType) { |
| 36 case Node.DOCUMENT_TYPE_NODE: |
| 37 if (element.name) { |
| 38 if (element.publicId || element.systemId) { |
| 39 var publicId = element.publicId ? element.publicId : ""; |
| 40 var systemId = element.systemId ? element.systemId : ""; |
| 41 lines.push(format("|%s<!DOCTYPE %s \"%s\" \"%s\">", indent_spaces, |
| 42 element.name, publicId, systemId)); |
| 43 } else { |
| 44 lines.push(format("|%s<!DOCTYPE %s>", indent_spaces, |
| 45 element.name)); |
| 46 } |
| 47 } else { |
| 48 lines.push(format("|%s<!DOCTYPE >", indent_spaces)); |
| 49 } |
| 50 break; |
| 51 case Node.DOCUMENT_NODE: |
| 52 lines.push("#document"); |
| 53 break; |
| 54 case Node.DOCUMENT_FRAGMENT_NODE: |
| 55 lines.push("#document-fragment"); |
| 56 break; |
| 57 case Node.COMMENT_NODE: |
| 58 lines.push(format("|%s<!-- %s -->", indent_spaces, element.nodeValue)); |
| 59 break; |
| 60 case Node.TEXT_NODE: |
| 61 lines.push(format("|%s\"%s\"", indent_spaces, element.nodeValue)); |
| 62 break; |
| 63 case Node.ELEMENT_NODE: |
| 64 if (element.getAttribute("data-skip") !== null) { |
| 65 return; |
| 66 } |
| 67 if (element.namespaceURI !== null && element.namespaceURI !== namespaces
.html) { |
| 68 var name = format("%s %s", prefixes[element.namespaceURI], |
| 69 element.localName); |
| 70 } else { |
| 71 var name = element.localName; |
| 72 } |
| 73 lines.push(format("|%s<%s>", indent_spaces, name)); |
| 74 |
| 75 var attributes = Array.prototype.map.call( |
| 76 element.attributes, |
| 77 function(attr) { |
| 78 var name = (attr.namespaceURI ? prefixes[attr.namespaceURI] + " " : "
") + |
| 79 attr.localName; |
| 80 return [name, attr.value]; |
| 81 }); |
| 82 attributes.sort(function (a, b) { |
| 83 var x = a[0]; |
| 84 var y = b[0]; |
| 85 if (x === y) { |
| 86 return 0; |
| 87 } |
| 88 return x > y ? 1 : -1; |
| 89 }); |
| 90 |
| 91 attributes.forEach( |
| 92 function(attr) { |
| 93 var indent_spaces = (new Array(indent + 2)).join(" "); |
| 94 lines.push(format("|%s%s=\"%s\"", indent_spaces, attr[0], attr[1])); |
| 95 } |
| 96 ); |
| 97 break; |
| 98 } |
| 99 indent += 2; |
| 100 Array.prototype.forEach.call(element.childNodes, |
| 101 function(node) { |
| 102 serialize_element(node, indent); |
| 103 }); |
| 104 } |
| 105 serialize_element(element, 0); |
| 106 return lines.join("\n"); |
| 107 } |
| 108 |
| 109 function parse_query() { |
| 110 var query = location.search.slice(1); |
| 111 var vars = query.split("&"); |
| 112 var fields = vars.map(function (x) { |
| 113 var split = x.split("="); |
| 114 return [split[0], split.slice(1).join("=")]; |
| 115 }); |
| 116 return fields; |
| 117 } |
| 118 |
| 119 function get_type() { |
| 120 var run_type = "uri"; |
| 121 var fields = parse_query(); |
| 122 fields.forEach(function(x) { |
| 123 if(x[0] == "run_type") { |
| 124 run_type = x[1]; |
| 125 } |
| 126 }); |
| 127 return run_type; |
| 128 }; |
| 129 |
| 130 var test_in_data_uri = get_test_func(function (iframe, uri_encoded_input) { |
| 131 iframe.src = "data:text/html;charset=utf8
," + uri_encoded_input; |
| 132 }); |
| 133 |
| 134 var test_document_write = get_test_func(function(iframe, uri_encoded_input) { |
| 135 iframe.contentDocument.open(); |
| 136 var input = decodeURIComponent(uri_enc
oded_input); |
| 137 iframe.contentDocument.write(input); |
| 138 iframe.contentDocument.close(); |
| 139 }); |
| 140 |
| 141 var test_document_write_single = get_test_func(function(iframe, uri_encoded_inpu
t) { |
| 142 iframe.contentDocument.open(); |
| 143 var input = decodeURIComponent(
uri_encoded_input); |
| 144 for (var i=0; i< input.length;
i++) { |
| 145 iframe.contentDocument.write(
input[i]); |
| 146 } |
| 147 iframe.contentDocument.close(); |
| 148 }); |
| 149 |
| 150 function get_test_func(inject_func) { |
| 151 function test_func(iframe, t, test_id, uri_encoded_input, escaped_expected) { |
| 152 var expected = decodeURIComponent(escaped_expected); |
| 153 current_tests[iframe.id] = {test_id:test_id, |
| 154 uri_encoded_input:uri_encoded_input, |
| 155 expected:expected, |
| 156 actual:null |
| 157 }; |
| 158 |
| 159 iframe.onload = function() { |
| 160 t.step(function() { |
| 161 iframe.onload = null; |
| 162 var serialized_dom = test_serializer(iframe.contentDocument); |
| 163 current_tests[iframe.id].actual = serialized_dom; |
| 164 assert_equals(serialized_dom, expected); |
| 165 t.done(); |
| 166 } |
| 167 ); |
| 168 }; |
| 169 inject_func(iframe, uri_encoded_input); |
| 170 } |
| 171 return test_func; |
| 172 } |
| 173 |
| 174 function test_fragment(iframe, t, test_id, uri_encoded_input, escaped_expected,
container) { |
| 175 var input_string = decodeURIComponent(uri_encoded_input); |
| 176 var expected = decodeURIComponent(escaped_expected); |
| 177 current_tests[iframe.id] = { |
| 178 test_id:test_id, |
| 179 input:uri_encoded_input, |
| 180 expected:expected, |
| 181 actual:null, |
| 182 container:container |
| 183 }; |
| 184 |
| 185 var components = container.split(" "); |
| 186 var container_elem = null; |
| 187 if (components.length > 1) { |
| 188 var namespace = namespaces[components[0]]; |
| 189 container_elem = document.createElementNS(namespace, |
| 190 components[0] + ":" + |
| 191 components[1]); |
| 192 } else { |
| 193 container_elem = document.createElement(container); |
| 194 } |
| 195 container_elem.innerHTML = input_string; |
| 196 var serialized_dom = test_serializer(container_elem); |
| 197 current_tests[iframe.id].actual = serialized_dom; |
| 198 serialized_dom = convert_innerHTML(serialized_dom); |
| 199 assert_equals(serialized_dom, expected); |
| 200 t.done(); |
| 201 } |
| 202 |
| 203 function convert_innerHTML(serialized_dom) { |
| 204 var lines = serialized_dom.split("\n"); |
| 205 lines[0] = "#document"; |
| 206 return lines.join("\n"); |
| 207 } |
| 208 |
| 209 function print_diffs(test_id, uri_encoded_input, expected, actual, container) { |
| 210 container = container ? container : null; |
| 211 if (actual) { |
| 212 var diffs = mark_diffs(expected, actual); |
| 213 var expected_text = diffs[0]; |
| 214 var actual_text = diffs[1]; |
| 215 } else { |
| 216 var expected_text = expected; |
| 217 var actual_text = ""; |
| 218 } |
| 219 |
| 220 var tmpl = ["div", {"id":"${test_id}"}, |
| 221 ["h2", {}, "${test_id}"], |
| 222 function(vars) { |
| 223 if (vars.container !== null) { |
| 224 return ["div", {"class":"container"}, |
| 225 ["h3", {}, "innerHTML Container"], |
| 226 ["pre", {}, vars.container]]; |
| 227 } else { |
| 228 return null; |
| 229 } |
| 230 }, |
| 231 ["div", {"id":"input_${test_id}"}, ["h3", {}, "Input"], ["pre", {}
, |
| 232 ["code",
{}, decodeURIComponent(uri_encoded_input)]]], |
| 233 ["div", {"id":"expected_${test_id}"}, ["h3", {}, "Expected"], |
| 234 ["pre", {}, ["code", {}, expected_text]]], |
| 235 ["div", {"id":"actual_${test_id}"}, ["h3", {}, "Actual"], |
| 236 ["pre", {}, ["code", {}, actual_text]]] |
| 237 ]; |
| 238 |
| 239 var diff_dom = template.render(tmpl, {test_id:test_id, container:container}); |
| 240 document.body.appendChild(diff_dom); |
| 241 } |
| 242 |
| 243 var current_tests = {}; |
| 244 var iframe_map = {}; |
| 245 |
| 246 function init_tests(test_type) { |
| 247 var test_func = null; |
| 248 var test_funcs = { |
| 249 "write":test_document_write, |
| 250 "write_single":test_document_write_single, |
| 251 "uri":test_in_data_uri, |
| 252 "innerHTML":test_fragment |
| 253 }; |
| 254 var tests_started = 0; |
| 255 var tests_complete = 0; |
| 256 |
| 257 setup(function() { |
| 258 test_func = test_funcs[test_type]; |
| 259 |
| 260 var fails = []; |
| 261 |
| 262 add_result_callback(function(test) { |
| 263 tests_complete++; |
| 264 var iframe = document.getElementById(iframe_map[test.name]); |
| 265 if (test.status !== test.PASS) { |
| 266 fails.push(current_tests[iframe.id]); |
| 267 var new_iframe = document.createElement("iframe"); |
| 268 new_iframe.style.display = "none"; |
| 269 new_iframe.id = iframe.id; |
| 270 document.body.replaceChild(new_iframe, iframe); |
| 271 iframe = new_iframe; |
| 272 } |
| 273 if (tests_complete === order.length) { |
| 274 done(); |
| 275 } else if (tests_started < order.length) { |
| 276 test_next(iframe); |
| 277 } |
| 278 }); |
| 279 |
| 280 add_completion_callback(function() { |
| 281 fails.forEach(function(t) { |
| 282 print_diffs(t.test_id, t.uri_encoded_input, |
| 283 t.expected, t.actual); |
| 284 }); |
| 285 }); |
| 286 |
| 287 //Create the iframes we will use to test |
| 288 //in the innerHTML case these are not actually used |
| 289 //but it is convenient to reuse the same code |
| 290 for (var i=0; i<num_iframes; i++) { |
| 291 var iframe = document.createElement("iframe"); |
| 292 iframe.id = "iframe_" + i; |
| 293 iframe.style.display = "none"; |
| 294 document.body.appendChild(iframe); |
| 295 } |
| 296 }, |
| 297 {explicit_done:true}); |
| 298 |
| 299 function test_next(iframe) { |
| 300 var test_id = order[tests_started]; |
| 301 tests_started++; |
| 302 var x = tests[test_id]; |
| 303 var t = x[0]; |
| 304 iframe_map[t.name] = iframe.id; |
| 305 setTimeout(function() { |
| 306 t.step(function() { |
| 307 var string_uri_encoded_input = x[1]; |
| 308 var string_escaped_expected = x[2]; |
| 309 if (test_type === "innerHTML") { |
| 310 var container = x[3]; |
| 311 } |
| 312 test_func(iframe, t, test_id, string_uri_encoded_input, strin
g_escaped_expected, |
| 313 container); |
| 314 }); |
| 315 }, 0); |
| 316 } |
| 317 |
| 318 onload = function() { |
| 319 Array.prototype.forEach.call(document.getElementsByTagName("iframe"), |
| 320 function(iframe) { |
| 321 if (tests_started<order.length) { |
| 322 test_next(iframe); |
| 323 } |
| 324 }); |
| 325 }; |
| 326 } |
OLD | NEW |