summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/infrastructure/channels/serialize_child.html
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /testing/web-platform/tests/infrastructure/channels/serialize_child.html
parentInitial commit. (diff)
downloadthunderbird-upstream.tar.xz
thunderbird-upstream.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/infrastructure/channels/serialize_child.html')
-rw-r--r--testing/web-platform/tests/infrastructure/channels/serialize_child.html173
1 files changed, 173 insertions, 0 deletions
diff --git a/testing/web-platform/tests/infrastructure/channels/serialize_child.html b/testing/web-platform/tests/infrastructure/channels/serialize_child.html
new file mode 100644
index 0000000000..6ad3accfee
--- /dev/null
+++ b/testing/web-platform/tests/infrastructure/channels/serialize_child.html
@@ -0,0 +1,173 @@
+<!doctype html>
+<script src="/resources/channel.sub.js"></script>
+<script src="serialize-data.js"></script>
+<script>
+
+let lastData;
+
+// Hack: these will be converted into testharness AssertionError instances in the test
+// This means they will be treated identically to asserts raised by `assert_` in the harness
+// In the long term we want to be able to use parts of testharness.js directly in remote
+// contexts and automatically send the results over a channel.
+function AssertionError(message) {
+ this.message = message;
+}
+AssertionError.prototype = Object.create(Error.prototype);
+
+function compareResult(name, actual) {
+ let obj = objects[name];
+ // If there's an output property use that, otherwise assume the output is equal to the input
+ let expected = obj.hasOwnProperty("output") ? obj.output : obj.input;
+ seen = new Set();
+ try {
+ compareValue(actual, expected, seen);
+ } catch(e) {
+ throw new AssertionError(e.message);
+ }
+ return true;
+}
+
+function compareValue(actualValue, expectedValue, seen) {
+ let seenActual;
+ if (typeof actualValue != typeof expectedValue) {
+ throw new Error(`Types differ, expected ${typeof expectedValue}, got ${typeof actualValue}`);
+ }
+ if (["undefined", "string", "boolean", "number", "bigint"].includes(typeof expectedValue) ||
+ actualValue === null) {
+ if (!Object.is(actualValue, expectedValue)) {
+ throw new Error(`Expected ${typeof expected} ${expected}, got ${actual}`);
+ }
+ return;
+ }
+
+ if (expectedValue.constructor && actualValue.constructor && expectedValue.constructor.name !== actualValue.constructor.name) {
+ throw new Error(`Constructors differ, expected ${expectedValue.constructor.name}, got ${actualValue.constructor.name}`);
+ }
+ if (expectedValue.constructor && expectedValue.constructor.name === "SendChannel") {
+ if (expectedValue.uuid !== actualValue.uuid) {
+ throw new Error(`SendChannels differ, expected uuid ${expectedValue.uuid}, got ${actualValue.uuid}`);
+ }
+ }
+ else if (expectedValue.constructor && expectedValue.constructor.name === "RegExp") {
+ if (expectedValue.source !== actualValue.source ||
+ expectedValue.flags !== actualValue.flags) {
+ throw new Error(`RegExps differ, expected ${expectedValue}, got ${actualValue}`);
+ }
+ } else if (expectedValue.constructor && expectedValue.constructor.name == "Date") {
+ if (expectedValue.valueOf() !== actualValue.valueOf()) {
+ throw new Error(`Dates differ, expected ${expectedValue.valueOf()} (${expectedValue.toDateString()}), `
+ `got ${actualValue.valueOf()} (${actualValue.toDateString()})`);
+ }
+ } else if (expectedValue instanceof Error) {
+ if (expectedValue.message !== actualValue.message ||
+ expectedValue.lineNumber !== actualValue.lineNumber ||
+ expectedValue.columnNumber !== actualValue.columnNumber ||
+ expectedValue.fileName !== actualValue.fileName) {
+ throw new Error(`Errors differ, expected ${expectedValue}, got ${actualValue}`);
+ }
+ } else if (Array.isArray(expectedValue)) {
+ seenActual = seen.has(actualValue);
+ seenExpected = seen.has(expectedValue)
+ if (seenActual && seenExpected) {
+ return;
+ } else if (seenExpected && !seenActual) {
+ throw new Error(`Expected cyclic array`);
+ } else if (!seenExpected && seenActual) {
+ throw new Error(`Got unexpected cyclic array`);
+ }
+ seen.add(actualValue);
+ seen.add(expectedValue);
+
+ if (actualValue.length !== expectedValue.length) {
+ throw new Error(`Array lengths differ, expected ${expectedValue.length}, got ${actualValue.length}`);
+ }
+ for (let i=0; i<actualValue.length; i++) {
+ compareValue(actualValue[i], expectedValue[i], seen);
+ }
+ } else if (expectedValue.constructor && expectedValue.constructor.name === "Set") {
+ seenActual = seen.has(actualValue);
+ seenExpected = seen.has(expectedValue)
+ if (seenActual && seenExpected) {
+ return;
+ } else if (seenExpected && !seenActual) {
+ throw new Error(`Expected cyclic set`);
+ } else if (!seenExpected && seenActual) {
+ throw new Error(`Got unexpected cyclic set`);
+ }
+ seen.add(actualValue);
+ seen.add(expectedValue);
+
+
+ if (actualValue.size !== expectedValue.size) {
+ throw new Error(`Set sizes differ, expected ${expectedValue.size}, got ${actualValue.size}`);
+ }
+ // For an arbitary set it's complex to check if two sets are equivalent, since
+ // we'd need to compare every object in one set with every object in the
+ // other set, so we end up with quadratic complexity. Instead, just support sets
+ // containing primitives and rely on the other tests for correct handling of
+ // objects.
+ for (let entry of expectedValue) {
+ if (["undefined", "string", "boolean", "number", "bigint"].includes(typeof entry) || entry === null) {
+ if(!actualValue.has(entry)) {
+ throw new Error(`Set missing entry, expected ${entry}`);
+ }
+ } else {
+ throw new Error(`Can't compare non-primitive value ${entry} inside sets`);
+ }
+ }
+ } else if (expectedValue.constructor && expectedValue.constructor.name === "Map") {
+ seenActual = seen.has(actualValue);
+ seenExpected = seen.has(expectedValue)
+ if (seenActual && seenExpected) {
+ return;
+ } else if (seenExpected && !seenActual) {
+ throw new Error(`Expected cyclic map`);
+ } else if (!seenExpected && seenActual) {
+ throw new Error(`Got unexpected cyclic map`);
+ }
+ seen.add(actualValue);
+ seen.add(expectedValue);
+
+ if (actualValue.size !== expectedValue.size) {
+ throw new Error(`Map sizes differ, expected ${expectedValue.size}, got ${actualValue.size}`);
+ }
+ // So for a set we can't really check if the values are the same
+ // except where they're primitives
+ for (let [key, value] of expectedValue.entries()) {
+ if(!actualValue.has(key)) {
+ throw new Error(`Map missing key, expected key ${key} with value ${value}`);
+ }
+ compareValue(actualValue.get(key), value, seen);
+ }
+ } else {
+ seenActual = seen.has(actualValue);
+ seenExpected = seen.has(expectedValue)
+ if (seenActual && seenExpected) {
+ return;
+ } else if (seenExpected && !seenActual) {
+ throw new Error(`Expected cyclic object`);
+ } else if (!seenExpected && seenActual) {
+ throw new Error(`Got unexpected cyclic object`);
+ }
+ seen.add(actualValue);
+ seen.add(expectedValue);
+
+
+ // Compare as a general Object
+ let expectedEntries = Object.entries(expectedValue);
+ if (Object.keys(actualValue).length !== expectedEntries.length) {
+ throw new Error(`Object keys differ, expected [${Object.keys(expectedValue).join(",")}], got [${Object.keys(actualValue).join(",")}]`);
+ }
+ // So for a set we can't really check if the values are the same
+ // except where they're primitives
+ for (let [name, entry] of expectedEntries) {
+ if(!actualValue.hasOwnProperty(name)) {
+ throw new Error(`Object missing key ${name}`);
+ }
+ compareValue(actualValue[name], entry, seen);
+ }
+ }
+}
+
+ctx = start_global_channel();
+</script>