diff options
author | bptato <nincsnevem662@gmail.com> | 2024-04-21 21:26:27 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-04-21 21:28:45 +0200 |
commit | e3d9ee2c6224cd30bf56e24f7988899e0e3985c1 (patch) | |
tree | 31116d7d751d058f32bf43313c12673423e8d8be /test/js | |
parent | ba88f015ea500bcc574b621392c721ef2c9dbcd0 (diff) | |
download | chawan-e3d9ee2c6224cd30bf56e24f7988899e0e3985c1.tar.gz |
test: add js & layout tests
(Sadly some layout tests still fail.)
Diffstat (limited to 'test/js')
-rw-r--r-- | test/js/all.expected | 1 | ||||
-rw-r--r-- | test/js/array_proto_at.html | 9 | ||||
-rw-r--r-- | test/js/asserts.js | 19 | ||||
-rw-r--r-- | test/js/base64.html | 44 | ||||
-rw-r--r-- | test/js/class.html | 23 | ||||
-rw-r--r-- | test/js/config.toml | 13 | ||||
-rw-r--r-- | test/js/console.html | 5 | ||||
-rw-r--r-- | test/js/data_url.html | 4 | ||||
-rw-r--r-- | test/js/date.html | 14 | ||||
-rw-r--r-- | test/js/document.html | 11 | ||||
-rw-r--r-- | test/js/documentall.html | 19 | ||||
-rw-r--r-- | test/js/docwrite1.html | 101 | ||||
-rw-r--r-- | test/js/docwrite2.html | 31 | ||||
-rw-r--r-- | test/js/docwrite3.html | 43 | ||||
-rw-r--r-- | test/js/docwrite4.html | 49 | ||||
-rw-r--r-- | test/js/encode_decode.html | 39 | ||||
-rw-r--r-- | test/js/htmlcollection.html | 22 | ||||
-rw-r--r-- | test/js/outerhtml.html | 9 | ||||
-rw-r--r-- | test/js/prev_next_parent_child.html | 22 | ||||
-rw-r--r-- | test/js/query_selector_plus.html | 11 | ||||
-rw-r--r-- | test/js/reflect.html | 18 | ||||
-rwxr-xr-x | test/js/run_js_tests.sh | 13 | ||||
-rw-r--r-- | test/js/settimeout.html | 8 | ||||
-rw-r--r-- | test/js/template.html | 8 | ||||
-rw-r--r-- | test/js/text.html | 8 | ||||
-rw-r--r-- | test/js/window.html | 11 |
26 files changed, 555 insertions, 0 deletions
diff --git a/test/js/all.expected b/test/js/all.expected new file mode 100644 index 00000000..35821117 --- /dev/null +++ b/test/js/all.expected @@ -0,0 +1 @@ +Success diff --git a/test/js/array_proto_at.html b/test/js/array_proto_at.html new file mode 100644 index 00000000..844aa563 --- /dev/null +++ b/test/js/array_proto_at.html @@ -0,0 +1,9 @@ +<!doctype html> +<div id=x>Fail</div> +<script src=asserts.js></script> +<script> +assert(!![].at); +assert_equals([1, 2, 3].at(-2), 2); +assert_equals([1, 2, 3].at(-4), undefined); +document.getElementById("x").textContent = "Success"; +</script> diff --git a/test/js/asserts.js b/test/js/asserts.js new file mode 100644 index 00000000..4d8fd62c --- /dev/null +++ b/test/js/asserts.js @@ -0,0 +1,19 @@ +function assert(x, msg) { + const mymsg = msg ? ": " + msg : ""; + if (!x) + throw new TypeError("Assertion failed" + mymsg); +} + +function assert_throws(expr, error) { + try { + eval(expr); + } catch (e) { + if (e instanceof error) + return; + } + throw new TypeError("Assertion failed"); +} + +function assert_equals(a, b) { + assert(a === b, "Expected " + b + " but got " + a); +} diff --git a/test/js/base64.html b/test/js/base64.html new file mode 100644 index 00000000..0573d477 --- /dev/null +++ b/test/js/base64.html @@ -0,0 +1,44 @@ +<!doctype html> +<title>base64 test</title> +<div id=x>Fail</div> +<script src=asserts.js></script> +<script> + +const div = document.getElementById("x"); +assert_equals(atob(""), ""); +assert_equals(atob(" "), ""); +assert_equals(atob("YQ"), "a"); +assert_equals(atob("YR"), "a"); +assert_throws('atob("!")', DOMException); +assert_throws('atob("a")', DOMException); +assert_throws('atob("aaaaa")', DOMException); +assert_throws('atob("Aaa==")', DOMException); +assert_throws('atob("Aaaa==")', DOMException); +assert_throws('atob("Aaaaa==")', DOMException); +assert_throws('atob("Aa aaa= = ")', DOMException); +assert_equals(atob("AAAAAA=="), atob("AAAAAA")); +assert_equals(atob("AAAAAA"), atob("A A A A A A")); +assert_equals(atob("AAAAAA"), "\u0000\u0000\u0000\u0000"); +assert_equals(atob("ABCDEF"), "\u0000\u0010\u0083\u0010"); +assert_equals(atob("//////"), "ÿÿÿÿ"); +const longa = + "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz" + + "IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg" + + "dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu" + + "dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo" + + "ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4K"; +const longb = "Man is distinguished, not only by his reason, but by this " + + "singular passion from other animals, which is a lust of the mind, " + + "that by a perseverance of delight in the continued and " + + "indefatigable generation of knowledge, exceeds the short vehemence " + + "of any carnal pleasure.\n"; +assert_equals(atob(longa), longb); +assert_equals(btoa(""), ""); +assert_equals(btoa("a"), "YQ=="); +assert_equals(btoa("aa"), "YWE="); +assert_equals(btoa("aaa"), "YWFh"); +assert_equals(btoa("aaazdxfksljdf"), "YWFhemR4ZmtzbGpkZg=="); +assert_equals(btoa(longb), longa); +assert_throws('btoa("őÉéeé")', DOMException); +div.textContent = "Success"; +</script> diff --git a/test/js/class.html b/test/js/class.html new file mode 100644 index 00000000..7c14049e --- /dev/null +++ b/test/js/class.html @@ -0,0 +1,23 @@ +<!doctype html> +<title>Element class test</title> +<div class="a b c">Fail</div> +<script> +(function() { + let div = document.getElementsByClassName("a")[0] + const classes = ["a", "b", "c"]; + let cl = div.classList; + for (let i = 0; i < classes.length; ++i) { + if (cl[i] !== classes[i]) + return; + } + const classes2 = ["x", "y", "z"]; + div.setAttribute("class", classes2.join(' ')); + let i = 0; + for (let x of cl) { + if (x != classes2[i]) + return; + ++i; + } + div.textContent = "Success"; +})(); +</script> diff --git a/test/js/config.toml b/test/js/config.toml new file mode 100644 index 00000000..32cb3cd0 --- /dev/null +++ b/test/js/config.toml @@ -0,0 +1,13 @@ +[[siteconf]] +match = "file:///.*" +scripting = true + +[display] +columns = 80 +lines = 24 +pixels-per-column = 9 +pixels-per-line = 18 +force-columns = true +force-lines = true +force-pixels-per-column = true +force-pixels-per-line = true diff --git a/test/js/console.html b/test/js/console.html new file mode 100644 index 00000000..67b244a7 --- /dev/null +++ b/test/js/console.html @@ -0,0 +1,5 @@ +<!doctype html> +<div>Success</div> +<script> +console.log("Hello, world!") +</script> diff --git a/test/js/data_url.html b/test/js/data_url.html new file mode 100644 index 00000000..5da3f920 --- /dev/null +++ b/test/js/data_url.html @@ -0,0 +1,4 @@ +<!DOCTYPE html> +<div id=abc>Fail</div> +<script src="data:text/javascript,document.getElementById('abc').textContent='Success'"> +</script> diff --git a/test/js/date.html b/test/js/date.html new file mode 100644 index 00000000..86a2818b --- /dev/null +++ b/test/js/date.html @@ -0,0 +1,14 @@ +<!doctype html> +<!-- +Test for whether the Date constructor works at all. +QuickJS uses some syscalls and library calls for this, and sandboxing +sometimes isn't very cooperative in this regard. +--> +<title>Date constructor test</title> +<div id=x>Fail</div> +<script> +(function() { + new Date(); + document.getElementById("x").textContent = "Success"; +})(); +</script> diff --git a/test/js/document.html b/test/js/document.html new file mode 100644 index 00000000..26dfa528 --- /dev/null +++ b/test/js/document.html @@ -0,0 +1,11 @@ +<!doctype html> +<title>Window test</title> +<div id="abc">Fail</div> +<script> +(function() { + if (document.toString() !== "[object Document]") return; + if (document !== window.document) return; + if (document.implementation !== document.implementation) return; + document.getElementById("abc").textContent = "Success"; +})() +</script> diff --git a/test/js/documentall.html b/test/js/documentall.html new file mode 100644 index 00000000..14db9d70 --- /dev/null +++ b/test/js/documentall.html @@ -0,0 +1,19 @@ +<!doctype html> +<title>HTMLCollection test</title> +<div id="result">Fail</div> +<style>style 1</style> +<style>style 2</style> +<style>style 3</style> +<script> +(function() { + const abc = document.all; + if (document.all || abc) return; /* document.all must be falsy */ + if (abc.length !== 9) return; + const styles = [abc[5], abc[6], abc[7]]; + if (styles[0].textContent !== "style 1") return; + if (styles[1].textContent !== "style 2") return; + if (styles[2].textContent !== "style 3") return; + const result = document.getElementById("result"); + result.textContent = "Success"; +})() +</script> diff --git a/test/js/docwrite1.html b/test/js/docwrite1.html new file mode 100644 index 00000000..bc7f8882 --- /dev/null +++ b/test/js/docwrite1.html @@ -0,0 +1,101 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<title>document.write test</title> +<script> +window.onload = function() { + const success = document.body.innerHTML == document.querySelector("style").textContent; + while (document.body.childNodes[0]) + document.body.childNodes[0].remove(); + document.body.innerHTML = success ? "Success" : "Fail"; +} +let checkpointCounter = 0; +function checkpoint(n) { + if (++checkpointCounter != n) + throw new TypeError(`Checkpoint failed: expected ${n} but got ${checkpointCounter}`); +} +</script> +<style><h1>Main title</h1> + + +<p>Text.</p> +<script> +document.write(`<h2>Subtitle</h2> +<script> +checkpoint(1); +</scr` + `ipt> +`); + +checkpoint(2); + +document.write(` +<script> +checkpoint(3); +document.write( +'<p>before subtext</p>\\n' + +'<script>\\n' + +'checkpoint(4);\\n' + +'document.write("third nest");\\n' + +'</scr' + 'ipt>\\n' +); +</scr` + `ipt> +<p>fin</p> +`); +</script><h2>Subtitle</h2> +<script> +checkpoint(1); +</script> + +<script> +checkpoint(3); +document.write( +'<p>before subtext</p>\n' + +'<script>\n' + +'checkpoint(4);\n' + +'document.write("third nest");\n' + +'</scr' + 'ipt>\n' +); +</script><p>before subtext</p> +<script> +checkpoint(4); +document.write("third nest"); +</script>third nest + +<p>fin</p> + +<p>Subtext.</p> + + +</style> +<script> +document.write("<h1>Main title</h1>"); +</script> +</head> +<body> +<p>Text.</p> +<script> +document.write(`<h2>Subtitle</h2> +<script> +checkpoint(1); +</scr` + `ipt> +`); + +checkpoint(2); + +document.write(` +<script> +checkpoint(3); +document.write( +'<p>before subtext</p>\\n' + +'<script>\\n' + +'checkpoint(4);\\n' + +'document.write("third nest");\\n' + +'</scr' + 'ipt>\\n' +); +</scr` + `ipt> +<p>fin</p> +`); +</script> +<p>Subtext.</p> +</body> +</html> diff --git a/test/js/docwrite2.html b/test/js/docwrite2.html new file mode 100644 index 00000000..876f3cdd --- /dev/null +++ b/test/js/docwrite2.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<title>document.write test</title> +<script> +window.onload = function() { + const success = document.body.innerHTML == document.querySelector("style").textContent; + while (document.body.childNodes[0]) + document.body.childNodes[0].remove(); + document.body.innerHTML = success ? "Success" : "Fail"; +} +let checkpointCounter = 0; +function checkpoint(n) { + if (++checkpointCounter != n) + throw new TypeError(`Checkpoint failed: expected ${n} but got ${checkpointCounter}`); +} +</script> +<style><script> +document.write("a"); +document.write("<script></scr" + "ipt>x"); +document.write("t"); +</script>a<script></script>xt + +</style> +</head> +<body><script> +document.write("a"); +document.write("<script></scr" + "ipt>x"); +document.write("t"); +</script></body> +</html> diff --git a/test/js/docwrite3.html b/test/js/docwrite3.html new file mode 100644 index 00000000..24fc2222 --- /dev/null +++ b/test/js/docwrite3.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<script> +window.onload = function() { + const success = document.body.outerHTML == document.querySelector("style").textContent; + /* + console.log("BODY", document.body.outerHTML) + console.log("STYLE", document.querySelector("style").textContent) + */ + while (document.body.childNodes[0]) + document.body.childNodes[0].remove(); + document.body.innerHTML = success ? "Success" : "Fail"; +} +</script> +<style><body><h1>Main title</h1> + + +<p>Text.</p> +<script> +document.write("<h2>Subtitle</h2>"); +document.write("<scr" + "ipt>document.write('<p>before subtext</p><scri'+'pt>document.write(`third nest`)</scri'+'pt>')</scrip" + "t><p>fin</p>"); +</script><h2>Subtitle</h2><script>document.write('<p>before subtext</p><scri'+'pt>document.write(`third nest`)</scri'+'pt>')</script><p>before subtext</p><script>document.write(`third nest`)</script>third nest<p>fin</p> +<p>Subtext.</p> + + + +</body></style> +<title>Write example</title> +<script> +document.write("<h1>Main title</h1>"); +</script> +</head> +<body> +<p>Text.</p> +<script> +document.write("<h2>Subtitle</h2>"); +document.write("<scr" + "ipt>document.write('<p>before subtext</p><scri'+'pt>document.write(`third nest`)</scri'+'pt>')</scrip" + "t><p>fin</p>"); +</script> +<p>Subtext.</p> +</body> +</html> + diff --git a/test/js/docwrite4.html b/test/js/docwrite4.html new file mode 100644 index 00000000..0f0988b5 --- /dev/null +++ b/test/js/docwrite4.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<title>document.write test</title> +<script> +window.onload = function() { + const success = document.body.innerHTML == document.querySelector("style").textContent; + while (document.body.childNodes[0]) + document.body.childNodes[0].remove(); + document.body.innerHTML = success ? "Success" : "Fail"; +} +let checkpointCounter = 0; +function checkpoint(n) { + if (++checkpointCounter != n) + throw new TypeError(`Checkpoint failed: expected ${n} but got ${checkpointCounter}`); +} +</script> +<style><script> +document.write(`<script> +document.write("a"); +`); +document.write(` +document.write("<script></scr" + "ipt>x"); +`); +document.write(` +document.write("t"); +</scr` + "ipt>"); +</script><script> +document.write("a"); + +document.write("<script></scr" + "ipt>x"); + +document.write("t"); +</script>a<script></script>xt + +</style> +</head> +<body><script> +document.write(`<script> +document.write("a"); +`); +document.write(` +document.write("<script></scr" + "ipt>x"); +`); +document.write(` +document.write("t"); +</scr` + "ipt>"); +</script></body> +</html> diff --git a/test/js/encode_decode.html b/test/js/encode_decode.html new file mode 100644 index 00000000..069ddc72 --- /dev/null +++ b/test/js/encode_decode.html @@ -0,0 +1,39 @@ +<!doctype html> +<title>TextEncoder/TextDecoder test</title> +<div id="success">Fail</div> +<script> +(function() { + /* Adapted from: https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem */ + function base64ToBytes(base64) { + const binString = atob(base64); + const result = []; + for (const c of binString) + result.push(Uint8Array.from(c, (m) => m.codePointAt(0))); + return result; + } + + function bytesToBase64(bytes) { + const binString = String.fromCodePoint(...bytes); + return btoa(binString); + } + + const utf8 = new TextEncoder().encode("a Ā 𐀀 文 🦄") + const b64utf8 = bytesToBase64(utf8); + if (b64utf8 !== "YSDEgCDwkICAIOaWhyDwn6aE") { + console.log(b64utf8); + return; + } + const dec = new TextDecoder(); + const bytes = base64ToBytes(b64utf8); + const a = []; + let res = ""; + for (const c of bytes) + res += dec.decode(c, {stream: true}); + res += dec.decode(); + if (res !== "a Ā 𐀀 文 🦄") { + console.log(res); + return; + } + document.getElementById("success").textContent = "Success"; +})(); +</script> diff --git a/test/js/htmlcollection.html b/test/js/htmlcollection.html new file mode 100644 index 00000000..6231237a --- /dev/null +++ b/test/js/htmlcollection.html @@ -0,0 +1,22 @@ +<!doctype html> +<title>HTMLCollection test</title> +<div class="abc">Fail</div> +<style>style 1</style> +<style>style 2</style> +<style>style 3</style> +<script> +(function() { + const abc = document.getElementsByClassName("abc"); + if (abc.length !== 1) return; + abc[0].className = "defg"; + if (abc.length !== 0) return; + const styles = document.getElementsByTagName("style"); + if (styles.length !== 3) return; + if (styles[0].textContent !== "style 1") return; + if (styles[1].textContent !== "style 2") return; + if (styles[2].textContent !== "style 3") return; + for (const style of styles) style.remove(); + let defg = document.getElementsByClassName("defg"); + defg[0].textContent = "Success"; +})() +</script> diff --git a/test/js/outerhtml.html b/test/js/outerhtml.html new file mode 100644 index 00000000..5c30bc52 --- /dev/null +++ b/test/js/outerhtml.html @@ -0,0 +1,9 @@ +<!doctype html> +<title>innerHTML test</title> +<div id="test">Fail</div> +<script> +const div = document.getElementById("test"); +if (div.outerHTML != '<div id="test">Fail</div>') + throw new TypeError("invalid outerHTML " + div.outerHTML); +div.textContent = "Success"; +</script> diff --git a/test/js/prev_next_parent_child.html b/test/js/prev_next_parent_child.html new file mode 100644 index 00000000..85abe7fe --- /dev/null +++ b/test/js/prev_next_parent_child.html @@ -0,0 +1,22 @@ +<!doctype html> +<main> +<div id=x>Fail</div> +test +<a id=y>test test</a> +</main> +<script> +(function() { + let x = document.getElementById("x") + let y = document.getElementById("y"); + if (y.previousSibling === x) return; + if (y.previousSibling.textContent.trim() !== "test") return; + if (y.previousElementSibling !== x) return; + if (x.nextElementSibling !== y) return; + if (x.nextSibling.textContent.trim() !== "test") return; + x.nextSibling.remove(); + x.nextSibling.remove(); + if (x.parentElement.children.length !== 1) return; + if (x.parentElement.children[0] !== x) return; + x.textContent = "Success"; +})() +</script> diff --git a/test/js/query_selector_plus.html b/test/js/query_selector_plus.html new file mode 100644 index 00000000..0bbe1677 --- /dev/null +++ b/test/js/query_selector_plus.html @@ -0,0 +1,11 @@ +<!DOCTYPE HTML> +<div id=success>Fail</div> +<script one> +</script> +<script two> +</script> +<script> +if (document.querySelector("script[one] + script").attributes["two"]) { + document.getElementById("success").textContent = "Success"; +} +</script> diff --git a/test/js/reflect.html b/test/js/reflect.html new file mode 100644 index 00000000..45debe39 --- /dev/null +++ b/test/js/reflect.html @@ -0,0 +1,18 @@ +<!doctype html> +<div id=abc>Fail</div> +<a class=claz target="abcd">test test</a> +<script> +(function() { + let x = document.getElementById("abc") + let a = document.getElementsByTagName("a")[0]; + if (a.target != "abcd") return; + a.target = "defg"; + if (a.target != "defg") return; + if (a.relList != "") return; + a.relList = "..."; + if (a.relList != "...") return; + if (a.className != "claz") return; + x.textContent = "Success"; + a.remove(); /* ignore target... */ +})() +</script> diff --git a/test/js/run_js_tests.sh b/test/js/run_js_tests.sh new file mode 100755 index 00000000..a8cad435 --- /dev/null +++ b/test/js/run_js_tests.sh @@ -0,0 +1,13 @@ +#!/bin/sh +if ! test "$CHA_TEST_BIN" +then test -f ../../../cha && CHA_TEST_BIN=../../../cha || CHA_TEST_BIN=cha +fi +failed=0 +for h in *.html +do printf '%s\n' "$h" + if ! "$CHA_TEST_BIN" -C config.toml "$h" | diff all.expected - + then failed=$(($failed+1)) + printf 'FAIL: %s\n' "$h" + fi +done +exit "$failed" diff --git a/test/js/settimeout.html b/test/js/settimeout.html new file mode 100644 index 00000000..e57dba7f --- /dev/null +++ b/test/js/settimeout.html @@ -0,0 +1,8 @@ +<!doctype html> +<title>setTimeout test</title> +<!-- For now, this only tests whether setTimeout crashes the buffer + or not. (There has been a bug where it did.) --> +<script> +setTimeout(() => void(0), 1000); +</script> +Success diff --git a/test/js/template.html b/test/js/template.html new file mode 100644 index 00000000..33bbdc34 --- /dev/null +++ b/test/js/template.html @@ -0,0 +1,8 @@ +<!doctype html> +<title>Test template</title> +<div id=x>Fail</div> +<script src=asserts.js></script> +<script> +assert(true); +document.getElementById("x").textContent = "Success"; +</script> diff --git a/test/js/text.html b/test/js/text.html new file mode 100644 index 00000000..7d7bcfca --- /dev/null +++ b/test/js/text.html @@ -0,0 +1,8 @@ +<!doctype html> +<div id="succ">Fail</div> +<script> +(function() { + if (new Text("data").ownerDocument != document) return; + document.getElementById("succ").textContent = "Success" +})() +</script> diff --git a/test/js/window.html b/test/js/window.html new file mode 100644 index 00000000..5aef5186 --- /dev/null +++ b/test/js/window.html @@ -0,0 +1,11 @@ +<!doctype html> +<title>Window test</title> +<div id=x>Fail</div> +<script src=asserts.js></script> +<script> +assert_equals(window.toString(), "[object Window]"); +const desc = Object.getOwnPropertyDescriptor(window, "window"); +assert(desc.enumerable, "window must be enumerable"); +assert(!desc.configurable, "window must not be configurable"); +document.getElementById("x").textContent = "Success"; +</script> |