aboutsummaryrefslogtreecommitdiffstats
path: root/tests/wpt/web-platform-tests/FileAPI/blob
diff options
context:
space:
mode:
Diffstat (limited to 'tests/wpt/web-platform-tests/FileAPI/blob')
-rw-r--r--tests/wpt/web-platform-tests/FileAPI/blob/Blob-Request-revoke-fetch.html41
-rw-r--r--tests/wpt/web-platform-tests/FileAPI/blob/Blob-constructor-endings.html104
-rw-r--r--tests/wpt/web-platform-tests/FileAPI/blob/Blob-constructor.html64
3 files changed, 180 insertions, 29 deletions
diff --git a/tests/wpt/web-platform-tests/FileAPI/blob/Blob-Request-revoke-fetch.html b/tests/wpt/web-platform-tests/FileAPI/blob/Blob-Request-revoke-fetch.html
new file mode 100644
index 00000000000..2cac5343cd8
--- /dev/null
+++ b/tests/wpt/web-platform-tests/FileAPI/blob/Blob-Request-revoke-fetch.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<title>Revoking blob URL used with Request/fetch</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+promise_test(function(t) {
+ const blob = new Blob(["test"]);
+ const url = URL.createObjectURL(blob);
+ const request = new Request(url);
+
+ // Revoke the object URL. Request should take a reference to the blob as
+ // soon as it receives it in open(), so the request succeeds even though we
+ // revoke the URL before calling fetch().
+ URL.revokeObjectURL(url);
+
+ return fetch(request).then(response => response.text()).then(text => {
+ assert_equals(text, 'test');
+ });
+}, "Revoke blob URL after creating Request, will fetch");
+
+promise_test(function(t) {
+ const blob = new Blob(["test"]);
+ const url = URL.createObjectURL(blob);
+
+ return fetch(url).then(response => response.text()).then(text => {
+ assert_equals(text, 'test');
+ });
+
+ // Revoke the object URL. fetch should have already resolved the blob URL.
+ URL.revokeObjectURL(url);
+}, "Revoke blob URL after fetch, will fetch");
+
+promise_test(t => {
+ const blob = new Blob(["test"]);
+ const url = URL.createObjectURL(blob);
+ URL.revokeObjectURL(url);
+ const request = new Request(url);
+ return promise_rejects(t, new TypeError, fetch(request));
+}, "Revoke blob URL before creating Request, network error (after fetch)")
+</script>
diff --git a/tests/wpt/web-platform-tests/FileAPI/blob/Blob-constructor-endings.html b/tests/wpt/web-platform-tests/FileAPI/blob/Blob-constructor-endings.html
new file mode 100644
index 00000000000..1dee99ff775
--- /dev/null
+++ b/tests/wpt/web-platform-tests/FileAPI/blob/Blob-constructor-endings.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Blob constructor: endings option</title>
+<link rel=help href="https://w3c.github.io/FileAPI/#constructorBlob">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+// Windows platforms use CRLF as the native line ending. All others use LF.
+const crlf = navigator.platform.startsWith('Win');
+const native_ending = crlf ? '\r\n' : '\n';
+
+function readBlobAsPromise(blob) {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.readAsText(blob);
+ reader.onload = e => resolve(reader.result);
+ reader.onerror = e => reject(reader.error);
+ });
+}
+
+[
+ 'transparent',
+ 'native'
+].forEach(value => test(t => {
+ assert_class_string(new Blob([], {endings: value}), 'Blob',
+ `Constructor should allow "${value}" endings`);
+}, `Valid "endings" value: ${JSON.stringify(value)}`));
+
+[
+ null,
+ '',
+ 'invalidEnumValue',
+ 'Transparent',
+ 'NATIVE',
+ 0,
+ {}
+].forEach(value => test(t => {
+ assert_throws(new TypeError(), () => new Blob([], {endings: value}),
+ 'Blob constructor should throw');
+}, `Invalid "endings" value: ${JSON.stringify(value)}`));
+
+test(t => {
+ const test_error = {name: 'test'};
+ assert_throws(
+ test_error,
+ () => new Blob([], { get endings() { throw test_error; }}),
+ 'Blob constructor should propagate exceptions from "endings" property');
+}, 'Exception propagation from options');
+
+test(t => {
+ let got = false;
+ new Blob([], { get endings() { got = true; } });
+ assert_true(got, 'The "endings" property was accessed during construction.');
+}, 'The "endings" options property is used');
+
+[
+ {name: 'LF', input: '\n', native: native_ending},
+ {name: 'CR', input: '\r', native: native_ending},
+
+ {name: 'CRLF', input: '\r\n', native: native_ending},
+ {name: 'CRCR', input: '\r\r', native: native_ending.repeat(2)},
+ {name: 'LFCR', input: '\n\r', native: native_ending.repeat(2)},
+ {name: 'LFLF', input: '\n\n', native: native_ending.repeat(2)},
+
+ {name: 'CRCRLF', input: '\r\r\n', native: native_ending.repeat(2)},
+ {name: 'CRLFLF', input: '\r\n\n', native: native_ending.repeat(2)},
+ {name: 'CRLFCR', input: '\r\n\r\n', native: native_ending.repeat(2)},
+
+ {name: 'CRLFCRLF', input: '\r\n\r\n', native: native_ending.repeat(2)},
+ {name: 'LFCRLFCR', input: '\n\r\n\r', native: native_ending.repeat(3)},
+
+].forEach(testCase => {
+ promise_test(async t => {
+ const blob = new Blob([testCase.input]);
+ assert_equals(
+ await readBlobAsPromise(blob), testCase.input,
+ 'Newlines should not change with endings unspecified');
+ }, `Input ${testCase.name} with endings unspecified`);
+
+ promise_test(async t => {
+ const blob = new Blob([testCase.input], {endings: 'transparent'});
+ assert_equals(
+ await readBlobAsPromise(blob), testCase.input,
+ 'Newlines should not change with endings "transparent"');
+ }, `Input ${testCase.name} with endings 'transparent'`);
+
+ promise_test(async t => {
+ const blob = new Blob([testCase.input], {endings: 'native'});
+ assert_equals(
+ await readBlobAsPromise(blob), testCase.native,
+ 'Newlines should match the platform with endings "native"');
+ }, `Input ${testCase.name} with endings 'native'`);
+});
+
+promise_test(async t => {
+ const blob = new Blob(['\r', '\n'], {endings: 'native'});
+ const expected = native_ending.repeat(2);
+ assert_equals(
+ await readBlobAsPromise(blob), expected,
+ 'CR/LF in adjacent strings should be converted to two platform newlines');
+}, `CR/LF in adjacent input strings`);
+
+</script>
diff --git a/tests/wpt/web-platform-tests/FileAPI/blob/Blob-constructor.html b/tests/wpt/web-platform-tests/FileAPI/blob/Blob-constructor.html
index d8375c2a6e8..4d39ed78e0e 100644
--- a/tests/wpt/web-platform-tests/FileAPI/blob/Blob-constructor.html
+++ b/tests/wpt/web-platform-tests/FileAPI/blob/Blob-constructor.html
@@ -74,6 +74,20 @@ test_blob(function() {
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],
@@ -392,26 +406,20 @@ test_blob(function() {
desc: "Array with mixed types"
});
-// options argument
test(function() {
- new Blob([], { endings: "invalidEnumValue" });
- new Blob([], { endings: null });
- new Blob([], { endings: undefined });
- new Blob([], { endings: 0 });
- new Blob([], { get endings() { assert_unreached("Should not call getter"); } });
-}, "The 'endings' property should be ignored.");
+ const accessed = [];
+ const stringified = [];
-test(function() {
- assert_throws(test_error, function() {
- new Blob([], {
- get type() { throw test_error; }
- });
+ new Blob([], {
+ get type() { accessed.push('type'); },
+ get endings() { accessed.push('endings'); }
});
- assert_throws(test_error, function() {
- new Blob([], {
- type: { toString: function() { throw test_error; } }
- });
+ 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() {
@@ -449,19 +457,16 @@ test(function() {
});
});
-test_blob(function() {
- return new Blob(["\na\r\nb\n\rc\r"], { endings: "transparent" });
-}, {
- expected: "\na\r\nb\n\rc\r",
- type: "",
- desc: "Newlines should not change when endings is 'transparent'."
-});
-test_blob(function() {
- return new Blob(["\na\r\nb\n\rc\r"], { endings: "native" });
-}, {
- expected: "\na\r\nb\n\rc\r",
- type: "",
- desc: "Newlines should not change when endings is 'native'."
+[
+ 123,
+ 123.4,
+ true,
+ 'abc'
+].forEach(arg => {
+ test(t => {
+ assert_throws(new TypeError(), () => new Blob([], arg),
+ 'Blob constructor should throw with invalid property bag');
+ }, `Passing ${JSON.stringify(arg)} for options should throw`);
});
var type_tests = [
@@ -471,6 +476,7 @@ var type_tests = [
[[], '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 '],