summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/entries-api/support.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/entries-api/support.js')
-rw-r--r--testing/web-platform/tests/entries-api/support.js138
1 files changed, 138 insertions, 0 deletions
diff --git a/testing/web-platform/tests/entries-api/support.js b/testing/web-platform/tests/entries-api/support.js
new file mode 100644
index 0000000000..1cf3ad95b9
--- /dev/null
+++ b/testing/web-platform/tests/entries-api/support.js
@@ -0,0 +1,138 @@
+// ----------------------------------------
+// Test Utilities
+// ----------------------------------------
+
+setup({explicit_timeout: true});
+
+const tests = [];
+window.addEventListener('DOMContentLoaded', e => {
+ const header = document.createElement('h1');
+ header.innerText = document.title;
+ document.body.appendChild(header);
+ const elem = document.createElement('div');
+ elem.style.cssText = 'height: 50px; border: 1px dotted red;';
+ elem.innerHTML = 'Drop or paste the <b>support/upload</b> directory here.</div>';
+ document.body.appendChild(elem);
+ elem.addEventListener('dragover', e => {
+ e.preventDefault();
+ });
+ const onDropOrPaste = dataTransfer => {
+ for (let i = 0; i < dataTransfer.items.length; ++i) {
+ const item = dataTransfer.items[i];
+ if (item.kind !== 'file')
+ continue;
+ const entry = item.webkitGetAsEntry();
+ elem.parentElement.removeChild(elem);
+ tests.forEach(f => f(entry, item));
+ break;
+ }
+ };
+ elem.addEventListener('drop', e => {
+ e.preventDefault();
+ onDropOrPaste(e.dataTransfer);
+ });
+ elem.addEventListener('paste', e => {
+ e.preventDefault();
+ onDropOrPaste(e.clipboardData);
+ });
+});
+
+
+// Registers a test to be run when an entry is dropped. Calls |func|
+// with (test, entry, item); |func| must call `test.done()` when complete.
+function entry_test(func, description) {
+ const test = async_test(description);
+ tests.push(test.step_func((entry, item) => func(test, entry, item)));
+}
+
+// Registers a test to be run when an entry is dropped. Digs the named
+// |file| out of the dropped entry and calls |func| with
+// (test, file_entry); |func| must call `test.done()` when complete.
+function file_entry_test(name, func, description) {
+ return entry_test((t, entry, item) => {
+ getChildEntry(entry, name,
+ t.step_func((entry) => func(t, entry)),
+ t.unreached_func('Did not find expected file: ' + name));
+ }, description);
+}
+
+
+// ----------------------------------------
+// Paths
+// ----------------------------------------
+
+const INVALID_PATHS = [
+ '\x00', 'a-\x00-b',
+ '\\', 'a-\\-b'
+];
+const EMPTY_PATHS = ['', null, undefined];
+const NOT_FOUND_PATHS = [
+ 'nope',
+ '/upload/nope',
+ './nope',
+ 'subdir/../nope',
+ '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f',
+ '\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f',
+];
+
+const DIR_PATHS = [
+ 'subdir',
+ '/upload/subdir',
+ './subdir',
+ 'subdir/.',
+ 'subdir/../subdir',
+ 'subdir/./../subdir',
+ 'subdir/../subdir/.',
+ '//upload/subdir',
+ '/upload//subdir',
+ './/subdir',
+ 'subdir//.',
+];
+const FILE_PATHS = [
+ 'file.txt',
+ '/upload/file.txt',
+ 'subdir/../file.txt',
+ '//upload/file.txt',
+ '/upload//file.txt',
+ 'subdir/./../file.txt',
+];
+
+// ----------------------------------------
+// Helpers
+// ----------------------------------------
+
+// Wrapper for FileSystemDirectoryReader that yields all entries via a
+// Promise.
+
+function getEntriesAsPromise(dirEntry) {
+ return new Promise((resolve, reject) => {
+ const result = [];
+ const reader = dirEntry.createReader();
+ const doBatch = () => {
+ reader.readEntries(entries => {
+ if (entries.length > 0) {
+ entries.forEach(e => result.push(e));
+ doBatch();
+ } else {
+ resolve(result);
+ }
+ }, reject);
+ };
+ doBatch();
+ });
+}
+
+
+// Wrapper for FileSystemDirectoryReader that yields a single entry by
+// name via a callback. Can be used instead of getFile() or
+// getDirectory() since not all implementations support those.
+
+function getChildEntry(dirEntry, name, callback, errback) {
+ getEntriesAsPromise(dirEntry)
+ .then(entries => {
+ const entry = entries.filter(entry => entry.name === name)[0];
+ if (!entry)
+ throw new Error('No such file: ' + name);
+ return entry;
+ }).then(callback, errback);
+}