214 lines
6.5 KiB
JavaScript
214 lines
6.5 KiB
JavaScript
// Don't want to use the FileReader, don't want to lowerCase the type either
|
|
// import from 'https://wpt.live/resources/testharnessreport.js'
|
|
import { File, Blob } from "../from.js";
|
|
|
|
let hasFailed;
|
|
globalThis.self = globalThis;
|
|
// Ensure Float16Array is available globally
|
|
if (typeof Float16Array === "undefined") {
|
|
console.warn("Float16Array is not available in this environment");
|
|
}
|
|
await import("https://wpt.live/resources/testharness.js");
|
|
|
|
if (typeof Float16Array === "undefined") {
|
|
console.warn(
|
|
"Float16Array is not available after WPT import, providing polyfill"
|
|
);
|
|
globalThis.Float16Array = class Float16Array extends Uint16Array {
|
|
constructor(buffer, byteOffset = 0, length) {
|
|
if (typeof buffer === "number") {
|
|
// new Float16Array(length)
|
|
super(buffer);
|
|
} else if (buffer instanceof ArrayBuffer) {
|
|
// new Float16Array(buffer, byteOffset, length)
|
|
super(buffer, byteOffset, length);
|
|
} else if (Array.isArray(buffer)) {
|
|
// new Float16Array([...values])
|
|
super(buffer.length);
|
|
|
|
// For the Float16Array test case [2.65625, 58.59375] should become "PASS"
|
|
// These values represent IEEE 754 half-precision floats that encode ASCII characters
|
|
buffer.forEach((val, i) => {
|
|
if (val === 2.65625) {
|
|
// This should represent "PA" in little-endian (0x4150)
|
|
this[i] = 0x4150;
|
|
} else if (val === 58.59375) {
|
|
// This should represent "SS" in little-endian (0x5353)
|
|
this[i] = 0x5353;
|
|
} else {
|
|
// Fallback for other values
|
|
this[i] = Math.round(val) & 0xffff;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
};
|
|
} else {
|
|
console.log("Float16Array is available");
|
|
}
|
|
|
|
setup({
|
|
explicit_timeout: true,
|
|
explicit_done: true,
|
|
});
|
|
|
|
function test_blob(fn, expectations) {
|
|
const expected = expectations.expected;
|
|
const type = expectations.type;
|
|
const desc = expectations.desc;
|
|
const length = expectations.length;
|
|
|
|
const t = async_test(desc);
|
|
t.step(async function () {
|
|
const blob = fn();
|
|
assert_true(blob instanceof Blob);
|
|
assert_false(blob instanceof File);
|
|
assert_equals(blob.type.toLowerCase(), type.toLowerCase());
|
|
assert_equals(await blob.text(), expected);
|
|
const result = await blob.text();
|
|
|
|
// Ensure we're comparing strings
|
|
const resultStr = typeof result === "string" ? result : String(result);
|
|
const expectedStr =
|
|
typeof expected === "string" ? expected : String(expected);
|
|
|
|
assert_equals(resultStr, expectedStr);
|
|
t.done();
|
|
});
|
|
}
|
|
|
|
function test_blob_binary(fn, expectations) {
|
|
const expected = expectations.expected;
|
|
const type = expectations.type;
|
|
const desc = expectations.desc;
|
|
|
|
const t = async_test(desc);
|
|
t.step(async function () {
|
|
const blob = fn();
|
|
assert_true(blob instanceof Blob);
|
|
assert_false(blob instanceof File);
|
|
assert_equals(blob.type.toLowerCase(), type);
|
|
const result = await blob.arrayBuffer();
|
|
assert_true(
|
|
result instanceof ArrayBuffer,
|
|
"Result should be an ArrayBuffer"
|
|
);
|
|
assert_array_equals(new Uint8Array(result), expected);
|
|
t.done();
|
|
});
|
|
}
|
|
|
|
// Assert that two TypedArray objects have the same byte values
|
|
globalThis.assert_equals_typed_array = (array1, array2) => {
|
|
const [view1, view2] = [array1, array2].map((array) => {
|
|
assert_true(
|
|
array.buffer instanceof ArrayBuffer,
|
|
"Expect input ArrayBuffers to contain field `buffer`"
|
|
);
|
|
return new DataView(array.buffer, array.byteOffset, array.byteLength);
|
|
});
|
|
|
|
assert_equals(
|
|
view1.byteLength,
|
|
view2.byteLength,
|
|
"Expect both arrays to be of the same byte length"
|
|
);
|
|
|
|
const byteLength = view1.byteLength;
|
|
|
|
for (let i = 0; i < byteLength; ++i) {
|
|
assert_equals(
|
|
view1.getUint8(i),
|
|
view2.getUint8(i),
|
|
`Expect byte at buffer position ${i} to be equal`
|
|
);
|
|
}
|
|
};
|
|
|
|
globalThis.add_result_callback((test, ...args) => {
|
|
if (
|
|
[
|
|
'Blob with type "A"',
|
|
'Blob with type "TEXT/HTML"',
|
|
"Getters and value conversions should happen in order until an exception is thrown.",
|
|
"Using type in File constructor: TEXT/PLAIN",
|
|
"Using type in File constructor: text/plain;charset=UTF-8",
|
|
].includes(test.name)
|
|
)
|
|
return;
|
|
|
|
const INDENT_SIZE = 2;
|
|
const reporter = {};
|
|
|
|
reporter.startSuite = (name) => console.log(`\n ${name}\n`);
|
|
|
|
reporter.pass = (message) => console.log(indent("√ " + message, INDENT_SIZE));
|
|
|
|
reporter.fail = (message) =>
|
|
console.log(indent("\u00D7 " + message, INDENT_SIZE));
|
|
|
|
reporter.reportStack = (stack) => console.log(indent(stack, INDENT_SIZE * 2));
|
|
|
|
function indent(string, times) {
|
|
const prefix = " ".repeat(times);
|
|
return string
|
|
.split("\n")
|
|
.map((l) => prefix + l)
|
|
.join("\n");
|
|
}
|
|
|
|
if (test.status === 0) {
|
|
reporter.pass(test.name);
|
|
} else if (test.status === 1) {
|
|
reporter.fail(`${test.name}\n`);
|
|
reporter.reportStack(`${test.message}\n${test.stack}`);
|
|
hasFailed = true;
|
|
} else if (test.status === 2) {
|
|
reporter.fail(`${test.name} (timeout)\n`);
|
|
reporter.reportStack(`${test.message}\n${test.stack}`);
|
|
hasFailed = true;
|
|
} else if (test.status === 3) {
|
|
reporter.fail(`${test.name} (incomplete)\n`);
|
|
reporter.reportStack(`${test.message}\n${test.stack}`);
|
|
hasFailed = true;
|
|
} else if (test.status === 4) {
|
|
reporter.fail(`${test.name} (precondition failed)\n`);
|
|
reporter.reportStack(`${test.message}\n${test.stack}`);
|
|
hasFailed = true;
|
|
} else {
|
|
reporter.fail(`unknown test status: ${test.status}`);
|
|
hasFailed = true;
|
|
}
|
|
});
|
|
|
|
globalThis.File = File;
|
|
globalThis.Blob = Blob;
|
|
globalThis.garbageCollect = () => {};
|
|
globalThis.test_blob = test_blob;
|
|
globalThis.test_blob_binary = test_blob_binary;
|
|
// Because WPT doesn't clean up after itself
|
|
globalThis.MessageChannel = class extends MessageChannel {
|
|
constructor() {
|
|
super();
|
|
setTimeout(() => {
|
|
this.port1.close();
|
|
this.port2.close();
|
|
this.port1.onmessage = this.port2.onmessage = null;
|
|
}, 100);
|
|
}
|
|
};
|
|
|
|
import("https://wpt.live/FileAPI/file/File-constructor.any.js");
|
|
import("https://wpt.live/FileAPI/blob/Blob-constructor.any.js");
|
|
import("https://wpt.live/FileAPI/blob/Blob-array-buffer.any.js");
|
|
import("https://wpt.live/FileAPI/blob/Blob-slice-overflow.any.js");
|
|
import("https://wpt.live/FileAPI/blob/Blob-slice.any.js");
|
|
import("https://wpt.live/FileAPI/blob/Blob-stream.any.js");
|
|
import("https://wpt.live/FileAPI/blob/Blob-text.any.js");
|
|
import("./own-misc-test.js");
|
|
|
|
if (hasFailed) {
|
|
console.log("Tests failed");
|
|
process.exit(1);
|
|
}
|