summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/workers/semantics
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/workers/semantics')
-rw-r--r--testing/web-platform/tests/workers/semantics/encodings/001.html21
-rw-r--r--testing/web-platform/tests/workers/semantics/encodings/001.html.headers1
-rw-r--r--testing/web-platform/tests/workers/semantics/encodings/002.html23
-rw-r--r--testing/web-platform/tests/workers/semantics/encodings/002.html.headers1
-rw-r--r--testing/web-platform/tests/workers/semantics/encodings/003-1.py4
-rw-r--r--testing/web-platform/tests/workers/semantics/encodings/003.html26
-rw-r--r--testing/web-platform/tests/workers/semantics/encodings/004.html27
-rw-r--r--testing/web-platform/tests/workers/semantics/encodings/004.worker.js5
-rw-r--r--testing/web-platform/tests/workers/semantics/interface-objects/001.worker.js79
-rw-r--r--testing/web-platform/tests/workers/semantics/interface-objects/002.worker.js49
-rw-r--r--testing/web-platform/tests/workers/semantics/interface-objects/003.html106
-rw-r--r--testing/web-platform/tests/workers/semantics/interface-objects/004.html73
-rw-r--r--testing/web-platform/tests/workers/semantics/multiple-workers/001.html41
-rw-r--r--testing/web-platform/tests/workers/semantics/multiple-workers/002.html28
-rw-r--r--testing/web-platform/tests/workers/semantics/multiple-workers/003.html34
-rw-r--r--testing/web-platform/tests/workers/semantics/multiple-workers/004-1.html7
-rw-r--r--testing/web-platform/tests/workers/semantics/multiple-workers/004-2.js6
-rw-r--r--testing/web-platform/tests/workers/semantics/multiple-workers/004.html34
-rw-r--r--testing/web-platform/tests/workers/semantics/multiple-workers/005.html37
-rw-r--r--testing/web-platform/tests/workers/semantics/multiple-workers/006-1.js3
-rw-r--r--testing/web-platform/tests/workers/semantics/multiple-workers/006.html35
-rw-r--r--testing/web-platform/tests/workers/semantics/multiple-workers/007.html39
-rw-r--r--testing/web-platform/tests/workers/semantics/multiple-workers/008-1.html8
-rw-r--r--testing/web-platform/tests/workers/semantics/multiple-workers/008.html31
-rw-r--r--testing/web-platform/tests/workers/semantics/navigation/001-1.html23
-rw-r--r--testing/web-platform/tests/workers/semantics/navigation/001.html36
-rw-r--r--testing/web-platform/tests/workers/semantics/navigation/002.html36
-rw-r--r--testing/web-platform/tests/workers/semantics/reporting-errors/001.html53
-rw-r--r--testing/web-platform/tests/workers/semantics/reporting-errors/002.html59
-rw-r--r--testing/web-platform/tests/workers/semantics/reporting-errors/003.html39
-rw-r--r--testing/web-platform/tests/workers/semantics/reporting-errors/004-1.html18
-rw-r--r--testing/web-platform/tests/workers/semantics/reporting-errors/004.html39
-rw-r--r--testing/web-platform/tests/workers/semantics/run-a-worker/001.html22
-rw-r--r--testing/web-platform/tests/workers/semantics/run-a-worker/002.html24
-rw-r--r--testing/web-platform/tests/workers/semantics/run-a-worker/003.html21
-rw-r--r--testing/web-platform/tests/workers/semantics/structured-clone/common.js596
-rw-r--r--testing/web-platform/tests/workers/semantics/structured-clone/dedicated.html9
-rw-r--r--testing/web-platform/tests/workers/semantics/structured-clone/dedicated.js4
-rw-r--r--testing/web-platform/tests/workers/semantics/structured-clone/shared.html9
-rw-r--r--testing/web-platform/tests/workers/semantics/structured-clone/shared.js6
-rw-r--r--testing/web-platform/tests/workers/semantics/structured-clone/worker-common.js1018
-rw-r--r--testing/web-platform/tests/workers/semantics/xhr/001-1.xml1
-rw-r--r--testing/web-platform/tests/workers/semantics/xhr/001.html35
-rw-r--r--testing/web-platform/tests/workers/semantics/xhr/002.html32
-rw-r--r--testing/web-platform/tests/workers/semantics/xhr/003.html41
-rw-r--r--testing/web-platform/tests/workers/semantics/xhr/004.html36
-rw-r--r--testing/web-platform/tests/workers/semantics/xhr/005.html21
-rw-r--r--testing/web-platform/tests/workers/semantics/xhr/006.html21
-rw-r--r--testing/web-platform/tests/workers/semantics/xhr/support/001-1.xml1
-rw-r--r--testing/web-platform/tests/workers/semantics/xhr/support/005-1.js5
-rw-r--r--testing/web-platform/tests/workers/semantics/xhr/support/006-1.js7
51 files changed, 2930 insertions, 0 deletions
diff --git a/testing/web-platform/tests/workers/semantics/encodings/001.html b/testing/web-platform/tests/workers/semantics/encodings/001.html
new file mode 100644
index 000000000..0ebec0b03
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/encodings/001.html
@@ -0,0 +1,21 @@
+<!--
+postMessage('Ã¥');
+/*
+-->
+<!doctype html>
+<title>encoding, dedicated worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function() {
+ var worker = new Worker('#');
+ worker.onmessage = this.step_func(function(e) {
+ assert_equals(e.data, '\u00e5');
+ this.done();
+ });
+});
+</script>
+<!--
+*/
+//--> \ No newline at end of file
diff --git a/testing/web-platform/tests/workers/semantics/encodings/001.html.headers b/testing/web-platform/tests/workers/semantics/encodings/001.html.headers
new file mode 100644
index 000000000..2340a89c9
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/encodings/001.html.headers
@@ -0,0 +1 @@
+Content-Type: text/html; charset=windows-1252
diff --git a/testing/web-platform/tests/workers/semantics/encodings/002.html b/testing/web-platform/tests/workers/semantics/encodings/002.html
new file mode 100644
index 000000000..fdcc4f0a2
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/encodings/002.html
@@ -0,0 +1,23 @@
+<!--
+onconnect = function(e) {
+ e.ports[0].postMessage('Ã¥');
+}
+/*
+-->
+<!doctype html>
+<title>encoding, shared worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function() {
+ var worker = new SharedWorker('#', '');
+ worker.port.onmessage = this.step_func(function(e) {
+ assert_equals(e.data, '\u00e5');
+ this.done();
+ });
+});
+</script>
+<!--
+*/
+//--> \ No newline at end of file
diff --git a/testing/web-platform/tests/workers/semantics/encodings/002.html.headers b/testing/web-platform/tests/workers/semantics/encodings/002.html.headers
new file mode 100644
index 000000000..2340a89c9
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/encodings/002.html.headers
@@ -0,0 +1 @@
+Content-Type: text/html; charset=windows-1252
diff --git a/testing/web-platform/tests/workers/semantics/encodings/003-1.py b/testing/web-platform/tests/workers/semantics/encodings/003-1.py
new file mode 100644
index 000000000..1e899aac2
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/encodings/003-1.py
@@ -0,0 +1,4 @@
+ # -*- coding: utf-8 -*-
+
+def main(request, response):
+ return "PASS" if request.GET.first('x') == 'Ã¥' else "FAIL"
diff --git a/testing/web-platform/tests/workers/semantics/encodings/003.html b/testing/web-platform/tests/workers/semantics/encodings/003.html
new file mode 100644
index 000000000..a0f964c3c
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/encodings/003.html
@@ -0,0 +1,26 @@
+<!--
+var xhr = new XMLHttpRequest();
+xhr.open('GET', '003-1.py?x=Ã¥', false);
+xhr.send();
+var passed = xhr.responseText == 'PASS';
+postMessage(passed);
+
+/*
+-->
+<!doctype html>
+<title>URL encoding, dedicated worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function() {
+ var worker = new Worker('#');
+ worker.onmessage = this.step_func(function(e) {
+ assert_true(e.data);
+ this.done();
+ });
+});
+</script>
+<!--
+*/
+//-->
diff --git a/testing/web-platform/tests/workers/semantics/encodings/004.html b/testing/web-platform/tests/workers/semantics/encodings/004.html
new file mode 100644
index 000000000..bb1442633
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/encodings/004.html
@@ -0,0 +1,27 @@
+<!--
+onconnect = function(e) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', '003-1.py?x=Ã¥', false);
+ xhr.send();
+ var passed = xhr.responseText == 'PASS';
+ e.ports[0].postMessage(passed);
+}
+/*
+-->
+<!doctype html>
+<title>URL encoding, shared worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function() {
+ var worker = new SharedWorker('#');
+ worker.port.onmessage = this.step_func(function(e) {
+ assert_true(e.data);
+ this.done();
+ });
+});
+</script>
+<!--
+*/
+//--> \ No newline at end of file
diff --git a/testing/web-platform/tests/workers/semantics/encodings/004.worker.js b/testing/web-platform/tests/workers/semantics/encodings/004.worker.js
new file mode 100644
index 000000000..28489a572
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/encodings/004.worker.js
@@ -0,0 +1,5 @@
+importScripts("/resources/testharness.js");
+test(function() {
+ assert_equals("ÿ", "\ufffd");
+}, "Decoding invalid utf-8");
+done();
diff --git a/testing/web-platform/tests/workers/semantics/interface-objects/001.worker.js b/testing/web-platform/tests/workers/semantics/interface-objects/001.worker.js
new file mode 100644
index 000000000..23df42036
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/interface-objects/001.worker.js
@@ -0,0 +1,79 @@
+importScripts("/resources/testharness.js");
+var expected = [
+ // https://html.spec.whatwg.org/
+ "WorkerGlobalScope",
+ "DedicatedWorkerGlobalScope",
+ "Worker",
+ "SharedWorker",
+ "MessagePort",
+ "MessageEvent",
+ "WorkerNavigator",
+ "MessageChannel",
+ "WorkerLocation",
+ "ImageData",
+ "ImageBitmap",
+ "CanvasPath",
+ "Path2D",
+ "PromiseRejectionEvent",
+ "EventSource",
+ "WebSocket",
+ "CloseEvent",
+ "BroadcastChannel",
+ // https://tc39.github.io/ecma262/
+ "ArrayBuffer",
+ "Int8Array",
+ "Uint8Array",
+ "Uint8ClampedArray",
+ "Int16Array",
+ "Uint16Array",
+ "Int32Array",
+ "Uint32Array",
+ "Float32Array",
+ "Float64Array",
+ "DataView",
+ // https://xhr.spec.whatwg.org/
+ "XMLHttpRequestEventTarget",
+ "XMLHttpRequestUpload",
+ "XMLHttpRequest",
+ "ProgressEvent",
+ "FormData",
+ // https://url.spec.whatwg.org/
+ "URL",
+ "URLSearchParams",
+ // https://w3c.github.io/FileAPI/
+ "File",
+ "Blob",
+ "FileList",
+ "FileReader",
+ "FileReaderSync",
+ // https://dom.spec.whatwg.org/
+ "EventTarget",
+ "ErrorEvent",
+ "Event",
+ "CustomEvent",
+ // http://heycam.github.io/webidl/
+ "DOMException",
+ // https://streams.spec.whatwg.org/
+ "ReadableStream",
+ "WritableStream",
+ "ByteLengthQueuingStrategy",
+ "CountQueuingStrategy",
+ // http://w3c.github.io/IndexedDB/
+ "IDBRequest",
+ "IDBOpenDBRequest",
+ "IDBVersionChangeEvent",
+ "IDBFactory",
+ "IDBDatabase",
+ "IDBObjectStore",
+ "IDBIndex",
+ "IDBKeyRange",
+ "IDBCursor",
+ "IDBCursorWithValue",
+ "IDBTransaction",
+];
+for (var i = 0; i < expected.length; ++i) {
+ test(function () {
+ assert_own_property(self, expected[i]);
+ }, "The " + expected[i] + " interface object should be exposed.");
+}
+done();
diff --git a/testing/web-platform/tests/workers/semantics/interface-objects/002.worker.js b/testing/web-platform/tests/workers/semantics/interface-objects/002.worker.js
new file mode 100644
index 000000000..0f514988b
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/interface-objects/002.worker.js
@@ -0,0 +1,49 @@
+importScripts("/resources/testharness.js");
+var unexpected = [
+ // https://html.spec.whatwg.org/
+ "SharedWorkerGlobalScope",
+ "AbstractView",
+ "AbstractWorker",
+ "ApplicationCache",
+ "Location",
+ "Navigator",
+ "Audio",
+ "HTMLCanvasElement",
+ "Path",
+ "TextMetrics",
+ "CanvasProxy",
+ "CanvasRenderingContext2D",
+ "DrawingStyle",
+ "CanvasGradient",
+ "CanvasPattern",
+ "PopStateEvent",
+ "HashChangeEvent",
+ "PageTransitionEvent",
+ // https://dom.spec.whatwg.org/
+ "DOMImplementation",
+ // https://streams.spec.whatwg.org/
+ "ReadableStreamDefaultReader",
+ "ReadableStreamBYOBReader",
+ "ReadableStreamDefaultController",
+ "ReadableByteStreamController",
+ "WritableStreamDefaultWriter",
+ "WritableStreamDefaultController",
+ // http://w3c.github.io/IndexedDB/
+ "IDBEnvironment",
+ // https://www.w3.org/TR/2010/NOTE-webdatabase-20101118/
+ "Database",
+ // https://w3c.github.io/uievents/
+ "UIEvent",
+ "FocusEvent",
+ "MouseEvent",
+ "WheelEvent",
+ "InputEvent",
+ "KeyboardEvent",
+ "CompositionEvent",
+];
+for (var i = 0; i < unexpected.length; ++i) {
+ test(function () {
+ assert_false(unexpected[i] in self);
+ }, "The " + unexpected[i] + " interface object should not be exposed.");
+}
+done();
diff --git a/testing/web-platform/tests/workers/semantics/interface-objects/003.html b/testing/web-platform/tests/workers/semantics/interface-objects/003.html
new file mode 100644
index 000000000..5277825db
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/interface-objects/003.html
@@ -0,0 +1,106 @@
+<!--
+onconnect = function(e) {
+ var expected = [
+ // https://html.spec.whatwg.org/
+ "ApplicationCache",
+ "WorkerGlobalScope",
+ "SharedWorkerGlobalScope",
+ "Worker",
+ "SharedWorker",
+ "MessagePort",
+ "MessageEvent",
+ "WorkerNavigator",
+ "MessageChannel",
+ "WorkerLocation",
+ "ImageData",
+ "ImageBitmap",
+ "CanvasPath",
+ "Path2D",
+ "PromiseRejectionEvent",
+ "EventSource",
+ "WebSocket",
+ "CloseEvent",
+ "BroadcastChannel",
+ // https://tc39.github.io/ecma262/
+ "ArrayBuffer",
+ "Int8Array",
+ "Uint8Array",
+ "Uint8ClampedArray",
+ "Int16Array",
+ "Uint16Array",
+ "Int32Array",
+ "Uint32Array",
+ "Float32Array",
+ "Float64Array",
+ "DataView",
+ // https://xhr.spec.whatwg.org/
+ "XMLHttpRequestEventTarget",
+ "XMLHttpRequestUpload",
+ "XMLHttpRequest",
+ "ProgressEvent",
+ "FormData",
+ // https://url.spec.whatwg.org/
+ "URL",
+ "URLSearchParams",
+ // https://w3c.github.io/FileAPI/
+ "File",
+ "Blob",
+ "FileList",
+ "FileReader",
+ "FileReaderSync",
+ // https://dom.spec.whatwg.org/
+ "EventTarget",
+ "ErrorEvent",
+ "Event",
+ "CustomEvent",
+ // http://heycam.github.io/webidl/
+ "DOMException",
+ // https://streams.spec.whatwg.org/
+ "ReadableStream",
+ "WritableStream",
+ "ByteLengthQueuingStrategy",
+ "CountQueuingStrategy",
+ // http://w3c.github.io/IndexedDB/
+ "IDBRequest",
+ "IDBOpenDBRequest",
+ "IDBVersionChangeEvent",
+ "IDBFactory",
+ "IDBDatabase",
+ "IDBObjectStore",
+ "IDBIndex",
+ "IDBKeyRange",
+ "IDBCursor",
+ "IDBCursorWithValue",
+ "IDBTransaction",
+ ];
+ var result = [];
+ for (var i = 0; i < expected.length; ++i) {
+ result.push([expected[i], expected[i] in self]);
+ }
+ e.ports[0].postMessage(result);
+}
+/*
+-->
+<!doctype html>
+<title>available interface objects in shared worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+setup(function() {
+ window.worker = new SharedWorker('#');
+ worker.port.onmessage = function(e) {
+ var result = e.data;
+ for (var i = 0; i < result.length; ++i) {
+ test(function() {
+ assert_true(result[i][1]);
+ }, "The " + result[i][0] + " interface object should be exposed");
+ }
+ done();
+ }
+}, {explicit_done: true});
+</script>
+<!--
+*/
+//-->
+
diff --git a/testing/web-platform/tests/workers/semantics/interface-objects/004.html b/testing/web-platform/tests/workers/semantics/interface-objects/004.html
new file mode 100644
index 000000000..2e4387ede
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/interface-objects/004.html
@@ -0,0 +1,73 @@
+<!--
+onconnect = function(e) {
+ var unexpected = [
+ // https://html.spec.whatwg.org/
+ "DedicatedWorkerGlobalScope",
+ "AbstractView",
+ "AbstractWorker",
+ "Location",
+ "Navigator",
+ "DOMImplementation",
+ "Audio",
+ "HTMLCanvasElement",
+ "Path",
+ "TextMetrics",
+ "CanvasProxy",
+ "CanvasRenderingContext2D",
+ "DrawingStyle",
+ "CanvasGradient",
+ "CanvasPattern",
+ "PopStateEvent",
+ "HashChangeEvent",
+ "PageTransitionEvent",
+ // https://streams.spec.whatwg.org/
+ "ReadableStreamDefaultReader",
+ "ReadableStreamBYOBReader",
+ "ReadableStreamDefaultController",
+ "ReadableByteStreamController",
+ "WritableStreamDefaultWriter",
+ "WritableStreamDefaultController",
+ // http://w3c.github.io/IndexedDB/
+ "IDBEnvironment",
+ // https://www.w3.org/TR/2010/NOTE-webdatabase-20101118/
+ "Database",
+ // https://w3c.github.io/uievents/
+ "UIEvent",
+ "FocusEvent",
+ "MouseEvent",
+ "WheelEvent",
+ "InputEvent",
+ "KeyboardEvent",
+ "CompositionEvent",
+ ];
+ var result = [];
+ for (var i = 0; i < unexpected.length; ++i) {
+ result.push([unexpected[i], unexpected[i] in self]);
+ }
+ e.ports[0].postMessage(result);
+}
+/*
+-->
+<!doctype html>
+<title>unavailable interface objects in shared worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+setup(function() {
+ window.worker = new SharedWorker('#');
+ worker.port.onmessage = function(e) {
+ var result = e.data;
+ for (var i = 0; i < result.length; ++i) {
+ test(function() {
+ assert_false(result[i][1]);
+ }, "The " + result[i][0] + " interface object should not be exposed");
+ }
+ done();
+ }
+}, {explicit_done: true});
+</script>
+<!--
+*/
+//-->
+
diff --git a/testing/web-platform/tests/workers/semantics/multiple-workers/001.html b/testing/web-platform/tests/workers/semantics/multiple-workers/001.html
new file mode 100644
index 000000000..82ddcc3c1
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/multiple-workers/001.html
@@ -0,0 +1,41 @@
+<!--
+if ('onmessage' in self) { // dedicated worker
+ onmessage = function(e) {
+ postMessage(e.data);
+ }
+} else { // shared worker
+ onconnect = function(e) {
+ e.ports[0].onmessage = function(e) {
+ this.postMessage(e.data);
+ }
+ }
+}
+/*
+-->
+<!doctype html>
+<title>dedicated and shared worker in same page</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function() {
+ var worker = new Worker('#');
+ worker.onmessage = this.step_func(function(e) {
+ assert_equals(e.data, 'dedicated');
+ this.done();
+ });
+ worker.postMessage('dedicated');
+}, 'dedicated');
+async_test(function() {
+ var shared = new SharedWorker('#', '');
+ shared.port.onmessage = this.step_func(function(e) {
+ assert_equals(e.data, 'shared');
+ this.done();
+ });
+ shared.port.postMessage('shared');
+}, 'shared');
+</script>
+<!--
+*/
+//-->
+
diff --git a/testing/web-platform/tests/workers/semantics/multiple-workers/002.html b/testing/web-platform/tests/workers/semantics/multiple-workers/002.html
new file mode 100644
index 000000000..9ab1f54f4
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/multiple-workers/002.html
@@ -0,0 +1,28 @@
+<!--
+postMessage(1);
+/*
+-->
+<!doctype html>
+<title>creating 3 sibling dedicated workers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var w1 = new Worker('#');
+ var w2 = new Worker('#');
+ var w3 = new Worker('#');
+ var got = [false, false, false];
+ var check_done = t.step_func(function() {
+ if (got.every(function(x) {return x})) {
+ t.done();
+ }
+ });
+ w1.onmessage = t.step_func(function(e) {got[0] = true; check_done()});
+ w2.onmessage = t.step_func(function(e) {got[1] = true; check_done()});
+ w3.onmessage = t.step_func(function(e) {got[2] = true; check_done()});
+});
+</script>
+<!--
+*/
+//-->
diff --git a/testing/web-platform/tests/workers/semantics/multiple-workers/003.html b/testing/web-platform/tests/workers/semantics/multiple-workers/003.html
new file mode 100644
index 000000000..85c688bc0
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/multiple-workers/003.html
@@ -0,0 +1,34 @@
+<!--
+if (location.hash == '#1') {
+ var w2 = new Worker('#2');
+ w2.onmessage = function(e) {
+ postMessage('1'+e.data);
+ }
+} else if (location.hash == '#2') {
+ var w3 = new Worker('#3');
+ w3.onmessage = function(e) {
+ postMessage('2'+e.data);
+ }
+} else {
+ postMessage('3');
+}
+
+/*
+-->
+<!doctype html>
+<title>creating 3 nested dedicated workers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function() {
+ var w1 = new Worker('#1');
+ w1.onmessage = this.step_func(function(e) {
+ assert_equals(e.data, '123');
+ this.done();
+ });
+});
+</script>
+<!--
+*/
+//-->
diff --git a/testing/web-platform/tests/workers/semantics/multiple-workers/004-1.html b/testing/web-platform/tests/workers/semantics/multiple-workers/004-1.html
new file mode 100644
index 000000000..eac038c5b
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/multiple-workers/004-1.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<title></title>
+<script>
+window.onload = function() {
+ var w=new SharedWorker('004-2.js', 'x');
+};
+</script>
diff --git a/testing/web-platform/tests/workers/semantics/multiple-workers/004-2.js b/testing/web-platform/tests/workers/semantics/multiple-workers/004-2.js
new file mode 100644
index 000000000..e59cd6927
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/multiple-workers/004-2.js
@@ -0,0 +1,6 @@
+var port;
+onconnect = function(e) {
+ if (!port)
+ port = e.ports[0];
+ port.postMessage(1);
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/workers/semantics/multiple-workers/004.html b/testing/web-platform/tests/workers/semantics/multiple-workers/004.html
new file mode 100644
index 000000000..c47337008
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/multiple-workers/004.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<title>shared worker with multiple documents</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var i = 0;
+var load_count = 0;
+
+var w1 = new SharedWorker('004-2.js', 'x');
+w1.port.onmessage = function(e) {
+ i++;
+ check_result();
+};
+
+
+function iframe_loaded() {
+ load_count++;
+ check_result();
+}
+
+function check_result() {
+ //timeout to allow for extra, unexpected, messages to arrive
+ if (i == 3 && load_count == 2) {
+ setTimeout(function() {
+ assert_equals(load_count, 2);
+ assert_equals(i, 3);
+ done();
+ }, 500);
+ }
+}
+</script>
+<iframe src=004-1.html onload="iframe_loaded()"></iframe>
+<iframe src=004-1.html onload="iframe_loaded()"></iframe>
diff --git a/testing/web-platform/tests/workers/semantics/multiple-workers/005.html b/testing/web-platform/tests/workers/semantics/multiple-workers/005.html
new file mode 100644
index 000000000..289c25ec6
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/multiple-workers/005.html
@@ -0,0 +1,37 @@
+<!--
+if (location.hash == '#1') {
+ var w2 = new SharedWorker('#2');
+ w2.port.onmessage = function(e) {
+ postMessage('1'+e.data);
+ }
+} else if (location.hash == '#2') {
+ onconnect = function(e) {
+ var port = e.ports[0];
+ var w3 = new Worker('#3');
+ w3.onmessage = function(e) {
+ port.postMessage('2'+e.data);
+ }
+ }
+} else {
+ postMessage('3');
+}
+
+/*
+-->
+<!doctype html>
+<title>dedicated worker in shared worker in dedicated worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function() {
+ var w1 = new Worker('#1');
+ w1.onmessage = this.step_func(function(e) {
+ assert_equals(e.data, '123');
+ this.done();
+ });
+});
+</script>
+<!--
+*/
+//-->
diff --git a/testing/web-platform/tests/workers/semantics/multiple-workers/006-1.js b/testing/web-platform/tests/workers/semantics/multiple-workers/006-1.js
new file mode 100644
index 000000000..6c1ed9323
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/multiple-workers/006-1.js
@@ -0,0 +1,3 @@
+ onconnect = function(e) {
+ e.ports[0].postMessage('3');
+ } \ No newline at end of file
diff --git a/testing/web-platform/tests/workers/semantics/multiple-workers/006.html b/testing/web-platform/tests/workers/semantics/multiple-workers/006.html
new file mode 100644
index 000000000..ef2124256
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/multiple-workers/006.html
@@ -0,0 +1,35 @@
+<!--
+if (location.hash == '#1') {
+ onconnect = function(e) {
+ var port = e.ports[0];
+ var w2 = new Worker('#2');
+ w2.onmessage = function(e) {
+ port.postMessage('1'+e.data);
+ }
+ }
+} else if (location.hash == '#2') {
+ var w3 = new SharedWorker('006-1.js');
+ w3.port.onmessage = function(e) {
+ postMessage('2'+e.data);
+ }
+}
+
+/*
+-->
+<!doctype html>
+<title>shared worker in dedicated worker in shared worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function() {
+ var w1 = new SharedWorker('#1');
+ w1.port.onmessage = this.step_func(function(e) {
+ assert_equals(e.data, '123');
+ this.done();
+ });
+});
+</script>
+<!--
+*/
+//-->
diff --git a/testing/web-platform/tests/workers/semantics/multiple-workers/007.html b/testing/web-platform/tests/workers/semantics/multiple-workers/007.html
new file mode 100644
index 000000000..e99345073
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/multiple-workers/007.html
@@ -0,0 +1,39 @@
+<!--
+if (location.hash == '#1') {
+ onconnect = function(e) {
+ var port = e.ports[0];
+ var w2 = new Worker('#2');
+ w2.onmessage = function(e) {
+ port.postMessage('1'+e.data);
+ }
+ }
+} else if (location.hash == '#2') {
+ var w3 = new SharedWorker('#3');
+ w3.port.onmessage = function(e) {
+ postMessage('2'+e.data);
+ }
+} else {
+ onconnect = function(e) {
+ e.ports[0].postMessage('3');
+ }
+}
+
+/*
+-->
+<!doctype html>
+<title>shared worker in dedicated worker in shared worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function() {
+ var w1 = new SharedWorker('#1');
+ w1.port.onmessage = this.step_func(function(e) {
+ assert_equals(e.data, '123');
+ this.done();
+ });
+});
+</script>
+<!--
+*/
+//-->
diff --git a/testing/web-platform/tests/workers/semantics/multiple-workers/008-1.html b/testing/web-platform/tests/workers/semantics/multiple-workers/008-1.html
new file mode 100644
index 000000000..82a8a3835
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/multiple-workers/008-1.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<title>008-1</title>
+<script>
+var w1 = new SharedWorker('008.html#');
+w1.port.onmessage = function(e) {
+ e.ports[0].postMessage(2);
+}
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/workers/semantics/multiple-workers/008.html b/testing/web-platform/tests/workers/semantics/multiple-workers/008.html
new file mode 100644
index 000000000..fbb41e0d0
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/multiple-workers/008.html
@@ -0,0 +1,31 @@
+<!--
+var channel = new MessageChannel();
+var i = 0;
+onconnect = function(e) {
+ i++;
+ e.ports[0].postMessage(1, [channel['port' + i]]);
+}
+
+/*
+-->
+<!doctype html>
+<title>messagechannel in shared worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<iframe src=008-1.html></iframe>
+<script>
+var t = async_test();
+onload = t.step_func(function() {
+ var w1 = new SharedWorker('#');
+ w1.port.onmessage = this.step_func(function(e) {
+ e.ports[0].onmessage = this.step_func(function(e) {
+ assert_equals(e.data, 2);
+ this.done();
+ });
+ });
+});
+</script>
+<!--
+*/
+//-->
diff --git a/testing/web-platform/tests/workers/semantics/navigation/001-1.html b/testing/web-platform/tests/workers/semantics/navigation/001-1.html
new file mode 100644
index 000000000..9d7ecee17
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/navigation/001-1.html
@@ -0,0 +1,23 @@
+<!--
+setInterval(function() { postMessage(new Date()) }, 10)
+/*
+-->
+<!doctype html>
+<title>001-1</title>
+<script>
+onload = function() {
+ var worker = new Worker('#');
+ worker.onmessage = function(e) {
+ var started = !!parent.date;
+ parent.date = e.data;
+ if (!started) {
+ parent.start_test()
+ }
+ }
+}
+</script>
+<a href='data:text/html,<title>foo</title><script>onload=function(){parent.after_load()}</script>'>link</a>
+<!--
+*/
+//-->
+
diff --git a/testing/web-platform/tests/workers/semantics/navigation/001.html b/testing/web-platform/tests/workers/semantics/navigation/001.html
new file mode 100644
index 000000000..658df0624
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/navigation/001.html
@@ -0,0 +1,36 @@
+<!--
+
+/*
+-->
+<!doctype html>
+<title>navigating</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var date;
+var newDate;
+</script>
+<iframe></iframe>
+<script>
+var iframe = document.querySelector('iframe');
+onload = function() {
+ iframe.src = "001-1.html?" + Math.random();
+};
+var start_test = function() {
+ window[0].document.links[0].click();
+};
+var after_load = function() {
+ history.back();
+ newDate = new Date();
+ setTimeout(function() {
+ assert_greater_than(Number(date), Number(newDate));
+ assert_equals(window[0].document.title, '001-1');
+ done();
+ }, 2000);
+};
+</script>
+<!--
+*/
+//-->
+
diff --git a/testing/web-platform/tests/workers/semantics/navigation/002.html b/testing/web-platform/tests/workers/semantics/navigation/002.html
new file mode 100644
index 000000000..c0d5eb5c0
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/navigation/002.html
@@ -0,0 +1,36 @@
+<!--
+
+/*
+-->
+<!doctype html>
+<title>navigating 2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var date;
+var newDate;
+</script>
+<iframe></iframe>
+<script>
+var t = async_test();
+var iframe = document.querySelector('iframe');
+onload = t.step_func(function() {
+ iframe.src = "001-1.html?" + Math.random();
+});
+var start_test = t.step_func(function() {
+ window[0].document.links[0].click();
+});
+var after_load = t.step_func(function() {
+ newDate = new Date();
+ setTimeout(this.step_func(function() {
+ assert_less_than(Number(date), Number(newDate));
+ assert_equals(window[0].document.title, 'foo');
+ this.done();
+ }), 500);
+});
+</script>
+<!--
+*/
+//-->
+
diff --git a/testing/web-platform/tests/workers/semantics/reporting-errors/001.html b/testing/web-platform/tests/workers/semantics/reporting-errors/001.html
new file mode 100644
index 000000000..adba81f63
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/reporting-errors/001.html
@@ -0,0 +1,53 @@
+<!--
+var port;
+var timeout;
+onerror = function(a,b,c,d,e) {
+ // will return undefined, thus the error is "not handled"
+ // so error should be reported to the user, but this test doesn't check
+ // that.
+ // just make sure that this method is invoked with five arguments
+ clearTimeout(timeout);
+ var log = '';
+ if (arguments.length != 5)
+ log += 'got ' + arguments.length + ' arguments, expected 5. ';
+ if (typeof a != 'string')
+ log += 'first argument wasn\'t a string. ';
+ if (b != location.href)
+ log += 'second argument was ' + b + ', expected ' + location.href + '. ';
+ if (typeof c != 'number')
+ log += 'third argument wasn\'t a number. ';
+ if (typeof d != 'number')
+ log += 'fourth argument wasn\'t a number. ';
+ if (e != 42)
+ log += 'fifth argument wasn\'t the thrown exception. ';
+ port.postMessage(log);
+}
+onconnect = function (e) {
+ port = e.ports[0];
+ timeout = setTimeout(function() { port.postMessage('self.onerror was not invoked'); }, 250);
+ throw 42; // will "report the error"
+}
+
+
+/*
+-->
+<!doctype html>
+<title>shared worker, not handled</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+setup({allow_uncaught_exception:true});
+async_test(function() {
+ window.onerror = this.step_func(function(a) {
+ assert_unreached('window.onerror invoked: ' + a);
+ });
+ var worker = new SharedWorker('#', '');
+ worker.port.onmessage = this.step_func_done(function(e) {
+ assert_equals(e.data, '');
+ });
+});
+</script>
+<!--
+*/
+//-->
diff --git a/testing/web-platform/tests/workers/semantics/reporting-errors/002.html b/testing/web-platform/tests/workers/semantics/reporting-errors/002.html
new file mode 100644
index 000000000..c2cd377b4
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/reporting-errors/002.html
@@ -0,0 +1,59 @@
+<!--
+var port;
+var timeout;
+addEventListener('error', function(e) {
+ // event is not canceled, thus the error is "not handled"
+ // so error should be reported to the user, but this test doesn't check
+ // that.
+ // just make sure that this event has the right properties
+ clearTimeout(timeout);
+ var log = '';
+ if (!self.ErrorEvent || Object.getPrototypeOf(e) != ErrorEvent.prototype)
+ log += 'event should be an ErrorEvent. ';
+ if (e.bubbles)
+ log += 'event should not bubble. ';
+ if (!e.cancelable)
+ log += 'event should be cancelable. ';
+ if (!e.isTrusted)
+ log += 'event should be trusted. ';
+ if (typeof e.message != 'string')
+ log += 'message wasn\'t a string. ';
+ if (e.filename != location.href)
+ log += 'filename was ' + e.filename + ', expected ' + location.href + '. ';
+ if (typeof e.lineno != 'number')
+ log += 'lineno wasn\'t a number. ';
+ if (typeof e.colno != 'number')
+ log += 'colno argument wasn\'t a number. ';
+ if (e.error != 42)
+ log += 'fifth argument wasn\'t the thrown exception. ';
+ port.postMessage(log);
+}, false);
+onconnect = function (e) {
+ port = e.ports[0];
+ timeout = setTimeout(function() { port.postMessage('No error event fired'); }, 250);
+ throw 42; // will "report the error"
+}
+
+
+/*
+-->
+<!doctype html>
+<title>shared worker, addEventListener</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+setup({allow_uncaught_exception:true});
+async_test(function() {
+ window.onerror = this.step_func(function(a) {
+ assert_unreached('window.onerror invoked: ' + a);
+ });
+ var worker = new SharedWorker('#', '');
+ worker.port.onmessage = this.step_func_done(function(e) {
+ assert_equals(e.data, '');
+ });
+});
+</script>
+<!--
+*/
+//-->
diff --git a/testing/web-platform/tests/workers/semantics/reporting-errors/003.html b/testing/web-platform/tests/workers/semantics/reporting-errors/003.html
new file mode 100644
index 000000000..1b01c7caf
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/reporting-errors/003.html
@@ -0,0 +1,39 @@
+<!--
+onconnect = function (e) {
+ setTimeout(function() { e.ports[0].postMessage(''); }, 250);
+ y(); // will "report the error"
+ // onerror is null so it'll be "not handled", and the error should be
+ // reported to the user, although we don't test that here
+ // make sure we don't fire an error event on the message port or the
+ // SharedWorker object
+}
+
+
+/*
+-->
+<!doctype html>
+<title>shared worker, no error event on worker or port</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+setup({allow_uncaught_exception:true});
+async_test(function() {
+ window.onerror = this.step_func(function(a) {
+ assert_unreached('window.onerror invoked: ' + a);
+ });
+ var worker = new SharedWorker('#', '');
+ worker.addEventListener('error', this.step_func(function(e) {
+ assert_unreached('error on worker');
+ }), false);
+ worker.port.addEventListener('error', this.step_func(function(e) {
+ assert_unreached('error on port');
+ }), false);
+ worker.port.onmessage = this.step_func_done(function(e) {
+ assert_equals(e.data, '');
+ });
+});
+</script>
+<!--
+*/
+//-->
diff --git a/testing/web-platform/tests/workers/semantics/reporting-errors/004-1.html b/testing/web-platform/tests/workers/semantics/reporting-errors/004-1.html
new file mode 100644
index 000000000..676c21e60
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/reporting-errors/004-1.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script>
+parent.t.step(function() {
+ window.onerror = this.step_func(function(a) {
+ assert_unreached('(inner) window.onerror invoked: ' + a);
+ });
+ var worker = new SharedWorker('004.html#', '');
+ worker.addEventListener('error', this.step_func(function(e) {
+ parent.assert_unreached('(inner) error on worker');
+ }), false);
+ worker.port.addEventListener('error', this.step_func(function(e) {
+ parent.assert_unreached('(inner) error on port');
+ }), false);
+ worker.port.onmessage = this.step_func_done(function(e) {
+ parent.assert_equals(e.data, 2);
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/workers/semantics/reporting-errors/004.html b/testing/web-platform/tests/workers/semantics/reporting-errors/004.html
new file mode 100644
index 000000000..1dd1eb3b5
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/reporting-errors/004.html
@@ -0,0 +1,39 @@
+<!--
+var i = 0;
+onconnect = function (e) {
+ i++;
+ setTimeout(function() { e.ports[0].postMessage(i); }, 250);
+ y(); // will "report the error"
+}
+
+/*
+-->
+<!doctype html>
+<title>shared worker in two documents and window.onerror</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+setup({allow_uncaught_exception:true});
+var t = async_test(function() {
+ window.onerror = this.step_func(function(a) {
+ assert_unreached('(outer) window.onerror invoked: ' + a);
+ });
+ var worker = new SharedWorker('#', '');
+ worker.addEventListener('error', this.step_func(function(e) {
+ assert_unreached('(outer) error on worker');
+ }), false);
+ worker.port.addEventListener('error', this.step_func(function(e) {
+ assert_unreached('(outer) error on port');
+ }), false);
+ worker.port.onmessage = this.step_func(function(e) {
+ assert_equals(e.data, 1);
+ var iframe = document.createElement('iframe');
+ iframe.src = '004-1.html';
+ document.body.appendChild(iframe);
+ });
+});
+</script>
+<!--
+*/
+//-->
diff --git a/testing/web-platform/tests/workers/semantics/run-a-worker/001.html b/testing/web-platform/tests/workers/semantics/run-a-worker/001.html
new file mode 100644
index 000000000..aa0fc67ef
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/run-a-worker/001.html
@@ -0,0 +1,22 @@
+<!--
+postMessage(this === self);
+
+/*
+-->
+<!doctype html>
+<title>worker global scope, dedicated worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function() {
+ var worker = new Worker('#');
+ worker.onmessage = this.step_func(function(e) {
+ assert_true(e.data);
+ this.done();
+ });
+});
+</script>
+<!--
+*/
+//--> \ No newline at end of file
diff --git a/testing/web-platform/tests/workers/semantics/run-a-worker/002.html b/testing/web-platform/tests/workers/semantics/run-a-worker/002.html
new file mode 100644
index 000000000..3617ad727
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/run-a-worker/002.html
@@ -0,0 +1,24 @@
+<!--
+var passed = this === self;
+onconnect = function(e) {
+ e.ports[0].postMessage(passed);
+}
+/*
+-->
+<!doctype html>
+<title>worker global scope, shared worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function() {
+ var worker = new SharedWorker('#');
+ worker.port.onmessage = this.step_func(function(e) {
+ assert_true(e.data);
+ this.done();
+ });
+});
+</script>
+<!--
+*/
+//--> \ No newline at end of file
diff --git a/testing/web-platform/tests/workers/semantics/run-a-worker/003.html b/testing/web-platform/tests/workers/semantics/run-a-worker/003.html
new file mode 100644
index 000000000..8c2f07ee7
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/run-a-worker/003.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>handling for 404 response</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+setup({allow_uncaught_exception: true});
+
+async_test(function() {
+ var worker = new Worker('404_worker');
+ worker.onerror = this.step_func(function(e) { this.done(); });
+}, 'worker');
+
+async_test(function() {
+ var shared = new SharedWorker('404_shared');
+ // NOTE: this handler will not fire, as runtime scripting errors
+ // are not forwarded to SharedWorker objects, but instead reported to the user directly.
+ shared.onerror = this.step_func(function(e) { assert_unreached(); }, shared, 'error');
+ step_timeout(this.step_func(function() { this.done(); }), 5000);
+}, 'shared');
+</script>
diff --git a/testing/web-platform/tests/workers/semantics/structured-clone/common.js b/testing/web-platform/tests/workers/semantics/structured-clone/common.js
new file mode 100644
index 000000000..56c2a3004
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/structured-clone/common.js
@@ -0,0 +1,596 @@
+function createWorker(msg) {
+ // `type` is defined in the test case itself
+ if (type == 'dedicated')
+ return new Worker('dedicated.js#'+encodeURIComponent(msg));
+ else if (type == 'shared')
+ return (new SharedWorker('shared.js#'+encodeURIComponent(msg))).port;
+ else
+ assert_unreached('invalid or missing `type`');
+}
+
+function check(msg, input, callback, test_obj) {
+ if (!test_obj)
+ test_obj = async_test(msg);
+ test_obj.step(function() {
+ var w = createWorker(msg);
+ if (typeof input === 'function')
+ input = this.step(input);
+ w.postMessage(input);
+ w.onmessage = this.step_func(function(ev) { callback(ev.data, input, this); });
+ });
+}
+
+function compare_primitive(actual, input, test_obj) {
+ assert_equals(actual, input);
+ if (test_obj)
+ test_obj.done();
+}
+function compare_Array(callback, callback_is_async) {
+ return function(actual, input, test_obj) {
+ if (typeof actual === 'string')
+ assert_unreached(actual);
+ assert_true(actual instanceof Array, 'instanceof Array');
+ assert_not_equals(actual, input);
+ assert_equals(actual.length, input.length, 'length');
+ callback(actual, input);
+ if (test_obj && !callback_is_async)
+ test_obj.done();
+ }
+}
+
+function compare_Object(callback, callback_is_async) {
+ return function(actual, input, test_obj) {
+ if (typeof actual === 'string')
+ assert_unreached(actual);
+ assert_true(actual instanceof Object, 'instanceof Object');
+ assert_false(actual instanceof Array, 'instanceof Array');
+ assert_not_equals(actual, input);
+ callback(actual, input);
+ if (test_obj && !callback_is_async)
+ test_obj.done();
+ }
+}
+
+function enumerate_props(compare_func, test_obj) {
+ return function(actual, input) {
+ for (var x in input) {
+ compare_func(actual[x], input[x], test_obj);
+ }
+ };
+}
+
+check('primitive undefined', undefined, compare_primitive);
+check('primitive null', null, compare_primitive);
+check('primitive true', true, compare_primitive);
+check('primitive false', false, compare_primitive);
+check('primitive string, empty string', '', compare_primitive);
+check('primitive string, lone high surrogate', '\uD800', compare_primitive);
+check('primitive string, lone low surrogate', '\uDC00', compare_primitive);
+check('primitive string, NUL', '\u0000', compare_primitive);
+check('primitive string, astral character', '\uDBFF\uDFFD', compare_primitive);
+check('primitive number, 0.2', 0.2, compare_primitive);
+check('primitive number, 0', 0, compare_primitive);
+check('primitive number, -0', -0, compare_primitive);
+check('primitive number, NaN', NaN, compare_primitive);
+check('primitive number, Infinity', Infinity, compare_primitive);
+check('primitive number, -Infinity', -Infinity, compare_primitive);
+check('primitive number, 9007199254740992', 9007199254740992, compare_primitive);
+check('primitive number, -9007199254740992', -9007199254740992, compare_primitive);
+check('primitive number, 9007199254740994', 9007199254740994, compare_primitive);
+check('primitive number, -9007199254740994', -9007199254740994, compare_primitive);
+
+check('Array primitives', [undefined,
+ null,
+ true,
+ false,
+ '',
+ '\uD800',
+ '\uDC00',
+ '\u0000',
+ '\uDBFF\uDFFD',
+ 0.2,
+ 0,
+ -0,
+ NaN,
+ Infinity,
+ -Infinity,
+ 9007199254740992,
+ -9007199254740992,
+ 9007199254740994,
+ -9007199254740994], compare_Array(enumerate_props(compare_primitive)));
+check('Object primitives', {'undefined':undefined,
+ 'null':null,
+ 'true':true,
+ 'false':false,
+ 'empty':'',
+ 'high surrogate':'\uD800',
+ 'low surrogate':'\uDC00',
+ 'nul':'\u0000',
+ 'astral':'\uDBFF\uDFFD',
+ '0.2':0.2,
+ '0':0,
+ '-0':-0,
+ 'NaN':NaN,
+ 'Infinity':Infinity,
+ '-Infinity':-Infinity,
+ '9007199254740992':9007199254740992,
+ '-9007199254740992':-9007199254740992,
+ '9007199254740994':9007199254740994,
+ '-9007199254740994':-9007199254740994}, compare_Object(enumerate_props(compare_primitive)));
+
+function compare_Boolean(actual, input, test_obj) {
+ if (typeof actual === 'string')
+ assert_unreached(actual);
+ assert_true(actual instanceof Boolean, 'instanceof Boolean');
+ assert_equals(String(actual), String(input), 'converted to primitive');
+ assert_not_equals(actual, input);
+ if (test_obj)
+ test_obj.done();
+}
+check('Boolean true', new Boolean(true), compare_Boolean);
+check('Boolean false', new Boolean(false), compare_Boolean);
+check('Array Boolean objects', [new Boolean(true), new Boolean(false)], compare_Array(enumerate_props(compare_Boolean)));
+check('Object Boolean objects', {'true':new Boolean(true), 'false':new Boolean(false)}, compare_Object(enumerate_props(compare_Boolean)));
+
+function compare_obj(what) {
+ var Type = window[what];
+ return function(actual, input, test_obj) {
+ if (typeof actual === 'string')
+ assert_unreached(actual);
+ assert_true(actual instanceof Type, 'instanceof '+what);
+ assert_equals(Type(actual), Type(input), 'converted to primitive');
+ assert_not_equals(actual, input);
+ if (test_obj)
+ test_obj.done();
+ };
+}
+check('String empty string', new String(''), compare_obj('String'));
+check('String lone high surrogate', new String('\uD800'), compare_obj('String'));
+check('String lone low surrogate', new String('\uDC00'), compare_obj('String'));
+check('String NUL', new String('\u0000'), compare_obj('String'));
+check('String astral character', new String('\uDBFF\uDFFD'), compare_obj('String'));
+check('Array String objects', [new String(''),
+ new String('\uD800'),
+ new String('\uDC00'),
+ new String('\u0000'),
+ new String('\uDBFF\uDFFD')], compare_Array(enumerate_props(compare_obj('String'))));
+check('Object String objects', {'empty':new String(''),
+ 'high surrogate':new String('\uD800'),
+ 'low surrogate':new String('\uDC00'),
+ 'nul':new String('\u0000'),
+ 'astral':new String('\uDBFF\uDFFD')}, compare_Object(enumerate_props(compare_obj('String'))));
+
+check('Number 0.2', new Number(0.2), compare_obj('Number'));
+check('Number 0', new Number(0), compare_obj('Number'));
+check('Number -0', new Number(-0), compare_obj('Number'));
+check('Number NaN', new Number(NaN), compare_obj('Number'));
+check('Number Infinity', new Number(Infinity), compare_obj('Number'));
+check('Number -Infinity', new Number(-Infinity), compare_obj('Number'));
+check('Number 9007199254740992', new Number(9007199254740992), compare_obj('Number'));
+check('Number -9007199254740992', new Number(-9007199254740992), compare_obj('Number'));
+check('Number 9007199254740994', new Number(9007199254740994), compare_obj('Number'));
+check('Number -9007199254740994', new Number(-9007199254740994), compare_obj('Number'));
+check('Array Number objects', [new Number(0.2),
+ new Number(0),
+ new Number(-0),
+ new Number(NaN),
+ new Number(Infinity),
+ new Number(-Infinity),
+ new Number(9007199254740992),
+ new Number(-9007199254740992),
+ new Number(9007199254740994),
+ new Number(-9007199254740994)], compare_Array(enumerate_props(compare_obj('Number'))));
+check('Object Number objects', {'0.2':new Number(0.2),
+ '0':new Number(0),
+ '-0':new Number(-0),
+ 'NaN':new Number(NaN),
+ 'Infinity':new Number(Infinity),
+ '-Infinity':new Number(-Infinity),
+ '9007199254740992':new Number(9007199254740992),
+ '-9007199254740992':new Number(-9007199254740992),
+ '9007199254740994':new Number(9007199254740994),
+ '-9007199254740994':new Number(-9007199254740994)}, compare_Object(enumerate_props(compare_obj('Number'))));
+
+function compare_Date(actual, input, test_obj) {
+ if (typeof actual === 'string')
+ assert_unreached(actual);
+ assert_true(actual instanceof Date, 'instanceof Date');
+ assert_equals(Number(actual), Number(input), 'converted to primitive');
+ assert_not_equals(actual, input);
+ if (test_obj)
+ test_obj.done();
+}
+check('Date 0', new Date(0), compare_Date);
+check('Date -0', new Date(-0), compare_Date);
+check('Date -8.64e15', new Date(-8.64e15), compare_Date);
+check('Date 8.64e15', new Date(8.64e15), compare_Date);
+check('Array Date objects', [new Date(0),
+ new Date(-0),
+ new Date(-8.64e15),
+ new Date(8.64e15)], compare_Array(enumerate_props(compare_Date)));
+check('Object Date objects', {'0':new Date(0),
+ '-0':new Date(-0),
+ '-8.64e15':new Date(-8.64e15),
+ '8.64e15':new Date(8.64e15)}, compare_Object(enumerate_props(compare_Date)));
+
+function compare_RegExp(expected_source) {
+ // XXX ES6 spec doesn't define exact serialization for `source` (it allows several ways to escape)
+ return function(actual, input, test_obj) {
+ if (typeof actual === 'string')
+ assert_unreached(actual);
+ assert_true(actual instanceof RegExp, 'instanceof RegExp');
+ assert_equals(actual.global, input.global, 'global');
+ assert_equals(actual.ignoreCase, input.ignoreCase, 'ignoreCase');
+ assert_equals(actual.multiline, input.multiline, 'multiline');
+ assert_equals(actual.source, expected_source, 'source');
+ assert_equals(actual.sticky, input.sticky, 'sticky');
+ assert_equals(actual.unicode, input.unicode, 'unicode');
+ assert_equals(actual.lastIndex, 0, 'lastIndex');
+ assert_not_equals(actual, input);
+ if (test_obj)
+ test_obj.done();
+ }
+}
+function func_RegExp_flags_lastIndex() {
+ var r = /foo/gim;
+ r.lastIndex = 2;
+ return r;
+}
+function func_RegExp_sticky() {
+ return new RegExp('foo', 'y');
+}
+function func_RegExp_unicode() {
+ return new RegExp('foo', 'u');
+}
+check('RegExp flags and lastIndex', func_RegExp_flags_lastIndex, compare_RegExp('foo'));
+check('RegExp sticky flag', func_RegExp_sticky, compare_RegExp('foo'));
+check('RegExp unicode flag', func_RegExp_unicode, compare_RegExp('foo'));
+check('RegExp empty', new RegExp(''), compare_RegExp('(?:)'));
+check('RegExp slash', new RegExp('/'), compare_RegExp('\\/'));
+check('RegExp new line', new RegExp('\n'), compare_RegExp('\\n'));
+check('Array RegExp object, RegExp flags and lastIndex', [func_RegExp_flags_lastIndex()], compare_Array(enumerate_props(compare_RegExp('foo'))));
+check('Array RegExp object, RegExp sticky flag', function() { return [func_RegExp_sticky()]; }, compare_Array(enumerate_props(compare_RegExp('foo'))));
+check('Array RegExp object, RegExp unicode flag', function() { return [func_RegExp_unicode()]; }, compare_Array(enumerate_props(compare_RegExp('foo'))));
+check('Array RegExp object, RegExp empty', [new RegExp('')], compare_Array(enumerate_props(compare_RegExp('(?:)'))));
+check('Array RegExp object, RegExp slash', [new RegExp('/')], compare_Array(enumerate_props(compare_RegExp('\\/'))));
+check('Array RegExp object, RegExp new line', [new RegExp('\n')], compare_Array(enumerate_props(compare_RegExp('\\n'))));
+check('Object RegExp object, RegExp flags and lastIndex', {'x':func_RegExp_flags_lastIndex()}, compare_Object(enumerate_props(compare_RegExp('foo'))));
+check('Object RegExp object, RegExp sticky flag', function() { return {'x':func_RegExp_sticky()}; }, compare_Object(enumerate_props(compare_RegExp('foo'))));
+check('Object RegExp object, RegExp unicode flag', function() { return {'x':func_RegExp_unicode()}; }, compare_Object(enumerate_props(compare_RegExp('foo'))));
+check('Object RegExp object, RegExp empty', {'x':new RegExp('')}, compare_Object(enumerate_props(compare_RegExp('(?:)'))));
+check('Object RegExp object, RegExp slash', {'x':new RegExp('/')}, compare_Object(enumerate_props(compare_RegExp('\\/'))));
+check('Object RegExp object, RegExp new line', {'x':new RegExp('\n')}, compare_Object(enumerate_props(compare_RegExp('\\n'))));
+
+function compare_Blob(actual, input, test_obj, expect_File) {
+ if (typeof actual === 'string')
+ assert_unreached(actual);
+ assert_true(actual instanceof Blob, 'instanceof Blob');
+ if (!expect_File)
+ assert_false(actual instanceof File, 'instanceof File');
+ assert_equals(actual.size, input.size, 'size');
+ assert_equals(actual.type, input.type, 'type');
+ assert_not_equals(actual, input);
+ var ev_reader = new FileReader();
+ var input_reader = new FileReader();
+ var read_count = 0;
+ var read_done = test_obj.step_func(function() {
+ read_count++;
+ if (read_count == 2) {
+ var ev_result = ev_reader.result;
+ var input_result = input_reader.result;
+ assert_equals(ev_result.byteLength, input_result.byteLength, 'byteLength');
+ var ev_view = new DataView(ev_result);
+ var input_view = new DataView(input_result);
+ for (var i = 0; i < ev_result.byteLength; ++i) {
+ assert_equals(ev_view.getUint8(i), input_view.getUint8(i), 'getUint8('+i+')');
+ }
+ if (test_obj)
+ test_obj.done();
+ }
+ });
+ var read_error = test_obj.step_func(function() { assert_unreached('FileReader error'); });
+ ev_reader.readAsArrayBuffer(actual);
+ ev_reader.onload = read_done;
+ ev_reader.onabort = ev_reader.onerror = read_error;
+ input_reader.readAsArrayBuffer(input);
+ input_reader.onload = read_done;
+ input_reader.onabort = input_reader.onerror = read_error;
+}
+function func_Blob_basic() {
+ return new Blob(['foo'], {type:'text/x-bar'});
+}
+check('Blob basic', func_Blob_basic, compare_Blob);
+
+function b(str) {
+ return parseInt(str, 2);
+}
+function encode_cesu8(codeunits) {
+ // http://www.unicode.org/reports/tr26/ section 2.2
+ // only the 3-byte form is supported
+ var rv = [];
+ codeunits.forEach(function(codeunit) {
+ rv.push(b('11100000') + ((codeunit & b('1111000000000000')) >> 12));
+ rv.push(b('10000000') + ((codeunit & b('0000111111000000')) >> 6));
+ rv.push(b('10000000') + (codeunit & b('0000000000111111')));
+ });
+ return rv;
+}
+function func_Blob_bytes(arr) {
+ return function() {
+ var buffer = new ArrayBuffer(arr.length);
+ var view = new DataView(buffer);
+ for (var i = 0; i < arr.length; ++i) {
+ view.setUint8(i, arr[i]);
+ }
+ return new Blob([view]);
+ };
+}
+check('Blob unpaired high surrogate (invalid utf-8)', func_Blob_bytes(encode_cesu8([0xD800])), compare_Blob);
+check('Blob unpaired low surrogate (invalid utf-8)', func_Blob_bytes(encode_cesu8([0xDC00])), compare_Blob);
+check('Blob paired surrogates (invalid utf-8)', func_Blob_bytes(encode_cesu8([0xD800, 0xDC00])), compare_Blob);
+
+function func_Blob_empty() {
+ return new Blob(['']);
+}
+check('Blob empty', func_Blob_empty , compare_Blob);
+function func_Blob_NUL() {
+ return new Blob(['\u0000']);
+}
+check('Blob NUL', func_Blob_NUL, compare_Blob);
+
+async_test(function(test_obj) {
+ check(test_obj.name, [test_obj.step(func_Blob_basic)], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Array Blob object, Blob basic');
+async_test(function(test_obj) {
+ check(test_obj.name, [test_obj.step(func_Blob_bytes([0xD800]))], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Array Blob object, Blob unpaired high surrogate (invalid utf-8)');
+async_test(function(test_obj) {
+ check(test_obj.name, [test_obj.step(func_Blob_bytes([0xDC00]))], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Array Blob object, Blob unpaired low surrogate (invalid utf-8)');
+async_test(function(test_obj) {
+ check(test_obj.name, [test_obj.step(func_Blob_bytes([0xD800, 0xDC00]))], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Array Blob object, Blob paired surrogates (invalid utf-8)');
+async_test(function(test_obj) {
+ check(test_obj.name, [test_obj.step(func_Blob_empty)], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Array Blob object, Blob empty');
+async_test(function(test_obj) {
+ check(test_obj.name, [test_obj.step(func_Blob_NUL)], compare_Array(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Array Blob object, Blob NUL');
+
+async_test(function(test_obj) {
+ check(test_obj.name, {'x':test_obj.step(func_Blob_basic)}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Object Blob object, Blob basic');
+async_test(function(test_obj) {
+ check(test_obj.name, {'x':test_obj.step(func_Blob_bytes([0xD800]))}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Object Blob object, Blob unpaired high surrogate (invalid utf-8)');
+async_test(function(test_obj) {
+ check(test_obj.name, {'x':test_obj.step(func_Blob_bytes([0xDC00]))}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Object Blob object, Blob unpaired low surrogate (invalid utf-8)');
+async_test(function(test_obj) {
+ check(test_obj.name, {'x':test_obj.step(func_Blob_bytes([0xD800, 0xDC00]))}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Object Blob object, Blob paired surrogates (invalid utf-8)');
+async_test(function(test_obj) {
+ check(test_obj.name, {'x':test_obj.step(func_Blob_empty)}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Object Blob object, Blob empty');
+async_test(function(test_obj) {
+ check(test_obj.name, {'x':test_obj.step(func_Blob_NUL)}, compare_Object(enumerate_props(compare_Blob, test_obj), true), test_obj);
+}, 'Object Blob object, Blob NUL');
+
+function compare_File(actual, input, test_obj) {
+ assert_true(actual instanceof File, 'instanceof File');
+ assert_equals(actual.name, input.name, 'name');
+ assert_equals(actual.lastModified, input.lastModified, 'lastModified');
+ compare_Blob(actual, input, test_obj, true);
+}
+function func_File_basic() {
+ return new File(['foo'], 'bar', {type:'text/x-bar', lastModified:42});
+}
+check('File basic', func_File_basic, compare_File);
+
+function compare_FileList(actual, input, test_obj) {
+ if (typeof actual === 'string')
+ assert_unreached(actual);
+ assert_true(actual instanceof FileList, 'instanceof FileList');
+ assert_equals(actual.length, input.length, 'length');
+ assert_not_equals(actual, input);
+ // XXX when there's a way to populate or construct a FileList,
+ // check the items in the FileList
+ if (test_obj)
+ test_obj.done();
+}
+function func_FileList_empty() {
+ var input = document.createElement('input');
+ input.type = 'file';
+ return input.files;
+}
+check('FileList empty', func_FileList_empty, compare_FileList);
+check('Array FileList object, FileList empty', [func_FileList_empty], compare_Array(enumerate_props(compare_FileList)));
+check('Object FileList object, FileList empty', {'x':func_FileList_empty}, compare_Object(enumerate_props(compare_FileList)));
+
+function compare_ArrayBufferView(view) {
+ var Type = window[view];
+ return function(actual, input, test_obj) {
+ if (typeof actual === 'string')
+ assert_unreached(actual);
+ assert_true(actual instanceof Type, 'instanceof '+view);
+ assert_equals(actual.length, input.length, 'length');
+ assert_not_equals(actual.buffer, input.buffer, 'buffer');
+ for (var i = 0; i < actual.length; ++i) {
+ assert_equals(actual[i], input[i], 'actual['+i+']');
+ }
+ if (test_obj)
+ test_obj.done();
+ };
+}
+function compare_ImageData(actual, input, test_obj) {
+ if (typeof actual === 'string')
+ assert_unreached(actual);
+ assert_equals(actual.width, input.width, 'width');
+ assert_equals(actual.height, input.height, 'height');
+ assert_not_equals(actual.data, input.data, 'data');
+ compare_ArrayBufferView('Uint8ClampedArray')(actual.data, input.data, null);
+ if (test_obj)
+ test_obj.done();
+}
+function func_ImageData_1x1_transparent_black() {
+ var canvas = document.createElement('canvas');
+ var ctx = canvas.getContext('2d');
+ return ctx.createImageData(1, 1);
+}
+check('ImageData 1x1 transparent black', func_ImageData_1x1_transparent_black, compare_ImageData);
+function func_ImageData_1x1_non_transparent_non_black() {
+ var canvas = document.createElement('canvas');
+ var ctx = canvas.getContext('2d');
+ var imagedata = ctx.createImageData(1, 1);
+ imagedata.data[0] = 100;
+ imagedata.data[1] = 101;
+ imagedata.data[2] = 102;
+ imagedata.data[3] = 103;
+ return imagedata;
+}
+check('ImageData 1x1 non-transparent non-black', func_ImageData_1x1_non_transparent_non_black, compare_ImageData);
+async_test(function(test_obj) {
+ check(test_obj.name, [test_obj.step(func_ImageData_1x1_transparent_black)], compare_Array(enumerate_props(compare_ImageData)), test_obj);
+}, 'Array ImageData object, ImageData 1x1 transparent black');
+async_test(function(test_obj) {
+ check(test_obj.name, [test_obj.step(func_ImageData_1x1_non_transparent_non_black)], compare_Array(enumerate_props(compare_ImageData)), test_obj);
+}, 'Array ImageData object, ImageData 1x1 non-transparent non-black');
+async_test(function(test_obj) {
+ check(test_obj.name, {'x':test_obj.step(func_ImageData_1x1_transparent_black)}, compare_Object(enumerate_props(compare_ImageData)), test_obj);
+}, 'Object ImageData object, ImageData 1x1 transparent black');
+async_test(function(test_obj) {
+ check(test_obj.name, {'x':test_obj.step(func_ImageData_1x1_non_transparent_non_black)}, compare_Object(enumerate_props(compare_ImageData)), test_obj);
+}, 'Object ImageData object, ImageData 1x1 non-transparent non-black');
+
+function compare_ImageBitmap(actual, input, test_obj) {
+ if (typeof actual === 'string')
+ assert_unreached(actual);
+ assert_equals(actual instanceof ImageBitmap, 'instanceof ImageBitmap');
+ assert_not_equals(actual, input);
+ // XXX paint the ImageBitmap on a canvas and check the data
+ if (test_obj)
+ test_obj.done();
+}
+function get_canvas_1x1_transparent_black() {
+ var canvas = document.createElement('canvas');
+ canvas.width = 1;
+ canvas.height = 1;
+ return canvas;
+}
+async_test(function(test_obj) {
+ var canvas = get_canvas_1x1_transparent_black();
+ createImageBitmap(canvas, function(image) { check(test_obj.name, image, compare_ImageBitmap, test_obj); });
+}, 'ImageBitmap 1x1 transparent black');
+function get_canvas_1x1_non_transparent_non_black() {
+ var canvas = document.createElement('canvas');
+ canvas.width = 1;
+ canvas.height = 1;
+ var ctx = canvas.getContext('2d');
+ var imagedata = ctx.getImageData(0, 0, 1, 1);
+ imagedata.data[0] = 100;
+ imagedata.data[1] = 101;
+ imagedata.data[2] = 102;
+ imagedata.data[3] = 103;
+ return canvas;
+}
+async_test(function(test_obj) {
+ var canvas = get_canvas_1x1_non_transparent_non_black();
+ createImageBitmap(canvas, function(image) { check(test_obj.name, image, compare_ImageBitmap, test_obj); });
+}, 'ImageBitmap 1x1 non-transparent non-black');
+
+async_test(function(test_obj) {
+ var canvas = get_canvas_1x1_transparent_black();
+ createImageBitmap(canvas, function(image) { check(test_obj.name, [image], compare_Array(enumerate_props(compare_ImageBitmap)), test_obj); });
+}, 'Array ImageBitmap object, ImageBitmap 1x1 transparent black');
+async_test(function(test_obj) {
+ var canvas = get_canvas_1x1_non_transparent_non_black();
+ createImageBitmap(canvas, function(image) { check(test_obj.name, [image], compare_Array(enumerate_props(compare_ImageBitmap)), test_obj); });
+}, 'Array ImageBitmap object, ImageBitmap 1x1 non-transparent non-black');
+
+async_test(function(test_obj) {
+ var canvas = get_canvas_1x1_transparent_black();
+ createImageBitmap(canvas, function(image) { check(test_obj.name, {'x':image}, compare_Object(enumerate_props(compare_ImageBitmap)), test_obj); });
+}, 'Object ImageBitmap object, ImageBitmap 1x1 transparent black');
+async_test(function(test_obj) {
+ var canvas = get_canvas_1x1_non_transparent_non_black();
+ createImageBitmap(canvas, function(image) { check(test_obj.name, {'x':image}, compare_Object(enumerate_props(compare_ImageBitmap)), test_obj); });
+}, 'Object ImageBitmap object, ImageBitmap 1x1 non-transparent non-black');
+
+check('Array sparse', new Array(10), compare_Array(enumerate_props(compare_primitive)));
+check('Array with non-index property', function() {
+ var rv = [];
+ rv.foo = 'bar';
+ return rv;
+}, compare_Array(enumerate_props(compare_primitive)));
+check('Object with index property and length', {'0':'foo', 'length':1}, compare_Object(enumerate_props(compare_primitive)));
+function check_circular_property(prop) {
+ return function(actual) {
+ assert_equals(actual[prop], actual);
+ };
+}
+check('Array with circular reference', function() {
+ var rv = [];
+ rv[0] = rv;
+ return rv;
+}, compare_Array(check_circular_property('0')));
+check('Object with circular reference', function() {
+ var rv = {};
+ rv['x'] = rv;
+ return rv;
+}, compare_Object(check_circular_property('x')));
+function check_identical_property_values(prop1, prop2) {
+ return function(actual) {
+ assert_equals(actual[prop1], actual[prop2]);
+ };
+}
+check('Array with identical property values', function() {
+ var obj = {}
+ return [obj, obj];
+}, compare_Array(check_identical_property_values('0', '1')));
+check('Object with identical property values', function() {
+ var obj = {}
+ return {'x':obj, 'y':obj};
+}, compare_Object(check_identical_property_values('x', 'y')));
+
+function check_absent_property(prop) {
+ return function(actual) {
+ assert_false(prop in actual);
+ };
+}
+check('Object with property on prototype', function() {
+ var Foo = function() {};
+ Foo.prototype = {'foo':'bar'};
+ return new Foo();
+}, compare_Object(check_absent_property('foo')));
+
+check('Object with non-enumerable property', function() {
+ var rv = {};
+ Object.defineProperty(rv, 'foo', {value:'bar', enumerable:false, writable:true, configurable:true});
+ return rv;
+}, compare_Object(check_absent_property('foo')));
+
+function check_writable_property(prop) {
+ return function(actual, input) {
+ assert_equals(actual[prop], input[prop]);
+ actual[prop] += ' baz';
+ assert_equals(actual[prop], input[prop] + ' baz');
+ };
+}
+check('Object with non-writable property', function() {
+ var rv = {};
+ Object.defineProperty(rv, 'foo', {value:'bar', enumerable:true, writable:false, configurable:true});
+ return rv;
+}, compare_Object(check_writable_property('foo')));
+
+function check_configurable_property(prop) {
+ return function(actual, input) {
+ assert_equals(actual[prop], input[prop]);
+ delete actual[prop];
+ assert_false('prop' in actual);
+ };
+}
+check('Object with non-configurable property', function() {
+ var rv = {};
+ Object.defineProperty(rv, 'foo', {value:'bar', enumerable:true, writable:true, configurable:false});
+ return rv;
+}, compare_Object(check_configurable_property('foo')));
diff --git a/testing/web-platform/tests/workers/semantics/structured-clone/dedicated.html b/testing/web-platform/tests/workers/semantics/structured-clone/dedicated.html
new file mode 100644
index 000000000..5dd8c3561
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/structured-clone/dedicated.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>structured clone to dedicated worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var type = 'dedicated';
+</script>
+<script src="common.js"></script>
diff --git a/testing/web-platform/tests/workers/semantics/structured-clone/dedicated.js b/testing/web-platform/tests/workers/semantics/structured-clone/dedicated.js
new file mode 100644
index 000000000..4744578b2
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/structured-clone/dedicated.js
@@ -0,0 +1,4 @@
+importScripts('worker-common.js');
+onmessage = function(ev) {
+ check(ev.data, self);
+};
diff --git a/testing/web-platform/tests/workers/semantics/structured-clone/shared.html b/testing/web-platform/tests/workers/semantics/structured-clone/shared.html
new file mode 100644
index 000000000..6f74354d4
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/structured-clone/shared.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>structured clone to shared worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var type = 'shared';
+</script>
+<script src="common.js"></script>
diff --git a/testing/web-platform/tests/workers/semantics/structured-clone/shared.js b/testing/web-platform/tests/workers/semantics/structured-clone/shared.js
new file mode 100644
index 000000000..372a9ec98
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/structured-clone/shared.js
@@ -0,0 +1,6 @@
+importScripts('worker-common.js');
+onconnect = function(connect_ev) {
+ connect_ev.ports[0].onmessage = function(message_ev) {
+ check(message_ev.data, this);
+ };
+};
diff --git a/testing/web-platform/tests/workers/semantics/structured-clone/worker-common.js b/testing/web-platform/tests/workers/semantics/structured-clone/worker-common.js
new file mode 100644
index 000000000..fd63ff5a5
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/structured-clone/worker-common.js
@@ -0,0 +1,1018 @@
+var msg = decodeURIComponent(location.hash.substr(1));
+
+var log = [];
+function check_true(actual, msg) {
+ if (actual !== true) {
+ log.push(msg);
+ return false;
+ }
+ return true;
+}
+
+function check_Blob(msg, input, port, expect_File, orig_input) {
+ expect_File = !!expect_File;
+ orig_input = orig_input || input;
+ try {
+ var expected;
+ switch (msg) {
+ case 'Blob basic':
+ case 'File basic':
+ expected = [0x66, 0x6F, 0x6F];
+ expected.type = 'text/x-bar';
+ if (expect_File) {
+ expected.name = 'bar';
+ expected.lastModified = 42;
+ }
+ break;
+ case 'Blob unpaired high surrogate (invalid utf-8)':
+ expected = [0xED, 0xA0, 0x80];
+ expected.type = '';
+ break;
+ case 'Blob unpaired low surrogate (invalid utf-8)':
+ expected = [0xED, 0xB0, 0x80];
+ expected.type = '';
+ break;
+ case 'Blob paired surrogates (invalid utf-8)':
+ expected = [0xED, 0xA0, 0x80, 0xED, 0xB0, 0x80];
+ expected.type = '';
+ break;
+ case 'Blob empty':
+ expected = [];
+ expected.type = '';
+ break;
+ case 'Blob NUL':
+ var expected = [0x00];
+ expected.type = '';
+ break;
+ default:
+ check_true(false, 'check_Blob: unknown test');
+ return;
+ break;
+ }
+ if (check_true(input instanceof Blob, 'input instanceof Blob') &&
+ check_true((input instanceof File) == expect_File, '(input instanceof File) == expect_File') &&
+ check_true(input.size === expected.length, 'input.size === expected.length') &&
+ check_true(input.type === expected.type, 'input.type === expected.type')) {
+ if (!expect_File || (check_true(input.name === expected.name, 'input.name === expected.name') &&
+ check_true(input.lastModified === expected.lastModified))) {
+ var reader = new FileReader();
+ var read_done = function() {
+ try {
+ var result = reader.result;
+ check_true(result.byteLength === expected.length, 'result.byteLength === expected.length')
+ var view = new DataView(result);
+ for (var i = 0; i < result.byteLength; ++i) {
+ check_true(view.getUint8(i) === expected[i], 'view.getUint8('+i+') === expected['+i+']')
+ }
+ if (log.length === 0) {
+ port.postMessage(orig_input);
+ } else {
+ port.postMessage('FAIL '+log);
+ }
+ close();
+ } catch(ex) {
+ postMessage('FAIL '+ex);
+ close();
+ }
+ }
+ var read_error = function() { port.postMessage('FAIL (got FileReader error)'); close(); };
+ reader.readAsArrayBuffer(input);
+ reader.onload = read_done;
+ reader.onabort = reader.onerror = read_error;
+ }
+ } else {
+ port.postMessage('FAIL '+log);
+ close();
+ }
+ } catch(ex) {
+ postMessage('FAIL '+ex);
+ close();
+ }
+}
+
+function check_ImageData(input, expected) {
+ if (check_true(input instanceof ImageData, 'input instanceof ImageData') &&
+ check_true(input.width === expected.width, 'input.width === '+expected.width) &&
+ check_true(input.height === expected.height, 'input.height === '+expected.height) &&
+ check_true(input.data instanceof Uint8ClampedArray, 'input.data instanceof Uint8ClampedArray') &&
+ check_true(input.data.length === expected.data.length, 'input.data.length === '+expected.data.length) &&
+ check_true(!('CanvasPixelArray' in self), "!('CanvasPixelArray' in self)")) {
+ for (var i = 0; i < input.length; ++i) {
+ if (!(check_true(input.data[i] === expected.data[i], 'input.data['+i+'] === '+expected.data[i]))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+function check_ImageBitmap(input, expected) {
+ return check_true(input instanceof ImageBitmap, 'input instanceof ImageBitmap');
+ // XXX paint it on a proxy canvas and check the data
+}
+
+function check_RegExp(msg, input) {
+ // XXX ES6 spec doesn't define exact serialization for `source` (it allows several ways to escape)
+ switch (msg) {
+ case 'RegExp flags and lastIndex':
+ return check_true(input instanceof RegExp, "input instanceof RegExp") &&
+ check_true(input.source === 'foo', "input.source === 'foo'") &&
+ check_true(input.global === true, "input.global === true") &&
+ check_true(input.ignoreCase === true, "input.ignoreCase === true") &&
+ check_true(input.multiline === true, "input.multiline === true") &&
+ check_true(input.lastIndex === 0, "input.lastIndex === 0");
+ break;
+ case 'RegExp sticky flag':
+ return check_true(input instanceof RegExp, "input instanceof RegExp") &&
+ check_true(input.source === 'foo', "input.source === 'foo'") &&
+ check_true(input.global === false, "input.global === false") &&
+ check_true(input.ignoreCase === false, "input.ignoreCase === false") &&
+ check_true(input.multiline === false, "input.multiline === false") &&
+ check_true(input.sticky === true, "input.sticky === true") &&
+ check_true(input.unicode === false, "input.unicode === false") &&
+ check_true(input.lastIndex === 0, "input.lastIndex === 0");
+ break;
+ case 'RegExp unicode flag':
+ return check_true(input instanceof RegExp, "input instanceof RegExp") &&
+ check_true(input.source === 'foo', "input.source === 'foo'") &&
+ check_true(input.global === false, "input.global === false") &&
+ check_true(input.ignoreCase === false, "input.ignoreCase === false") &&
+ check_true(input.multiline === false, "input.multiline === false") &&
+ check_true(input.sticky === false, "input.sticky === false") &&
+ check_true(input.unicode === true, "input.unicode === true") &&
+ check_true(input.lastIndex === 0, "input.lastIndex === 0");
+ break;
+ case 'RegExp empty':
+ return check_true(input instanceof RegExp, "input instanceof RegExp") &&
+ check_true(input.source === '(?:)', "input.source === '(?:)'") &&
+ check_true(input.global === false, "input.global === false") &&
+ check_true(input.ignoreCase === false, "input.ignoreCase === false") &&
+ check_true(input.multiline === false, "input.multiline === false") &&
+ check_true(input.lastIndex === 0, "input.lastIndex === 0");
+ break;
+ case 'RegExp slash':
+ return check_true(input instanceof RegExp, "input instanceof RegExp") &&
+ check_true(input.source === '\\/', "input.source === '\\\\/'") &&
+ check_true(input.global === false, "input.global === false") &&
+ check_true(input.ignoreCase === false, "input.ignoreCase === false") &&
+ check_true(input.multiline === false, "input.multiline === false") &&
+ check_true(input.lastIndex === 0, "input.lastIndex === 0");
+ break;
+ case 'RegExp new line':
+ return check_true(input instanceof RegExp, "input instanceof RegExp") &&
+ check_true(input.source === '\\n', "input.source === '\\\\n'") &&
+ check_true(input.global === false, "input.global === false") &&
+ check_true(input.ignoreCase === false, "input.ignoreCase === false") &&
+ check_true(input.multiline === false, "input.multiline === false") &&
+ check_true(input.lastIndex === 0, "input.lastIndex === 0");
+ break;
+ default:
+ check_true(false, 'check_RegExp: unknown test');
+ return false;
+ break;
+ }
+}
+
+function check_FileList(msg, input) {
+ try {
+ return check_true(input instanceof FileList, 'input instanceof FileList') &&
+ check_true(input.length === 0, 'input.length === 0');
+ } catch(ex) {
+ return check_true(false, ex);
+ }
+}
+
+function check(input, port) {
+ try {
+ switch (msg) {
+ case 'primitive undefined':
+ if (check_true(input === undefined, 'input === undefined')) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive null':
+ if (check_true(input === null, 'input === null')) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive true':
+ if (check_true(input === true, 'input === true')) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive false':
+ if (check_true(input === false, 'input === false')) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive string, empty string':
+ if (check_true(input === '', "input === ''")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive string, lone high surrogate':
+ if (check_true(input === '\uD800', "input === '\uD800'")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive string, lone low surrogate':
+ if (check_true(input === '\uDC00', "input === '\uDC00'")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive string, NUL':
+ if (check_true(input === '\u0000', "input === '\u0000'")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive string, astral character':
+ if (check_true(input === '\uDBFF\uDFFD', "input === '\uDBFF\uDFFD'")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive number, 0.2':
+ if (check_true(input === 0.2, "input === 0.2")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive number, 0':
+ if (check_true(input === 0, "input === 0") &&
+ check_true(1/input === Infinity, "1/input === Infinity")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive number, -0':
+ if (check_true(input === 0, "input === 0") &&
+ check_true(1/input === -Infinity, "1/input === -Infinity")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive number, NaN':
+ if (check_true(input !== input, "input !== input")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive number, Infinity':
+ if (check_true(input === Infinity, "input === Infinity")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive number, -Infinity':
+ if (check_true(input === -Infinity, "input === -Infinity")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive number, 9007199254740992':
+ if (check_true(input === 9007199254740992, "input === 9007199254740992")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive number, -9007199254740992':
+ if (check_true(input === -9007199254740992, "input === -9007199254740992")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive number, 9007199254740994':
+ if (check_true(input === 9007199254740994, "input === 9007199254740994")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'primitive number, -9007199254740994':
+ if (check_true(input === -9007199254740994, "input === -9007199254740994")) {
+ port.postMessage(input);
+ close();
+ break;
+ }
+ case 'Array primitives':
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 19, 'input.length === 19') &&
+ check_true(input[0] === undefined, 'input[0] === undefined') &&
+ check_true(input[1] === null, 'input[1] === null') &&
+ check_true(input[2] === true, 'input[2] === true') &&
+ check_true(input[3] === false, 'input[3] === false') &&
+ check_true(input[4] === '', "input[4] === ''") &&
+ check_true(input[5] === '\uD800', "input[5] === '\\uD800'") &&
+ check_true(input[6] === '\uDC00', "input[6] === '\\uDC00'") &&
+ check_true(input[7] === '\u0000', "input[7] === '\\u0000'") &&
+ check_true(input[8] === '\uDBFF\uDFFD', "input[8] === '\\uDBFF\\uDFFD'") &&
+ check_true(input[9] === 0.2, "input[9] === 0.2") &&
+ check_true(1/input[10] === Infinity, "1/input[10] === Infinity") &&
+ check_true(1/input[11] === -Infinity, "1/input[11] === -Infinity") &&
+ check_true(input[12] !== input[11], "input[12] !== input[11]") &&
+ check_true(input[13] === Infinity, "input[13] === Infinity") &&
+ check_true(input[14] === -Infinity, "input[14] === -Infinity") &&
+ check_true(input[15] === 9007199254740992, "input[15] === 9007199254740992") &&
+ check_true(input[16] === -9007199254740992, "input[16] === -9007199254740992") &&
+ check_true(input[17] === 9007199254740994, "input[17] === 9007199254740994") &&
+ check_true(input[18] === -9007199254740994, "input[18] === -9007199254740994")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Object primitives':
+ (function() {
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_true(input['undefined'] === undefined, "input['undefined'] === undefined") &&
+ check_true(input['null'] === null, "input['null'] === null") &&
+ check_true(input['true'] === true, "input['true'] === true") &&
+ check_true(input['false'] === false, "input['false'] === false") &&
+ check_true(input['empty'] === '', "input['empty'] === ''") &&
+ check_true(input['high surrogate'] === '\uD800', "input['high surrogate'] === '\uD800'") &&
+ check_true(input['low surrogate'] === '\uDC00', "input['low surrogate'] === '\uDC00'") &&
+ check_true(input['nul'] === '\u0000', "input['nul'] === '\u0000'") &&
+ check_true(input['astral'] === '\uDBFF\uDFFD', "input['astral'] === '\uDBFF\uDFFD'") &&
+ check_true(input['0.2'] === 0.2, "input['0.2'] === 0.2") &&
+ check_true(1/input['0'] === Infinity, "1/input['0'] === Infinity") &&
+ check_true(1/input['-0'] === -Infinity, "1/input['-0'] === -Infinity") &&
+ check_true(input['NaN'] !== input['NaN'], "input['NaN'] !== input['NaN']") &&
+ check_true(input['Infinity'] === Infinity, "input['Infinity'] === Infinity") &&
+ check_true(input['-Infinity'] === -Infinity, "input['-Infinity'] === -Infinity") &&
+ check_true(input['9007199254740992'] === 9007199254740992, "input['9007199254740992'] === 9007199254740992") &&
+ check_true(input['-9007199254740992'] === -9007199254740992, "input['-9007199254740992'] === -9007199254740992") &&
+ check_true(input['9007199254740994'] === 9007199254740994, "input['9007199254740994'] === 9007199254740994") &&
+ check_true(input['-9007199254740994'] === -9007199254740994, "input['9007199254740994'] === -9007199254740994")) {
+ var i = 0;
+ for (var x in input) {
+ i++;
+ }
+ if (check_true(i === 19, 'i === 19')) {
+ port.postMessage(input);
+ close();
+ }
+ }
+ })();
+ break;
+ case 'Boolean true':
+ if (check_true(input instanceof Boolean, "input instanceof Boolean") &&
+ check_true(String(input) === 'true', "String(input) === 'true'")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Boolean false':
+ if (check_true(input instanceof Boolean, "input instanceof Boolean") &&
+ check_true(String(input) === 'false', "String(input) === 'false'")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Array Boolean objects':
+ (function() {
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 2, 'input.length === 2') &&
+ check_true(String(input[0]) === 'true', "String(input[0]) === 'true'") &&
+ check_true(String(input[1]) === 'false', "String(input[1]) === 'false'")) {
+ for (var i = 0; i < input.length; ++i) {
+ if (!check_true(input[i] instanceof Boolean, 'input['+i+'] instanceof Boolean'))
+ return;
+ }
+ port.postMessage(input);
+ close();
+ }
+ })();
+ break;
+ case 'Object Boolean objects':
+ (function() {
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_true(String(input['true']) === 'true', "String(input['true']) === 'true'") &&
+ check_true(String(input['false']) === 'false', "String(input['false']) === 'false'")) {
+ var i = 0;
+ for (var x in input) {
+ i++;
+ if (!check_true(input[x] instanceof Boolean, 'input['+x+'] instanceof Boolean'))
+ return;
+ }
+ if (check_true(i === 2, 'i === 2')) {
+ port.postMessage(input);
+ close();
+ }
+ }
+ })();
+ break;
+ case 'String empty string':
+ if (check_true(input instanceof String, "input instanceof String") &&
+ check_true(String(input) === '', "String(input) === ''")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'String lone high surrogate':
+ if (check_true(input instanceof String, "input instanceof String") &&
+ check_true(String(input) === '\uD800', "String(input) === '\\uD800'")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'String lone low surrogate':
+ if (check_true(input instanceof String, "input instanceof String") &&
+ check_true(String(input) === '\uDC00', "String(input) === '\\uDC00'")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'String NUL':
+ if (check_true(input instanceof String, "input instanceof String") &&
+ check_true(String(input) === '\u0000', "String(input) === '\\u0000'")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'String astral character':
+ if (check_true(input instanceof String, "input instanceof String") &&
+ check_true(String(input) === '\uDBFF\uDFFD', "String(input) === '\\uDBFF\\uDFFD'")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Array String objects':
+ (function() {
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 5, 'input.length === 5') &&
+ check_true(String(input[0]) === '', "String(input[0]) === ''") &&
+ check_true(String(input[1]) === '\uD800', "String(input[1]) === '\\uD800'") &&
+ check_true(String(input[2]) === '\uDC00', "String(input[1]) === '\\uDC00'") &&
+ check_true(String(input[3]) === '\u0000', "String(input[2]) === '\\u0000'") &&
+ check_true(String(input[4]) === '\uDBFF\uDFFD', "String(input[3]) === '\\uDBFF\\uDFFD'")) {
+ for (var i = 0; i < input.length; ++i) {
+ if (!check_true(input[i] instanceof String, 'input['+i+'] instanceof String'))
+ return;
+ }
+ port.postMessage(input);
+ close();
+ }
+ })();
+ break;
+ case 'Object String objects':
+ (function() {
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_true(String(input['empty']) === '', "String(input['empty']) === ''") &&
+ check_true(String(input['high surrogate']) === '\uD800', "String(input['high surrogate']) === '\\uD800'") &&
+ check_true(String(input['low surrogate']) === '\uDC00', "String(input['low surrogate']) === '\\uDC00'") &&
+ check_true(String(input['nul']) === '\u0000', "String(input['nul']) === '\\u0000'") &&
+ check_true(String(input['astral']) === '\uDBFF\uDFFD', "String(input['astral']) === '\\uDBFF\\uDFFD'")) {
+ var i = 0;
+ for (var x in input) {
+ i++;
+ if (!check_true(input[x] instanceof String, 'input['+x+'] instanceof Boolean'))
+ return;
+ }
+ if (check_true(i === 5, 'i === 5')) {
+ port.postMessage(input);
+ close();
+ }
+ }
+ })();
+ break;
+ case 'Number 0.2':
+ if (check_true(input instanceof Number, "input instanceof Number") &&
+ check_true(Number(input) === 0.2, "Number(input) === 0.2")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Number 0':
+ if (check_true(input instanceof Number, "input instanceof Number") &&
+ check_true(1/Number(input) === Infinity, "1/Number(input) === Infinity")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Number -0':
+ if (check_true(input instanceof Number, "input instanceof Number") &&
+ check_true(1/Number(input) === -Infinity, "1/Number(input) === -Infinity")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Number NaN':
+ if (check_true(input instanceof Number, "input instanceof Number") &&
+ check_true(Number(input) !== Number(input), "Number(input) !== Number(input)")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Number Infinity':
+ if (check_true(input instanceof Number, "input instanceof Number") &&
+ check_true(Number(input) === Infinity, "Number(input) === Infinity")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Number -Infinity':
+ if (check_true(input instanceof Number, "input instanceof Number") &&
+ check_true(Number(input) === -Infinity, "Number(input) === -Infinity")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Number 9007199254740992':
+ if (check_true(input instanceof Number) &&
+ check_true(Number(input) === 9007199254740992, "Number(input) === 9007199254740992")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Number -9007199254740992':
+ if (check_true(input instanceof Number, "input instanceof Number") &&
+ check_true(Number(input) === -9007199254740992, "Number(input) === -9007199254740992")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Number 9007199254740994':
+ if (check_true(input instanceof Number, "input instanceof Number") &&
+ check_true(Number(input) === 9007199254740994, "Number(input) === 9007199254740994")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Number -9007199254740994':
+ if (check_true(input instanceof Number, "input instanceof Number") &&
+ check_true(Number(input) === -9007199254740994, "Number(input) === -9007199254740994")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Array Number objects':
+ (function() {
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 10, 'input.length === 10') &&
+ check_true(Number(input[0]) === 0.2, "Number(input[0]) === 0.2") &&
+ check_true(1/Number(input[1]) === Infinity, "1/Number(input[1]) === Infinity") &&
+ check_true(1/Number(input[2]) === -Infinity, "1/Number(input[2]) === -Infinity") &&
+ check_true(Number(input[3]) !== Number(input[3]), "Number(input[3]) !== Number(input[3])") &&
+ check_true(Number(input[4]) === Infinity, "Number(input[4]) === Infinity") &&
+ check_true(Number(input[5]) === -Infinity, "Number(input[5]) === -Infinity") &&
+ check_true(Number(input[6]) === 9007199254740992, "Number(input[6]) === 9007199254740992") &&
+ check_true(Number(input[7]) === -9007199254740992, "Number(input[7]) === -9007199254740992") &&
+ check_true(Number(input[8]) === 9007199254740994, "Number(input[8]) === 9007199254740994") &&
+ check_true(Number(input[9]) === -9007199254740994, "Number(input[9]) === -9007199254740994")) {
+ for (var i = 0; i < input.length; ++i) {
+ if (!check_true(input[i] instanceof Number, 'input['+i+'] instanceof Number'))
+ return;
+ }
+ port.postMessage(input);
+ close();
+ }
+ })();
+ break;
+ case 'Object Number objects':
+ (function() {
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_true(Number(input['0.2']) === 0.2, "Number(input['0.2']) === 0.2") &&
+ check_true(1/Number(input['0']) === Infinity, "1/Number(input['0']) === Infinity") &&
+ check_true(1/Number(input['-0']) === -Infinity, "1/Number(input['-0']) === -Infinity") &&
+ check_true(Number(input['NaN']) !== Number(input['NaN']), "Number(input['NaN']) !== Number(input['NaN'])") &&
+ check_true(Number(input['Infinity']) === Infinity, "Number(input['Infinity']) === Infinity") &&
+ check_true(Number(input['-Infinity']) === -Infinity, "Number(input['-Infinity']) === -Infinity") &&
+ check_true(Number(input['9007199254740992']) === 9007199254740992, "Number(input['9007199254740992']) === 9007199254740992") &&
+ check_true(Number(input['-9007199254740992']) === -9007199254740992, "Number(input['-9007199254740992']) === -9007199254740992") &&
+ check_true(Number(input['9007199254740994']) === 9007199254740994, "Number(input['9007199254740994']) === 9007199254740994") &&
+ check_true(Number(input['-9007199254740994']) === -9007199254740994, "Number(input['-9007199254740994']) === -9007199254740994")) {
+ var i = 0;
+ for (var x in input) {
+ i++;
+ if (!check_true(input[x] instanceof Number, 'input['+x+'] instanceof Number'))
+ return;
+ }
+ if (check_true(i === 10, 'i === 10')) {
+ port.postMessage(input);
+ close();
+ }
+ }
+ })();
+ break;
+ case 'Date 0':
+ if (check_true(input instanceof Date, "input instanceof Date") &&
+ check_true(1/Number(input) === 1/Number(new Date(0)), "1/Number(input) === 1/Number(new Date(0))")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Date -0':
+ if (check_true(input instanceof Date, "input instanceof Date") &&
+ check_true(1/Number(input) === 1/Number(new Date(-0)), "1/Number(input) === 1/Number(new Date(-0))")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Date -8.64e15':
+ if (check_true(input instanceof Date, "input instanceof Date") &&
+ check_true(Number(input) === -8.64e15, "Number(input) === -8.64e15")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Date 8.64e15':
+ if (check_true(input instanceof Date, "input instanceof Date") &&
+ check_true(Number(input) === 8.64e15, "Number(input) === 8.64e15")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Array Date objects':
+ (function() {
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 4, 'input.length === 4') &&
+ check_true(1/Number(input[0]) === 1/new Date(0), '1/Number(input[0]) === 1/new Date(0)') &&
+ check_true(1/Number(input[1]) === 1/new Date(-0), '1/Number(input[1]) === 1/new Date(-0)') &&
+ check_true(Number(input[2]) === -8.64e15, 'Number(input[2]) === -8.64e15') &&
+ check_true(Number(input[3]) === 8.64e15, 'Number(input[3]) === 8.64e15')) {
+ for (var i = 0; i < input.length; ++i) {
+ if (!check_true(input[i] instanceof Date, 'input['+i+'] instanceof Date'))
+ return;
+ }
+ port.postMessage(input);
+ close();
+ }
+ })();
+ break;
+ case 'Object Date objects':
+ (function() {
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_true(1/Number(input['0']) === 1/new Date(0), "1/Number(input['0']) === 1/new Date(0)") &&
+ check_true(1/Number(input['-0']) === 1/new Date(-0), "1/Number(input[1]) === 1/new Date(-0)") &&
+ check_true(Number(input['-8.64e15']) === -8.64e15, "Number(input['-8.64e15']) === -8.64e15") &&
+ check_true(Number(input['8.64e15']) === 8.64e15, "Number(input['8.64e15']) === 8.64e15")) {
+ var i = 0;
+ for (var x in input) {
+ i++;
+ if (!check_true(input[x] instanceof Date, 'input['+x+'] instanceof Date'))
+ return;
+ }
+ port.postMessage(input);
+ close();
+ }
+ })();
+ break;
+ case 'RegExp flags and lastIndex':
+ case 'RegExp empty':
+ case 'RegExp slash':
+ case 'RegExp new line':
+ if (check_RegExp(msg, input)) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Array RegExp object, RegExp flags and lastIndex':
+ case 'Array RegExp object, RegExp empty':
+ case 'Array RegExp object, RegExp slash':
+ case 'Array RegExp object, RegExp new line':
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 1, 'input.length === 1') &&
+ check_RegExp(msg.substr('Array RegExp object, '.length), input[0])) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Object RegExp object, RegExp flags and lastIndex':
+ case 'Object RegExp object, RegExp empty':
+ case 'Object RegExp object, RegExp slash':
+ case 'Object RegExp object, RegExp new line':
+ (function() {
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_RegExp(msg.substr('Object RegExp object, '.length), input['x'])) {
+ var i = 0;
+ for (var x in input) {
+ i++;
+ }
+ if (check_true(i === 1, 'i === 1')) {
+ port.postMessage(input);
+ close();
+ }
+ }
+ })();
+ break;
+ case 'Blob basic':
+ case 'Blob unpaired high surrogate (invalid utf-8)':
+ case 'Blob unpaired low surrogate (invalid utf-8)':
+ case 'Blob paired surrogates (invalid utf-8)':
+ case 'Blob empty':
+ case 'Blob NUL':
+ check_Blob(msg, input, port);
+ // no postMessage or close here, check_Blob takes care of that
+ break;
+ case 'Array Blob object, Blob basic':
+ case 'Array Blob object, Blob unpaired high surrogate (invalid utf-8)':
+ case 'Array Blob object, Blob unpaired low surrogate (invalid utf-8)':
+ case 'Array Blob object, Blob paired surrogates (invalid utf-8)':
+ case 'Array Blob object, Blob empty':
+ case 'Array Blob object, Blob NUL':
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 1, 'input.length === 1')) {
+ check_Blob(msg.substr('Array Blob object, '.length), input[0], port, false, input);
+ // no postMessage or close here, check_Blob takes care of that
+ }
+ break;
+ case 'Object Blob object, Blob basic':
+ case 'Object Blob object, Blob unpaired high surrogate (invalid utf-8)':
+ case 'Object Blob object, Blob unpaired low surrogate (invalid utf-8)':
+ case 'Object Blob object, Blob paired surrogates (invalid utf-8)':
+ case 'Object Blob object, Blob empty':
+ case 'Object Blob object, Blob NUL':
+ (function() {
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)')) {
+ var i = 0;
+ for (var x in input) {
+ i++;
+ }
+ if (check_true(i === 1, 'i === 1')) {
+ check_Blob(msg.substr('Object Blob object, '.length), input['x'], port, false, input);
+ // no postMessage or close here, check_Blob takes care of that
+ }
+ }
+ })();
+ break;
+ case 'File basic':
+ check_Blob(msg, input, port, true);
+ // no postMessage or close here, check_Blob takes care of that
+ break;
+ case 'FileList empty':
+ if (check_FileList(msg, input)) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Array FileList object, FileList empty':
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 1, 'input.length === 1') &&
+ check_FileList(msg.substr('Array FileList object, '.length), input[0])) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Object FileList object, FileList empty':
+ (function() {
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_FileList(msg.substr('Array FileList object, '.length), input['x'])) {
+ var i = 0;
+ for (var x in input) {
+ i++;
+ }
+ if (check_true(i === 1, 'i === 1')) {
+ port.postMessage(input);
+ close();
+ }
+ }
+ })();
+ break;
+ case 'ImageData 1x1 transparent black':
+ if (check_ImageData(input, {width:1, height:1, data:[0,0,0,0]})) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'ImageData 1x1 non-transparent non-black':
+ if (check_ImageData(input, {width:1, height:1, data:[100, 101, 102, 103]})) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Array ImageData object, ImageData 1x1 transparent black':
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 1, 'input.length === 1') &&
+ check_ImageData(input[0], {width:1, height:1, data:[0,0,0,0]})) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Array ImageData object, ImageData 1x1 non-transparent non-black':
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 1, 'input.length === 1') &&
+ check_ImageData(input[0], {width:1, height:1, data:[100, 101, 102, 103]})) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Object ImageData object, ImageData 1x1 transparent black':
+ (function(){
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_ImageData(input['x'], {width:1, height:1, data:[0,0,0,0]})) {
+ var i = 0;
+ for (var x in input) {
+ i++;
+ }
+ if (check_true(i === 1, 'i === 1')) {
+ port.postMessage(input);
+ close();
+ }
+ }
+ })();
+ break;
+ case 'Object ImageData object, ImageData 1x1 non-transparent non-black':
+ (function() {
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_ImageData(input['x'], {width:1, height:1, data:[100, 101, 102, 103]})) {
+ var i = 0;
+ for (var x in input) {
+ i++;
+ }
+ if (check_true(i === 1, 'i === 1')) {
+ port.postMessage(input);
+ close();
+ }
+ }
+ })();
+ break;
+ case 'ImageBitmap 1x1 transparent black':
+ if (check_ImageBitmap(input, {width:1, height:1, data:[0, 0, 0, 0]})) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'ImageBitmap 1x1 non-transparent non-black':
+ if (check_ImageBitmap(input, {width:1, height:1, data:[100, 101, 102, 103]})) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Array ImageBitmap object, ImageBitmap 1x1 transparent black':
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 1, 'input.length === 1') &&
+ check_ImageBitmap(input[0], {width:1, height:1, data:[0, 0, 0, 0]})) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Array ImageBitmap object, ImageBitmap 1x1 non-transparent non-black':
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 1, 'input.length === 1') &&
+ check_ImageBitmap(input[0], {width:1, height:1, data:[100, 101, 102, 103]})) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Object ImageBitmap object, ImageBitmap 1x1 transparent black':
+ (function() {
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_ImageBitmap(input['x'], {width:1, height:1, data:[0, 0, 0, 0]})) {
+ var i = 0;
+ for (var x in input) {
+ i++;
+ }
+ if (check_true(i === 1, 'i === 1')) {
+ port.postMessage(input);
+ close();
+ }
+ }
+ })();
+ break;
+ case 'Object ImageBitmap object, ImageBitmap 1x1 non-transparent non-black':
+ (function() {
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_ImageBitmap(input['x'], {width:1, height:1, data:[100, 101, 102, 103]})) {
+ var i = 0;
+ for (var x in input) {
+ i++;
+ }
+ if (check_true(i === 1, 'i === 1')) {
+ port.postMessage(input);
+ close();
+ }
+ }
+ })();
+ break;
+ case 'Array sparse':
+ (function() {
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 10, 'input.length === 10')) {
+ for (var x in input) {
+ check_true(false, 'unexpected enumerable property '+x);
+ return;
+ }
+ port.postMessage(input);
+ close();
+ }
+ })();
+ break;
+ case 'Array with non-index property':
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 0, 'input.length === 0') &&
+ check_true(input.foo === 'bar', "input.foo === 'bar'")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Object with index property and length':
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_true(input[0] === 'foo', "input[0] === 'foo'") &&
+ check_true(input.length === 1, 'input.length === 1')) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Array with circular reference':
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 1, 'input.length === 1') &&
+ check_true(input[0] === input, "input[0] === input")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Object with circular reference':
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_true(input['x'] === input, "input['x'] === input")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Array with identical property values':
+ if (check_true(input instanceof Array, 'input instanceof Array') &&
+ check_true(input.length === 2, 'input.length === 2') &&
+ check_true(input[0] === input[1], "input[0] === input[1]")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Object with identical property values':
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_true(input['x'] === input['y'], "input['x'] === input['y']")) {
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Object with property on prototype':
+ case 'Object with non-enumerable property':
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_true(!('foo' in input), "!('foo' in input)")) {
+ input = {};
+ Object.defineProperty(input, 'foo', {value:'bar', enumerable:false, writable:true, configurable:true});
+ port.postMessage(input);
+ close();
+ }
+ break;
+ case 'Object with non-writable property':
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_true(input.foo === 'bar', "input.foo === bar")) {
+ input.foo += ' baz';
+ if (check_true(input.foo === 'bar baz', "input.foo === 'bar baz'")) {
+ input = {};
+ Object.defineProperty(input, 'foo', {value:'bar', enumerable:true, writable:false, configurable:true});
+ port.postMessage(input);
+ close();
+ }
+ }
+ break;
+ case 'Object with non-configurable property':
+ if (check_true(input instanceof Object, 'input instanceof Object') &&
+ check_true(!(input instanceof Array), '!(input instanceof Array)') &&
+ check_true(input.foo === 'bar', "input.foo === bar")) {
+ delete input.foo;
+ if (check_true(!('foo' in input), "!('foo' in input)")) {
+ input = {};
+ Object.defineProperty(input, 'foo', {value:'bar', enumerable:true, writable:true, configurable:false});
+ port.postMessage(input);
+ close();
+ }
+ }
+ break;
+
+ default:
+ port.postMessage('FAIL: unknown test');
+ close();
+ }
+ if (log.length > 0) {
+ port.postMessage('FAIL '+log);
+ close();
+ }
+ } catch (ex) {
+ port.postMessage('FAIL '+ex);
+ close();
+ }
+}
diff --git a/testing/web-platform/tests/workers/semantics/xhr/001-1.xml b/testing/web-platform/tests/workers/semantics/xhr/001-1.xml
new file mode 100644
index 000000000..5d735bdf6
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/xhr/001-1.xml
@@ -0,0 +1 @@
+<x>foo</x> \ No newline at end of file
diff --git a/testing/web-platform/tests/workers/semantics/xhr/001.html b/testing/web-platform/tests/workers/semantics/xhr/001.html
new file mode 100644
index 000000000..e26e21c62
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/xhr/001.html
@@ -0,0 +1,35 @@
+<!--
+var xhr = new XMLHttpRequest();
+var log = '';
+xhr.onreadystatechange = function(e) {
+ if (this.readyState == 4) {
+ if (this.responseXML != null)
+ log += 'responseXML was not null. ';
+ if (this.responseText != '<x>foo</x>')
+ log += 'responseText was ' + this.responseText + ', expected <x>foo</x>. ';
+ postMessage(log);
+ }
+}
+xhr.open('GET', '001-1.xml', true);
+xhr.send();
+/*
+-->
+<!doctype html>
+<title>async XMLHttpRequest in dedicated worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var t = async_test();
+function runtest() {
+ var worker = new Worker('#');
+ worker.onmessage = this.step_func(function(e) {
+ assert_equals(e.data, '');
+ this.done();
+ });
+}
+</script>
+<iframe src=001-1.xml onload="t.step(runtest);"></iframe>
+<!--
+*/
+//--> \ No newline at end of file
diff --git a/testing/web-platform/tests/workers/semantics/xhr/002.html b/testing/web-platform/tests/workers/semantics/xhr/002.html
new file mode 100644
index 000000000..0d3386e98
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/xhr/002.html
@@ -0,0 +1,32 @@
+<!--
+var xhr = new XMLHttpRequest();
+var log = '';
+xhr.open('GET', '001-1.xml', false);
+xhr.send();
+if (xhr.responseXML != null)
+ log += 'responseXML was not null. ';
+if (xhr.responseText != '<x>foo</x>')
+ log += 'responseText was ' + this.responseText + ', expected <x>foo</x>. ';
+postMessage(log);
+
+/*
+-->
+<!doctype html>
+<title>sync XMLHttpRequest in dedicated worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var t = async_test();
+function runtest() {
+ var worker = new Worker('#');
+ worker.onmessage = this.step_func(function(e) {
+ assert_equals(e.data, '');
+ this.done();
+ });
+}
+</script>
+<iframe src=001-1.xml onload="t.step(runtest);"></iframe>
+<!--
+*/
+//--> \ No newline at end of file
diff --git a/testing/web-platform/tests/workers/semantics/xhr/003.html b/testing/web-platform/tests/workers/semantics/xhr/003.html
new file mode 100644
index 000000000..70edaf417
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/xhr/003.html
@@ -0,0 +1,41 @@
+<!--
+onconnect = function(e) {
+ var xhr = new XMLHttpRequest();
+ var log = '';
+ var port = e.ports[0];
+ var postMessage = port.postMessage;
+ xhr.onreadystatechange = function(e) {
+ if (this.readyState == 4) {
+ if (this.responseXML != null)
+ log += 'responseXML was not null. ';
+ if (this.responseText && this.responseText != '<x>foo</x>')
+ log += 'responseText was ' + this.responseText + ', expected <x>foo</x>. ';
+ postMessage.call(port, log);
+ }
+ }
+ xhr.open('GET', '001-1.xml', true);
+ xhr.send();
+}
+
+/*
+-->
+<!doctype html>
+<title>async XMLHttpRequest in shared worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var t = async_test();
+function runtest() {
+ var worker = new SharedWorker('#', '');
+ worker.port.onmessage = this.step_func(function(e) {
+ assert_equals(e.data, '');
+ this.done();
+ });
+}
+</script>
+<iframe src=001-1.xml onload="t.step(runtest);"></iframe>
+<!--
+*/
+//-->
+
diff --git a/testing/web-platform/tests/workers/semantics/xhr/004.html b/testing/web-platform/tests/workers/semantics/xhr/004.html
new file mode 100644
index 000000000..ec5893a4b
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/xhr/004.html
@@ -0,0 +1,36 @@
+<!--
+onconnect = function(e) {
+ var xhr = new XMLHttpRequest();
+ var log = '';
+ xhr.open('GET', '001-1.xml', false);
+ xhr.send();
+ if (xhr.responseXML != null)
+ log += 'responseXML was not null. ';
+ if (xhr.responseText != '<x>foo</x>')
+ log += 'responseText was ' + xhr.responseText + ', expected <x>foo</x>. ';
+ e.ports[0].postMessage(log);
+}
+
+/*
+-->
+<!doctype html>
+<title>sync XMLHttpRequest in shared worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var t = async_test();
+function runtest() {
+ var worker = new SharedWorker('#', '');
+ worker.port.onmessage = this.step_func(function(e) {
+ assert_equals(e.data, '');
+ this.done();
+ });
+}
+</script>
+<iframe src=001-1.xml onload="t.step(runtest);"></iframe>
+<!--
+*/
+//-->
+
+
diff --git a/testing/web-platform/tests/workers/semantics/xhr/005.html b/testing/web-platform/tests/workers/semantics/xhr/005.html
new file mode 100644
index 000000000..84abdb0c4
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/xhr/005.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>base url, dedicated worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var t = async_test();
+var i = 0;
+function runtest() {
+ i++;
+ if (i != 2)
+ return;
+ var worker = new Worker('support/005-1.js');
+ worker.onmessage = this.step_func(function(e) {
+ assert_true(e.data);
+ this.done();
+ });
+}
+</script>
+<iframe src=001-1.xml onload="t.step(runtest);"></iframe>
+<iframe src=support/001-1.xml onload="t.step(runtest);"></iframe>
diff --git a/testing/web-platform/tests/workers/semantics/xhr/006.html b/testing/web-platform/tests/workers/semantics/xhr/006.html
new file mode 100644
index 000000000..7411b4bae
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/xhr/006.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>base url, shared worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var t = async_test();
+var i = 0;
+function runtest() {
+ i++;
+ if (i != 2)
+ return;
+ var worker = new SharedWorker('support/006-1.js','');
+ worker.port.onmessage = this.step_func(function(e) {
+ assert_true(e.data);
+ this.done();
+ });
+}
+</script>
+<iframe src=001-1.xml onload="t.step(runtest);"></iframe>
+<iframe src=support/001-1.xml onload="t.step(runtest);"></iframe>
diff --git a/testing/web-platform/tests/workers/semantics/xhr/support/001-1.xml b/testing/web-platform/tests/workers/semantics/xhr/support/001-1.xml
new file mode 100644
index 000000000..ecea58a93
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/xhr/support/001-1.xml
@@ -0,0 +1 @@
+<x>bar</x> \ No newline at end of file
diff --git a/testing/web-platform/tests/workers/semantics/xhr/support/005-1.js b/testing/web-platform/tests/workers/semantics/xhr/support/005-1.js
new file mode 100644
index 000000000..45f6519a2
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/xhr/support/005-1.js
@@ -0,0 +1,5 @@
+var xhr = new XMLHttpRequest();
+xhr.open('GET', '001-1.xml', false);
+xhr.send();
+var passed = xhr.responseText == '<x>bar</x>';
+postMessage(passed); \ No newline at end of file
diff --git a/testing/web-platform/tests/workers/semantics/xhr/support/006-1.js b/testing/web-platform/tests/workers/semantics/xhr/support/006-1.js
new file mode 100644
index 000000000..d446781eb
--- /dev/null
+++ b/testing/web-platform/tests/workers/semantics/xhr/support/006-1.js
@@ -0,0 +1,7 @@
+onconnect = function(e) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', '001-1.xml', false);
+ xhr.send();
+ var passed = xhr.responseText == '<x>bar</x>';
+ e.ports[0].postMessage(passed);
+} \ No newline at end of file