Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2021-02-13 21:56:06 +0300
committerMichaël Zasso <targos@protonmail.com>2021-02-28 16:39:53 +0300
commit0d564ce2148dd48bbbec731d789cdfcb9cb38879 (patch)
tree006fd16f3ebb0b2e5d27880f28c9681758714c0e /test
parentdaad7bbd3447f04f50af24dd487563c60bc1a9dd (diff)
buffer: make Blob's slice method more spec-compliant
PR-URL: https://github.com/nodejs/node/pull/37361 Fixes: https://github.com/nodejs/node/issues/37335 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'test')
-rw-r--r--test/fixtures/wpt/FileAPI/blob/Blob-constructor-dom.window.js53
-rw-r--r--test/fixtures/wpt/FileAPI/blob/Blob-constructor.any.js459
-rw-r--r--test/fixtures/wpt/FileAPI/blob/Blob-slice-overflow.any.js32
-rw-r--r--test/fixtures/wpt/FileAPI/blob/Blob-slice.any.js231
-rw-r--r--test/fixtures/wpt/FileAPI/file/send-file-form-controls.html113
-rw-r--r--test/fixtures/wpt/FileAPI/file/send-file-form-iso-2022-jp.html65
-rw-r--r--test/fixtures/wpt/FileAPI/file/send-file-form-punctuation.html226
-rw-r--r--test/fixtures/wpt/FileAPI/file/send-file-form-windows-1252.html62
-rw-r--r--test/fixtures/wpt/FileAPI/file/send-file-form-x-user-defined.html63
-rw-r--r--test/fixtures/wpt/README.md2
-rw-r--r--test/fixtures/wpt/versions.json2
-rw-r--r--test/parallel/test-blob.js22
-rw-r--r--test/wpt/status/FileAPI/blob.json9
13 files changed, 1325 insertions, 14 deletions
diff --git a/test/fixtures/wpt/FileAPI/blob/Blob-constructor-dom.window.js b/test/fixtures/wpt/FileAPI/blob/Blob-constructor-dom.window.js
new file mode 100644
index 00000000000..4fd4a43ec4b
--- /dev/null
+++ b/test/fixtures/wpt/FileAPI/blob/Blob-constructor-dom.window.js
@@ -0,0 +1,53 @@
+// META: title=Blob constructor
+// META: script=../support/Blob.js
+'use strict';
+
+var test_error = {
+ name: "test",
+ message: "test error",
+};
+
+test(function() {
+ var args = [
+ document.createElement("div"),
+ window,
+ ];
+ args.forEach(function(arg) {
+ assert_throws_js(TypeError, function() {
+ new Blob(arg);
+ }, "Should throw for argument " + format_value(arg) + ".");
+ });
+}, "Passing platform objects for blobParts should throw a TypeError.");
+
+test(function() {
+ var element = document.createElement("div");
+ element.appendChild(document.createElement("div"));
+ element.appendChild(document.createElement("p"));
+ var list = element.children;
+ Object.defineProperty(list, "length", {
+ get: function() { throw test_error; }
+ });
+ assert_throws_exactly(test_error, function() {
+ new Blob(list);
+ });
+}, "A platform object that supports indexed properties should be treated as a sequence for the blobParts argument (overwritten 'length'.)");
+
+test_blob(function() {
+ var select = document.createElement("select");
+ select.appendChild(document.createElement("option"));
+ return new Blob(select);
+}, {
+ expected: "[object HTMLOptionElement]",
+ type: "",
+ desc: "Passing an platform object that supports indexed properties as the blobParts array should work (select)."
+});
+
+test_blob(function() {
+ var elm = document.createElement("div");
+ elm.setAttribute("foo", "bar");
+ return new Blob(elm.attributes);
+}, {
+ expected: "[object Attr]",
+ type: "",
+ desc: "Passing an platform object that supports indexed properties as the blobParts array should work (attributes)."
+}); \ No newline at end of file
diff --git a/test/fixtures/wpt/FileAPI/blob/Blob-constructor.any.js b/test/fixtures/wpt/FileAPI/blob/Blob-constructor.any.js
new file mode 100644
index 00000000000..6c34d7e34b9
--- /dev/null
+++ b/test/fixtures/wpt/FileAPI/blob/Blob-constructor.any.js
@@ -0,0 +1,459 @@
+// META: title=Blob constructor
+// META: script=../support/Blob.js
+'use strict';
+
+test(function() {
+ assert_true("Blob" in globalThis, "globalThis should have a Blob property.");
+ assert_equals(Blob.length, 0, "Blob.length should be 0.");
+ assert_true(Blob instanceof Function, "Blob should be a function.");
+}, "Blob interface object");
+
+// Step 1.
+test(function() {
+ var blob = new Blob();
+ assert_true(blob instanceof Blob);
+ assert_equals(String(blob), '[object Blob]');
+ assert_equals(blob.size, 0);
+ assert_equals(blob.type, "");
+}, "Blob constructor with no arguments");
+test(function() {
+ assert_throws_js(TypeError, function() { var blob = Blob(); });
+}, "Blob constructor with no arguments, without 'new'");
+test(function() {
+ var blob = new Blob;
+ assert_true(blob instanceof Blob);
+ assert_equals(blob.size, 0);
+ assert_equals(blob.type, "");
+}, "Blob constructor without brackets");
+test(function() {
+ var blob = new Blob(undefined);
+ assert_true(blob instanceof Blob);
+ assert_equals(String(blob), '[object Blob]');
+ assert_equals(blob.size, 0);
+ assert_equals(blob.type, "");
+}, "Blob constructor with undefined as first argument");
+
+// blobParts argument (WebIDL).
+test(function() {
+ var args = [
+ null,
+ true,
+ false,
+ 0,
+ 1,
+ 1.5,
+ "FAIL",
+ new Date(),
+ new RegExp(),
+ {},
+ { 0: "FAIL", length: 1 },
+ ];
+ args.forEach(function(arg) {
+ assert_throws_js(TypeError, function() {
+ new Blob(arg);
+ }, "Should throw for argument " + format_value(arg) + ".");
+ });
+}, "Passing non-objects, Dates and RegExps for blobParts should throw a TypeError.");
+
+test_blob(function() {
+ return new Blob({
+ [Symbol.iterator]: Array.prototype[Symbol.iterator],
+ });
+}, {
+ expected: "",
+ type: "",
+ desc: "A plain object with @@iterator should be treated as a sequence for the blobParts argument."
+});
+test(t => {
+ const blob = new Blob({
+ [Symbol.iterator]() {
+ var i = 0;
+ return {next: () => [
+ {done:false, value:'ab'},
+ {done:false, value:'cde'},
+ {done:true}
+ ][i++]
+ };
+ }
+ });
+ assert_equals(blob.size, 5, 'Custom @@iterator should be treated as a sequence');
+}, "A plain object with custom @@iterator should be treated as a sequence for the blobParts argument.");
+test_blob(function() {
+ return new Blob({
+ [Symbol.iterator]: Array.prototype[Symbol.iterator],
+ 0: "PASS",
+ length: 1
+ });
+}, {
+ expected: "PASS",
+ type: "",
+ desc: "A plain object with @@iterator and a length property should be treated as a sequence for the blobParts argument."
+});
+test_blob(function() {
+ return new Blob(new String("xyz"));
+}, {
+ expected: "xyz",
+ type: "",
+ desc: "A String object should be treated as a sequence for the blobParts argument."
+});
+test_blob(function() {
+ return new Blob(new Uint8Array([1, 2, 3]));
+}, {
+ expected: "123",
+ type: "",
+ desc: "A Uint8Array object should be treated as a sequence for the blobParts argument."
+});
+
+var test_error = {
+ name: "test",
+ message: "test error",
+};
+
+test(function() {
+ var obj = {
+ [Symbol.iterator]: Array.prototype[Symbol.iterator],
+ get length() { throw test_error; }
+ };
+ assert_throws_exactly(test_error, function() {
+ new Blob(obj);
+ });
+}, "The length getter should be invoked and any exceptions should be propagated.");
+
+test(function() {
+ assert_throws_exactly(test_error, function() {
+ var obj = {
+ [Symbol.iterator]: Array.prototype[Symbol.iterator],
+ length: {
+ valueOf: null,
+ toString: function() { throw test_error; }
+ }
+ };
+ new Blob(obj);
+ });
+ assert_throws_exactly(test_error, function() {
+ var obj = {
+ [Symbol.iterator]: Array.prototype[Symbol.iterator],
+ length: { valueOf: function() { throw test_error; } }
+ };
+ new Blob(obj);
+ });
+}, "ToUint32 should be applied to the length and any exceptions should be propagated.");
+
+test(function() {
+ var received = [];
+ var obj = {
+ get [Symbol.iterator]() {
+ received.push("Symbol.iterator");
+ return Array.prototype[Symbol.iterator];
+ },
+ get length() {
+ received.push("length getter");
+ return {
+ valueOf: function() {
+ received.push("length valueOf");
+ return 3;
+ }
+ };
+ },
+ get 0() {
+ received.push("0 getter");
+ return {
+ toString: function() {
+ received.push("0 toString");
+ return "a";
+ }
+ };
+ },
+ get 1() {
+ received.push("1 getter");
+ throw test_error;
+ },
+ get 2() {
+ received.push("2 getter");
+ assert_unreached("Should not call the getter for 2 if the getter for 1 threw.");
+ }
+ };
+ assert_throws_exactly(test_error, function() {
+ new Blob(obj);
+ });
+ assert_array_equals(received, [
+ "Symbol.iterator",
+ "length getter",
+ "length valueOf",
+ "0 getter",
+ "0 toString",
+ "length getter",
+ "length valueOf",
+ "1 getter",
+ ]);
+}, "Getters and value conversions should happen in order until an exception is thrown.");
+
+// XXX should add tests edge cases of ToLength(length)
+
+test(function() {
+ assert_throws_exactly(test_error, function() {
+ new Blob([{ toString: function() { throw test_error; } }]);
+ }, "Throwing toString");
+ assert_throws_exactly(test_error, function() {
+ new Blob([{ toString: undefined, valueOf: function() { throw test_error; } }]);
+ }, "Throwing valueOf");
+ assert_throws_exactly(test_error, function() {
+ new Blob([{
+ toString: function() { throw test_error; },
+ valueOf: function() { assert_unreached("Should not call valueOf if toString is present."); }
+ }]);
+ }, "Throwing toString and valueOf");
+ assert_throws_js(TypeError, function() {
+ new Blob([{toString: null, valueOf: null}]);
+ }, "Null toString and valueOf");
+}, "ToString should be called on elements of the blobParts array and any exceptions should be propagated.");
+
+test_blob(function() {
+ var arr = [
+ { toString: function() { arr.pop(); return "PASS"; } },
+ { toString: function() { assert_unreached("Should have removed the second element of the array rather than called toString() on it."); } }
+ ];
+ return new Blob(arr);
+}, {
+ expected: "PASS",
+ type: "",
+ desc: "Changes to the blobParts array should be reflected in the returned Blob (pop)."
+});
+
+test_blob(function() {
+ var arr = [
+ {
+ toString: function() {
+ if (arr.length === 3) {
+ return "A";
+ }
+ arr.unshift({
+ toString: function() {
+ assert_unreached("Should only access index 0 once.");
+ }
+ });
+ return "P";
+ }
+ },
+ {
+ toString: function() {
+ return "SS";
+ }
+ }
+ ];
+ return new Blob(arr);
+}, {
+ expected: "PASS",
+ type: "",
+ desc: "Changes to the blobParts array should be reflected in the returned Blob (unshift)."
+});
+
+test_blob(function() {
+ // https://www.w3.org/Bugs/Public/show_bug.cgi?id=17652
+ return new Blob([
+ null,
+ undefined,
+ true,
+ false,
+ 0,
+ 1,
+ new String("stringobject"),
+ [],
+ ['x', 'y'],
+ {},
+ { 0: "FAIL", length: 1 },
+ { toString: function() { return "stringA"; } },
+ { toString: undefined, valueOf: function() { return "stringB"; } },
+ { valueOf: function() { assert_unreached("Should not call valueOf if toString is present on the prototype."); } }
+ ]);
+}, {
+ expected: "nullundefinedtruefalse01stringobjectx,y[object Object][object Object]stringAstringB[object Object]",
+ type: "",
+ desc: "ToString should be called on elements of the blobParts array."
+});
+
+test_blob(function() {
+ return new Blob([
+ new ArrayBuffer(8)
+ ]);
+}, {
+ expected: "\0\0\0\0\0\0\0\0",
+ type: "",
+ desc: "ArrayBuffer elements of the blobParts array should be supported."
+});
+
+test_blob(function() {
+ return new Blob([
+ new Uint8Array([0x50, 0x41, 0x53, 0x53]),
+ new Int8Array([0x50, 0x41, 0x53, 0x53]),
+ new Uint16Array([0x4150, 0x5353]),
+ new Int16Array([0x4150, 0x5353]),
+ new Uint32Array([0x53534150]),
+ new Int32Array([0x53534150]),
+ new Float32Array([0xD341500000])
+ ]);
+}, {
+ expected: "PASSPASSPASSPASSPASSPASSPASS",
+ type: "",
+ desc: "Passing typed arrays as elements of the blobParts array should work."
+});
+test_blob(function() {
+ return new Blob([
+ // 0x535 3415053534150
+ // 0x535 = 0b010100110101 -> Sign = +, Exponent = 1333 - 1023 = 310
+ // 0x13415053534150 * 2**(-52)
+ // ==> 0x13415053534150 * 2**258 = 2510297372767036725005267563121821874921913208671273727396467555337665343087229079989707079680
+ new Float64Array([2510297372767036725005267563121821874921913208671273727396467555337665343087229079989707079680])
+ ]);
+}, {
+ expected: "PASSPASS",
+ type: "",
+ desc: "Passing a Float64Array as element of the blobParts array should work."
+});
+
+
+
+var t_ports = async_test("Passing a FrozenArray as the blobParts array should work (FrozenArray<MessagePort>).");
+t_ports.step(function() {
+ var channel = new MessageChannel();
+ channel.port2.onmessage = this.step_func(function(e) {
+ var b_ports = new Blob(e.ports);
+ assert_equals(b_ports.size, "[object MessagePort]".length);
+ this.done();
+ });
+ var channel2 = new MessageChannel();
+ channel.port1.postMessage('', [channel2.port1]);
+});
+
+test_blob(function() {
+ var blob = new Blob(['foo']);
+ return new Blob([blob, blob]);
+}, {
+ expected: "foofoo",
+ type: "",
+ desc: "Array with two blobs"
+});
+
+test_blob_binary(function() {
+ var view = new Uint8Array([0, 255, 0]);
+ return new Blob([view.buffer, view.buffer]);
+}, {
+ expected: [0, 255, 0, 0, 255, 0],
+ type: "",
+ desc: "Array with two buffers"
+});
+
+test_blob_binary(function() {
+ var view = new Uint8Array([0, 255, 0, 4]);
+ var blob = new Blob([view, view]);
+ assert_equals(blob.size, 8);
+ var view1 = new Uint16Array(view.buffer, 2);
+ return new Blob([view1, view.buffer, view1]);
+}, {
+ expected: [0, 4, 0, 255, 0, 4, 0, 4],
+ type: "",
+ desc: "Array with two bufferviews"
+});
+
+test_blob(function() {
+ var view = new Uint8Array([0]);
+ var blob = new Blob(["fo"]);
+ return new Blob([view.buffer, blob, "foo"]);
+}, {
+ expected: "\0fofoo",
+ type: "",
+ desc: "Array with mixed types"
+});
+
+test(function() {
+ const accessed = [];
+ const stringified = [];
+
+ new Blob([], {
+ get type() { accessed.push('type'); },
+ get endings() { accessed.push('endings'); }
+ });
+ new Blob([], {
+ type: { toString: () => { stringified.push('type'); return ''; } },
+ endings: { toString: () => { stringified.push('endings'); return 'transparent'; } }
+ });
+ assert_array_equals(accessed, ['endings', 'type']);
+ assert_array_equals(stringified, ['endings', 'type']);
+}, "options properties should be accessed in lexicographic order.");
+
+test(function() {
+ assert_throws_exactly(test_error, function() {
+ new Blob(
+ [{ toString: function() { throw test_error } }],
+ {
+ get type() { assert_unreached("type getter should not be called."); }
+ }
+ );
+ });
+}, "Arguments should be evaluated from left to right.");
+
+[
+ null,
+ undefined,
+ {},
+ { unrecognized: true },
+ /regex/,
+ function() {}
+].forEach(function(arg, idx) {
+ test_blob(function() {
+ return new Blob([], arg);
+ }, {
+ expected: "",
+ type: "",
+ desc: "Passing " + format_value(arg) + " (index " + idx + ") for options should use the defaults."
+ });
+ test_blob(function() {
+ return new Blob(["\na\r\nb\n\rc\r"], arg);
+ }, {
+ expected: "\na\r\nb\n\rc\r",
+ type: "",
+ desc: "Passing " + format_value(arg) + " (index " + idx + ") for options should use the defaults (with newlines)."
+ });
+});
+
+[
+ 123,
+ 123.4,
+ true,
+ 'abc'
+].forEach(arg => {
+ test(t => {
+ assert_throws_js(TypeError, () => new Blob([], arg),
+ 'Blob constructor should throw with invalid property bag');
+ }, `Passing ${JSON.stringify(arg)} for options should throw`);
+});
+
+var type_tests = [
+ // blobParts, type, expected type
+ [[], '', ''],
+ [[], 'a', 'a'],
+ [[], 'A', 'a'],
+ [[], 'text/html', 'text/html'],
+ [[], 'TEXT/HTML', 'text/html'],
+ [[], 'text/plain;charset=utf-8', 'text/plain;charset=utf-8'],
+ [[], '\u00E5', ''],
+ [[], '\uD801\uDC7E', ''], // U+1047E
+ [[], ' image/gif ', ' image/gif '],
+ [[], '\timage/gif\t', ''],
+ [[], 'image/gif;\u007f', ''],
+ [[], '\u0130mage/gif', ''], // uppercase i with dot
+ [[], '\u0131mage/gif', ''], // lowercase dotless i
+ [[], 'image/gif\u0000', ''],
+ // check that type isn't changed based on sniffing
+ [[0x3C, 0x48, 0x54, 0x4D, 0x4C, 0x3E], 'unknown/unknown', 'unknown/unknown'], // "<HTML>"
+ [[0x00, 0xFF], 'text/plain', 'text/plain'],
+ [[0x47, 0x49, 0x46, 0x38, 0x39, 0x61], 'image/png', 'image/png'], // "GIF89a"
+];
+
+type_tests.forEach(function(t) {
+ test(function() {
+ var arr = new Uint8Array([t[0]]).buffer;
+ var b = new Blob([arr], {type:t[1]});
+ assert_equals(b.type, t[2]);
+ }, "Blob with type " + format_value(t[1]));
+});
diff --git a/test/fixtures/wpt/FileAPI/blob/Blob-slice-overflow.any.js b/test/fixtures/wpt/FileAPI/blob/Blob-slice-overflow.any.js
new file mode 100644
index 00000000000..388fd9282c9
--- /dev/null
+++ b/test/fixtures/wpt/FileAPI/blob/Blob-slice-overflow.any.js
@@ -0,0 +1,32 @@
+// META: title=Blob slice overflow
+'use strict';
+
+var text = '';
+
+for (var i = 0; i < 2000; ++i) {
+ text += 'A';
+}
+
+test(function() {
+ var blob = new Blob([text]);
+ var sliceBlob = blob.slice(-1, blob.size);
+ assert_equals(sliceBlob.size, 1, "Blob slice size");
+}, "slice start is negative, relativeStart will be max((size + start), 0)");
+
+test(function() {
+ var blob = new Blob([text]);
+ var sliceBlob = blob.slice(blob.size + 1, blob.size);
+ assert_equals(sliceBlob.size, 0, "Blob slice size");
+}, "slice start is greater than blob size, relativeStart will be min(start, size)");
+
+test(function() {
+ var blob = new Blob([text]);
+ var sliceBlob = blob.slice(blob.size - 2, -1);
+ assert_equals(sliceBlob.size, 1, "Blob slice size");
+}, "slice end is negative, relativeEnd will be max((size + end), 0)");
+
+test(function() {
+ var blob = new Blob([text]);
+ var sliceBlob = blob.slice(blob.size - 2, blob.size + 999);
+ assert_equals(sliceBlob.size, 2, "Blob slice size");
+}, "slice end is greater than blob size, relativeEnd will be min(end, size)");
diff --git a/test/fixtures/wpt/FileAPI/blob/Blob-slice.any.js b/test/fixtures/wpt/FileAPI/blob/Blob-slice.any.js
new file mode 100644
index 00000000000..1f85d44d269
--- /dev/null
+++ b/test/fixtures/wpt/FileAPI/blob/Blob-slice.any.js
@@ -0,0 +1,231 @@
+// META: title=Blob slice
+// META: script=../support/Blob.js
+'use strict';
+
+test_blob(function() {
+ var blobTemp = new Blob(["PASS"]);
+ return blobTemp.slice();
+}, {
+ expected: "PASS",
+ type: "",
+ desc: "no-argument Blob slice"
+});
+
+test(function() {
+ var blob1, blob2;
+
+ test_blob(function() {
+ return blob1 = new Blob(["squiggle"]);
+ }, {
+ expected: "squiggle",
+ type: "",
+ desc: "blob1."
+ });
+
+ test_blob(function() {
+ return blob2 = new Blob(["steak"], {type: "content/type"});
+ }, {
+ expected: "steak",
+ type: "content/type",
+ desc: "blob2."
+ });
+
+ test_blob(function() {
+ return new Blob().slice(0,0,null);
+ }, {
+ expected: "",
+ type: "null",
+ desc: "null type Blob slice"
+ });
+
+ test_blob(function() {
+ return new Blob().slice(0,0,undefined);
+ }, {
+ expected: "",
+ type: "",
+ desc: "undefined type Blob slice"
+ });
+
+ test_blob(function() {
+ return new Blob().slice(0,0);
+ }, {
+ expected: "",
+ type: "",
+ desc: "no type Blob slice"
+ });
+
+ var arrayBuffer = new ArrayBuffer(16);
+ var int8View = new Int8Array(arrayBuffer);
+ for (var i = 0; i < 16; i++) {
+ int8View[i] = i + 65;
+ }
+
+ var testData = [
+ [
+ ["PASSSTRING"],
+ [{start: -6, contents: "STRING"},
+ {start: -12, contents: "PASSSTRING"},
+ {start: 4, contents: "STRING"},
+ {start: 12, contents: ""},
+ {start: 0, end: -6, contents: "PASS"},
+ {start: 0, end: -12, contents: ""},
+ {start: 0, end: 4, contents: "PASS"},
+ {start: 0, end: 12, contents: "PASSSTRING"},
+ {start: 7, end: 4, contents: ""}]
+ ],
+
+ // Test 3 strings
+ [
+ ["foo", "bar", "baz"],
+ [{start: 0, end: 9, contents: "foobarbaz"},
+ {start: 0, end: 3, contents: "foo"},
+ {start: 3, end: 9, contents: "barbaz"},
+ {start: 6, end: 9, contents: "baz"},
+ {start: 6, end: 12, contents: "baz"},
+ {start: 0, end: 9, contents: "foobarbaz"},
+ {start: 0, end: 11, contents: "foobarbaz"},
+ {start: 10, end: 15, contents: ""}]
+ ],
+
+ // Test string, Blob, string
+ [
+ ["foo", blob1, "baz"],
+ [{start: 0, end: 3, contents: "foo"},
+ {start: 3, end: 11, contents: "squiggle"},
+ {start: 2, end: 4, contents: "os"},
+ {start: 10, end: 12, contents: "eb"}]
+ ],
+
+ // Test blob, string, blob
+ [
+ [blob1, "foo", blob1],
+ [{start: 0, end: 8, contents: "squiggle"},
+ {start: 7, end: 9, contents: "ef"},
+ {start: 10, end: 12, contents: "os"},
+ {start: 1, end: 4, contents: "qui"},
+ {start: 12, end: 15, contents: "qui"},
+ {start: 40, end: 60, contents: ""}]
+ ],
+
+ // Test blobs all the way down
+ [
+ [blob2, blob1, blob2],
+ [{start: 0, end: 5, contents: "steak"},
+ {start: 5, end: 13, contents: "squiggle"},
+ {start: 13, end: 18, contents: "steak"},
+ {start: 1, end: 3, contents: "te"},
+ {start: 6, end: 10, contents: "quig"}]
+ ],
+
+ // Test an ArrayBufferView
+ [
+ [int8View, blob1, "foo"],
+ [{start: 0, end: 8, contents: "ABCDEFGH"},
+ {start: 8, end: 18, contents: "IJKLMNOPsq"},
+ {start: 17, end: 20, contents: "qui"},
+ {start: 4, end: 12, contents: "EFGHIJKL"}]
+ ],
+
+ // Test a partial ArrayBufferView
+ [
+ [new Uint8Array(arrayBuffer, 3, 5), blob1, "foo"],
+ [{start: 0, end: 8, contents: "DEFGHsqu"},
+ {start: 8, end: 18, contents: "igglefoo"},
+ {start: 4, end: 12, contents: "Hsquiggl"}]
+ ],
+
+ // Test type coercion of a number
+ [
+ [3, int8View, "foo"],
+ [{start: 0, end: 8, contents: "3ABCDEFG"},
+ {start: 8, end: 18, contents: "HIJKLMNOPf"},
+ {start: 17, end: 21, contents: "foo"},
+ {start: 4, end: 12, contents: "DEFGHIJK"}]
+ ],
+
+ [
+ [(new Uint8Array([0, 255, 0])).buffer,
+ new Blob(['abcd']),
+ 'efgh',
+ 'ijklmnopqrstuvwxyz'],
+ [{start: 1, end: 4, contents: "\uFFFD\u0000a"},
+ {start: 4, end: 8, contents: "bcde"},
+ {start: 8, end: 12, contents: "fghi"},
+ {start: 1, end: 12, contents: "\uFFFD\u0000abcdefghi"}]
+ ]
+ ];
+
+ testData.forEach(function(data, i) {
+ var blobs = data[0];
+ var tests = data[1];
+ tests.forEach(function(expectations, j) {
+ test(function() {
+ var blob = new Blob(blobs);
+ assert_true(blob instanceof Blob);
+ assert_false(blob instanceof File);
+
+ test_blob(function() {
+ return expectations.end === undefined
+ ? blob.slice(expectations.start)
+ : blob.slice(expectations.start, expectations.end);
+ }, {
+ expected: expectations.contents,
+ type: "",
+ desc: "Slicing test: slice (" + i + "," + j + ")."
+ });
+ }, "Slicing test (" + i + "," + j + ").");
+ });
+ });
+}, "Slices");
+
+var invalidTypes = [
+ "\xFF",
+ "te\x09xt/plain",
+ "te\x00xt/plain",
+ "te\x1Fxt/plain",
+ "te\x7Fxt/plain"
+];
+invalidTypes.forEach(function(type) {
+ test_blob(function() {
+ var blob = new Blob(["PASS"]);
+ return blob.slice(0, 4, type);
+ }, {
+ expected: "PASS",
+ type: "",
+ desc: "Invalid contentType (" + format_value(type) + ")"
+ });
+});
+
+var validTypes = [
+ "te(xt/plain",
+ "te)xt/plain",
+ "te<xt/plain",
+ "te>xt/plain",
+ "te@xt/plain",
+ "te,xt/plain",
+ "te;xt/plain",
+ "te:xt/plain",
+ "te\\xt/plain",
+ "te\"xt/plain",
+ "te/xt/plain",
+ "te[xt/plain",
+ "te]xt/plain",
+ "te?xt/plain",
+ "te=xt/plain",
+ "te{xt/plain",
+ "te}xt/plain",
+ "te\x20xt/plain",
+ "TEXT/PLAIN",
+ "text/plain;charset = UTF-8",
+ "text/plain;charset=UTF-8"
+];
+validTypes.forEach(function(type) {
+ test_blob(function() {
+ var blob = new Blob(["PASS"]);
+ return blob.slice(0, 4, type);
+ }, {
+ expected: "PASS",
+ type: type.toLowerCase(),
+ desc: "Valid contentType (" + format_value(type) + ")"
+ });
+});
diff --git a/test/fixtures/wpt/FileAPI/file/send-file-form-controls.html b/test/fixtures/wpt/FileAPI/file/send-file-form-controls.html
new file mode 100644
index 00000000000..6347065bcae
--- /dev/null
+++ b/test/fixtures/wpt/FileAPI/file/send-file-form-controls.html
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>Upload files named using controls</title>
+<link
+ rel="help"
+ href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart-form-data"
+/>
+<link
+ rel="help"
+ href="https://html.spec.whatwg.org/multipage/dnd.html#datatransferitemlist"
+/>
+<link rel="help" href="https://w3c.github.io/FileAPI/#file-constructor" />
+<link
+ rel="author"
+ title="Benjamin C. Wiley Sittler"
+ href="mailto:bsittler@chromium.org"
+/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/send-file-form-helper.js"></script>
+<script>
+ "use strict";
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-NUL-[\0].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-NUL-[\0].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-BS-[\b].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-BS-[\b].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-VT-[\v].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-VT-[\v].txt",
+ });
+
+ // These have characters that undergo processing in name=,
+ // filename=, and/or value; formPostFileUploadTest postprocesses
+ // expectedEncodedBaseName for these internally.
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-LF-[\n].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-LF-[\n].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-LF-CR-[\n\r].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-LF-CR-[\n\r].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-CR-[\r].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-CR-[\r].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-CR-LF-[\r\n].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-CR-LF-[\r\n].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-HT-[\t].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-HT-[\t].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-FF-[\f].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-FF-[\f].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-DEL-[\x7F].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-DEL-[\x7F].txt",
+ });
+
+ // The rest should be passed through unmodified:
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-ESC-[\x1B].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-ESC-[\x1B].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-SPACE-[ ].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-SPACE-[ ].txt",
+ });
+</script>
diff --git a/test/fixtures/wpt/FileAPI/file/send-file-form-iso-2022-jp.html b/test/fixtures/wpt/FileAPI/file/send-file-form-iso-2022-jp.html
new file mode 100644
index 00000000000..c931c9be3ab
--- /dev/null
+++ b/test/fixtures/wpt/FileAPI/file/send-file-form-iso-2022-jp.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name=timeout content=long>
+<title>Upload files in ISO-2022-JP form</title>
+<link rel="help"
+ href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart-form-data">
+<link rel="help"
+ href="https://html.spec.whatwg.org/multipage/dnd.html#datatransferitemlist">
+<link rel="help"
+ href="https://w3c.github.io/FileAPI/#file-constructor">
+<link rel="author" title="Benjamin C. Wiley Sittler"
+ href="mailto:bsittler@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/send-file-form-helper.js"></script>
+<script>
+'use strict';
+
+formPostFileUploadTest({
+ fileNameSource: 'ASCII',
+ fileBaseName: 'file-for-upload-in-form.txt',
+ formEncoding: 'ISO-2022-JP',
+ expectedEncodedBaseName: 'file-for-upload-in-form.txt',
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'x-user-defined',
+ fileBaseName: 'file-for-upload-in-form-\uF7F0\uF793\uF783\uF7A0.txt',
+ formEncoding: 'ISO-2022-JP',
+ expectedEncodedBaseName: (
+ 'file-for-upload-in-form-&#63472;&#63379;&#63363;&#63392;.txt'),
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'windows-1252',
+ fileBaseName: 'file-for-upload-in-form-☺😂.txt',
+ formEncoding: 'ISO-2022-JP',
+ expectedEncodedBaseName: (
+ 'file-for-upload-in-form-&#226;&#732;&#186;&#240;&#376;&#732;&#8218;.txt'),
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'JIS X 0201 and JIS X 0208',
+ fileBaseName: 'file-for-upload-in-form-★星★.txt',
+ formEncoding: 'ISO-2022-JP',
+ expectedEncodedBaseName: 'file-for-upload-in-form-\x1B$B!z@1!z\x1B(B.txt',
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'Unicode',
+ fileBaseName: 'file-for-upload-in-form-☺😂.txt',
+ formEncoding: 'ISO-2022-JP',
+ expectedEncodedBaseName: 'file-for-upload-in-form-&#9786;&#128514;.txt',
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'Unicode',
+ fileBaseName: `file-for-upload-in-form-${kTestChars}.txt`,
+ formEncoding: 'ISO-2022-JP',
+ expectedEncodedBaseName: `file-for-upload-in-form-${
+ kTestFallbackIso2022jp
+ }.txt`,
+});
+
+</script>
diff --git a/test/fixtures/wpt/FileAPI/file/send-file-form-punctuation.html b/test/fixtures/wpt/FileAPI/file/send-file-form-punctuation.html
new file mode 100644
index 00000000000..a6568e2e56e
--- /dev/null
+++ b/test/fixtures/wpt/FileAPI/file/send-file-form-punctuation.html
@@ -0,0 +1,226 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>Upload files named using punctuation</title>
+<link
+ rel="help"
+ href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart-form-data"
+/>
+<link
+ rel="help"
+ href="https://html.spec.whatwg.org/multipage/dnd.html#datatransferitemlist"
+/>
+<link rel="help" href="https://w3c.github.io/FileAPI/#file-constructor" />
+<link
+ rel="author"
+ title="Benjamin C. Wiley Sittler"
+ href="mailto:bsittler@chromium.org"
+/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/send-file-form-helper.js"></script>
+<script>
+ "use strict";
+
+ // These have characters that undergo processing in name=,
+ // filename=, and/or value; formPostFileUploadTest postprocesses
+ // expectedEncodedBaseName for these internally.
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-QUOTATION-MARK-[\x22].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName:
+ "file-for-upload-in-form-QUOTATION-MARK-[\x22].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: '"file-for-upload-in-form-double-quoted.txt"',
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: '"file-for-upload-in-form-double-quoted.txt"',
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-REVERSE-SOLIDUS-[\\].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName:
+ "file-for-upload-in-form-REVERSE-SOLIDUS-[\\].txt",
+ });
+
+ // The rest should be passed through unmodified:
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-EXCLAMATION-MARK-[!].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-EXCLAMATION-MARK-[!].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-DOLLAR-SIGN-[$].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-DOLLAR-SIGN-[$].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-PERCENT-SIGN-[%].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-PERCENT-SIGN-[%].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-AMPERSAND-[&].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-AMPERSAND-[&].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-APOSTROPHE-['].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-APOSTROPHE-['].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-LEFT-PARENTHESIS-[(].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-LEFT-PARENTHESIS-[(].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-RIGHT-PARENTHESIS-[)].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName:
+ "file-for-upload-in-form-RIGHT-PARENTHESIS-[)].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-ASTERISK-[*].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-ASTERISK-[*].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-PLUS-SIGN-[+].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-PLUS-SIGN-[+].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-COMMA-[,].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-COMMA-[,].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-FULL-STOP-[.].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-FULL-STOP-[.].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-SOLIDUS-[/].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-SOLIDUS-[/].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-COLON-[:].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-COLON-[:].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-SEMICOLON-[;].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-SEMICOLON-[;].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-EQUALS-SIGN-[=].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-EQUALS-SIGN-[=].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-QUESTION-MARK-[?].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-QUESTION-MARK-[?].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-CIRCUMFLEX-ACCENT-[^].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName:
+ "file-for-upload-in-form-CIRCUMFLEX-ACCENT-[^].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-LEFT-SQUARE-BRACKET-[[].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName:
+ "file-for-upload-in-form-LEFT-SQUARE-BRACKET-[[].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-RIGHT-SQUARE-BRACKET-[]].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName:
+ "file-for-upload-in-form-RIGHT-SQUARE-BRACKET-[]].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-LEFT-CURLY-BRACKET-[{].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName:
+ "file-for-upload-in-form-LEFT-CURLY-BRACKET-[{].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-VERTICAL-LINE-[|].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-VERTICAL-LINE-[|].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-RIGHT-CURLY-BRACKET-[}].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName:
+ "file-for-upload-in-form-RIGHT-CURLY-BRACKET-[}].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "file-for-upload-in-form-TILDE-[~].txt",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "file-for-upload-in-form-TILDE-[~].txt",
+ });
+
+ formPostFileUploadTest({
+ fileNameSource: "ASCII",
+ fileBaseName: "'file-for-upload-in-form-single-quoted.txt'",
+ formEncoding: "UTF-8",
+ expectedEncodedBaseName: "'file-for-upload-in-form-single-quoted.txt'",
+ });
+</script>
diff --git a/test/fixtures/wpt/FileAPI/file/send-file-form-windows-1252.html b/test/fixtures/wpt/FileAPI/file/send-file-form-windows-1252.html
new file mode 100644
index 00000000000..21b219ffd2d
--- /dev/null
+++ b/test/fixtures/wpt/FileAPI/file/send-file-form-windows-1252.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Upload files in Windows-1252 form</title>
+<link rel="help"
+ href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart-form-data">
+<link rel="help"
+ href="https://html.spec.whatwg.org/multipage/dnd.html#datatransferitemlist">
+<link rel="help"
+ href="https://w3c.github.io/FileAPI/#file-constructor">
+<link rel="author" title="Benjamin C. Wiley Sittler"
+ href="mailto:bsittler@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/send-file-form-helper.js"></script>
+<script>
+'use strict';
+
+formPostFileUploadTest({
+ fileNameSource: 'ASCII',
+ fileBaseName: 'file-for-upload-in-form.txt',
+ formEncoding: 'windows-1252',
+ expectedEncodedBaseName: 'file-for-upload-in-form.txt',
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'x-user-defined',
+ fileBaseName: 'file-for-upload-in-form-\uF7F0\uF793\uF783\uF7A0.txt',
+ formEncoding: 'windows-1252',
+ expectedEncodedBaseName: 'file-for-upload-in-form-&#63472;&#63379;&#63363;&#63392;.txt',
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'windows-1252',
+ fileBaseName: 'file-for-upload-in-form-☺😂.txt',
+ formEncoding: 'windows-1252',
+ expectedEncodedBaseName: 'file-for-upload-in-form-\xE2\x98\xBA\xF0\x9F\x98\x82.txt',
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'JIS X 0201 and JIS X 0208',
+ fileBaseName: 'file-for-upload-in-form-★星★.txt',
+ formEncoding: 'windows-1252',
+ expectedEncodedBaseName: 'file-for-upload-in-form-&#9733;&#26143;&#9733;.txt',
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'Unicode',
+ fileBaseName: 'file-for-upload-in-form-☺😂.txt',
+ formEncoding: 'windows-1252',
+ expectedEncodedBaseName: 'file-for-upload-in-form-&#9786;&#128514;.txt',
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'Unicode',
+ fileBaseName: `file-for-upload-in-form-${kTestChars}.txt`,
+ formEncoding: 'windows-1252',
+ expectedEncodedBaseName: `file-for-upload-in-form-${
+ kTestFallbackWindows1252
+ }.txt`,
+});
+
+</script>
diff --git a/test/fixtures/wpt/FileAPI/file/send-file-form-x-user-defined.html b/test/fixtures/wpt/FileAPI/file/send-file-form-x-user-defined.html
new file mode 100644
index 00000000000..8d6605d86de
--- /dev/null
+++ b/test/fixtures/wpt/FileAPI/file/send-file-form-x-user-defined.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Upload files in x-user-defined form</title>
+<link rel="help"
+ href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart-form-data">
+<link rel="help"
+ href="https://html.spec.whatwg.org/multipage/dnd.html#datatransferitemlist">
+<link rel="help"
+ href="https://w3c.github.io/FileAPI/#file-constructor">
+<link rel="author" title="Benjamin C. Wiley Sittler"
+ href="mailto:bsittler@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/send-file-form-helper.js"></script>
+<script>
+'use strict';
+
+formPostFileUploadTest({
+ fileNameSource: 'ASCII',
+ fileBaseName: 'file-for-upload-in-form.txt',
+ formEncoding: 'x-user-defined',
+ expectedEncodedBaseName: 'file-for-upload-in-form.txt',
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'x-user-defined',
+ fileBaseName: 'file-for-upload-in-form-\uF7F0\uF793\uF783\uF7A0.txt',
+ formEncoding: 'x-user-defined',
+ expectedEncodedBaseName: 'file-for-upload-in-form-\xF0\x93\x83\xA0.txt',
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'windows-1252',
+ fileBaseName: 'file-for-upload-in-form-☺😂.txt',
+ formEncoding: 'x-user-defined',
+ expectedEncodedBaseName: ('file-for-upload-in-form-' +
+ '&#226;&#732;&#186;&#240;&#376;&#732;&#8218;.txt'),
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'JIS X 0201 and JIS X 0208',
+ fileBaseName: 'file-for-upload-in-form-★星★.txt',
+ formEncoding: 'x-user-defined',
+ expectedEncodedBaseName: 'file-for-upload-in-form-&#9733;&#26143;&#9733;.txt',
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'Unicode',
+ fileBaseName: 'file-for-upload-in-form-☺😂.txt',
+ formEncoding: 'x-user-defined',
+ expectedEncodedBaseName: 'file-for-upload-in-form-&#9786;&#128514;.txt',
+});
+
+formPostFileUploadTest({
+ fileNameSource: 'Unicode',
+ fileBaseName: `file-for-upload-in-form-${kTestChars}.txt`,
+ formEncoding: 'x-user-defined',
+ expectedEncodedBaseName: `file-for-upload-in-form-${
+ kTestFallbackXUserDefined
+ }.txt`,
+});
+
+</script>
diff --git a/test/fixtures/wpt/README.md b/test/fixtures/wpt/README.md
index 1bcebbec49f..a3cbbe66743 100644
--- a/test/fixtures/wpt/README.md
+++ b/test/fixtures/wpt/README.md
@@ -20,7 +20,7 @@ Last update:
- hr-time: https://github.com/web-platform-tests/wpt/tree/a5d1774ecf/hr-time
- common: https://github.com/web-platform-tests/wpt/tree/841a51412f/common
- dom/abort: https://github.com/web-platform-tests/wpt/tree/7caa3de747/dom/abort
-- FileAPI: https://github.com/web-platform-tests/wpt/tree/d9d921b8f9/FileAPI
+- FileAPI: https://github.com/web-platform-tests/wpt/tree/3b279420d4/FileAPI
[Web Platform Tests]: https://github.com/web-platform-tests/wpt
[`git node wpt`]: https://github.com/nodejs/node-core-utils/blob/master/docs/git-node.md#git-node-wpt
diff --git a/test/fixtures/wpt/versions.json b/test/fixtures/wpt/versions.json
index 31d7041697d..91bb213072c 100644
--- a/test/fixtures/wpt/versions.json
+++ b/test/fixtures/wpt/versions.json
@@ -40,7 +40,7 @@
"path": "dom/abort"
},
"FileAPI": {
- "commit": "d9d921b8f9235e0d2ec92672040c0ccfc8262e21",
+ "commit": "3b279420d40afea32506e823f9ac005448f4f3d8",
"path": "FileAPI"
}
} \ No newline at end of file
diff --git a/test/parallel/test-blob.js b/test/parallel/test-blob.js
index fdcc0177279..a3a0aeaaf4e 100644
--- a/test/parallel/test-blob.js
+++ b/test/parallel/test-blob.js
@@ -145,24 +145,22 @@ assert.throws(() => new Blob(['test', 1]), {
}));
const g = f.slice(1, -1);
- assert.strictEqual(g.type, 'foo');
+ assert.strictEqual(g.type, '');
g.text().then(common.mustCall((text) => {
assert.strictEqual(text, '');
}));
- assert.strictEqual(b.size, 10);
- assert.strictEqual(b.type, '');
+ const h = b.slice(-1, 1);
+ assert.strictEqual(h.size, 0);
- assert.throws(() => b.slice(-1, 1), {
- code: 'ERR_OUT_OF_RANGE'
- });
- assert.throws(() => b.slice(1, 100), {
- code: 'ERR_OUT_OF_RANGE'
- });
+ const i = b.slice(1, 100);
+ assert.strictEqual(i.size, 9);
- assert.throws(() => b.slice(1, 2, false), {
- code: 'ERR_INVALID_ARG_TYPE'
- });
+ const j = b.slice(1, 2, false);
+ assert.strictEqual(j.type, 'false');
+
+ assert.strictEqual(b.size, 10);
+ assert.strictEqual(b.type, '');
}
{
diff --git a/test/wpt/status/FileAPI/blob.json b/test/wpt/status/FileAPI/blob.json
index 1b463a1f0a1..23505105eaf 100644
--- a/test/wpt/status/FileAPI/blob.json
+++ b/test/wpt/status/FileAPI/blob.json
@@ -1,4 +1,13 @@
{
+ "Blob-constructor.any.js": {
+ "skip": "https://github.com/nodejs/node/issues/37358"
+ },
+ "Blob-constructor-dom.window.js": {
+ "skip": "Depends on DOM API"
+ },
+ "Blob-slice.any.js": {
+ "skip": "Depends on File API"
+ },
"Blob-stream.any.js": {
"skip": "Depends on Web Streams API"
},