From ef99632fa7447aee580dd1060d7e027f186be38d Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Mon, 22 Jun 2026 21:07:29 +0200 Subject: [PATCH] Tests/LibWeb: Add some encoding options related WPT tests --- .../streams/decode-ignore-bom.any.txt | 17 +++++++ .../textdecoder-fatal-streaming.any.txt | 8 ++++ .../streams/decode-ignore-bom.any.html | 16 +++++++ .../encoding/streams/decode-ignore-bom.any.js | 38 ++++++++++++++++ .../textdecoder-fatal-streaming.any.html | 15 +++++++ .../textdecoder-fatal-streaming.any.js | 45 +++++++++++++++++++ 6 files changed, 139 insertions(+) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/encoding/streams/decode-ignore-bom.any.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/encoding/textdecoder-fatal-streaming.any.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/encoding/streams/decode-ignore-bom.any.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/encoding/streams/decode-ignore-bom.any.js create mode 100644 Tests/LibWeb/Text/input/wpt-import/encoding/textdecoder-fatal-streaming.any.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/encoding/textdecoder-fatal-streaming.any.js diff --git a/Tests/LibWeb/Text/expected/wpt-import/encoding/streams/decode-ignore-bom.any.txt b/Tests/LibWeb/Text/expected/wpt-import/encoding/streams/decode-ignore-bom.any.txt new file mode 100644 index 0000000000..6c337ae5ef --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/encoding/streams/decode-ignore-bom.any.txt @@ -0,0 +1,17 @@ +Harness status: OK + +Found 12 tests + +12 Fail +Fail ignoreBOM should work for encoding utf-8, split at character 0 +Fail ignoreBOM should work for encoding utf-8, split at character 1 +Fail ignoreBOM should work for encoding utf-8, split at character 2 +Fail ignoreBOM should work for encoding utf-8, split at character 3 +Fail ignoreBOM should work for encoding utf-16le, split at character 0 +Fail ignoreBOM should work for encoding utf-16le, split at character 1 +Fail ignoreBOM should work for encoding utf-16le, split at character 2 +Fail ignoreBOM should work for encoding utf-16le, split at character 3 +Fail ignoreBOM should work for encoding utf-16be, split at character 0 +Fail ignoreBOM should work for encoding utf-16be, split at character 1 +Fail ignoreBOM should work for encoding utf-16be, split at character 2 +Fail ignoreBOM should work for encoding utf-16be, split at character 3 \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/encoding/textdecoder-fatal-streaming.any.txt b/Tests/LibWeb/Text/expected/wpt-import/encoding/textdecoder-fatal-streaming.any.txt new file mode 100644 index 0000000000..503d5902f8 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/encoding/textdecoder-fatal-streaming.any.txt @@ -0,0 +1,8 @@ +Harness status: OK + +Found 2 tests + +1 Pass +1 Fail +Pass Fatal flag, non-streaming cases +Fail Fatal flag, streaming cases \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/encoding/streams/decode-ignore-bom.any.html b/Tests/LibWeb/Text/input/wpt-import/encoding/streams/decode-ignore-bom.any.html new file mode 100644 index 0000000000..f1df4ea729 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/encoding/streams/decode-ignore-bom.any.html @@ -0,0 +1,16 @@ + + + + + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/encoding/streams/decode-ignore-bom.any.js b/Tests/LibWeb/Text/input/wpt-import/encoding/streams/decode-ignore-bom.any.js new file mode 100644 index 0000000000..92f89c8015 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/encoding/streams/decode-ignore-bom.any.js @@ -0,0 +1,38 @@ +// META: global=window,worker +// META: script=resources/readable-stream-from-array.js +// META: script=resources/readable-stream-to-array.js + +const cases = [ + {encoding: 'utf-8', bytes: [0xEF, 0xBB, 0xBF, 0x61, 0x62, 0x63]}, + {encoding: 'utf-16le', bytes: [0xFF, 0xFE, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00]}, + {encoding: 'utf-16be', bytes: [0xFE, 0xFF, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63]} +]; +const BOM = '\uFEFF'; + +// |inputChunks| is an array of chunks, each represented by an array of +// integers. |ignoreBOM| is true or false. The result value is the output of the +// pipe, concatenated into a single string. +async function pipeAndAssemble(inputChunks, encoding, ignoreBOM) { + const chunksAsUint8 = inputChunks.map(values => new Uint8Array(values)); + const readable = readableStreamFromArray(chunksAsUint8); + const outputArray = await readableStreamToArray(readable.pipeThrough( + new TextDecoderStream(encoding, {ignoreBOM}))); + return outputArray.join(''); +} + +for (const testCase of cases) { + for (let splitPoint = 0; splitPoint < 4; ++splitPoint) { + promise_test(async () => { + const inputChunks = [testCase.bytes.slice(0, splitPoint), + testCase.bytes.slice(splitPoint)]; + const withIgnoreBOM = + await pipeAndAssemble(inputChunks, testCase.encoding, true); + assert_equals(withIgnoreBOM, BOM + 'abc', 'BOM should be preserved'); + + const withoutIgnoreBOM = + await pipeAndAssemble(inputChunks, testCase.encoding, false); + assert_equals(withoutIgnoreBOM, 'abc', 'BOM should be stripped') + }, `ignoreBOM should work for encoding ${testCase.encoding}, split at ` + + `character ${splitPoint}`); + } +} diff --git a/Tests/LibWeb/Text/input/wpt-import/encoding/textdecoder-fatal-streaming.any.html b/Tests/LibWeb/Text/input/wpt-import/encoding/textdecoder-fatal-streaming.any.html new file mode 100644 index 0000000000..bc0dfdc5f3 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/encoding/textdecoder-fatal-streaming.any.html @@ -0,0 +1,15 @@ + + +Encoding API: End-of-file + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/encoding/textdecoder-fatal-streaming.any.js b/Tests/LibWeb/Text/input/wpt-import/encoding/textdecoder-fatal-streaming.any.js new file mode 100644 index 0000000000..872962fbd0 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/encoding/textdecoder-fatal-streaming.any.js @@ -0,0 +1,45 @@ +// META: global=window,dedicatedworker +// META: title=Encoding API: End-of-file + +test(function() { + [ + {encoding: 'utf-8', sequence: [0xC0]}, + {encoding: 'utf-16le', sequence: [0x00]}, + {encoding: 'utf-16be', sequence: [0x00]} + ].forEach(function(testCase) { + + assert_throws_js(TypeError, function() { + var decoder = new TextDecoder(testCase.encoding, {fatal: true}); + decoder.decode(new Uint8Array(testCase.sequence)); + }, 'Unterminated ' + testCase.encoding + ' sequence should throw if fatal flag is set'); + + assert_equals( + new TextDecoder(testCase.encoding).decode(new Uint8Array([testCase.sequence])), + '\uFFFD', + 'Unterminated UTF-8 sequence should emit replacement character if fatal flag is unset'); + }); +}, 'Fatal flag, non-streaming cases'); + +test(function() { + + var decoder = new TextDecoder('utf-16le', {fatal: true}); + var odd = new Uint8Array([0x00]); + var even = new Uint8Array([0x00, 0x00]); + + assert_equals(decoder.decode(odd, {stream: true}), ''); + assert_equals(decoder.decode(odd), '\u0000'); + + assert_throws_js(TypeError, function() { + decoder.decode(even, {stream: true}); + decoder.decode(odd) + }); + + assert_throws_js(TypeError, function() { + decoder.decode(odd, {stream: true}); + decoder.decode(even); + }); + + assert_equals(decoder.decode(even, {stream: true}), '\u0000'); + assert_equals(decoder.decode(even), '\u0000'); + +}, 'Fatal flag, streaming cases');