diff options
Diffstat (limited to 'testing/web-platform/tests/entries-api/support.js')
-rw-r--r-- | testing/web-platform/tests/entries-api/support.js | 138 |
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); +} |