summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/xhr/formdata
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/xhr/formdata')
-rw-r--r--testing/web-platform/tests/xhr/formdata/append-formelement.html52
-rw-r--r--testing/web-platform/tests/xhr/formdata/append.any.js37
-rw-r--r--testing/web-platform/tests/xhr/formdata/constructor-formelement.html150
-rw-r--r--testing/web-platform/tests/xhr/formdata/constructor-submitter.html100
-rw-r--r--testing/web-platform/tests/xhr/formdata/constructor.any.js6
-rw-r--r--testing/web-platform/tests/xhr/formdata/delete-formelement.html41
-rw-r--r--testing/web-platform/tests/xhr/formdata/delete.any.js26
-rw-r--r--testing/web-platform/tests/xhr/formdata/foreach.any.js56
-rw-r--r--testing/web-platform/tests/xhr/formdata/get-formelement.html34
-rw-r--r--testing/web-platform/tests/xhr/formdata/get.any.js28
-rw-r--r--testing/web-platform/tests/xhr/formdata/has-formelement.html25
-rw-r--r--testing/web-platform/tests/xhr/formdata/has.any.js19
-rw-r--r--testing/web-platform/tests/xhr/formdata/iteration.any.js65
-rw-r--r--testing/web-platform/tests/xhr/formdata/set-blob.any.js61
-rw-r--r--testing/web-platform/tests/xhr/formdata/set-formelement.html51
-rw-r--r--testing/web-platform/tests/xhr/formdata/set.any.js36
16 files changed, 787 insertions, 0 deletions
diff --git a/testing/web-platform/tests/xhr/formdata/append-formelement.html b/testing/web-platform/tests/xhr/formdata/append-formelement.html
new file mode 100644
index 0000000000..72c81aa808
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/append-formelement.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>FormData.append (with form element)
+</title>
+<link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-append">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form id="form"></form>
+<script>
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.append('key', 'value1');
+ assert_equals(fd.get('key'), "value1");
+ }, 'testFormDataAppendToForm1');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.append('key', 'value2');
+ fd.append('key', 'value1');
+ assert_equals(fd.get('key'), "value2");
+ }, 'testFormDataAppendToForm2');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.append('key', undefined);
+ assert_equals(fd.get('key'), "undefined");
+ }, 'testFormDataAppendToFormUndefined1');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.append('key', undefined);
+ fd.append('key', 'value1');
+ assert_equals(fd.get('key'), "undefined");
+ }, 'testFormDataAppendToFormUndefined2');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.append('key', null);
+ assert_equals(fd.get('key'), "null");
+ }, 'testFormDataAppendToFormNull1');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.append('key', null);
+ fd.append('key', 'value1');
+ assert_equals(fd.get('key'), "null");
+ }, 'testFormDataAppendToFormNull2');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ assert_throws_js(TypeError, () => {fd.append('name', "string", 'filename')});
+ }, 'testFormDataAppendToFormString');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ assert_throws_js(TypeError, () => {fd.append('name', new URLSearchParams(), 'filename')});
+ }, 'testFormDataAppendToFormWrongPlatformObject');
+</script>
diff --git a/testing/web-platform/tests/xhr/formdata/append.any.js b/testing/web-platform/tests/xhr/formdata/append.any.js
new file mode 100644
index 0000000000..fb365618d2
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/append.any.js
@@ -0,0 +1,37 @@
+// META: title=FormData.append
+
+ test(function() {
+ assert_equals(create_formdata(['key', 'value1']).get('key'), "value1");
+ }, 'testFormDataAppend1');
+ test(function() {
+ assert_equals(create_formdata(['key', 'value2'], ['key', 'value1']).get('key'), "value2");
+ }, 'testFormDataAppend2');
+ test(function() {
+ assert_equals(create_formdata(['key', undefined]).get('key'), "undefined");
+ }, 'testFormDataAppendUndefined1');
+ test(function() {
+ assert_equals(create_formdata(['key', undefined], ['key', 'value1']).get('key'), "undefined");
+ }, 'testFormDataAppendUndefined2');
+ test(function() {
+ assert_equals(create_formdata(['key', null]).get('key'), "null");
+ }, 'testFormDataAppendNull1');
+ test(function() {
+ assert_equals(create_formdata(['key', null], ['key', 'value1']).get('key'), "null");
+ }, 'testFormDataAppendNull2');
+ test(function() {
+ var before = new Date(new Date().getTime() - 2000); // two seconds ago, in case there's clock drift
+ var fd = create_formdata(['key', new Blob(), 'blank.txt']).get('key');
+ assert_equals(fd.name, "blank.txt");
+ assert_equals(fd.type, "");
+ assert_equals(fd.size, 0);
+ assert_greater_than_equal(fd.lastModified, before);
+ assert_less_than_equal(fd.lastModified, new Date());
+ }, 'testFormDataAppendEmptyBlob');
+
+ function create_formdata() {
+ var fd = new FormData();
+ for (var i = 0; i < arguments.length; i++) {
+ fd.append.apply(fd, arguments[i]);
+ };
+ return fd;
+ }
diff --git a/testing/web-platform/tests/xhr/formdata/constructor-formelement.html b/testing/web-platform/tests/xhr/formdata/constructor-formelement.html
new file mode 100644
index 0000000000..813e1d2a6c
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/constructor-formelement.html
@@ -0,0 +1,150 @@
+<!DOCTYPE html>
+<title>FormData: constructor (with form element)</title>
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+<link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#constructing-form-data-set">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<form>
+ <output name="do-not-submit-me-1"></output>
+
+ <datalist>
+ <input type="text" name="do-not-submit-me-2" value="bad">
+ <select name="do-not-submit-me-3">
+ <option value="bad" selected></option>
+ </select>
+ <input type="checkbox" name="do-not-submit-me-4" checked>
+ </datalist>
+
+ <input type="text" name="do-not-submit-me-5" disabled value="bad">
+ <fieldset disabled>
+ <input type="text" name="do-not-submit-me-6" value="bad">
+ </fieldset>
+
+ <button name="do-not-submit-me-7">bad</button>
+ <input type="submit" name="do-not-submit-me-8" value="bad">
+ <input type="reset" name="do-not-submit-me-9" value="bad">
+ <input type="image" name="do-not-submit-me-10" value="bad">
+
+ <input type="checkbox" name="do-not-submit-me-11">
+ <input type="radio" name="do-not-submit-me-12">
+
+ <input type="text" value="do-not-submit-me-13">
+ <input type="text" name="" value="do-not-submit-me-14">
+
+ <object name="do-not-submit-me-15"></object>
+
+ <select name="select-1">
+ <option disabled value="do-not-submit-me-16"></option>
+ <option value="do-not-submit-me-17"></option>
+ <option disabled value="do-not-submit-me-18" selected></option>
+ </select>
+
+ <select name="select-2">
+ <option value="do-not-submit-me-19"></option>
+ <option value="submit-me-1" selected></option>
+ </select>
+
+ <select name="select-3" multiple>
+ <option value="do-not-submit-me-20"></option>
+ <option value="submit-me-2" selected></option>
+ <option value="do-not-submit-me-21"></option>
+ <option value="submit-me-3" selected></option>
+ </select>
+
+ <input type="checkbox" name="submit-me-4" value="checkbox-1" checked>
+ <input type="checkbox" name="submit-me-5" checked>
+
+ <input type="radio" name="submit-me-6" value="radio-1" checked>
+ <input type="radio" name="submit-me-7" checked>
+
+ <!-- not tested: <input type="file"> with selected files -->
+
+ <input type="file" name="file-1">
+
+ <!-- not tested: <object>s that allow form submission -->
+
+ <input type="text" name="submit-me-8" value="text-1">
+ <input type="text" name="submit-me-8" value="text-2">
+ <input type="search" name="submit-me-9" value="search-1">
+ <input type="url" name="submit-me-10" value="url-1">
+ <input type="hidden" name="submit-me-11" value="hidden-1">
+ <input type="password" name="submit-me-12" value="password-1">
+ <input type="number" name="submit-me-13" value="11">
+ <input type="range" name="submit-me-14" value="11">
+ <input type="color" name="submit-me-15" value="#123456">
+
+ <textarea name="submit-me-16">textarea value
+with linebreaks set to LF</textarea>
+
+ <!-- this generates two form data entries! -->
+ <input type="text" name="dirname-is-special" dirname="submit-me-17" value="dirname-value">
+
+ <input type="text" name="submit-me-21">
+</form>
+
+<script>
+"use strict";
+
+test(() => {
+
+ const form = document.querySelector("form");
+
+ const input = document.createElement("input");
+ input.name = "submit-me-18-\uDC01";
+ input.value = "value-\uDC01";
+ assert_equals(input.name, "submit-me-18-\uDC01", "input.name accepts unpaired surrogates");
+ assert_equals(input.value, "value-\uDC01", "input.value accepts unpaired surrogates");
+ form.appendChild(input);
+
+ const input2 = document.createElement("input");
+ input2.name = "submit-me-\r19\n";
+ input2.value = "value\n\r";
+ assert_equals(input2.name, "submit-me-\r19\n", "input.name accepts \\r and \\n");
+ assert_equals(input2.value, "value", "input.value when type=text should not contain newlines");
+ form.appendChild(input2);
+
+ const formData = new FormData(form);
+
+ const expected = [
+ ["select-2", "submit-me-1"],
+ ["select-3", ["submit-me-2", "submit-me-3"]],
+ ["submit-me-4", "checkbox-1"],
+ ["submit-me-5", "on"],
+ ["submit-me-6", "radio-1"],
+ ["submit-me-7", "on"],
+ ["submit-me-8", ["text-1", "text-2"]],
+ ["submit-me-9", "search-1"],
+ ["submit-me-10", "url-1"],
+ ["submit-me-11", "hidden-1"],
+ ["submit-me-12", "password-1"],
+ ["submit-me-13", "11"],
+ ["submit-me-14", "11"],
+ ["submit-me-15", "#123456"],
+ ["submit-me-16", "textarea value\nwith linebreaks set to LF"],
+ ["dirname-is-special", "dirname-value"],
+ ["submit-me-17", "ltr"],
+ ["submit-me-18-\uFFFD", "value-\uFFFD"],
+ ["submit-me-\r19\n", "value"],
+ ["submit-me-21", ""]
+ ];
+
+ for (const t of expected) {
+ const field = t[0];
+ const valueOrValues = t[1];
+ const values = Array.isArray(valueOrValues) ? valueOrValues : [valueOrValues];
+ assert_array_equals(formData.getAll(field), values, field);
+ }
+
+ const fileEntry = formData.getAll("file-1");
+ assert_equals(fileEntry.length, 1);
+ assert_equals(fileEntry[0], formData.get("file-1"));
+ assert_equals(fileEntry[0].constructor, File);
+ assert_equals(fileEntry[0].size, 0);
+ assert_equals(fileEntry[0].name, "");
+ assert_equals(fileEntry[0].type, "application/octet-stream");
+
+}, "test that FormData is correctly constructed from the form data set");
+</script>
diff --git a/testing/web-platform/tests/xhr/formdata/constructor-submitter.html b/testing/web-platform/tests/xhr/formdata/constructor-submitter.html
new file mode 100644
index 0000000000..542357df34
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/constructor-submitter.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<meta charset='utf-8'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-the-form-data-set'>
+<link ref='help' href='https://xhr.spec.whatwg.org/#dom-formdata'>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+
+<button name=outerNamed value=GO form='myform'></button>
+<form id='myform' onsubmit='return false'>
+ <input name=n1 value=v1>
+ <button name=named value=GO></button>
+ <button id=unnamed value=unnamed></button>
+ <button form="another" name=unassociated value=unassociated></button>
+ <input type=image name=namedImage src='/media/1x1-green.png'></button>
+ <input type=image id=unnamedImage src='/media/1x1-green.png'></button>
+ <input type=image name=unactivatedImage src='/media/1x1-green.png'></button>
+ <input name=n3 value=v3>
+</form>
+
+<form id='another'>
+ <button name=unassociated2 value=unassociated></button>
+</form>
+
+<script>
+function assertFormDataEntries(formData, expectedEntries) {
+ const expectedEntryNames = expectedEntries.map((entry) => entry[0]);
+ const actualEntries = [...formData.entries()];
+ const actualEntryNames = actualEntries.map((entry) => entry[0]);
+ assert_array_equals(actualEntryNames, expectedEntryNames);
+ for (let i = 0; i < actualEntries.length; i++) {
+ assert_array_equals(actualEntries[i], expectedEntries[i]);
+ }
+}
+
+const form = document.querySelector('#myform');
+
+test(() => {
+ assertFormDataEntries(
+ new FormData(form, null),
+ [['n1', 'v1'], ['n3', 'v3']]
+ );
+}, 'FormData construction should allow a null submitter'); // the use case here is so web developers can avoid null checks, e.g. `new FormData(e.target, e.submitter)`
+
+test(() => {
+ assertFormDataEntries(new FormData(undefined, undefined), []);
+}, 'FormData construction should allow an undefined form and an undefined submitter');
+
+test(() => {
+ assertFormDataEntries(new FormData(undefined, null), []);
+}, 'FormData construction should allow an undefined form and a null submitter');
+
+test(() => {
+ assert_throws_js(TypeError, () => new FormData(form, document.querySelector('[name=n1]')));
+}, 'FormData construction should throw a TypeError if a non-null submitter is not a submit button');
+
+test(() => {
+ assert_throws_dom('NotFoundError', () => new FormData(form, document.querySelector('[name=unassociated]')));
+ assert_throws_dom('NotFoundError', () => new FormData(form, document.querySelector('[name=unassociated2]')));
+}, "FormData construction should throw a 'NotFoundError' DOMException if a non-null submitter is not owned by the form");
+
+test(() => {
+ assertFormDataEntries(
+ new FormData(form, document.querySelector('[name=named]')),
+ [['n1', 'v1'], ['named', 'GO'], ['n3', 'v3']]
+ );
+ assertFormDataEntries(
+ new FormData(form, document.querySelector('[name=outerNamed]')),
+ [['outerNamed', 'GO'], ['n1', 'v1'], ['n3', 'v3']]
+ );
+}, 'The constructed FormData object should contain an in-tree-order entry for a named submit button submitter');
+
+test(() => {
+ assertFormDataEntries(
+ new FormData(form, document.querySelector('#unnamed')),
+ [['n1', 'v1'], ['n3', 'v3']]
+ );
+}, 'The constructed FormData object should not contain an entry for an unnamed submit button submitter');
+
+test(() => {
+ const submitter1 = document.querySelector('[name=namedImage]');
+ submitter1.click();
+ const submitter2 = document.querySelector('#unnamedImage');
+ submitter2.click();
+ assertFormDataEntries(
+ new FormData(form, submitter1),
+ [['n1', 'v1'], ['namedImage.x', '0'], ['namedImage.y', '0'], ['n3', 'v3']]
+ );
+ assertFormDataEntries(
+ new FormData(form, submitter2),
+ [['n1', 'v1'], ['x', '0'], ['y', '0'], ['n3', 'v3']]
+ );
+}, 'The constructed FormData object should contain in-tree-order entries for an activated Image Button submitter');
+
+test(() => {
+ assertFormDataEntries(
+ new FormData(form, document.querySelector('[name=unactivatedImage]')),
+ [['n1', 'v1'], ['unactivatedImage.x', '0'], ['unactivatedImage.y', '0'], ['n3', 'v3']]
+ );
+}, 'The constructed FormData object should contain in-tree-order entries for an unactivated Image Button submitter');
+</script>
diff --git a/testing/web-platform/tests/xhr/formdata/constructor.any.js b/testing/web-platform/tests/xhr/formdata/constructor.any.js
new file mode 100644
index 0000000000..43704538ab
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/constructor.any.js
@@ -0,0 +1,6 @@
+// META: title=FormData: constructor
+
+test(() => {
+ assert_throws_js(TypeError, () => { new FormData(null); });
+ assert_throws_js(TypeError, () => { new FormData("string"); });
+}, "Constructors should throw a type error");
diff --git a/testing/web-platform/tests/xhr/formdata/delete-formelement.html b/testing/web-platform/tests/xhr/formdata/delete-formelement.html
new file mode 100644
index 0000000000..62862bd571
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/delete-formelement.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<html lang=en>
+<meta charset=utf-8>
+<title>FormData: delete (with form element)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-get" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-getall" />
+<div id="log"></div>
+<form id="form1">
+ <input type="hidden" name="key" value="value1">
+ <input type="hidden" name="key" value="value2">
+</form>
+<form id="form2">
+ <input type="hidden" name="key1" value="value1">
+ <input type="hidden" name="key2" value="value2">
+</form>
+<form id="empty-form"></form>
+<script>
+ test(function() {
+ var fd = new FormData(document.getElementById('form1'));
+ fd.delete('key');
+ assert_equals(fd.get('key'), null);
+ }, 'testFormDataDeleteFromForm');
+ test(function() {
+ var fd = new FormData(document.getElementById('form1'));
+ fd.delete('nil');
+ assert_equals(fd.get('key'), 'value1');
+ }, 'testFormDataDeleteFromFormNonExistentKey');
+ test(function() {
+ var fd = new FormData(document.getElementById('form2'));
+ fd.delete('key1');
+ assert_equals(fd.get('key1'), null);
+ assert_equals(fd.get('key2'), 'value2');
+ }, 'testFormDataDeleteFromFormOtherKey');
+ test(function() {
+ var fd = new FormData(document.getElementById('empty-form'));
+ fd.delete('key');
+ assert_equals(fd.get('key'), null);
+ }, 'testFormDataDeleteFromEmptyForm');
+</script>
diff --git a/testing/web-platform/tests/xhr/formdata/delete.any.js b/testing/web-platform/tests/xhr/formdata/delete.any.js
new file mode 100644
index 0000000000..9424614f96
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/delete.any.js
@@ -0,0 +1,26 @@
+// META: title=FormData: delete
+
+ test(function() {
+ var fd = create_formdata(['key', 'value1'], ['key', 'value2']);
+ fd.delete('key');
+ assert_equals(fd.get('key'), null);
+ }, 'testFormDataDelete');
+ test(function() {
+ var fd = create_formdata(['key', 'value1'], ['key', 'value2']);
+ fd.delete('nil');
+ assert_equals(fd.get('key'), 'value1');
+ }, 'testFormDataDeleteNonExistentKey');
+ test(function() {
+ var fd = create_formdata(['key1', 'value1'], ['key2', 'value2']);
+ fd.delete('key1');
+ assert_equals(fd.get('key1'), null);
+ assert_equals(fd.get('key2'), 'value2');
+ }, 'testFormDataDeleteOtherKey');
+
+ function create_formdata() {
+ var fd = new FormData();
+ for (var i = 0; i < arguments.length; i++) {
+ fd.append.apply(fd, arguments[i]);
+ };
+ return fd;
+ }
diff --git a/testing/web-platform/tests/xhr/formdata/foreach.any.js b/testing/web-platform/tests/xhr/formdata/foreach.any.js
new file mode 100644
index 0000000000..9fc1e2d9b3
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/foreach.any.js
@@ -0,0 +1,56 @@
+// META: title=FormData: foreach
+
+ var fd = new FormData();
+ fd.append('n1', 'v1');
+ fd.append('n2', 'v2');
+ fd.append('n3', 'v3');
+ fd.append('n1', 'v4');
+ fd.append('n2', 'v5');
+ fd.append('n3', 'v6');
+ fd.delete('n2');
+
+ var file = new File(['hello'], "hello.txt");
+ fd.append('f1', file);
+
+ var expected_keys = ['n1', 'n3', 'n1', 'n3', 'f1'];
+ var expected_values = ['v1', 'v3', 'v4', 'v6', file];
+ test(function() {
+ var mykeys = [], myvalues = [];
+ for(var entry of fd) {
+ assert_equals(entry.length, 2,
+ 'Default iterator should yield key/value pairs');
+ mykeys.push(entry[0]);
+ myvalues.push(entry[1]);
+ }
+ assert_array_equals(mykeys, expected_keys,
+ 'Default iterator should see duplicate keys');
+ assert_array_equals(myvalues, expected_values,
+ 'Default iterator should see non-deleted values');
+ }, 'Iterator should return duplicate keys and non-deleted values');
+ test(function() {
+ var mykeys = [], myvalues = [];
+ for(var entry of fd.entries()) {
+ assert_equals(entry.length, 2,
+ 'entries() iterator should yield key/value pairs');
+ mykeys.push(entry[0]);
+ myvalues.push(entry[1]);
+ }
+ assert_array_equals(mykeys, expected_keys,
+ 'entries() iterator should see duplicate keys');
+ assert_array_equals(myvalues, expected_values,
+ 'entries() iterator should see non-deleted values');
+ }, 'Entries iterator should return duplicate keys and non-deleted values');
+ test(function() {
+ var mykeys = [];
+ for(var entry of fd.keys())
+ mykeys.push(entry);
+ assert_array_equals(mykeys, expected_keys,
+ 'keys() iterator should see duplicate keys');
+ }, 'Keys iterator should return duplicates');
+ test(function() {
+ var myvalues = [];
+ for(var entry of fd.values())
+ myvalues.push(entry);
+ assert_array_equals(myvalues, expected_values,
+ 'values() iterator should see non-deleted values');
+ }, 'Values iterator should return non-deleted values');
diff --git a/testing/web-platform/tests/xhr/formdata/get-formelement.html b/testing/web-platform/tests/xhr/formdata/get-formelement.html
new file mode 100644
index 0000000000..801db6c6f6
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/get-formelement.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<html lang=en>
+<meta charset=utf-8>
+<title>FormData: get and getAll (with form element)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-get" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-getall" />
+<div id="log"></div>
+<form id="form">
+ <input type="hidden" name="key" value="value1">
+ <input type="hidden" name="key" value="value2">
+</form>
+<form id="empty-form"></form>
+<script>
+ test(function() {
+ assert_equals(new FormData(document.getElementById('form')).get('key'), "value1");
+ }, 'testFormDataGetFromForm');
+ test(function() {
+ assert_equals(new FormData(document.getElementById('form')).get('nil'), null);
+ }, 'testFormDataGetFromFormNull');
+ test(function() {
+ assert_equals(new FormData(document.getElementById('empty-form')).get('key'), null);
+ }, 'testFormDataGetFromEmptyForm');
+ test(function() {
+ assert_array_equals(new FormData(document.getElementById('form')).getAll('key'), ["value1", "value2"]);
+ }, 'testFormDataGetAllFromForm');
+ test(function() {
+ assert_array_equals(new FormData(document.getElementById('form')).getAll('nil'), []);
+ }, 'testFormDataGetAllFromFormNull');
+ test(function() {
+ assert_array_equals(new FormData(document.getElementById('empty-form')).getAll('key'), []);
+ }, 'testFormDataGetAllFromEmptyForm');
+</script>
diff --git a/testing/web-platform/tests/xhr/formdata/get.any.js b/testing/web-platform/tests/xhr/formdata/get.any.js
new file mode 100644
index 0000000000..b307f1edd0
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/get.any.js
@@ -0,0 +1,28 @@
+// META: title=FormData: get and getAll
+
+ test(function() {
+ assert_equals(create_formdata(['key', 'value1'], ['key', 'value2']).get('key'), "value1");
+ }, 'testFormDataGet');
+ test(function() {
+ assert_equals(create_formdata(['key', 'value1'], ['key', 'value2']).get('nil'), null);
+ }, 'testFormDataGetNull1');
+ test(function() {
+ assert_equals(create_formdata().get('key'), null);
+ }, 'testFormDataGetNull2');
+ test(function() {
+ assert_array_equals(create_formdata(['key', 'value1'], ['key', 'value2']).getAll('key'), ["value1", "value2"]);
+ }, 'testFormDataGetAll');
+ test(function() {
+ assert_array_equals(create_formdata(['key', 'value1'], ['key', 'value2']).getAll('nil'), []);
+ }, 'testFormDataGetAllEmpty1');
+ test(function() {
+ assert_array_equals(create_formdata().getAll('key'), []);
+ }, 'testFormDataGetAllEmpty2');
+
+ function create_formdata() {
+ var fd = new FormData();
+ for (var i = 0; i < arguments.length; i++) {
+ fd.append.apply(fd, arguments[i]);
+ };
+ return fd;
+ }
diff --git a/testing/web-platform/tests/xhr/formdata/has-formelement.html b/testing/web-platform/tests/xhr/formdata/has-formelement.html
new file mode 100644
index 0000000000..9edbad3665
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/has-formelement.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<html lang=en>
+<meta charset=utf-8>
+<title>FormData: has (with form element)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-get" />
+ <link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-getall" />
+<div id="log"></div>
+<form id="form">
+ <input type="hidden" name="key" value="value1">
+ <input type="hidden" name="key" value="value2">
+</form>
+<form id="empty-form"></form>
+<script>
+ test(function() {
+ assert_equals(new FormData(document.getElementById('form')).has('key'), true);
+ }, 'testFormDataHasFromForm');
+ test(function() {
+ assert_equals(new FormData(document.getElementById('form')).has('nil'), false);
+ }, 'testFormDataHasFromFormNull');
+ test(function() {
+ assert_equals(new FormData(document.getElementById('empty-form')).has('key'), false);
+ }, 'testFormDataHasFromEmptyForm');
+</script>
diff --git a/testing/web-platform/tests/xhr/formdata/has.any.js b/testing/web-platform/tests/xhr/formdata/has.any.js
new file mode 100644
index 0000000000..2c1a3fdafe
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/has.any.js
@@ -0,0 +1,19 @@
+// META: title=FormData: has
+
+ test(function() {
+ assert_equals(create_formdata(['key', 'value1'], ['key', 'value2']).has('key'), true);
+ }, 'testFormDataHas');
+ test(function() {
+ assert_equals(create_formdata(['key', 'value1'], ['key', 'value2']).has('nil'), false);
+ }, 'testFormDataHasEmpty1');
+ test(function() {
+ assert_equals(create_formdata().has('key'), false);
+ }, 'testFormDataHasEmpty2');
+
+ function create_formdata() {
+ var fd = new FormData();
+ for (var i = 0; i < arguments.length; i++) {
+ fd.append.apply(fd, arguments[i]);
+ };
+ return fd;
+ }
diff --git a/testing/web-platform/tests/xhr/formdata/iteration.any.js b/testing/web-platform/tests/xhr/formdata/iteration.any.js
new file mode 100644
index 0000000000..1633fd9c4d
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/iteration.any.js
@@ -0,0 +1,65 @@
+// META: title=FormData: changes to entry list during iteration
+
+// These are tests for next()'s behavior as specified in
+// https://webidl.spec.whatwg.org/#es-iterator-prototype-object
+
+"use strict";
+
+function createFormData(input) {
+ const formData = new FormData();
+
+ for (const [name, value] of input) {
+ formData.append(name, value);
+ }
+
+ return formData;
+}
+
+test(() => {
+ const formData = createFormData([["foo", "0"],
+ ["baz", "1"],
+ ["BAR", "2"]]);
+ const actualKeys = [];
+ const actualValues = [];
+ for (const [name, value] of formData) {
+ actualKeys.push(name);
+ actualValues.push(value);
+ formData.delete("baz");
+ }
+ assert_array_equals(actualKeys, ["foo", "BAR"]);
+ assert_array_equals(actualValues, ["0", "2"]);
+}, "Iteration skips elements removed while iterating");
+
+test(() => {
+ const formData = createFormData([["foo", "0"],
+ ["baz", "1"],
+ ["BAR", "2"],
+ ["quux", "3"]]);
+ const actualKeys = [];
+ const actualValues = [];
+ for (const [name, value] of formData) {
+ actualKeys.push(name);
+ actualValues.push(value);
+ if (name === "baz")
+ formData.delete("foo");
+ }
+ assert_array_equals(actualKeys, ["foo", "baz", "quux"]);
+ assert_array_equals(actualValues, ["0", "1", "3"]);
+}, "Removing elements already iterated over causes an element to be skipped during iteration");
+
+test(() => {
+ const formData = createFormData([["foo", "0"],
+ ["baz", "1"],
+ ["BAR", "2"],
+ ["quux", "3"]]);
+ const actualKeys = [];
+ const actualValues = [];
+ for (const [name, value] of formData) {
+ actualKeys.push(name);
+ actualValues.push(value);
+ if (name === "baz")
+ formData.append("X-yZ", "4");
+ }
+ assert_array_equals(actualKeys, ["foo", "baz", "BAR", "quux", "X-yZ"]);
+ assert_array_equals(actualValues, ["0", "1", "2", "3", "4"]);
+}, "Appending a value pair during iteration causes it to be reached during iteration");
diff --git a/testing/web-platform/tests/xhr/formdata/set-blob.any.js b/testing/web-platform/tests/xhr/formdata/set-blob.any.js
new file mode 100644
index 0000000000..01946faeab
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/set-blob.any.js
@@ -0,0 +1,61 @@
+// META: title=formData.set(blob) and formData.set(file)
+
+"use strict";
+
+const formData = new FormData();
+
+test(() => {
+ const value = new Blob();
+ formData.set("blob-1", value);
+ const blob1 = formData.get("blob-1");
+ assert_not_equals(blob1, value);
+ assert_equals(blob1.constructor.name, "File");
+ assert_equals(blob1.name, "blob");
+ assert_equals(blob1.type, "");
+ assert_equals(formData.get("blob-1") === formData.get("blob-1"), true, "should return the same value when get the same blob entry from FormData");
+ assert_less_than(Math.abs(blob1.lastModified - Date.now()), 200, "lastModified should be now");
+}, "blob without type");
+
+test(() => {
+ const value = new Blob([], { type: "text/plain" });
+ formData.set("blob-2", value);
+ const blob2 = formData.get("blob-2");
+ assert_not_equals(blob2, value);
+ assert_equals(blob2.constructor.name, "File");
+ assert_equals(blob2.name, "blob");
+ assert_equals(blob2.type, "text/plain");
+ assert_less_than(Math.abs(blob2.lastModified - Date.now()), 200, "lastModified should be now");
+}, "blob with type");
+
+test(() => {
+ const value = new Blob();
+ formData.set("blob-3", value, "custom name");
+ const blob3 = formData.get("blob-3");
+ assert_not_equals(blob3, value);
+ assert_equals(blob3.constructor.name, "File");
+ assert_equals(blob3.name, "custom name");
+ assert_equals(blob3.type, "");
+ assert_less_than(Math.abs(blob3.lastModified - Date.now()), 200, "lastModified should be now");
+}, "blob with custom name");
+
+test(() => {
+ const value = new File([], "name");
+ formData.set("file-1", value);
+ const file1 = formData.get("file-1");
+ assert_equals(file1, value);
+ assert_equals(file1.constructor.name, "File");
+ assert_equals(file1.name, "name");
+ assert_equals(file1.type, "");
+ assert_less_than(Math.abs(file1.lastModified - Date.now()), 200, "lastModified should be now");
+}, "file without lastModified or custom name");
+
+test(() => {
+ const value = new File([], "name", { lastModified: 123 });
+ formData.set("file-2", value, "custom name");
+ const file2 = formData.get("file-2");
+ assert_not_equals(file2, value);
+ assert_equals(file2.constructor.name, "File");
+ assert_equals(file2.name, "custom name");
+ assert_equals(file2.type, "");
+ assert_equals(file2.lastModified, 123, "lastModified should be 123");
+}, "file with lastModified and custom name");
diff --git a/testing/web-platform/tests/xhr/formdata/set-formelement.html b/testing/web-platform/tests/xhr/formdata/set-formelement.html
new file mode 100644
index 0000000000..d3213f8579
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/set-formelement.html
@@ -0,0 +1,51 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>FormData: set (with form element)</title>
+<link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-set">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form id="form"></form>
+<script>
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.set('key', 'value1');
+ assert_equals(fd.get('key'), "value1");
+ }, 'testFormDataSetToForm1');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.set('key', 'value2');
+ fd.set('key', 'value1');
+ assert_equals(fd.get('key'), "value1");
+ }, 'testFormDataSetToForm2');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.set('key', undefined);
+ assert_equals(fd.get('key'), "undefined");
+ }, 'testFormDataSetToFormUndefined1');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.set('key', undefined);
+ fd.set('key', 'value1');
+ assert_equals(fd.get('key'), "value1");
+ }, 'testFormDataSetToFormUndefined2');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.set('key', null);
+ assert_equals(fd.get('key'), "null");
+ }, 'testFormDataSetToFormNull1');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ fd.set('key', null);
+ fd.set('key', 'value1');
+ assert_equals(fd.get('key'), "value1");
+ }, 'testFormDataSetToFormNull2');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ assert_throws_js(TypeError, () => {fd.set('name', "string", 'filename')});
+ }, 'testFormDataSetToFormString');
+ test(function() {
+ var fd = new FormData(document.getElementById("form"));
+ assert_throws_js(TypeError, () => {fd.set('name', new URLSearchParams(), 'filename')});
+ }, 'testFormDataSetToFormWrongPlatformObject');
+</script>
diff --git a/testing/web-platform/tests/xhr/formdata/set.any.js b/testing/web-platform/tests/xhr/formdata/set.any.js
new file mode 100644
index 0000000000..734e55bb75
--- /dev/null
+++ b/testing/web-platform/tests/xhr/formdata/set.any.js
@@ -0,0 +1,36 @@
+// META: title=FormData: set
+
+ test(function() {
+ assert_equals(create_formdata(['key', 'value1']).get('key'), "value1");
+ }, 'testFormDataSet1');
+ test(function() {
+ assert_equals(create_formdata(['key', 'value2'], ['key', 'value1']).get('key'), "value1");
+ }, 'testFormDataSet2');
+ test(function() {
+ assert_equals(create_formdata(['key', undefined]).get('key'), "undefined");
+ }, 'testFormDataSetUndefined1');
+ test(function() {
+ assert_equals(create_formdata(['key', undefined], ['key', 'value1']).get('key'), "value1");
+ }, 'testFormDataSetUndefined2');
+ test(function() {
+ assert_equals(create_formdata(['key', null]).get('key'), "null");
+ }, 'testFormDataSetNull1');
+ test(function() {
+ assert_equals(create_formdata(['key', null], ['key', 'value1']).get('key'), "value1");
+ }, 'testFormDataSetNull2');
+ test(function() {
+ var fd = new FormData();
+ fd.set('key', new Blob([]), 'blank.txt');
+ var file = fd.get('key');
+
+ assert_true(file instanceof File);
+ assert_equals(file.name, 'blank.txt');
+ }, 'testFormDataSetEmptyBlob');
+
+ function create_formdata() {
+ var fd = new FormData();
+ for (var i = 0; i < arguments.length; i++) {
+ fd.set.apply(fd, arguments[i]);
+ };
+ return fd;
+ }