Commit cbd34702 authored by Marijn Kruisselbrink's avatar Marijn Kruisselbrink Committed by Commit Bot

[NativeFS] Refactor WPT tests to support native FS as well.

Also changes the sandboxed file system version of these tests to run in
both windows and workers.

The native file system version of these tests are currently manual tests.
In the future we can automate them. Also currently some of the writer
tests don't pass in the native file system version, because of things like
bug 998913.

Bug: 998917
Change-Id: I4aefee6e35008afd73c2cf316d16ea189717bd4b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1787869Reviewed-by: default avatarOlivier Yiptong <oyiptong@chromium.org>
Commit-Queue: Marijn Kruisselbrink <mek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#699539}
parent e317ec20
...@@ -6104,6 +6104,12 @@ crbug.com/919204 external/wpt/scroll-to-text-fragment/scroll-to-text-fragment.ht ...@@ -6104,6 +6104,12 @@ crbug.com/919204 external/wpt/scroll-to-text-fragment/scroll-to-text-fragment.ht
crbug.com/999209 virtual/lazyload-image/http/tests/lazyload/style-dimension.html [ Timeout ] crbug.com/999209 virtual/lazyload-image/http/tests/lazyload/style-dimension.html [ Timeout ]
# These tests are missing test automation
crbug.com/998917 external/wpt/native-file-system/native_FileSystemDirectoryHandle-getDirectory.tentative.https.manual.window.html [ Skip ]
crbug.com/998917 external/wpt/native-file-system/native_FileSystemDirectoryHandle-getFile.tentative.https.manual.window.html [ Skip ]
crbug.com/998917 external/wpt/native-file-system/native_FileSystemDirectoryHandle-removeEntry.tentative.https.manual.window.html [ Skip ]
crbug.com/998917 external/wpt/native-file-system/native_FileSystemWriter.tentative.https.manual.window.html [ Skip ]
crbug.com/1000051 media/controls/volume-slider.html [ Failure Timeout Pass ] crbug.com/1000051 media/controls/volume-slider.html [ Failure Timeout Pass ]
crbug.com/1000051 virtual/audio-service/media/controls/volume-slider.html [ Failure Timeout Pass ] crbug.com/1000051 virtual/audio-service/media/controls/volume-slider.html [ Failure Timeout Pass ]
......
...@@ -977,11 +977,6 @@ ...@@ -977,11 +977,6 @@
"base": "http/tests/navigation/frozen-useragent.html", "base": "http/tests/navigation/frozen-useragent.html",
"args": ["--enable-features=FreezeUserAgent"] "args": ["--enable-features=FreezeUserAgent"]
}, },
{
"prefix": "native-file-system",
"base": "external/wpt/native-file-system",
"args": ["--enable-features=NativeFileSystemAPI"]
},
{ {
"prefix": "file-handling", "prefix": "file-handling",
"base": "file-handling", "base": "file-handling",
......
// META: script=resources/test-helpers.js
promise_test(async t => cleanupSandboxedFileSystem(),
'Cleanup to setup test environment');
promise_test(async t => {
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const handle = await createFileWithContents(t, 'file-to-remove', '12345', root);
await createFileWithContents(t, 'file-to-keep', 'abc', root);
await root.removeEntry('file-to-remove');
assert_array_equals(await getSortedDirectoryEntries(root), ['file-to-keep']);
await promise_rejects(t, 'NotFoundError', getFileContents(handle));
}, 'removeEntry() to remove a file');
promise_test(async t => {
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const handle = await createFileWithContents(t, 'file-to-remove', '12345', root);
await root.removeEntry('file-to-remove');
await promise_rejects(t, 'NotFoundError', root.removeEntry('file-to-remove'));
}, 'removeEntry() on an already removed file should fail');
promise_test(async t => {
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const dir = await root.getDirectory('dir-to-remove', { create: true });
await createFileWithContents(t, 'file-to-keep', 'abc', root);
await root.removeEntry('dir-to-remove');
assert_array_equals(await getSortedDirectoryEntries(root), ['file-to-keep']);
await promise_rejects(t, 'NotFoundError', getSortedDirectoryEntries(dir));
}, 'removeEntry() to remove an empty directory');
promise_test(async t => {
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const dir = await root.getDirectory('dir-to-remove', { create: true });
t.add_cleanup(() => root.removeEntry('dir-to-remove', { recursive: true }));
await createEmptyFile(t, 'file-in-dir', dir);
await promise_rejects(t, 'InvalidModificationError', root.removeEntry('dir-to-remove'));
assert_array_equals(await getSortedDirectoryEntries(root), ['dir-to-remove/']);
assert_array_equals(await getSortedDirectoryEntries(dir), ['file-in-dir']);
}, 'removeEntry() on a non-empty directory should fail');
promise_test(async t => {
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const dir = await createDirectory(t, 'dir', root);
await promise_rejects(t, new TypeError(), dir.removeEntry(""));
}, 'removeEntry() with empty name should fail');
promise_test(async t => {
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const dir = await createDirectory(t, 'dir', root);
await promise_rejects(t, new TypeError(), dir.removeEntry(kCurrentDirectory));
}, `removeEntry() with "${kCurrentDirectory}" name should fail`);
promise_test(async t => {
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const dir = await createDirectory(t, 'dir', root);
await promise_rejects(t, new TypeError(), dir.removeEntry(kParentDirectory));
}, `removeEntry() with "${kParentDirectory}" name should fail`);
promise_test(async t => {
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const dir_name = 'dir-name';
const dir = await createDirectory(t, dir_name, root);
const file_name = 'file-name';
await createEmptyFile(t, file_name, dir);
for (let i = 0; i < kPathSeparators.length; ++i) {
const path_with_separator = `${dir_name}${kPathSeparators[i]}${file_name}`;
await promise_rejects(t, new TypeError(), root.removeEntry(path_with_separator),
`removeEntry() must reject names containing "${kPathSeparators[i]}"`);
}
}, 'removeEntry() with a path separator should fail.');
// META: script=resources/test-helpers.js
promise_test(async t => cleanupSandboxedFileSystem(),
'Cleanup to setup test environment');
promise_test(async t => {
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
await promise_rejects(t, 'NotFoundError', root.getDirectory('non-existing-dir'));
}, 'getDirectory(create=false) rejects for non-existing directories');
promise_test(async t => {
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const handle = await root.getDirectory('non-existing-dir', { create: true });
t.add_cleanup(() => root.removeEntry('non-existing-dir', { recursive: true }));
assert_false(handle.isFile);
assert_true(handle.isDirectory);
assert_equals(handle.name, 'non-existing-dir');
assert_equals(await getDirectoryEntryCount(handle), 0);
assert_array_equals(await getSortedDirectoryEntries(root), ['non-existing-dir/']);
}, 'getDirectory(create=true) creates an empty directory');
promise_test(async t => {
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const existing_handle = await root.getDirectory('dir-with-contents', { create: true });
t.add_cleanup(() => root.removeEntry('dir-with-contents', { recursive: true }));
const file_handle = await createEmptyFile(t, 'test-file', existing_handle);
const handle = await root.getDirectory('dir-with-contents', { create: false });
assert_false(handle.isFile);
assert_true(handle.isDirectory);
assert_equals(handle.name, 'dir-with-contents');
assert_array_equals(await getSortedDirectoryEntries(handle), ['test-file']);
}, 'getDirectory(create=false) returns existing directories');
promise_test(async t => {
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const existing_handle = await root.getDirectory('dir-with-contents', { create: true });
t.add_cleanup(() => root.removeEntry('dir-with-contents', { recursive: true }));
const file_handle = await existing_handle.getFile('test-file', { create: true });
const handle = await root.getDirectory('dir-with-contents', { create: true });
assert_false(handle.isFile);
assert_true(handle.isDirectory);
assert_equals(handle.name, 'dir-with-contents');
assert_array_equals(await getSortedDirectoryEntries(handle), ['test-file']);
}, 'getDirectory(create=true) returns existing directories without erasing');
promise_test(async t => {
const root = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
await createEmptyFile(t, 'file-name');
await promise_rejects(t, 'TypeMismatchError', root.getDirectory('file-name'));
await promise_rejects(t, 'TypeMismatchError', root.getDirectory('file-name', { create: false }));
await promise_rejects(t, 'TypeMismatchError', root.getDirectory('file-name', { create: true }));
}, 'getDirectory() when a file already exists with the same name');
promise_test(async t => {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
await promise_rejects(t, new TypeError(), dir.getDirectory("", { create: true }));
await promise_rejects(t, new TypeError(), dir.getDirectory("", { create: false }));
}, 'getDirectory() with empty name');
promise_test(async t => {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
await promise_rejects(t, new TypeError(), dir.getDirectory(kCurrentDirectory));
await promise_rejects(t, new TypeError(), dir.getDirectory(kCurrentDirectory, { create: true }));
}, `getDirectory() with "${kCurrentDirectory}" name`);
promise_test(async t => {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const subdir = await createDirectory(t, 'subdir-name', /*parent=*/dir);
await promise_rejects(t, new TypeError(), subdir.getDirectory(kParentDirectory));
await promise_rejects(t, new TypeError(), subdir.getDirectory(kParentDirectory, { create: true }));
}, `getDirectory() with "${kParentDirectory}" name`);
promise_test(async t => {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const first_subdir_name = 'first-subdir-name';
const first_subdir = await createDirectory(t, first_subdir_name, /*parent=*/dir);
const second_subdir_name = 'second-subdir-name';
const second_subdir = await createDirectory(t, second_subdir_name, /*parent=*/first_subdir);
for (let i = 0; i < kPathSeparators.length; ++i) {
const path_with_separator = `${first_subdir_name}${kPathSeparators[i]}${second_subdir_name}`;
await promise_rejects(t, new TypeError(), dir.getDirectory(path_with_separator),
`getDirectory() must reject names containing "${kPathSeparators[i]}"`);
}
}, 'getDirectory(create=false) with a path separator when the directory exists');
promise_test(async t => {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const subdir_name = 'subdir-name';
const subdir = await createDirectory(t, subdir_name, /*parent=*/dir);
for (let i = 0; i < kPathSeparators.length; ++i) {
const path_with_separator = `${subdir_name}${kPathSeparators[i]}file_name`;
await promise_rejects(t, new TypeError(), dir.getDirectory(path_with_separator, { create: true }),
`getDirectory(true) must reject names containing "${kPathSeparators[i]}"`);
}
}, 'getDirectory(create=true) with a path separator');
// META: script=resources/test-helpers.js
promise_test(async t => cleanupSandboxedFileSystem(),
'Cleanup to setup test environment');
promise_test(async t => {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
await promise_rejects(t, 'NotFoundError', dir.getFile('non-existing-file'));
}, 'getFile(create=false) rejects for non-existing files');
promise_test(async t => {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const handle = await dir.getFile('non-existing-file', { create: true });
t.add_cleanup(() => dir.removeEntry('non-existing-file'));
assert_true(handle.isFile);
assert_false(handle.isDirectory);
assert_equals(handle.name, 'non-existing-file');
assert_equals(await getFileSize(handle), 0);
assert_equals(await getFileContents(handle), '');
}, 'getFile(create=true) creates an empty file for non-existing files');
promise_test(async t => {
const existing_handle = await createFileWithContents(t, 'existing-file', '1234567890');
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const handle = await dir.getFile('existing-file');
assert_true(handle.isFile);
assert_false(handle.isDirectory);
assert_equals(handle.name, 'existing-file');
assert_equals(await getFileSize(handle), 10);
assert_equals(await getFileContents(handle), '1234567890');
}, 'getFile(create=false) returns existing files');
promise_test(async t => {
const existing_handle = await createFileWithContents(t, 'file-with-contents', '1234567890');
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const handle = await dir.getFile('file-with-contents', { create: true });
assert_true(handle.isFile);
assert_false(handle.isDirectory);
assert_equals(handle.name, 'file-with-contents');
assert_equals(await getFileSize(handle), 10);
assert_equals(await getFileContents(handle), '1234567890');
}, 'getFile(create=true) returns existing files without erasing');
promise_test(async t => {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const dir_handle = await dir.getDirectory('dir-name', { create: true });
t.add_cleanup(() => dir.removeEntry('dir-name', { recursive: true }));
await promise_rejects(t, 'TypeMismatchError', dir.getFile('dir-name'));
}, 'getFile(create=false) when a directory already exists with the same name');
promise_test(async t => {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const dir_handle = await dir.getDirectory('dir-name', { create: true });
t.add_cleanup(() => dir.removeEntry('dir-name', { recursive: true }));
await promise_rejects(t, 'TypeMismatchError', dir.getFile('dir-name', { create: true }));
}, 'getFile(create=true) when a directory already exists with the same name');
promise_test(async t => {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
await promise_rejects(t, new TypeError(), dir.getFile("", { create: true }));
await promise_rejects(t, new TypeError(), dir.getFile("", { create: false }));
}, 'getFile() with empty name');
promise_test(async t => {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
await promise_rejects(t, new TypeError(), dir.getFile(kCurrentDirectory));
await promise_rejects(t, new TypeError(), dir.getFile(kCurrentDirectory, { create: true }));
}, `getFile() with "${kCurrentDirectory}" name`);
promise_test(async t => {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const subdir = await createDirectory(t, 'subdir-name', /*parent=*/dir);
await promise_rejects(t, new TypeError(), subdir.getFile(kParentDirectory));
await promise_rejects(t, new TypeError(), subdir.getFile(kParentDirectory, { create: true }));
}, `getFile() with "${kParentDirectory}" name`);
promise_test(async t => {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const subdir_name = 'subdir-name';
const subdir = await createDirectory(t, subdir_name, /*parent=*/dir);
const file_name = 'file-name';
await createEmptyFile(t, file_name, /*parent=*/subdir);
for (let i = 0; i < kPathSeparators.length; ++i) {
const path_with_separator = `${subdir_name}${kPathSeparators[i]}${file_name}`;
await promise_rejects(t, new TypeError(), dir.getFile(path_with_separator),
`getFile() must reject names containing "${kPathSeparators[i]}"`);
}
}, 'getFile(create=false) with a path separator when the file exists.');
promise_test(async t => {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const subdir_name = 'subdir-name';
const subdir = await createDirectory(t, subdir_name, /*parent=*/dir);
for (let i = 0; i < kPathSeparators.length; ++i) {
const path_with_separator = `${subdir_name}${kPathSeparators[i]}file_name`;
await promise_rejects(t, new TypeError(), dir.getFile(path_with_separator, { create: true }),
`getFile(true) must reject names containing "${kPathSeparators[i]}"`);
}
}, 'getFile(create=true) with a path separator');
// META: script=/resources/testdriver.js
// META: script=resources/test-helpers.js
// META: script=resources/native-fs-test-helpers.js
// META: script=script-tests/FileSystemDirectoryHandle-getDirectory.js
// META: script=/resources/testdriver.js
// META: script=resources/test-helpers.js
// META: script=resources/native-fs-test-helpers.js
// META: script=script-tests/FileSystemDirectoryHandle-getFile.js
// META: script=/resources/testdriver.js
// META: script=resources/test-helpers.js
// META: script=resources/native-fs-test-helpers.js
// META: script=script-tests/FileSystemDirectoryHandle-removeEntry.js
// META: script=/resources/testdriver.js
// META: script=resources/test-helpers.js
// META: script=resources/native-fs-test-helpers.js
// META: script=script-tests/FileSystemWriter.js
// This file defines a directory_test() function that can be used to define
// tests that require a FileSystemDirectoryHandle. The implementation of that
// function in this file will ask the user to select an empty directory and
// uses that directory.
//
// Another implementation of this function exists in
// sandboxed-fs-test-helpers.js, where that version uses the sandboxed file
// system instead.
const directory_promise = (async () => {
await new Promise(resolve => {
window.addEventListener('DOMContentLoaded', resolve);
});
await window.test_driver.bless(
'show a file picker.<br />Please select an empty directory');
const entries = await self.chooseFileSystemEntries({type: 'openDirectory'});
assert_true(entries instanceof FileSystemHandle);
assert_true(entries instanceof FileSystemDirectoryHandle);
for await (const entry of entries.getEntries()) {
assert_unreached('Selected directory is not empty');
}
return entries;
})();
function directory_test(func, description) {
promise_test(async t => {
const directory = await directory_promise;
// To be resilient against tests not cleaning up properly, cleanup before
// every test.
for await (let entry of directory.getEntries()) {
await directory.removeEntry(entry.name, {recursive: entry.isDirectory});
}
await func(t, directory);
}, description);
}
directory_test(async (t, dir) => {
assert_equals(await dir.queryPermission({writable: false}), 'granted');
}, 'User succesfully selected an empty directory.');
directory_test(async (t, dir) => {
const status = await dir.queryPermission({writable: true});
if (status == 'granted')
return;
await window.test_driver.bless('ask for write permission');
assert_equals(await dir.requestPermission({writable: true}), 'granted');
}, 'User granted write access.');
// This file defines a directory_test() function that can be used to define
// tests that require a FileSystemDirectoryHandle. The implementation of that
// function in this file will return an empty directory in the sandboxed file
// system.
//
// Another implementation of this function exists in native-fs-test-helpers.js,
// where that version uses the native file system instead.
async function cleanupSandboxedFileSystem() {
const dir =
await FileSystemDirectoryHandle.getSystemDirectory({type: 'sandbox'});
for await (let entry of dir.getEntries())
await dir.removeEntry(entry.name, {recursive: entry.isDirectory});
}
function directory_test(func, description) {
promise_test(async t => {
// To be extra resilient against bad tests, cleanup before every test.
await cleanupSandboxedFileSystem();
const dir =
await FileSystemDirectoryHandle.getSystemDirectory({type: 'sandbox'});
await func(t, dir);
}, description);
}
// A special path component meaning "this directory." // A special path component meaning "this directory."
const kCurrentDirectory = "."; const kCurrentDirectory = '.';
// A special path component meaning "the parent directory." // A special path component meaning "the parent directory."
const kParentDirectory = ".."; const kParentDirectory = '..';
// Array of separators used to separate components in hierarchical paths. // Array of separators used to separate components in hierarchical paths.
let kPathSeparators; let kPathSeparators;
if (navigator.userAgent.includes("Windows NT")) { if (navigator.userAgent.includes('Windows NT')) {
// Windows uses both '/' and '\' as path separators. // Windows uses both '/' and '\' as path separators.
kPathSeparators = ['/', '\\' ]; kPathSeparators = ['/', '\\'];
} else { } else {
kPathSeparators = [ '/' ]; kPathSeparators = ['/'];
}
async function cleanupSandboxedFileSystem() {
const dir = await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
for await (let entry of dir.getEntries())
dir.removeEntry(entry.name, { recursive: entry.isDirectory });
} }
async function getFileSize(handle) { async function getFileSize(handle) {
const file = await handle.getFile(); const file = await handle.getFile();
return file.size; return file.size;
} }
async function getFileContents(handle) { async function getFileContents(handle) {
const file = await handle.getFile(); const file = await handle.getFile();
return new Response(file).text(); return new Response(file).text();
} }
async function getDirectoryEntryCount(handle) { async function getDirectoryEntryCount(handle) {
let result = 0; let result = 0;
for await (let entry of handle.getEntries()) { for await (let entry of handle.getEntries()) {
result++; result++;
} }
return result; return result;
} }
async function getSortedDirectoryEntries(handle) { async function getSortedDirectoryEntries(handle) {
let result = []; let result = [];
for await (let entry of handle.getEntries()) { for await (let entry of handle.getEntries()) {
if (entry.isDirectory) if (entry.isDirectory)
result.push(entry.name + '/'); result.push(entry.name + '/');
else else
result.push(entry.name); result.push(entry.name);
} }
result.sort(); result.sort();
return result; return result;
} }
async function createDirectory(test, name, parent) { async function createDirectory(test, name, parent) {
const parent_dir_handle = parent ? parent : const new_dir_handle = await parent.getDirectory(name, {create: true});
await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' });
const new_dir_handle = await parent_dir_handle.getDirectory(name, { create: true });
test.add_cleanup(async () => { test.add_cleanup(async () => {
try { try {
await parent_dir_handle.removeEntry(name, { recursive: true }); await parent.removeEntry(name, {recursive: true});
} catch (e) { } catch (e) {
// Ignore any errors when removing directories, as tests might // Ignore any errors when removing directories, as tests might
// have already removed the directory. // have already removed the directory.
} }
}); });
return new_dir_handle; return new_dir_handle;
} }
async function createEmptyFile(test, name, parent) { async function createEmptyFile(test, name, parent) {
const dir = parent ? parent : await FileSystemDirectoryHandle.getSystemDirectory({ type: 'sandbox' }); const handle = await parent.getFile(name, {create: true});
const handle = await dir.getFile(name, { create: true }); test.add_cleanup(async () => {
test.add_cleanup(async () => { try {
try { await parent.removeEntry(name);
await dir.removeEntry(name); } catch (e) {
} catch (e) { // Ignore any errors when removing files, as tests might already remove
// Ignore any errors when removing files, as tests might already remove the file. // the file.
} }
}); });
// Make sure the file is empty. // Make sure the file is empty.
assert_equals(await getFileSize(handle), 0); assert_equals(await getFileSize(handle), 0);
return handle; return handle;
} }
async function createFileWithContents(test, name, contents, parent) { async function createFileWithContents(test, name, contents, parent) {
const handle = await createEmptyFile(test, name, parent); const handle = await createEmptyFile(test, name, parent);
const writer = await handle.createWriter(); const writer = await handle.createWriter();
await writer.write(0, new Blob([contents])); await writer.write(0, new Blob([contents]));
await writer.close(); await writer.close();
return handle; return handle;
} }
function garbageCollect() { function garbageCollect() {
// TODO(https://github.com/web-platform-tests/wpt/issues/7899): Change to // TODO(https://github.com/web-platform-tests/wpt/issues/7899): Change to
// some sort of cross-browser GC trigger. // some sort of cross-browser GC trigger.
if (self.gc) self.gc(); if (self.gc)
self.gc();
}; };
// META: script=resources/test-helpers.js
// META: script=resources/sandboxed-fs-test-helpers.js
// META: script=script-tests/FileSystemDirectoryHandle-getDirectory.js
// META: script=resources/test-helpers.js
// META: script=resources/sandboxed-fs-test-helpers.js
// META: script=script-tests/FileSystemDirectoryHandle-getFile.js
// META: script=resources/test-helpers.js
// META: script=resources/sandboxed-fs-test-helpers.js
// META: script=script-tests/FileSystemDirectoryHandle-removeEntry.js
// META: script=resources/test-helpers.js
// META: script=resources/sandboxed-fs-test-helpers.js
// META: script=script-tests/FileSystemWriter.js
directory_test(async (t, root) => {
await promise_rejects(
t, 'NotFoundError', root.getDirectory('non-existing-dir'));
}, 'getDirectory(create=false) rejects for non-existing directories');
directory_test(async (t, root) => {
const handle = await root.getDirectory('non-existing-dir', {create: true});
t.add_cleanup(() => root.removeEntry('non-existing-dir', {recursive: true}));
assert_false(handle.isFile);
assert_true(handle.isDirectory);
assert_equals(handle.name, 'non-existing-dir');
assert_equals(await getDirectoryEntryCount(handle), 0);
assert_array_equals(
await getSortedDirectoryEntries(root), ['non-existing-dir/']);
}, 'getDirectory(create=true) creates an empty directory');
directory_test(async (t, root) => {
const existing_handle =
await root.getDirectory('dir-with-contents', {create: true});
t.add_cleanup(() => root.removeEntry('dir-with-contents', {recursive: true}));
const file_handle = await createEmptyFile(t, 'test-file', existing_handle);
const handle = await root.getDirectory('dir-with-contents', {create: false});
assert_false(handle.isFile);
assert_true(handle.isDirectory);
assert_equals(handle.name, 'dir-with-contents');
assert_array_equals(await getSortedDirectoryEntries(handle), ['test-file']);
}, 'getDirectory(create=false) returns existing directories');
directory_test(async (t, root) => {
const existing_handle =
await root.getDirectory('dir-with-contents', {create: true});
t.add_cleanup(() => root.removeEntry('dir-with-contents', {recursive: true}));
const file_handle =
await existing_handle.getFile('test-file', {create: true});
const handle = await root.getDirectory('dir-with-contents', {create: true});
assert_false(handle.isFile);
assert_true(handle.isDirectory);
assert_equals(handle.name, 'dir-with-contents');
assert_array_equals(await getSortedDirectoryEntries(handle), ['test-file']);
}, 'getDirectory(create=true) returns existing directories without erasing');
directory_test(async (t, root) => {
await createEmptyFile(t, 'file-name', root);
await promise_rejects(t, 'TypeMismatchError', root.getDirectory('file-name'));
await promise_rejects(
t, 'TypeMismatchError', root.getDirectory('file-name', {create: false}));
await promise_rejects(
t, 'TypeMismatchError', root.getDirectory('file-name', {create: true}));
}, 'getDirectory() when a file already exists with the same name');
directory_test(async (t, dir) => {
await promise_rejects(
t, new TypeError(), dir.getDirectory('', {create: true}));
await promise_rejects(
t, new TypeError(), dir.getDirectory('', {create: false}));
}, 'getDirectory() with empty name');
directory_test(async (t, dir) => {
await promise_rejects(
t, new TypeError(), dir.getDirectory(kCurrentDirectory));
await promise_rejects(
t, new TypeError(), dir.getDirectory(kCurrentDirectory, {create: true}));
}, `getDirectory() with "${kCurrentDirectory}" name`);
directory_test(async (t, dir) => {
const subdir = await createDirectory(t, 'subdir-name', /*parent=*/ dir);
await promise_rejects(
t, new TypeError(), subdir.getDirectory(kParentDirectory));
await promise_rejects(
t, new TypeError(),
subdir.getDirectory(kParentDirectory, {create: true}));
}, `getDirectory() with "${kParentDirectory}" name`);
directory_test(async (t, dir) => {
const first_subdir_name = 'first-subdir-name';
const first_subdir =
await createDirectory(t, first_subdir_name, /*parent=*/ dir);
const second_subdir_name = 'second-subdir-name';
const second_subdir =
await createDirectory(t, second_subdir_name, /*parent=*/ first_subdir);
for (let i = 0; i < kPathSeparators.length; ++i) {
const path_with_separator =
`${first_subdir_name}${kPathSeparators[i]}${second_subdir_name}`;
await promise_rejects(
t, new TypeError(), dir.getDirectory(path_with_separator),
`getDirectory() must reject names containing "${kPathSeparators[i]}"`);
}
}, 'getDirectory(create=false) with a path separator when the directory exists');
directory_test(async (t, dir) => {
const subdir_name = 'subdir-name';
const subdir = await createDirectory(t, subdir_name, /*parent=*/ dir);
for (let i = 0; i < kPathSeparators.length; ++i) {
const path_with_separator = `${subdir_name}${kPathSeparators[i]}file_name`;
await promise_rejects(
t, new TypeError(),
dir.getDirectory(path_with_separator, {create: true}),
`getDirectory(true) must reject names containing "${
kPathSeparators[i]}"`);
}
}, 'getDirectory(create=true) with a path separator');
directory_test(async (t, dir) => {
await promise_rejects(t, 'NotFoundError', dir.getFile('non-existing-file'));
}, 'getFile(create=false) rejects for non-existing files');
directory_test(async (t, dir) => {
const handle = await dir.getFile('non-existing-file', {create: true});
t.add_cleanup(() => dir.removeEntry('non-existing-file'));
assert_true(handle.isFile);
assert_false(handle.isDirectory);
assert_equals(handle.name, 'non-existing-file');
assert_equals(await getFileSize(handle), 0);
assert_equals(await getFileContents(handle), '');
}, 'getFile(create=true) creates an empty file for non-existing files');
directory_test(async (t, dir) => {
const existing_handle = await createFileWithContents(
t, 'existing-file', '1234567890', /*parent=*/ dir);
const handle = await dir.getFile('existing-file');
assert_true(handle.isFile);
assert_false(handle.isDirectory);
assert_equals(handle.name, 'existing-file');
assert_equals(await getFileSize(handle), 10);
assert_equals(await getFileContents(handle), '1234567890');
}, 'getFile(create=false) returns existing files');
directory_test(async (t, dir) => {
const existing_handle = await createFileWithContents(
t, 'file-with-contents', '1234567890', /*parent=*/ dir);
const handle = await dir.getFile('file-with-contents', {create: true});
assert_true(handle.isFile);
assert_false(handle.isDirectory);
assert_equals(handle.name, 'file-with-contents');
assert_equals(await getFileSize(handle), 10);
assert_equals(await getFileContents(handle), '1234567890');
}, 'getFile(create=true) returns existing files without erasing');
directory_test(async (t, dir) => {
const dir_handle = await dir.getDirectory('dir-name', {create: true});
t.add_cleanup(() => dir.removeEntry('dir-name', {recursive: true}));
await promise_rejects(t, 'TypeMismatchError', dir.getFile('dir-name'));
}, 'getFile(create=false) when a directory already exists with the same name');
directory_test(async (t, dir) => {
const dir_handle = await dir.getDirectory('dir-name', {create: true});
t.add_cleanup(() => dir.removeEntry('dir-name', {recursive: true}));
await promise_rejects(
t, 'TypeMismatchError', dir.getFile('dir-name', {create: true}));
}, 'getFile(create=true) when a directory already exists with the same name');
directory_test(async (t, dir) => {
await promise_rejects(t, new TypeError(), dir.getFile('', {create: true}));
await promise_rejects(t, new TypeError(), dir.getFile('', {create: false}));
}, 'getFile() with empty name');
directory_test(async (t, dir) => {
await promise_rejects(t, new TypeError(), dir.getFile(kCurrentDirectory));
await promise_rejects(
t, new TypeError(), dir.getFile(kCurrentDirectory, {create: true}));
}, `getFile() with "${kCurrentDirectory}" name`);
directory_test(async (t, dir) => {
const subdir = await createDirectory(t, 'subdir-name', /*parent=*/ dir);
await promise_rejects(t, new TypeError(), subdir.getFile(kParentDirectory));
await promise_rejects(
t, new TypeError(), subdir.getFile(kParentDirectory, {create: true}));
}, `getFile() with "${kParentDirectory}" name`);
directory_test(async (t, dir) => {
const subdir_name = 'subdir-name';
const subdir = await createDirectory(t, subdir_name, /*parent=*/ dir);
const file_name = 'file-name';
await createEmptyFile(t, file_name, /*parent=*/ subdir);
for (let i = 0; i < kPathSeparators.length; ++i) {
const path_with_separator =
`${subdir_name}${kPathSeparators[i]}${file_name}`;
await promise_rejects(
t, new TypeError(), dir.getFile(path_with_separator),
`getFile() must reject names containing "${kPathSeparators[i]}"`);
}
}, 'getFile(create=false) with a path separator when the file exists.');
directory_test(async (t, dir) => {
const subdir_name = 'subdir-name';
const subdir = await createDirectory(t, subdir_name, /*parent=*/ dir);
for (let i = 0; i < kPathSeparators.length; ++i) {
const path_with_separator = `${subdir_name}${kPathSeparators[i]}file_name`;
await promise_rejects(
t, new TypeError(), dir.getFile(path_with_separator, {create: true}),
`getFile(true) must reject names containing "${kPathSeparators[i]}"`);
}
}, 'getFile(create=true) with a path separator');
directory_test(async (t, root) => {
const handle =
await createFileWithContents(t, 'file-to-remove', '12345', root);
await createFileWithContents(t, 'file-to-keep', 'abc', root);
await root.removeEntry('file-to-remove');
assert_array_equals(await getSortedDirectoryEntries(root), ['file-to-keep']);
await promise_rejects(t, 'NotFoundError', getFileContents(handle));
}, 'removeEntry() to remove a file');
directory_test(async (t, root) => {
const handle =
await createFileWithContents(t, 'file-to-remove', '12345', root);
await root.removeEntry('file-to-remove');
await promise_rejects(t, 'NotFoundError', root.removeEntry('file-to-remove'));
}, 'removeEntry() on an already removed file should fail');
directory_test(async (t, root) => {
const dir = await root.getDirectory('dir-to-remove', {create: true});
await createFileWithContents(t, 'file-to-keep', 'abc', root);
await root.removeEntry('dir-to-remove');
assert_array_equals(await getSortedDirectoryEntries(root), ['file-to-keep']);
await promise_rejects(t, 'NotFoundError', getSortedDirectoryEntries(dir));
}, 'removeEntry() to remove an empty directory');
directory_test(async (t, root) => {
const dir = await root.getDirectory('dir-to-remove', {create: true});
t.add_cleanup(() => root.removeEntry('dir-to-remove', {recursive: true}));
await createEmptyFile(t, 'file-in-dir', dir);
await promise_rejects(
t, 'InvalidModificationError', root.removeEntry('dir-to-remove'));
assert_array_equals(
await getSortedDirectoryEntries(root), ['dir-to-remove/']);
assert_array_equals(await getSortedDirectoryEntries(dir), ['file-in-dir']);
}, 'removeEntry() on a non-empty directory should fail');
directory_test(async (t, root) => {
const dir = await createDirectory(t, 'dir', root);
await promise_rejects(t, new TypeError(), dir.removeEntry(''));
}, 'removeEntry() with empty name should fail');
directory_test(async (t, root) => {
const dir = await createDirectory(t, 'dir', root);
await promise_rejects(t, new TypeError(), dir.removeEntry(kCurrentDirectory));
}, `removeEntry() with "${kCurrentDirectory}" name should fail`);
directory_test(async (t, root) => {
const dir = await createDirectory(t, 'dir', root);
await promise_rejects(t, new TypeError(), dir.removeEntry(kParentDirectory));
}, `removeEntry() with "${kParentDirectory}" name should fail`);
directory_test(async (t, root) => {
const dir_name = 'dir-name';
const dir = await createDirectory(t, dir_name, root);
const file_name = 'file-name';
await createEmptyFile(t, file_name, dir);
for (let i = 0; i < kPathSeparators.length; ++i) {
const path_with_separator = `${dir_name}${kPathSeparators[i]}${file_name}`;
await promise_rejects(
t, new TypeError(), root.removeEntry(path_with_separator),
`removeEntry() must reject names containing "${kPathSeparators[i]}"`);
}
}, 'removeEntry() with a path separator should fail.');
# This suite runs the tests with
# --enable-features=NativeFilesystemAPI
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment