Commit 8a07e58b authored by hirono@chromium.org's avatar hirono@chromium.org

Files.app: Add more unit tests for FileOperationManager class.

The CL adds tests for 

 * Copy
 * Delete
 * Zip

operations of the class.

BUG=315439
TEST=run the test

Review URL: https://codereview.chromium.org/460963002

Cr-Commit-Position: refs/heads/master@{#289622}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289622 0039d316-1c4b-4281-b951-d872f2087c98
parent b5ed0496
...@@ -41,33 +41,6 @@ chrome.fileBrowserPrivate = { ...@@ -41,33 +41,6 @@ chrome.fileBrowserPrivate = {
chrome.fileBrowserPrivate.onCopyProgress.listener_ = null; chrome.fileBrowserPrivate.onCopyProgress.listener_ = null;
}, },
listener_: null listener_: null
},
startCopy: function(source, destination, newName, callback) {
var id = 1;
var events = [
'begin_copy_entry',
'progress',
'end_copy_entry',
'success'
].map(function(type) {
return [id, {type: type, sourceUrl: source, destinationUrl: destination}];
});
var sendEvent = function(index) {
// Call the function asynchronously.
return Promise.resolve().then(function() {
chrome.fileBrowserPrivate.onCopyProgress.listener_.apply(
null, events[index]);
if (index + 1 < events.length)
return sendEvent(index + 1);
else
return null;
}.bind(this));
}.bind(this);
callback(id);
sendEvent(0).catch(function(error) {
console.log(error.stack || error);
window.onerror();
});
} }
}; };
...@@ -82,14 +55,82 @@ function reportPromise(promise, callback) { ...@@ -82,14 +55,82 @@ function reportPromise(promise, callback) {
callback.bind(null, false), callback.bind(null, false),
function(error) { function(error) {
if (error instanceof FileOperationManager.Error) { if (error instanceof FileOperationManager.Error) {
console.log('FileOperationManager.Error: code=' + error.code); console.error('FileOperationManager.Error: code=' + error.code);
} else { } else {
console.log(error.stack || error.name || error); console.error(error.stack || error.name || error);
} }
callback(true); callback(true);
}); });
} }
/**
* Size of directory.
* @type {number}
* @const
*/
var DIRECTORY_SIZE = -1;
/**
* Creates test file system.
* @param {string} id File system ID.
* @param {Object.<string, number>} entries Map of entries' paths and their
* size. If the size is equals to DIRECTORY_SIZE, the entry is derectory.
*/
function createTestFileSystem(id, entries) {
var fileSystem = new TestFileSystem(id);
for (var path in entries) {
if (entries[path] === DIRECTORY_SIZE) {
fileSystem.entries[path] = new MockDirectoryEntry(fileSystem, path);
} else {
fileSystem.entries[path] =
new MockFileEntry(fileSystem, path, {size: entries[path]});
}
}
return fileSystem;
}
/**
* Resolves URL on the file system.
* @param {FakeFileSystem} fileSystem Fake file system.
* @param {string} url URL.
* @param {function(MockEntry)} success Success callback.
* @param {function()} failure Failure callback.
*/
function resolveTestFileSystemURL(fileSystem, url, success, failure) {
for (var name in fileSystem.entries) {
var entry = fileSystem.entries[name];
if (entry.toURL() == url) {
success(entry);
return;
}
}
failure();
}
/**
* Waits for events until 'success'.
* @param {FileOperationManager} fileOperationManager File operation manager.
* @return {Promise} Promise to be fulfilled with an event list.
*/
function waitForEvents(fileOperationManager) {
return new Promise(function(fulfill) {
var events = [];
fileOperationManager.addEventListener('copy-progress', function(event) {
events.push(event);
if (event.reason === 'SUCCESS')
fulfill(events);
});
fileOperationManager.addEventListener('entry-changed', function(event) {
events.push(event);
});
fileOperationManager.addEventListener('delete', function(event) {
events.push(event);
if (event.reason === 'SUCCESS')
fulfill(events);
});
});
}
/** /**
* Test target. * Test target.
* @type {FileOperationManager} * @type {FileOperationManager}
...@@ -109,22 +150,18 @@ function setUp() { ...@@ -109,22 +150,18 @@ function setUp() {
* error. * error.
*/ */
function testResolvePath(callback) { function testResolvePath(callback) {
var fileEntry = new MockFileEntry('testVolume', '/file', {}); var fileSystem = createTestFileSystem('testVolume', {
var directoryEntry = new MockDirectoryEntry('testVolume', '/directory', {}); '/': DIRECTORY_SIZE,
var root = new MockDirectoryEntry('testVolume', '/', { '/file': 10,
'/file': fileEntry, '/directory': DIRECTORY_SIZE
'/directory': directoryEntry
}); });
var root = fileSystem.root;
var rootPromise = fileOperationUtil.resolvePath(root, '/'); var rootPromise = fileOperationUtil.resolvePath(root, '/');
var filePromise = fileOperationUtil.resolvePath(root, '/file'); var filePromise = fileOperationUtil.resolvePath(root, '/file');
var directoryPromise = fileOperationUtil.resolvePath(root, '/directory'); var directoryPromise = fileOperationUtil.resolvePath(root, '/directory');
var errorPromise = fileOperationUtil.resolvePath(root, '/not_found').then( var errorPromise = fileOperationUtil.resolvePath(root, '/not_found').then(
function() { function() { assertTrue(false, 'The NOT_FOUND error is not reported.'); },
assertTrue(false, 'The NOT_FOUND error is not reported.'); function(error) { return error.name; });
},
function(error) {
assertEquals('NotFoundError', error.name);
});
reportPromise(Promise.all([ reportPromise(Promise.all([
rootPromise, rootPromise,
filePromise, filePromise,
...@@ -132,10 +169,10 @@ function testResolvePath(callback) { ...@@ -132,10 +169,10 @@ function testResolvePath(callback) {
errorPromise errorPromise
]).then(function(results) { ]).then(function(results) {
assertArrayEquals([ assertArrayEquals([
root, fileSystem.entries['/'],
fileEntry, fileSystem.entries['/file'],
directoryEntry, fileSystem.entries['/directory'],
undefined 'NotFoundError'
], results); ], results);
}), callback); }), callback);
} }
...@@ -146,39 +183,37 @@ function testResolvePath(callback) { ...@@ -146,39 +183,37 @@ function testResolvePath(callback) {
* error. * error.
*/ */
function testDeduplicatePath(callback) { function testDeduplicatePath(callback) {
var directoryEntry1 = new MockDirectoryEntry('testVolume', '/directory', {}); var fileSystem1 = createTestFileSystem('testVolume', {'/': DIRECTORY_SIZE});
var directoryEntry2 = new MockDirectoryEntry( var fileSystem2 = createTestFileSystem('testVolume', {
'testVolume', '/': DIRECTORY_SIZE,
'/directory', '/file.txt': 10
{'file.txt': new MockFileEntry('testVolume', '/file.txt', {})}); });
var directoryEntry3 = new MockDirectoryEntry( var fileSystem3 = createTestFileSystem('testVolume', {
'testVolume', '/': DIRECTORY_SIZE,
'/directory', '/file.txt': 10,
{ '/file (1).txt': 10,
'file.txt': new MockFileEntry('testVolume', '/file.txt', {}), '/file (2).txt': 10,
'file (1).txt': new MockFileEntry('testVolume', '/file (1).txt', {}), '/file (3).txt': 10,
'file (2).txt': new MockFileEntry('testVolume', '/file (2).txt', {}), '/file (4).txt': 10,
'file (3).txt': new MockFileEntry('testVolume', '/file (3).txt', {}), '/file (5).txt': 10,
'file (4).txt': new MockFileEntry('testVolume', '/file (4).txt', {}), '/file (6).txt': 10,
'file (5).txt': new MockFileEntry('testVolume', '/file (5).txt', {}), '/file (7).txt': 10,
'file (6).txt': new MockFileEntry('testVolume', '/file (6).txt', {}), '/file (8).txt': 10,
'file (7).txt': new MockFileEntry('testVolume', '/file (7).txt', {}), '/file (9).txt': 10,
'file (8).txt': new MockFileEntry('testVolume', '/file (8).txt', {}), });
'file (9).txt': new MockFileEntry('testVolume', '/file (9).txt', {})
});
var nonExistingPromise = var nonExistingPromise =
fileOperationUtil.deduplicatePath(directoryEntry1, 'file.txt'). fileOperationUtil.deduplicatePath(fileSystem1.root, 'file.txt').
then(function(path) { then(function(path) {
assertEquals('file.txt', path); assertEquals('file.txt', path);
}); });
var existingPathPromise = var existingPathPromise =
fileOperationUtil.deduplicatePath(directoryEntry2, 'file.txt'). fileOperationUtil.deduplicatePath(fileSystem2.root, 'file.txt').
then(function(path) { then(function(path) {
assertEquals('file (1).txt', path); assertEquals('file (1).txt', path);
}); });
var failedPromise = var failedPromise =
fileOperationUtil.deduplicatePath(directoryEntry3, 'file.txt'). fileOperationUtil.deduplicatePath(fileSystem3.root, 'file.txt').
then(function() { then(function() {
assertTrue(false, 'FileOperationManager.Error is not reported.'); assertTrue(false, 'FileOperationManager.Error is not reported.');
}, function(error) { }, function(error) {
...@@ -196,33 +231,36 @@ function testDeduplicatePath(callback) { ...@@ -196,33 +231,36 @@ function testDeduplicatePath(callback) {
/** /**
* Tests the fileOperationUtil.paste. * Tests the fileOperationUtil.paste.
* @param {function(boolean:hasError)} callback Callback to be passed true on
* error.
*/ */
function testCopy(callback) { function testCopy(callback) {
// Prepare entries and their resolver. // Prepare entries and their resolver.
var sourceEntries = var fileSystem = createTestFileSystem('testVolume', {
[new MockFileEntry('testVolume', '/test.txt', {size: 10})]; '/': DIRECTORY_SIZE,
var targetEntry = new MockDirectoryEntry('testVolume', '/', {}); '/test.txt': 10,
window.webkitResolveLocalFileSystemURL = function(url, success, failure) { });
if (url === sourceEntries[0].toURL()) window.webkitResolveLocalFileSystemURL =
success(sourceEntries[0]); resolveTestFileSystemURL.bind(null, fileSystem);
else if (url === targetEntry.toURL())
success(targetEntry); chrome.fileBrowserPrivate.startCopy =
else function(source, destination, newName, callback) {
failure(); var makeStatus = function(type) {
}; return {type: type, sourceUrl: source, destinationUrl: destination};
};
callback(1);
var listener = chrome.fileBrowserPrivate.onCopyProgress.listener_;
listener(1, makeStatus('begin_copy_entry'));
listener(1, makeStatus('progress'));
var newPath = joinPath('/', newName);
fileSystem.entries[newPath] =
fileSystem.entries['/test.txt'].clone(newPath);
listener(1, makeStatus('end_copy_entry'));
listener(1, makeStatus('success'));
};
// Observing manager's events. // Observing manager's events.
var eventsPromise = new Promise(function(fulfill) { var eventsPromise = waitForEvents(fileOperationManager);
var events = [];
fileOperationManager.addEventListener('copy-progress', function(event) {
events.push(event);
if (event.reason === 'SUCCESS')
fulfill(events);
});
fileOperationManager.addEventListener('entry-changed', function(event) {
events.push(event);
});
});
// Verify the events. // Verify the events.
reportPromise(eventsPromise.then(function(events) { reportPromise(eventsPromise.then(function(events) {
...@@ -237,7 +275,159 @@ function testCopy(callback) { ...@@ -237,7 +275,159 @@ function testCopy(callback) {
assertEquals(0, lastEvent.status.numRemainingItems); assertEquals(0, lastEvent.status.numRemainingItems);
assertEquals(10, lastEvent.status.processedBytes); assertEquals(10, lastEvent.status.processedBytes);
assertEquals(10, lastEvent.status.totalBytes); assertEquals(10, lastEvent.status.totalBytes);
assertTrue(events.some(function(event) {
return event.type === 'entry-changed' &&
event.kind === util.EntryChangedKind.CREATED &&
event.entry.fullPath === '/test (1).txt';
}));
assertFalse(events.some(function(event) {
return event.type === 'delete';
}));
}), callback);
fileOperationManager.paste(
[fileSystem.entries['/test.txt']],
fileSystem.entries['/'],
false);
}
/**
* Tests the fileOperationUtil.paste for move.
* @param {function(boolean:hasError)} callback Callback to be passed true on
* error.
*/
function testMove(callback) {
// Prepare entries and their resolver.
var fileSystem = createTestFileSystem('testVolume', {
'/': DIRECTORY_SIZE,
'/directory': DIRECTORY_SIZE,
'/test.txt': 10,
});
window.webkitResolveLocalFileSystemURL =
resolveTestFileSystemURL.bind(null, fileSystem);
// Observing manager's events.
var eventsPromise = waitForEvents(fileOperationManager);
// Verify the events.
reportPromise(eventsPromise.then(function(events) {
var firstEvent = events[0];
assertEquals('BEGIN', firstEvent.reason);
assertEquals(1, firstEvent.status.numRemainingItems);
assertEquals(0, firstEvent.status.processedBytes);
assertEquals(1, firstEvent.status.totalBytes);
var lastEvent = events[events.length - 1];
assertEquals('SUCCESS', lastEvent.reason);
assertEquals(0, lastEvent.status.numRemainingItems);
assertEquals(1, lastEvent.status.processedBytes);
assertEquals(1, lastEvent.status.totalBytes);
assertTrue(events.some(function(event) {
return event.type === 'entry-changed' &&
event.kind === util.EntryChangedKind.DELETED &&
event.entry.fullPath === '/test.txt';
}));
assertTrue(events.some(function(event) {
return event.type === 'entry-changed' &&
event.kind === util.EntryChangedKind.CREATED &&
event.entry.fullPath === '/directory/test.txt';
}));
assertFalse(events.some(function(event) {
return event.type === 'delete';
}));
}), callback);
fileOperationManager.paste(
[fileSystem.entries['/test.txt']],
fileSystem.entries['/directory'],
true);
}
/**
* Tests the fileOperationUtil.deleteEntries.
* @param {function(boolean:hasError)} callback Callback to be passed true on
* error.
*/
function testDelete(callback) {
// Prepare entries and their resolver.
var fileSystem = createTestFileSystem('testVolume', {
'/': DIRECTORY_SIZE,
'/test.txt': 10,
});
window.webkitResolveLocalFileSystemURL =
resolveTestFileSystemURL.bind(null, fileSystem);
// Observing manager's events.
reportPromise(waitForEvents(fileOperationManager).then(function(events) {
assertEquals('delete', events[0].type);
assertEquals('BEGIN', events[0].reason);
assertEquals(10, events[0].totalBytes);
assertEquals(0, events[0].processedBytes);
var lastEvent = events[events.length - 1];
assertEquals('delete', lastEvent.type);
assertEquals('SUCCESS', lastEvent.reason);
assertEquals(10, lastEvent.totalBytes);
assertEquals(10, lastEvent.processedBytes);
assertFalse(events.some(function(event) {
return event.type === 'copy-progress';
}));
}), callback);
fileOperationManager.deleteEntries([fileSystem.entries['/test.txt']]);
}
/**
* Tests the fileOperationUtil.zipSelection.
* @param {function(boolean:hasError)} callback Callback to be passed true on
* error.
*/
function testZip(callback) {
// Prepare entries and their resolver.
var fileSystem = createTestFileSystem('testVolume', {
'/': DIRECTORY_SIZE,
'/test.txt': 10,
});
window.webkitResolveLocalFileSystemURL =
resolveTestFileSystemURL.bind(null, fileSystem);
chrome.fileBrowserPrivate.zipSelection =
function(parentURL, sources, newName, success, error) {
var newPath = joinPath('/', newName);
var newEntry = new MockFileEntry(fileSystem, newPath, {size: 10});
fileSystem.entries[newPath] = newEntry;
success(newEntry);
};
// Observing manager's events.
reportPromise(waitForEvents(fileOperationManager).then(function(events) {
assertEquals('copy-progress', events[0].type);
assertEquals('BEGIN', events[0].reason);
assertEquals(1, events[0].status.totalBytes);
assertEquals(0, events[0].status.processedBytes);
var lastEvent = events[events.length - 1];
assertEquals('copy-progress', lastEvent.type);
assertEquals('SUCCESS', lastEvent.reason);
assertEquals(10, lastEvent.status.totalBytes);
assertEquals(10, lastEvent.status.processedBytes);
assertFalse(events.some(function(event) {
return event.type === 'delete';
}));
assertTrue(events.some(function(event) {
return event.type === 'entry-changed' &&
event.entry.fullPath === '/test.zip';
}));
}), callback); }), callback);
fileOperationManager.paste(sourceEntries, targetEntry, false); fileOperationManager.zipSelection(
fileSystem.entries['/'],
[fileSystem.entries['/test.txt']]);
} }
...@@ -2,40 +2,130 @@ ...@@ -2,40 +2,130 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
/**
* Joins paths so that the two paths are connected by only 1 '/'.
* @param {string} a Path.
* @param {string} b Path.
* @return {string} Joined path.
*/
function joinPath(a, b) {
return a.replace(/\/+$/, '') + '/' + b.replace(/^\/+/, '');
};
/**
* Test file system.
*
* @param {string} fileSystemId File system ID.
* @constructor
*/
function TestFileSystem(fileSystemId) {
this.fileSystemId = fileSystemId;
this.entries = {};
};
TestFileSystem.prototype = {
get root() { return this.entries['/']; }
};
/** /**
* Base class of mock entries. * Base class of mock entries.
* *
* @param {string} volumeId ID of the volume that contains the entry. * @param {TestFileSystem} filesystem File system where the entry is localed.
* @param {string} fullpath Full path of the entry. * @param {string} fullpath Full path of the entry.
* @constructor * @constructor
*/ */
function MockEntry(volumeId, fullPath) { function MockEntry(filesystem, fullPath) {
this.volumeId = volumeId; this.filesystem = filesystem;
this.fullPath = fullPath; this.fullPath = fullPath;
} }
MockEntry.prototype = {
/**
* @return {string} Name of the entry.
*/
get name() {
return this.fullPath.replace(/^.*\//, '');
}
};
/** /**
* Returns fake URL. * Returns fake URL.
* *
* @return {string} Fake URL. * @return {string} Fake URL.
*/ */
MockEntry.prototype.toURL = function() { MockEntry.prototype.toURL = function() {
return 'filesystem:' + this.volumeId + this.fullPath; return 'filesystem:' + this.filesystem.fileSystemId + this.fullPath;
};
/**
* Obtains parent directory.
*
* @param {function(MockDirectoryEntry)} onSuccess Callback invoked with
* the parent directory.
* @param {function(Object)} onError Callback invoked with an error
* object.
*/
MockEntry.prototype.getParent = function(
onSuccess, onError) {
var path = this.fullPath.replace(/\/[^\/]+$/, '') || '/';
if (this.filesystem.entries[path])
onSuccess(this.filesystem.entries[path]);
else
onError({name: util.FileError.NOT_FOUND_ERR});
};
/**
* Moves the entry to the directory.
*
* @param {MockDirectoryEntry} parent Destination directory.
* @param {string=} opt_newName New name.
* @param {function(MockDirectoryEntry)} onSuccess Callback invoked with the
* moved entry.
* @param {function(Object)} onError Callback invoked with an error object.
*/
MockEntry.prototype.moveTo = function(parent, opt_newName, onSuccess, onError) {
Promise.resolve().then(function() {
this.filesystem.entries[this.fullPath] = null;
return this.clone(joinPath(parent.fullPath, opt_newName || this.name));
}.bind(this)).then(onSuccess, onError);
};
/**
* Removes the entry.
*
* @param {function()} onSuccess Success callback.
* @param {function(Object)} onError Callback invoked with an error object.
*/
MockEntry.prototype.remove = function(onSuccess, onError) {
Promise.resolve().then(function() {
this.filesystem.entries[this.fullPath] = null;
}.bind(this)).then(onSuccess, onError);
};
/**
* Clones the entry with the new fullpath.
*
* @param {string} fullpath New fullpath.
* @return {MockEntry} Cloned entry.
*/
MockEntry.prototype.clone = function(fullpath) {
throw new Error('Not implemented.');
}; };
/** /**
* Mock class for FileEntry. * Mock class for FileEntry.
* *
* @param {string} volumeId Id of the volume containing the entry. * @param {FileSystem} filesystem File system where the entry is localed.
* @param {string} fullPath Full path for the entry. * @param {string} fullPath Full path for the entry.
* @param {Object} metadata Metadata.
* @extends {MockEntry} * @extends {MockEntry}
* @constructor * @constructor
*/ */
function MockFileEntry(volumeId, fullPath, metadata) { function MockFileEntry(filesystem, fullPath, metadata) {
MockEntry.call(this, volumeId, fullPath); MockEntry.call(this, filesystem, fullPath);
this.volumeId = volumeId;
this.fullPath = fullPath;
this.metadata_ = metadata; this.metadata_ = metadata;
this.isFile = true;
this.isDirectory = false;
} }
MockFileEntry.prototype = { MockFileEntry.prototype = {
...@@ -53,41 +143,55 @@ MockFileEntry.prototype.getMetadata = function(callback) { ...@@ -53,41 +143,55 @@ MockFileEntry.prototype.getMetadata = function(callback) {
}); });
}; };
/**
* @override
*/
MockFileEntry.prototype.clone = function(path) {
return new MockFileEntry(this.filesystem, path, this.metadata);
};
/** /**
* Mock class for DirectoryEntry. * Mock class for DirectoryEntry.
* *
* @param {string} volumeId Id of the volume containing the entry. * @param {FileSystem} filesystem File system where the entry is localed.
* @param {string} fullPath Full path for the entry. * @param {string} fullPath Full path for the entry.
* @param {Object.<String, MockFileEntry|MockDirectoryEntry>} contents Map of
* path and MockEntry contained in the directory.
* @extends {MockEntry} * @extends {MockEntry}
* @constructor * @constructor
*/ */
function MockDirectoryEntry(volumeId, fullPath, contents) { function MockDirectoryEntry(filesystem, fullPath) {
MockEntry.call(this, volumeId, fullPath); MockEntry.call(this, filesystem, fullPath);
this.contents_ = contents; this.isFile = false;
this.isDirectory = true;
} }
MockDirectoryEntry.prototype = { MockDirectoryEntry.prototype = {
__proto__: MockEntry.prototype __proto__: MockEntry.prototype
}; };
/**
* @override
*/
MockDirectoryEntry.prototype.clone = function(path) {
return new MockDirectoryEntry(this.filesystem, path);
};
/** /**
* Returns a file under the directory. * Returns a file under the directory.
* *
* @param {string} path Path. * @param {string} path Path.
* @param {Object} option Option. * @param {Object} option Option.
* @param {callback(MockFileEntry)} successCallback Success callback. * @param {callback(MockFileEntry)} onSuccess Success callback.
* @param {callback(Object)} failureCallback Failure callback; * @param {callback(Object)} onError Failure callback;
*/ */
MockDirectoryEntry.prototype.getFile = function( MockDirectoryEntry.prototype.getFile = function(
path, option, successCallback, failureCallback) { path, option, onSuccess, onError) {
if (!this.contents_[path]) var fullPath = path[0] === '/' ? path : joinPath(this.fullPath, path);
failureCallback({name: util.FileError.NOT_FOUND_ERR}); if (!this.filesystem.entries[fullPath])
else if (!(this.contents_[path] instanceof MockFileEntry)) onError({name: util.FileError.NOT_FOUND_ERR});
failureCallback({name: util.FileError.TYPE_MISMATCH_ERR}); else if (!(this.filesystem.entries[fullPath] instanceof MockFileEntry))
onError({name: util.FileError.TYPE_MISMATCH_ERR});
else else
successCallback(this.contents_[path]); onSuccess(this.filesystem.entries[fullPath]);
}; };
/** /**
...@@ -95,15 +199,16 @@ MockDirectoryEntry.prototype.getFile = function( ...@@ -95,15 +199,16 @@ MockDirectoryEntry.prototype.getFile = function(
* *
* @param {string} path Path. * @param {string} path Path.
* @param {Object} option Option. * @param {Object} option Option.
* @param {callback(MockDirectoryEntry)} successCallback Success callback. * @param {callback(MockDirectoryEntry)} onSuccess Success callback.
* @param {callback(Object)} failureCallback Failure callback; * @param {callback(Object)} onError Failure callback;
*/ */
MockDirectoryEntry.prototype.getDirectory = MockDirectoryEntry.prototype.getDirectory =
function(path, option, successCallback, failureCallback) { function(path, option, onSuccess, onError) {
if (!this.contents_[path]) var fullPath = path[0] === '/' ? path : joinPath(this.fullPath, path);
failureCallback({name: util.FileError.NOT_FOUND_ERR}); if (!this.filesystem.entries[fullPath])
else if (!(this.contents_[path] instanceof MockDirectoryEntry)) onError({name: util.FileError.NOT_FOUND_ERR});
failureCallback({name: util.FileError.TYPE_MISMATCH_ERR}); else if (!(this.filesystem.entries[fullPath] instanceof MockDirectoryEntry))
onError({name: util.FileError.TYPE_MISMATCH_ERR});
else else
successCallback(this.contents_[path]); onSuccess(this.filesystem.entries[fullPath]);
}; };
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