From f77693d768c1926ad48d55ed7cdf9154511084a7 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Wed, 10 Sep 2025 20:32:15 +0800 Subject: [PATCH] migrate more tests to htmlRunner --- src/browser/console/console.zig | 71 ---------------- src/browser/xhr/File.zig | 10 +-- src/browser/xhr/form_data.zig | 129 +---------------------------- src/browser/xhr/progress_event.zig | 16 +--- src/browser/xhr/xhr.zig | 115 +------------------------ src/tests/testing.js | 15 ++++ src/tests/xhr/file.html | 5 ++ src/tests/xhr/form_data.html | 129 +++++++++++++++++++++++++++++ src/tests/xhr/progress_event.html | 16 ++++ src/tests/xhr/xhr.html | 109 ++++++++++++++++++++++++ 10 files changed, 284 insertions(+), 331 deletions(-) create mode 100644 src/tests/xhr/file.html create mode 100644 src/tests/xhr/form_data.html create mode 100644 src/tests/xhr/progress_event.html create mode 100644 src/tests/xhr/xhr.html diff --git a/src/browser/console/console.zig b/src/browser/console/console.zig index f9b2ebda..172c0123 100644 --- a/src/browser/console/console.zig +++ b/src/browser/console/console.zig @@ -166,74 +166,3 @@ pub const Console = struct { fn timestamp() u32 { return @import("../../datetime.zig").timestamp(); } - -// const testing = @import("../../testing.zig"); -// test "Browser.Console" { -// defer testing.reset(); - -// var runner = try testing.jsRunner(testing.tracking_allocator, .{}); -// defer runner.deinit(); - -// { -// try runner.testCases(&.{ -// .{ "console.log('a')", "undefined" }, -// .{ "console.warn('hello world', 23, true, new Object())", "undefined" }, -// }, .{}); - -// const captured = test_capture.captured.items; -// try testing.expectEqual("[info] args= 1: a", captured[0]); -// try testing.expectEqual("[warn] args= 1: hello world 2: 23 3: true 4: #", captured[1]); -// } - -// { -// test_capture.reset(); -// try runner.testCases(&.{ -// .{ "console.countReset()", "undefined" }, -// .{ "console.count()", "undefined" }, -// .{ "console.count('teg')", "undefined" }, -// .{ "console.count('teg')", "undefined" }, -// .{ "console.count('teg')", "undefined" }, -// .{ "console.count()", "undefined" }, -// .{ "console.countReset('teg')", "undefined" }, -// .{ "console.countReset()", "undefined" }, -// .{ "console.count()", "undefined" }, -// }, .{}); - -// const captured = test_capture.captured.items; -// try testing.expectEqual("[invalid counter] label=default", captured[0]); -// try testing.expectEqual("[count] label=default count=1", captured[1]); -// try testing.expectEqual("[count] label=teg count=1", captured[2]); -// try testing.expectEqual("[count] label=teg count=2", captured[3]); -// try testing.expectEqual("[count] label=teg count=3", captured[4]); -// try testing.expectEqual("[count] label=default count=2", captured[5]); -// try testing.expectEqual("[count reset] label=teg count=3", captured[6]); -// try testing.expectEqual("[count reset] label=default count=2", captured[7]); -// try testing.expectEqual("[count] label=default count=1", captured[8]); -// } - -// { -// test_capture.reset(); -// try runner.testCases(&.{ -// .{ "console.assert(true)", "undefined" }, -// .{ "console.assert('a', 2, 3, 4)", "undefined" }, -// .{ "console.assert('')", "undefined" }, -// .{ "console.assert('', 'x', true)", "undefined" }, -// .{ "console.assert(false, 'x')", "undefined" }, -// }, .{}); - -// const captured = test_capture.captured.items; -// try testing.expectEqual("[assertion failed] values=", captured[0]); -// try testing.expectEqual("[assertion failed] values= 1: x 2: true", captured[1]); -// try testing.expectEqual("[assertion failed] values= 1: x", captured[2]); -// } - -// { -// test_capture.reset(); -// try runner.testCases(&.{ -// .{ "[1].forEach(console.log)", null }, -// }, .{}); - -// const captured = test_capture.captured.items; -// try testing.expectEqual("[info] args= 1: 1 2: 0 3: [1]", captured[0]); -// } -// } diff --git a/src/browser/xhr/File.zig b/src/browser/xhr/File.zig index c0a97234..ebec7be6 100644 --- a/src/browser/xhr/File.zig +++ b/src/browser/xhr/File.zig @@ -29,12 +29,6 @@ pub fn constructor() File { } const testing = @import("../../testing.zig"); -test "Browser.File" { - var runner = try testing.jsRunner(testing.tracking_allocator, .{ .html = "" }); - defer runner.deinit(); - - try runner.testCases(&.{ - .{ "let f = new File()", null }, - .{ "f instanceof File", "true" }, - }, .{}); +test "Browser: File" { + try testing.htmlRunner("xhr/file.html"); } diff --git a/src/browser/xhr/form_data.zig b/src/browser/xhr/form_data.zig index eefde975..a2fd8eeb 100644 --- a/src/browser/xhr/form_data.zig +++ b/src/browser/xhr/form_data.zig @@ -100,7 +100,7 @@ pub const FormData = struct { return kv.urlEncode(self.entries, .form, writer); } - log.warn(.web_api, "not implemented", .{ + log.debug(.web_api, "not implemented", .{ .feature = "form data encoding", .encoding = encoding, }); @@ -265,132 +265,11 @@ fn getSubmitterName(submitter_: ?*parser.ElementHTML) !?[]const u8 { } const testing = @import("../../testing.zig"); -test "Browser.FormData" { - var runner = try testing.jsRunner(testing.tracking_allocator, .{ .html = - \\
- \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\ - \\
- \\ - }); - defer runner.deinit(); - - try runner.testCases(&.{ - .{ "let f = new FormData()", null }, - .{ "f.get('a')", "null" }, - .{ "f.has('a')", "false" }, - .{ "f.getAll('a')", "" }, - .{ "f.delete('a')", "undefined" }, - - .{ "f.set('a', 1)", "undefined" }, - .{ "f.has('a')", "true" }, - .{ "f.get('a')", "1" }, - .{ "f.getAll('a')", "1" }, - - .{ "f.append('a', 2)", "undefined" }, - .{ "f.has('a')", "true" }, - .{ "f.get('a')", "1" }, - .{ "f.getAll('a')", "1,2" }, - - .{ "f.append('b', '3')", "undefined" }, - .{ "f.has('a')", "true" }, - .{ "f.get('a')", "1" }, - .{ "f.getAll('a')", "1,2" }, - .{ "f.has('b')", "true" }, - .{ "f.get('b')", "3" }, - .{ "f.getAll('b')", "3" }, - - .{ "let acc = [];", null }, - .{ "for (const key of f.keys()) { acc.push(key) }; acc;", "a,a,b" }, - - .{ "acc = [];", null }, - .{ "for (const value of f.values()) { acc.push(value) }; acc;", "1,2,3" }, - - .{ "acc = [];", null }, - .{ "for (const entry of f.entries()) { acc.push(entry) }; acc;", "a,1,a,2,b,3" }, - - .{ "acc = [];", null }, - .{ "for (const entry of f) { acc.push(entry) }; acc;", "a,1,a,2,b,3" }, - - .{ "f.delete('a')", "undefined" }, - .{ "f.has('a')", "false" }, - .{ "f.has('b')", "true" }, - - .{ "acc = [];", null }, - .{ "for (const key of f.keys()) { acc.push(key) }; acc;", "b" }, - - .{ "acc = [];", null }, - .{ "for (const value of f.values()) { acc.push(value) }; acc;", "3" }, - - .{ "acc = [];", null }, - .{ "for (const entry of f.entries()) { acc.push(entry) }; acc;", "b,3" }, - - .{ "acc = [];", null }, - .{ "for (const entry of f) { acc.push(entry) }; acc;", "b,3" }, - }, .{}); - - try runner.testCases(&.{ - .{ "let form1 = document.getElementById('form1')", null }, - .{ "let input = document.createElement('input');", null }, - .{ "input.name = 'dyn'; input.value= 'dyn-v'; form1.appendChild(input);", null }, - .{ "let submit1 = document.getElementById('s1')", null }, - .{ "let f2 = new FormData(form1, submit1)", null }, - .{ "acc = '';", null }, - .{ - \\ for (const entry of f2) { - \\ acc += entry[0] + '=' + entry[1] + '\n'; - \\ }; - \\ acc.slice(0, -1) - , - \\txt-1=txt-1-v - \\txt-2=txt-~-v - \\chk-3=chk-3-vb - \\chk-3=chk-3-vc - \\rdi-1=rdi-1-vc - \\ta-1= ta-1-v - \\ta= - \\h1=h1-v - \\sel-1=blue - \\sel-2=sel-2-v - \\mlt-2=water - \\mlt-2=tea - \\s1=s1-v - \\dyn=dyn-v - }, - }, .{}); +test "Browser: FormData" { + try testing.htmlRunner("xhr/form_data.html"); } -test "Browser.FormData: urlEncode" { +test "Browser: FormData.urlEncode" { var arr: std.ArrayListUnmanaged(u8) = .empty; defer arr.deinit(testing.allocator); diff --git a/src/browser/xhr/progress_event.zig b/src/browser/xhr/progress_event.zig index d082f7b2..7128ac0d 100644 --- a/src/browser/xhr/progress_event.zig +++ b/src/browser/xhr/progress_event.zig @@ -67,18 +67,6 @@ pub const ProgressEvent = struct { }; const testing = @import("../../testing.zig"); -test "Browser.XHR.ProgressEvent" { - var runner = try testing.jsRunner(testing.tracking_allocator, .{}); - defer runner.deinit(); - - try runner.testCases(&.{ - .{ "let pevt = new ProgressEvent('foo');", "undefined" }, - .{ "pevt.loaded", "0" }, - .{ "pevt instanceof ProgressEvent", "true" }, - .{ "var nnb = 0; var eevt = null; function ccbk(event) { nnb ++; eevt = event; }", "undefined" }, - .{ "document.addEventListener('foo', ccbk)", "undefined" }, - .{ "document.dispatchEvent(pevt)", "true" }, - .{ "eevt.type", "foo" }, - .{ "eevt instanceof ProgressEvent", "true" }, - }, .{}); +test "Browser: XHR.ProgressEvent" { + try testing.htmlRunner("xhr/progress_event.html"); } diff --git a/src/browser/xhr/xhr.zig b/src/browser/xhr/xhr.zig index afdaedee..93f07b7c 100644 --- a/src/browser/xhr/xhr.zig +++ b/src/browser/xhr/xhr.zig @@ -755,117 +755,6 @@ pub const XMLHttpRequest = struct { }; const testing = @import("../../testing.zig"); -test "Browser.XHR.XMLHttpRequest" { - var runner = try testing.jsRunner(testing.tracking_allocator, .{}); - defer runner.deinit(); - - try runner.testCases(&.{ - .{ "var nb = 0; var evt = null; function cbk(event) { nb ++; evt = event; }", "undefined" }, - .{ "const req = new XMLHttpRequest()", "undefined" }, - - .{ "req.onload = cbk", "function cbk(event) { nb ++; evt = event; }" }, - - .{ "req.onload", "function cbk(event) { nb ++; evt = event; }" }, - .{ "req.onload = cbk", "function cbk(event) { nb ++; evt = event; }" }, - - .{ "req.open('GET', 'http://127.0.0.1:9582/xhr')", null }, - - // ensure open resets values - .{ "req.status ", "0" }, - .{ "req.statusText", "" }, - .{ "req.getAllResponseHeaders()", "" }, - .{ "req.getResponseHeader('Content-Type')", "null" }, - .{ "req.responseText", "" }, - - .{ "req.send(); nb", "0" }, - - // Each case executed waits for all loop callback calls. - // So the url has been retrieved. - .{ "nb", "1" }, - .{ "evt.type", "load" }, - .{ "evt.loaded > 0", "true" }, - .{ "evt instanceof ProgressEvent", "true" }, - .{ "req.status", "200" }, - .{ "req.statusText", "OK" }, - .{ "req.getResponseHeader('Content-Type')", "text/html; charset=utf-8" }, - .{ "req.getAllResponseHeaders()", "content-length: 100\r\n" ++ - "Content-Type: text/html; charset=utf-8\r\n" }, - .{ "req.responseText.length", "100" }, - .{ "req.response.length == req.responseText.length", "true" }, - .{ "req.responseXML instanceof Document", "true" }, - }, .{}); - - try runner.testCases(&.{ - .{ "const req2 = new XMLHttpRequest()", "undefined" }, - .{ "req2.open('GET', 'http://127.0.0.1:9582/xhr')", "undefined" }, - .{ "req2.responseType = 'document'", "document" }, - - .{ "req2.send()", "undefined" }, - - // Each case executed waits for all loop callaback calls. - // So the url has been retrieved. - .{ "req2.status", "200" }, - .{ "req2.statusText", "OK" }, - .{ "req2.response instanceof Document", "true" }, - .{ "req2.responseXML instanceof Document", "true" }, - }, .{}); - - try runner.testCases(&.{ - .{ "const req3 = new XMLHttpRequest()", "undefined" }, - .{ "req3.open('GET', 'http://127.0.0.1:9582/xhr/json')", "undefined" }, - .{ "req3.responseType = 'json'", "json" }, - - .{ "req3.send()", "undefined" }, - - // Each case executed waits for all loop callaback calls. - // So the url has been retrieved. - .{ "req3.status", "200" }, - .{ "req3.statusText", "OK" }, - .{ "req3.response.over", "9000!!!" }, - }, .{}); - - try runner.testCases(&.{ - .{ "const req4 = new XMLHttpRequest()", "undefined" }, - .{ "req4.open('POST', 'http://127.0.0.1:9582/xhr')", "undefined" }, - .{ "req4.send('foo')", "undefined" }, - - // Each case executed waits for all loop callaback calls. - // So the url has been retrieved. - .{ "req4.status", "200" }, - .{ "req4.statusText", "OK" }, - .{ "req4.responseText.length > 64", "true" }, - }, .{}); - - try runner.testCases(&.{ - .{ "const req5 = new XMLHttpRequest()", "undefined" }, - .{ "req5.open('GET', 'http://127.0.0.1:9582/xhr')", "undefined" }, - .{ "var status = 0; req5.onload = function () { status = this.status };", "function () { status = this.status }" }, - .{ "req5.send()", "undefined" }, - - // Each case executed waits for all loop callaback calls. - // So the url has been retrieved. - .{ "status", "200" }, - }, .{}); - - try runner.testCases(&.{ - .{ "const req6 = new XMLHttpRequest()", null }, - .{ - \\ var readyStates = []; - \\ var currentTarget = null; - \\ req6.onreadystatechange = (e) => { - \\ currentTarget = e.currentTarget; - \\ readyStates.push(req6.readyState); - \\ } - , - null, - }, - .{ "req6.open('GET', 'http://127.0.0.1:9582/xhr')", null }, - .{ "req6.send()", null }, - .{ "readyStates.length", "4" }, - .{ "readyStates[0] === XMLHttpRequest.OPENED", "true" }, - .{ "readyStates[1] === XMLHttpRequest.HEADERS_RECEIVED", "true" }, - .{ "readyStates[2] === XMLHttpRequest.LOADING", "true" }, - .{ "readyStates[3] === XMLHttpRequest.DONE", "true" }, - .{ "currentTarget == req6", "true" }, - }, .{}); +test "Browser: XHR.XMLHttpRequest" { + try testing.htmlRunner("xhr/xhr.html"); } diff --git a/src/tests/testing.js b/src/tests/testing.js index faa9f123..f199b61c 100644 --- a/src/tests/testing.js +++ b/src/tests/testing.js @@ -92,6 +92,15 @@ _registerErrorCallback(); } + async function async(promise, cb) { + const script_id = document.currentScript.id; + const stack = new Error().stack; + const value = await promise; + this._captured = {script_id: script_id, stack: stack}; + cb(value); + this._captured = null; + } + function _recordExecution() { if (testing._status === 'fail') { return; @@ -161,6 +170,7 @@ _executed_scripts: new Set(), _captured: null, skip: skip, + async: async, getStatus: getStatus, eventually: eventually, expectEqual: expectEqual, @@ -177,4 +187,9 @@ window.$$ = function(sel) { return document.querySelectorAll(sel); } + + if (!console.lp) { + // make this work in the browser + console.lp = console.log; + } })(); diff --git a/src/tests/xhr/file.html b/src/tests/xhr/file.html new file mode 100644 index 00000000..4965ccb0 --- /dev/null +++ b/src/tests/xhr/file.html @@ -0,0 +1,5 @@ + + diff --git a/src/tests/xhr/form_data.html b/src/tests/xhr/form_data.html new file mode 100644 index 00000000..17dfd30c --- /dev/null +++ b/src/tests/xhr/form_data.html @@ -0,0 +1,129 @@ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ diff --git a/src/tests/xhr/progress_event.html b/src/tests/xhr/progress_event.html new file mode 100644 index 00000000..e57a59c4 --- /dev/null +++ b/src/tests/xhr/progress_event.html @@ -0,0 +1,16 @@ + + diff --git a/src/tests/xhr/xhr.html b/src/tests/xhr/xhr.html new file mode 100644 index 00000000..36792b3a --- /dev/null +++ b/src/tests/xhr/xhr.html @@ -0,0 +1,109 @@ + + + + + + + + + +