Source code

Revision control

Copy as Markdown

Other Tools

/**
* Any copyright is dedicated to the Public Domain.
*/
// This test must be first, since we need the actor not to be created already.
exported_symbols.testGetDirectoryTwice = async function () {
const promise1 = navigator.storage.getDirectory();
const promise2 = navigator.storage.getDirectory();
await Promise.all([promise1, promise2]);
Assert.ok(true, "Should not have thrown");
};
exported_symbols.testGetDirectoryDoesNotThrow = async function () {
await navigator.storage.getDirectory();
Assert.ok(true, "Should not have thrown");
};
exported_symbols.testGetDirectoryKindIsDirectory = async function () {
const root = await navigator.storage.getDirectory();
Assert.equal(root.kind, "directory");
};
exported_symbols.testDirectoryHandleStringConversion = async function () {
const root = await navigator.storage.getDirectory();
Assert.equal(
"" + root,
"[object FileSystemDirectoryHandle]",
"Is directoryHandle convertible to string?"
);
};
exported_symbols.testNewDirectoryHandleFromPrototype = async function () {
const root = await navigator.storage.getDirectory();
try {
Object.create(root.prototype);
Assert.ok(false, "Should have thrown");
} catch (ex) {
Assert.ok(true, "Should have thrown");
Assert.ok(ex instanceof TypeError, "Threw the right error type");
}
};
exported_symbols.testIsSameEntryRoot = async function () {
const root = await navigator.storage.getDirectory();
try {
await root.move(root);
Assert.ok(false, "root should not be movable");
} catch (ex) {
Assert.ok(true, "root isn't movable");
}
};
exported_symbols.testDirectoryHandleSupportsKeysIterator = async function () {
const root = await navigator.storage.getDirectory();
const it = await root.keys();
Assert.ok(!!it, "Does root support keys iterator?");
};
exported_symbols.testKeysIteratorNextIsCallable = async function () {
const root = await navigator.storage.getDirectory();
const it = await root.keys();
Assert.ok(!!it, "Does root support keys iterator?");
const item = await it.next();
Assert.ok(!!item, "Should return an item");
};
exported_symbols.testDirectoryHandleSupportsValuesIterator = async function () {
const root = await navigator.storage.getDirectory();
const it = await root.values();
Assert.ok(!!it, "Does root support values iterator?");
};
exported_symbols.testValuesIteratorNextIsCallable = async function () {
const root = await navigator.storage.getDirectory();
const it = await root.values();
Assert.ok(!!it, "Does root support values iterator?");
const item = await it.next();
Assert.ok(!!item, "Should return an item");
};
exported_symbols.testDirectoryHandleSupportsEntriesIterator =
async function () {
const root = await navigator.storage.getDirectory();
const it = await root.entries();
Assert.ok(!!it, "Does root support entries iterator?");
};
exported_symbols.testEntriesIteratorNextIsCallable = async function () {
const root = await navigator.storage.getDirectory();
const it = await root.entries();
Assert.ok(!!it, "Does root support entries iterator?");
const item = await it.next();
Assert.ok(!!item, "Should return an item");
};
exported_symbols.testGetFileHandleIsCallable = async function () {
const root = await navigator.storage.getDirectory();
const allowCreate = { create: true };
const item = await root.getFileHandle("fileName", allowCreate);
Assert.ok(!!item, "Should return an item");
await root.removeEntry("fileName");
};
exported_symbols.testGetDirectoryHandleIsCallable = async function () {
const root = await navigator.storage.getDirectory();
const allowCreate = { create: true };
const item = await root.getDirectoryHandle("dirName", allowCreate);
Assert.ok(!!item, "Should return an item");
await root.removeEntry("dirName");
};
exported_symbols.testRemoveEntryIsCallable = async function () {
const root = await navigator.storage.getDirectory();
const removeOptions = { recursive: true };
const allowCreate = { create: true };
// Ensure file and directory items exists
await root.getFileHandle("fileName", allowCreate);
await root.getDirectoryHandle("dirName", allowCreate);
await root.removeEntry("fileName", removeOptions);
await root.removeEntry("dirName", removeOptions);
try {
await root.removeEntry("doesNotExist", removeOptions);
Assert.ok(false, "Should have thrown");
} catch (ex) {
Assert.ok(true, "Should have thrown");
Assert.equal(
ex.message,
"Entry not found",
"Threw the right error message"
);
}
};
exported_symbols.testResolveIsCallable = async function () {
const root = await navigator.storage.getDirectory();
const allowCreate = { create: true };
const item = await root.getFileHandle("fileName", allowCreate);
let path = await root.resolve(item);
Assert.equal(path.length, 1);
Assert.equal(path[0], "fileName", "Resolve got the right path");
await root.removeEntry("fileName");
};
exported_symbols.testFileType = async function () {
const root = await navigator.storage.getDirectory();
const allowCreate = { create: true };
const nameStem = "testFileType";
const empty = "";
const extensions = [
"txt",
"jS",
"JSON",
"css",
"html",
"htm",
"xhtml",
"xml",
"xhtml+xml",
"png",
"apng",
"jPg",
"Jpeg",
"pdF",
"out",
"sh",
"ExE",
"psid",
"EXE ",
" EXE",
"EX\uff65",
"\udbff\udbff\udbff",
// XXX: Invalid surrogate combos like "\udc00\udc00\udc00" may map to the same names impacting cleanup.
"js\udbff",
"\udc00js",
"???",
"\root",
empty,
"AXS",
"dll",
"ocx",
"1",
"ps1",
"cmd",
"xpi",
"swf",
];
const expectedTypes = [
"text/plain",
"application/javascript",
"application/json",
"text/css",
"text/html",
"text/html",
"application/xhtml+xml",
"text/xml",
empty,
"image/png",
"image/apng",
"image/jpeg",
"image/jpeg",
"application/pdf",
empty,
"application/x-sh",
"application/octet-stream",
empty,
empty,
empty,
empty,
empty,
empty,
empty,
empty,
empty,
empty,
"application/olescript",
"application/x-msdownload",
"application/octet-stream",
empty,
empty,
"text/plain",
"application/x-xpinstall",
"application/x-shockwave-flash",
];
Assert.equal(extensions.length, expectedTypes.length);
await Promise.all(
extensions.map(async (ext, i) => {
const fileName = nameStem + "." + ext;
const fileHandle = await root.getFileHandle(fileName, allowCreate);
const fileObject = await fileHandle.getFile();
Assert.equal(fileObject.name, fileHandle.name);
Assert.equal(fileObject.type, expectedTypes[i]);
await root.removeEntry(fileName);
})
);
};
exported_symbols.testContentTypeChangesOnFileMove = async function () {
const allowCreate = { create: true };
const root = await navigator.storage.getDirectory();
const oldName = "testFile.txt";
const oldType = "text/plain";
const subdir = await root.getDirectoryHandle("subdir", allowCreate);
const fileHandle = await root.getFileHandle(oldName, allowCreate);
async function checkMove(newName, newType) {
Assert.equal(fileHandle.name, newName, "Has filename changed?");
{
const fileObject = await fileHandle.getFile();
Assert.equal(fileObject.name, newName, "Is the fileobject renamed?");
Assert.equal(fileObject.type, newType, "Is the fileobject type updated?");
}
}
async function restoreTest() {
await fileHandle.move(root, oldName);
await checkMove(oldName, oldType);
}
// No name change
await checkMove(oldName, oldType);
await fileHandle.move(subdir);
await checkMove(oldName, oldType);
await restoreTest();
// With name change
async function testMoveWithParams(testName, testType) {
async function testFileMoveCall(...combo) {
await fileHandle.move(...combo);
await checkMove(testName, testType);
await restoreTest();
}
await testFileMoveCall(subdir, testName);
await testFileMoveCall(root, testName);
await testFileMoveCall(testName);
}
const testParams = {
"testFile.json": "application/json",
testFile: oldType,
"testFile.äüö": "",
};
for (const [aName, aType] of Object.entries(testParams)) {
await testMoveWithParams(aName, aType);
}
};
exported_symbols.testContentTypeChangesOnDirMove = async function () {
const allowCreate = { create: true };
const root = await navigator.storage.getDirectory();
const oldName = "testFile.txt";
const oldType = "text/plain";
const subDirOrig = await root.getDirectoryHandle("subDirOrig", allowCreate);
const subDirOther = await root.getDirectoryHandle("subDirOther", allowCreate);
const subSubDir = await subDirOrig.getDirectoryHandle(
"subSubDir",
allowCreate
);
const testName = "testFile.json";
const testType = "application/json";
async function checkMove(newName, newType) {
const fileHandle = await subSubDir.getFileHandle(newName, allowCreate);
Assert.equal(fileHandle.name, newName, "Has filename changed?");
{
const fileObject = await fileHandle.getFile();
Assert.equal(fileObject.name, newName, "Is the fileobject renamed?");
Assert.equal(fileObject.type, newType, "Is the fileobject type updated?");
}
}
async function restoreTest() {
await subSubDir.move(subDirOrig, "subSubDir");
await checkMove(oldName, oldType);
}
await checkMove(oldName, oldType);
// No name change
await subSubDir.move(subDirOther, "other");
await checkMove(oldName, oldType);
await restoreTest();
// With name change
async function testDirMoveCall(...combo) {
await subSubDir.move(...combo);
await checkMove(testName, testType);
await restoreTest();
}
await testDirMoveCall(subDirOther);
await testDirMoveCall(subDirOther, testName);
await testDirMoveCall(subDirOrig, testName);
await testDirMoveCall(subDirOrig);
};
for (const [key, value] of Object.entries(exported_symbols)) {
Object.defineProperty(value, "name", {
value: key,
writable: false,
});
}