diff options
Diffstat (limited to 'dom/tests/mochitest/fetch/test_headers_common.js')
-rw-r--r-- | dom/tests/mochitest/fetch/test_headers_common.js | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/dom/tests/mochitest/fetch/test_headers_common.js b/dom/tests/mochitest/fetch/test_headers_common.js new file mode 100644 index 0000000000..3b2604f88f --- /dev/null +++ b/dom/tests/mochitest/fetch/test_headers_common.js @@ -0,0 +1,327 @@ +// +// Utility functions +// + +function shouldThrow(func, expected, msg) { + var err; + try { + func(); + } catch (e) { + err = e; + } finally { + ok(err instanceof expected, msg); + } +} + +function recursiveArrayCompare(actual, expected) { + is( + Array.isArray(actual), + Array.isArray(expected), + "Both should either be arrays, or not" + ); + if (Array.isArray(actual) && Array.isArray(expected)) { + var diff = actual.length !== expected.length; + + for (var i = 0, n = actual.length; !diff && i < n; ++i) { + diff = recursiveArrayCompare(actual[i], expected[i]); + } + + return diff; + } else { + return actual !== expected; + } +} + +function arrayEquals(actual, expected, msg) { + if (actual === expected) { + return; + } + + var diff = recursiveArrayCompare(actual, expected); + + ok(!diff, msg); + if (diff) { + is(actual, expected, msg); + } +} + +function checkHas(headers, name, msg) { + function doCheckHas(n) { + return headers.has(n); + } + return _checkHas(doCheckHas, headers, name, msg); +} + +function checkNotHas(headers, name, msg) { + function doCheckNotHas(n) { + return !headers.has(n); + } + return _checkHas(doCheckNotHas, headers, name, msg); +} + +function _checkHas(func, headers, name, msg) { + ok(func(name), msg); + ok(func(name.toLowerCase()), msg); + ok(func(name.toUpperCase()), msg); +} + +function checkGet(headers, name, expected, msg) { + is(headers.get(name), expected, msg); + is(headers.get(name.toLowerCase()), expected, msg); + is(headers.get(name.toUpperCase()), expected, msg); +} + +// +// Test Cases +// + +function TestCoreBehavior(headers, name) { + var start = headers.get(name); + + headers.append(name, "bar"); + + checkHas(headers, name, "Has the header"); + var expected = start ? start.concat(", bar") : "bar"; + checkGet(headers, name, expected, "Retrieve all headers for name"); + + headers.append(name, "baz"); + checkHas(headers, name, "Has the header"); + expected = start ? start.concat(", bar, baz") : "bar, baz"; + checkGet(headers, name, expected, "Retrieve all headers for name"); + + headers.set(name, "snafu"); + checkHas(headers, name, "Has the header after set"); + checkGet(headers, name, "snafu", "Retrieve all headers after set"); + + const value_bam = "boom"; + let testHTTPWhitespace = ["\t", "\n", "\r", " "]; + while (testHTTPWhitespace.length) { + headers.delete(name); + + let char = testHTTPWhitespace.shift(); + headers.set(name, char); + checkGet( + headers, + name, + "", + "Header value " + + char + + " should be normalized before checking and throwing" + ); + headers.delete(name); + + let valueFront = char + value_bam; + headers.set(name, valueFront); + checkGet( + headers, + name, + value_bam, + "Header value " + + valueFront + + " should be normalized before checking and throwing" + ); + + headers.delete(name); + + let valueBack = value_bam + char; + headers.set(name, valueBack); + checkGet( + headers, + name, + value_bam, + "Header value " + + valueBack + + " should be normalized before checking and throwing" + ); + } + + headers.delete(name.toUpperCase()); + checkNotHas(headers, name, "Does not have the header after delete"); + checkGet(headers, name, null, "Retrieve all headers after delete"); + + // should be ok to delete non-existent name + headers.delete(name); + + shouldThrow( + function () { + headers.append("foo,", "bam"); + }, + TypeError, + "Append invalid header name should throw TypeError." + ); + + shouldThrow( + function () { + headers.append(name, "ba\nm"); + }, + TypeError, + "Append invalid header value should throw TypeError." + ); + + shouldThrow( + function () { + headers.append(name, "ba\rm"); + }, + TypeError, + "Append invalid header value should throw TypeError." + ); + + ok(!headers.guard, "guard should be undefined in content"); +} + +function TestEmptyHeaders() { + is(typeof Headers, "function", "Headers global constructor exists."); + var headers = new Headers(); + ok(headers, "Constructed empty Headers object"); + TestCoreBehavior(headers, "foo"); +} + +function TestFilledHeaders() { + var source = new Headers(); + var filled = new Headers(source); + ok(filled, "Fill header from empty header"); + TestCoreBehavior(filled, "foo"); + + source = new Headers(); + source.append("abc", "123"); + source.append("def", "456"); + source.append("def", "789"); + + filled = new Headers(source); + checkGet( + filled, + "abc", + source.get("abc"), + "Single value header list matches" + ); + checkGet( + filled, + "def", + source.get("def"), + "Multiple value header list matches" + ); + TestCoreBehavior(filled, "def"); + + filled = new Headers({ + zxy: "987", + xwv: "654", + uts: "321", + }); + checkGet(filled, "zxy", "987", "Has first object filled key"); + checkGet(filled, "xwv", "654", "Has second object filled key"); + checkGet(filled, "uts", "321", "Has third object filled key"); + TestCoreBehavior(filled, "xwv"); + + filled = new Headers([ + ["zxy", "987"], + ["xwv", "654"], + ["xwv", "abc"], + ["uts", "321"], + ]); + checkGet(filled, "zxy", "987", "Has first sequence filled key"); + checkGet(filled, "xwv", "654, abc", "Has second sequence filled key"); + checkGet(filled, "uts", "321", "Has third sequence filled key"); + TestCoreBehavior(filled, "xwv"); + + shouldThrow( + function () { + filled = new Headers([ + ["zxy", "987", "654"], + ["uts", "321"], + ]); + }, + TypeError, + "Fill with non-tuple sequence should throw TypeError." + ); + + shouldThrow( + function () { + filled = new Headers([["zxy"], ["uts", "321"]]); + }, + TypeError, + "Fill with non-tuple sequence should throw TypeError." + ); +} + +function iterate(iter) { + var result = []; + for (var val = iter.next(); !val.done; ) { + result.push(val.value); + val = iter.next(); + } + return result; +} + +function iterateForOf(iter) { + var result = []; + for (var value of iter) { + result.push(value); + } + return result; +} + +function byteInflate(str) { + var encoder = new TextEncoder(); + var encoded = encoder.encode(str); + var result = ""; + for (var i = 0; i < encoded.length; ++i) { + result += String.fromCharCode(encoded[i]); + } + return result; +} + +function TestHeadersIterator() { + var ehsanInflated = byteInflate("احسان"); + var headers = new Headers(); + headers.set("foo0", "bar0"); + headers.append("foo", "bar"); + headers.append("foo", ehsanInflated); + headers.append("Foo2", "bar2"); + headers.set("Foo2", "baz2"); + headers.set("foo3", "bar3"); + headers.delete("foo0"); + headers.delete("foo3"); + + var key_iter = headers.keys(); + var value_iter = headers.values(); + var entries_iter = headers.entries(); + + arrayEquals(iterate(key_iter), ["foo", "foo2"], "Correct key iterator"); + arrayEquals( + iterate(value_iter), + ["bar, " + ehsanInflated, "baz2"], + "Correct value iterator" + ); + arrayEquals( + iterate(entries_iter), + [ + ["foo", "bar, " + ehsanInflated], + ["foo2", "baz2"], + ], + "Correct entries iterator" + ); + + arrayEquals( + iterateForOf(headers), + [ + ["foo", "bar, " + ehsanInflated], + ["foo2", "baz2"], + ], + "Correct entries iterator" + ); + arrayEquals( + iterateForOf(new Headers(headers)), + [ + ["foo", "bar, " + ehsanInflated], + ["foo2", "baz2"], + ], + "Correct entries iterator" + ); +} + +function runTest() { + TestEmptyHeaders(); + TestFilledHeaders(); + TestHeadersIterator(); + return Promise.resolve(); +} |