1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 * Joins paths so that the two paths are connected by only 1 '/'.
7 * @param {string} a Path.
8 * @param {string} b Path.
9 * @return {string} Joined path.
11 function joinPath(a, b) {
12 return a.replace(/\/+$/, '') + '/' + b.replace(/^\/+/, '');
18 * @param {string} fileSystemId File system ID.
21 function TestFileSystem(fileSystemId) {
22 this.fileSystemId = fileSystemId;
26 TestFileSystem.prototype = {
27 get root() { return this.entries['/']; }
31 * Base class of mock entries.
33 * @param {TestFileSystem} filesystem File system where the entry is localed.
34 * @param {string} fullpath Full path of the entry.
37 function MockEntry(filesystem, fullPath) {
38 this.filesystem = filesystem;
39 this.fullPath = fullPath;
42 MockEntry.prototype = {
44 * @return {string} Name of the entry.
47 return this.fullPath.replace(/^.*\//, '');
54 * @return {string} Fake URL.
56 MockEntry.prototype.toURL = function() {
57 return 'filesystem:' + this.filesystem.fileSystemId + this.fullPath;
61 * Obtains parent directory.
63 * @param {function(MockDirectoryEntry)} onSuccess Callback invoked with
64 * the parent directory.
65 * @param {function(Object)} onError Callback invoked with an error
68 MockEntry.prototype.getParent = function(
70 var path = this.fullPath.replace(/\/[^\/]+$/, '') || '/';
71 if (this.filesystem.entries[path])
72 onSuccess(this.filesystem.entries[path]);
74 onError({name: util.FileError.NOT_FOUND_ERR});
78 * Moves the entry to the directory.
80 * @param {MockDirectoryEntry} parent Destination directory.
81 * @param {string=} opt_newName New name.
82 * @param {function(MockDirectoryEntry)} onSuccess Callback invoked with the
84 * @param {function(Object)} onError Callback invoked with an error object.
86 MockEntry.prototype.moveTo = function(parent, opt_newName, onSuccess, onError) {
87 Promise.resolve().then(function() {
88 this.filesystem.entries[this.fullPath] = null;
89 return this.clone(joinPath(parent.fullPath, opt_newName || this.name));
90 }.bind(this)).then(onSuccess, onError);
96 * @param {function()} onSuccess Success callback.
97 * @param {function(Object)} onError Callback invoked with an error object.
99 MockEntry.prototype.remove = function(onSuccess, onError) {
100 Promise.resolve().then(function() {
101 this.filesystem.entries[this.fullPath] = null;
102 }.bind(this)).then(onSuccess, onError);
106 * Clones the entry with the new fullpath.
108 * @param {string} fullpath New fullpath.
109 * @return {MockEntry} Cloned entry.
111 MockEntry.prototype.clone = function(fullpath) {
112 throw new Error('Not implemented.');
116 * Mock class for FileEntry.
118 * @param {FileSystem} filesystem File system where the entry is localed.
119 * @param {string} fullPath Full path for the entry.
120 * @param {Object} metadata Metadata.
121 * @extends {MockEntry}
124 function MockFileEntry(filesystem, fullPath, metadata) {
125 MockEntry.call(this, filesystem, fullPath);
126 this.metadata_ = metadata;
128 this.isDirectory = false;
131 MockFileEntry.prototype = {
132 __proto__: MockEntry.prototype
136 * Obtains metadata of the entry.
137 * @param {function(Object)} callback Function to take the metadata.
139 MockFileEntry.prototype.getMetadata = function(callback) {
140 Promise.resolve(this.metadata_).then(callback).catch(function(error) {
141 console.error(error.stack || error);
149 MockFileEntry.prototype.clone = function(path) {
150 return new MockFileEntry(this.filesystem, path, this.metadata);
154 * Mock class for DirectoryEntry.
156 * @param {FileSystem} filesystem File system where the entry is localed.
157 * @param {string} fullPath Full path for the entry.
158 * @extends {MockEntry}
161 function MockDirectoryEntry(filesystem, fullPath) {
162 MockEntry.call(this, filesystem, fullPath);
164 this.isDirectory = true;
167 MockDirectoryEntry.prototype = {
168 __proto__: MockEntry.prototype
174 MockDirectoryEntry.prototype.clone = function(path) {
175 return new MockDirectoryEntry(this.filesystem, path);
179 * Returns a file under the directory.
181 * @param {string} path Path.
182 * @param {Object} option Option.
183 * @param {callback(MockFileEntry)} onSuccess Success callback.
184 * @param {callback(Object)} onError Failure callback;
186 MockDirectoryEntry.prototype.getFile = function(
187 path, option, onSuccess, onError) {
188 var fullPath = path[0] === '/' ? path : joinPath(this.fullPath, path);
189 if (!this.filesystem.entries[fullPath])
190 onError({name: util.FileError.NOT_FOUND_ERR});
191 else if (!(this.filesystem.entries[fullPath] instanceof MockFileEntry))
192 onError({name: util.FileError.TYPE_MISMATCH_ERR});
194 onSuccess(this.filesystem.entries[fullPath]);
198 * Returns a directory under the directory.
200 * @param {string} path Path.
201 * @param {Object} option Option.
202 * @param {callback(MockDirectoryEntry)} onSuccess Success callback.
203 * @param {callback(Object)} onError Failure callback;
205 MockDirectoryEntry.prototype.getDirectory =
206 function(path, option, onSuccess, onError) {
207 var fullPath = path[0] === '/' ? path : joinPath(this.fullPath, path);
208 if (!this.filesystem.entries[fullPath])
209 onError({name: util.FileError.NOT_FOUND_ERR});
210 else if (!(this.filesystem.entries[fullPath] instanceof MockDirectoryEntry))
211 onError({name: util.FileError.TYPE_MISMATCH_ERR});
213 onSuccess(this.filesystem.entries[fullPath]);