openEventsPlatformApp/plugins/cordova-plugin-file/tests/tests.js
plugins/cordova-plugin-file/tests/tests.jsRaw
1/*
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *
19 */
20
21/* jshint jasmine: true */
22/* global WebKitBlobBuilder */
23
24exports.defineAutoTests = function () {
25 var isBrowser = (cordova.platformId === "browser");
26 // Use feature detection to determine current browser instead of checking user-agent
27 var isChrome = isBrowser && window.webkitRequestFileSystem && window.webkitResolveLocalFileSystemURL;
28 var isIE = isBrowser && (window.msIndexedDB);
29 var isIndexedDBShim = isBrowser && !isChrome; // Firefox and IE for example
30
31 var isWindows = (cordova.platformId === "windows" || cordova.platformId === "windows8");
32
33 var MEDIUM_TIMEOUT = 15000;
34
35 describe('File API', function () {
36 // Adding a Jasmine helper matcher, to report errors when comparing to FileError better.
37 var fileErrorMap = {
38 1 : 'NOT_FOUND_ERR',
39 2 : 'SECURITY_ERR',
40 3 : 'ABORT_ERR',
41 4 : 'NOT_READABLE_ERR',
42 5 : 'ENCODING_ERR',
43 6 : 'NO_MODIFICATION_ALLOWED_ERR',
44 7 : 'INVALID_STATE_ERR',
45 8 : 'SYNTAX_ERR',
46 9 : 'INVALID_MODIFICATION_ERR',
47 10 : 'QUOTA_EXCEEDED_ERR',
48 11 : 'TYPE_MISMATCH_ERR',
49 12 : 'PATH_EXISTS_ERR'
50 },
51 root,
52 temp_root,
53 persistent_root;
54 beforeEach(function (done) {
55 // Custom Matchers
56 jasmine.Expectation.addMatchers({
57 toBeFileError : function () {
58 return {
59 compare : function (error, code) {
60 var pass = error.code === code;
61 return {
62 pass : pass,
63 message : 'Expected FileError with code ' + fileErrorMap[error.code] + ' (' + error.code + ') to be ' + fileErrorMap[code] + '(' + code + ')'
64 };
65 }
66 };
67 },
68 toCanonicallyMatch : function () {
69 return {
70 compare : function (currentPath, path) {
71 var a = path.split("/").join("").split("\\").join(""),
72 b = currentPath.split("/").join("").split("\\").join(""),
73 pass = a === b;
74 return {
75 pass : pass,
76 message : 'Expected paths to match : ' + path + ' should be ' + currentPath
77 };
78 }
79 };
80 },
81 toFailWithMessage : function () {
82 return {
83 compare : function (error, message) {
84 var pass = false;
85 return {
86 pass : pass,
87 message : message
88 };
89 }
90 };
91 },
92 toBeDataUrl: function () {
93 return {
94 compare : function (url) {
95 var pass = false;
96 // "data:application/octet-stream;base64,"
97 var header = url.substr(0, url.indexOf(','));
98 var headerParts = header.split(/[:;]/);
99 if (headerParts.length === 3 &&
100 headerParts[0] === 'data' &&
101 headerParts[2] === 'base64') {
102 pass = true;
103 }
104 var message = 'Expected ' + url + ' to be a valid data url. ' + header + ' is not valid header for data uris';
105 return {
106 pass : pass,
107 message : message
108 };
109 }
110 };
111 }
112 });
113 //Define global variables
114 var onError = function (e) {
115 console.log('[ERROR] Problem setting up root filesystem for test running! Error to follow.');
116 console.log(JSON.stringify(e));
117 };
118 window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fileSystem) {
119 root = fileSystem.root;
120 // set in file.tests.js
121 persistent_root = root;
122 window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, function (fileSystem) {
123 temp_root = fileSystem.root;
124 // set in file.tests.js
125 done();
126 }, onError);
127 }, onError);
128 });
129 // HELPER FUNCTIONS
130 // deletes specified file or directory
131 var deleteEntry = function (name, success, error) {
132 // deletes entry, if it exists
133 // entry.remove success callback is required: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#the-entry-interface
134 success = success || function() {};
135 error = error || failed.bind(null, success, 'deleteEntry failed.');
136
137 window.resolveLocalFileSystemURL(root.toURL() + '/' + name, function (entry) {
138 if (entry.isDirectory === true) {
139 entry.removeRecursively(success, error);
140 } else {
141 entry.remove(success, error);
142 }
143 }, success);
144 };
145 // deletes file, if it exists, then invokes callback
146 var deleteFile = function (fileName, callback) {
147 // entry.remove success callback is required: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#the-entry-interface
148 callback = callback || function() {};
149
150 root.getFile(fileName, null, // remove file system entry
151 function (entry) {
152 entry.remove(callback, function () {
153 console.log('[ERROR] deleteFile cleanup method invoked fail callback.');
154 });
155 }, // doesn't exist
156 callback);
157 };
158 // deletes and re-creates the specified file
159 var createFile = function (fileName, success, error) {
160 deleteEntry(fileName, function () {
161 root.getFile(fileName, {
162 create : true
163 }, success, error);
164 }, error);
165 };
166 // deletes and re-creates the specified directory
167 var createDirectory = function (dirName, success, error) {
168 deleteEntry(dirName, function () {
169 root.getDirectory(dirName, {
170 create : true
171 }, success, error);
172 }, error);
173 };
174 function failed(done, msg, error) {
175 var info = typeof msg == 'undefined' ? 'Unexpected error callback' : msg;
176 var codeMsg = (error && error.code) ? (': ' + fileErrorMap[error.code]) : '';
177 expect(true).toFailWithMessage(info + '\n' + JSON.stringify(error) + codeMsg);
178 done();
179 }
180 var succeed = function (done, msg) {
181 var info = typeof msg == 'undefined' ? 'Unexpected success callback' : msg;
182 expect(true).toFailWithMessage(info);
183 done();
184 };
185 var joinURL = function (base, extension) {
186 if (base.charAt(base.length - 1) !== '/' && extension.charAt(0) !== '/') {
187 return base + '/' + extension;
188 }
189 if (base.charAt(base.length - 1) === '/' && extension.charAt(0) === '/') {
190 return base + extension.substring(1);
191 }
192 return base + extension;
193 };
194 describe('FileError object', function () {
195 it("file.spec.1 should define FileError constants", function () {
196 expect(FileError.NOT_FOUND_ERR).toBe(1);
197 expect(FileError.SECURITY_ERR).toBe(2);
198 expect(FileError.ABORT_ERR).toBe(3);
199 expect(FileError.NOT_READABLE_ERR).toBe(4);
200 expect(FileError.ENCODING_ERR).toBe(5);
201 expect(FileError.NO_MODIFICATION_ALLOWED_ERR).toBe(6);
202 expect(FileError.INVALID_STATE_ERR).toBe(7);
203 expect(FileError.SYNTAX_ERR).toBe(8);
204 expect(FileError.INVALID_MODIFICATION_ERR).toBe(9);
205 expect(FileError.QUOTA_EXCEEDED_ERR).toBe(10);
206 expect(FileError.TYPE_MISMATCH_ERR).toBe(11);
207 expect(FileError.PATH_EXISTS_ERR).toBe(12);
208 });
209 });
210 describe('LocalFileSystem', function () {
211 it("file.spec.2 should define LocalFileSystem constants", function () {
212 expect(LocalFileSystem.TEMPORARY).toBe(0);
213 expect(LocalFileSystem.PERSISTENT).toBe(1);
214 });
215 describe('window.requestFileSystem', function () {
216 it("file.spec.3 should be defined", function () {
217 expect(window.requestFileSystem).toBeDefined();
218 });
219 it("file.spec.4 should be able to retrieve a PERSISTENT file system", function (done) {
220 var win = function (fileSystem) {
221 expect(fileSystem).toBeDefined();
222 expect(fileSystem.name).toBeDefined();
223 if (isChrome) {
224 expect(fileSystem.name).toContain("Persistent");
225 } else {
226 expect(fileSystem.name).toBe("persistent");
227 }
228 expect(fileSystem.root).toBeDefined();
229 expect(fileSystem.root.filesystem).toBeDefined();
230 // Shouldn't use cdvfile by default.
231 expect(fileSystem.root.toURL()).not.toMatch(/^cdvfile:/);
232 // All DirectoryEntry URLs should always have a trailing slash.
233 expect(fileSystem.root.toURL()).toMatch(/\/$/);
234 done();
235 };
236
237 // Request a little bit of space on the filesystem, unless we're running in a browser where that could cause a prompt.
238 var spaceRequired = isBrowser ? 0 : 1024;
239
240 // retrieve PERSISTENT file system
241 window.requestFileSystem(LocalFileSystem.PERSISTENT, spaceRequired, win, failed.bind(null, done, 'window.requestFileSystem - Error retrieving PERSISTENT file system'));
242 });
243 it("file.spec.5 should be able to retrieve a TEMPORARY file system", function (done) {
244 var win = function (fileSystem) {
245 expect(fileSystem).toBeDefined();
246 if (isChrome) {
247 expect(fileSystem.name).toContain("Temporary");
248 } else {
249 expect(fileSystem.name).toBe("temporary");
250 }
251 expect(fileSystem.root).toBeDefined();
252 expect(fileSystem.root.filesystem).toBeDefined();
253 expect(fileSystem.root.filesystem).toBe(fileSystem);
254 done();
255 };
256 //retrieve TEMPORARY file system
257 window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, win, failed.bind(null, done, 'window.requestFileSystem - Error retrieving TEMPORARY file system'));
258 });
259 it("file.spec.6 should error if you request a file system that is too large", function (done) {
260 if (isBrowser) {
261 /*window.requestFileSystem TEMPORARY and PERSISTENT filesystem quota is not limited in Chrome.
262 Firefox filesystem size is not limited but every 50MB request user permission.
263 IE10 allows up to 10mb of combined AppCache and IndexedDB used in implementation
264 of filesystem without prompting, once you hit that level you will be asked if you
265 want to allow it to be increased up to a max of 250mb per site.
266 So `size` parameter for `requestFileSystem` function does not affect on filesystem in Firefox and IE.*/
267 pending();
268 }
269
270 var fail = function (error) {
271 expect(error).toBeDefined();
272 expect(error).toBeFileError(FileError.QUOTA_EXCEEDED_ERR);
273 done();
274 };
275 //win = createWin('window.requestFileSystem');
276 // Request the file system
277 window.requestFileSystem(LocalFileSystem.TEMPORARY, 1000000000000000, failed.bind(null, done, 'window.requestFileSystem - Error retrieving TEMPORARY file system'), fail);
278 });
279 it("file.spec.7 should error out if you request a file system that does not exist", function (done) {
280
281 var fail = function (error) {
282 expect(error).toBeDefined();
283 if (isChrome) {
284 /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of SYNTAX_ERR(code: 8)
285 on requesting of a non-existant filesystem.*/
286 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
287 } else {
288 expect(error).toBeFileError(FileError.SYNTAX_ERR);
289 }
290 done();
291 };
292 // Request the file system
293 window.requestFileSystem(-1, 0, succeed.bind(null, done, 'window.requestFileSystem'), fail);
294 });
295 });
296 describe('window.resolveLocalFileSystemURL', function () {
297 it("file.spec.8 should be defined", function () {
298 expect(window.resolveLocalFileSystemURL).toBeDefined();
299 });
300 it("file.spec.9 should resolve a valid file name", function (done) {
301 var fileName = 'file.spec.9';
302 var win = function (fileEntry) {
303 expect(fileEntry).toBeDefined();
304 expect(fileEntry.isFile).toBe(true);
305 expect(fileEntry.isDirectory).toBe(false);
306 expect(fileEntry.name).toCanonicallyMatch(fileName);
307 expect(fileEntry.toURL()).not.toMatch(/^cdvfile:/, 'should not use cdvfile URL');
308 expect(fileEntry.toURL()).not.toMatch(/\/$/, 'URL should not end with a slash');
309 // Clean-up
310 deleteEntry(fileName, done);
311 };
312 createFile(fileName, function (entry) {
313 window.resolveLocalFileSystemURL(entry.toURL(), win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving file URL: ' + entry.toURL()));
314 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName), failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
315 });
316 it("file.spec.9.1 should resolve a file even with a terminating slash", function (done) {
317 var fileName = 'file.spec.9.1';
318 var win = function (fileEntry) {
319 expect(fileEntry).toBeDefined();
320 expect(fileEntry.isFile).toBe(true);
321 expect(fileEntry.isDirectory).toBe(false);
322 expect(fileEntry.name).toCanonicallyMatch(fileName);
323 expect(fileEntry.toURL()).not.toMatch(/^cdvfile:/, 'should not use cdvfile URL');
324 expect(fileEntry.toURL()).not.toMatch(/\/$/, 'URL should not end with a slash');
325 // Clean-up
326 deleteEntry(fileName, done);
327 };
328 createFile(fileName, function (entry) {
329 var entryURL = entry.toURL() + '/';
330 window.resolveLocalFileSystemURL(entryURL, win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving file URL: ' + entryURL));
331 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName), failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
332 });
333 it("file.spec.9.5 should resolve a directory", function (done) {
334 var fileName = 'file.spec.9.5';
335 var win = function (fileEntry) {
336 expect(fileEntry).toBeDefined();
337 expect(fileEntry.isFile).toBe(false);
338 expect(fileEntry.isDirectory).toBe(true);
339 expect(fileEntry.name).toCanonicallyMatch(fileName);
340 expect(fileEntry.toURL()).not.toMatch(/^cdvfile:/, 'should not use cdvfile URL');
341 expect(fileEntry.toURL()).toMatch(/\/$/, 'URL end with a slash');
342 // cleanup
343 deleteEntry(fileName, done);
344 };
345 function gotDirectory(entry) {
346 // lookup file system entry
347 window.resolveLocalFileSystemURL(entry.toURL(), win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving directory URL: ' + entry.toURL()));
348 }
349 createDirectory(fileName, gotDirectory, failed.bind(null, done, 'createDirectory - Error creating directory: ' + fileName), failed.bind(null, done, 'createDirectory - Error creating directory: ' + fileName));
350 });
351 it("file.spec.9.6 should resolve a directory even without a terminating slash", function (done) {
352 var fileName = 'file.spec.9.6';
353 var win = function (fileEntry) {
354 expect(fileEntry).toBeDefined();
355 expect(fileEntry.isFile).toBe(false);
356 expect(fileEntry.isDirectory).toBe(true);
357 expect(fileEntry.name).toCanonicallyMatch(fileName);
358 expect(fileEntry.toURL()).not.toMatch(/^cdvfile:/, 'should not use cdvfile URL');
359 expect(fileEntry.toURL()).toMatch(/\/$/, 'URL end with a slash');
360 // cleanup
361 deleteEntry(fileName, done);
362 };
363 function gotDirectory(entry) {
364 // lookup file system entry
365 var entryURL = entry.toURL();
366 entryURL = entryURL.substring(0, entryURL.length - 1);
367 window.resolveLocalFileSystemURL(entryURL, win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving directory URL: ' + entryURL));
368 }
369 createDirectory(fileName, gotDirectory, failed.bind(null, done, 'createDirectory - Error creating directory: ' + fileName), failed.bind(null, done, 'createDirectory - Error creating directory: ' + fileName));
370 });
371
372 it("file.spec.9.7 should resolve a file with valid nativeURL", function (done) {
373 var fileName = "de.create.file",
374 win = function (entry) {
375 var path = entry.nativeURL.split('///')[1];
376 expect(/\/{2,}/.test(path)).toBeFalsy();
377 // cleanup
378 deleteEntry(entry.name, done);
379 };
380 root.getFile(fileName, {
381 create: true
382 }, win, succeed.bind(null, done, 'root.getFile - Error unexpected callback, file should not exists: ' + fileName));
383 });
384
385 it("file.spec.10 resolve valid file name with parameters", function (done) {
386 var fileName = "resolve.file.uri.params",
387 win = function (fileEntry) {
388 expect(fileEntry).toBeDefined();
389 if (fileEntry.toURL().toLowerCase().substring(0, 10) === "cdvfile://") {
390 expect(fileEntry.fullPath).toBe("/" + fileName + "?1234567890");
391 }
392 expect(fileEntry.name).toBe(fileName);
393 // cleanup
394 deleteEntry(fileName, done);
395 };
396 // create a new file entry
397 createFile(fileName, function (entry) {
398 window.resolveLocalFileSystemURL(entry.toURL() + "?1234567890", win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving file URI: ' + entry.toURL()));
399 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
400 });
401 it("file.spec.11 should error (NOT_FOUND_ERR) when resolving (non-existent) invalid file name", function (done) {
402 var fileName = cordova.platformId === 'windowsphone' ? root.toURL() + "/" + "this.is.not.a.valid.file.txt" : joinURL(root.toURL(), "this.is.not.a.valid.file.txt"),
403 fail = function (error) {
404 expect(error).toBeDefined();
405 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
406 done();
407 };
408 // lookup file system entry
409 window.resolveLocalFileSystemURL(fileName, succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Error unexpected callback resolving file URI: ' + fileName), fail);
410 });
411 it("file.spec.12 should error (ENCODING_ERR) when resolving invalid URI with leading /", function (done) {
412 var fileName = "/this.is.not.a.valid.url",
413 fail = function (error) {
414 expect(error).toBeDefined();
415 expect(error).toBeFileError(FileError.ENCODING_ERR);
416 done();
417 };
418 // lookup file system entry
419 window.resolveLocalFileSystemURL(fileName, succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Error unexpected callback resolving file URI: ' + fileName), fail);
420 });
421 });
422 });
423 //LocalFileSystem
424 describe('Metadata interface', function () {
425 it("file.spec.13 should exist and have the right properties", function () {
426 var metadata = new Metadata();
427 expect(metadata).toBeDefined();
428 expect(metadata.modificationTime).toBeDefined();
429 });
430 });
431 describe('Flags interface', function () {
432 it("file.spec.14 should exist and have the right properties", function () {
433 var flags = new Flags(false, true);
434 expect(flags).toBeDefined();
435 expect(flags.create).toBeDefined();
436 expect(flags.create).toBe(false);
437 expect(flags.exclusive).toBeDefined();
438 expect(flags.exclusive).toBe(true);
439 });
440 });
441 describe('FileSystem interface', function () {
442 it("file.spec.15 should have a root that is a DirectoryEntry", function (done) {
443 var win = function (entry) {
444 expect(entry).toBeDefined();
445 expect(entry.isFile).toBe(false);
446 expect(entry.isDirectory).toBe(true);
447 expect(entry.name).toBeDefined();
448 expect(entry.fullPath).toBeDefined();
449 expect(entry.getMetadata).toBeDefined();
450 expect(entry.moveTo).toBeDefined();
451 expect(entry.copyTo).toBeDefined();
452 expect(entry.toURL).toBeDefined();
453 expect(entry.remove).toBeDefined();
454 expect(entry.getParent).toBeDefined();
455 expect(entry.createReader).toBeDefined();
456 expect(entry.getFile).toBeDefined();
457 expect(entry.getDirectory).toBeDefined();
458 expect(entry.removeRecursively).toBeDefined();
459 done();
460 };
461 window.resolveLocalFileSystemURL(root.toURL(), win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving file URI: ' + root.toURL()));
462 });
463 });
464 describe('DirectoryEntry', function () {
465 it("file.spec.16 getFile: get Entry for file that does not exist", function (done) {
466 var fileName = "de.no.file",
467 fail = function (error) {
468 expect(error).toBeDefined();
469 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
470 done();
471 };
472 // create:false, exclusive:false, file does not exist
473 root.getFile(fileName, {
474 create : false
475 }, succeed.bind(null, done, 'root.getFile - Error unexpected callback, file should not exists: ' + fileName), fail);
476 });
477 it("file.spec.17 getFile: create new file", function (done) {
478 var fileName = "de.create.file",
479 filePath = joinURL(root.fullPath, fileName),
480 win = function (entry) {
481 expect(entry).toBeDefined();
482 expect(entry.isFile).toBe(true);
483 expect(entry.isDirectory).toBe(false);
484 expect(entry.name).toCanonicallyMatch(fileName);
485 expect(entry.fullPath).toCanonicallyMatch(filePath);
486 // cleanup
487 deleteEntry(entry.name, done);
488 };
489 // create:true, exclusive:false, file does not exist
490 root.getFile(fileName, {
491 create : true
492 }, win, succeed.bind(null, done, 'root.getFile - Error unexpected callback, file should not exists: ' + fileName));
493 });
494 it("file.spec.18 getFile: create new file (exclusive)", function (done) {
495 var fileName = "de.create.exclusive.file",
496 filePath = joinURL(root.fullPath, fileName),
497 win = function (entry) {
498 expect(entry).toBeDefined();
499 expect(entry.isFile).toBe(true);
500 expect(entry.isDirectory).toBe(false);
501 expect(entry.name).toBe(fileName);
502 expect(entry.fullPath).toCanonicallyMatch(filePath);
503 // cleanup
504 deleteEntry(entry.name, done);
505 };
506 // create:true, exclusive:true, file does not exist
507 root.getFile(fileName, {
508 create : true,
509 exclusive : true
510 }, win, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName));
511 });
512 it("file.spec.19 getFile: create file that already exists", function (done) {
513 var fileName = "de.create.existing.file",
514 filePath = joinURL(root.fullPath, fileName);
515
516 function win(entry) {
517 expect(entry).toBeDefined();
518 expect(entry.isFile).toBe(true);
519 expect(entry.isDirectory).toBe(false);
520 expect(entry.name).toCanonicallyMatch(fileName);
521 expect(entry.fullPath).toCanonicallyMatch(filePath);
522 // cleanup
523 deleteEntry(entry.name, done);
524 }
525
526 function getFile(file) {
527 // create:true, exclusive:false, file exists
528 root.getFile(fileName, {
529 create : true
530 }, win, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName));
531 }
532
533 // create file to kick off it
534 root.getFile(fileName, {
535 create : true
536 }, getFile, failed.bind(null, done, 'root.getFile - Error on initial creating file: ' + fileName));
537 });
538 it("file.spec.20 getFile: create file that already exists (exclusive)", function (done) {
539 var fileName = "de.create.exclusive.existing.file",
540 existingFile;
541
542 function fail(error) {
543 expect(error).toBeDefined();
544 if (isChrome) {
545 /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of PATH_EXISTS_ERR(code: 12)
546 on trying to exclusively create a file, which already exists in Chrome.*/
547 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
548 } else {
549 expect(error).toBeFileError(FileError.PATH_EXISTS_ERR);
550 }
551 // cleanup
552 deleteEntry(existingFile.name, done);
553 }
554
555 function getFile(file) {
556 existingFile = file;
557 // create:true, exclusive:true, file exists
558 root.getFile(fileName, {
559 create : true,
560 exclusive : true
561 }, succeed.bind(null, done, 'root.getFile - getFile function - Error unexpected callback, file should exists: ' + fileName), fail);
562 }
563
564 // create file to kick off it
565 root.getFile(fileName, {
566 create : true
567 }, getFile, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName));
568 });
569 it("file.spec.21 DirectoryEntry.getFile: get Entry for existing file", function (done) {
570 var fileName = "de.get.file",
571 filePath = joinURL(root.fullPath, fileName),
572 win = function (entry) {
573 expect(entry).toBeDefined();
574 expect(entry.isFile).toBe(true);
575 expect(entry.isDirectory).toBe(false);
576 expect(entry.name).toCanonicallyMatch(fileName);
577 expect(entry.fullPath).toCanonicallyMatch(filePath);
578 expect(entry.filesystem).toBeDefined();
579 expect(entry.filesystem).toBe(root.filesystem);
580 //clean up
581 deleteEntry(entry.name, done);
582 },
583 getFile = function (file) {
584 // create:false, exclusive:false, file exists
585 root.getFile(fileName, {
586 create : false
587 }, win, failed.bind(null, done, 'root.getFile - Error getting file entry: ' + fileName));
588 };
589 // create file to kick off it
590 root.getFile(fileName, {
591 create : true
592 }, getFile, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName));
593 });
594 it("file.spec.22 DirectoryEntry.getFile: get FileEntry for invalid path", function (done) {
595 if (isBrowser) {
596 /*The plugin does not follow to ["8.3 Naming restrictions"]
597 (http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions).*/
598 pending();
599 }
600
601 var fileName = "de:invalid:path",
602 fail = function (error) {
603 expect(error).toBeDefined();
604 expect(error).toBeFileError(FileError.ENCODING_ERR);
605 done();
606 };
607 // create:false, exclusive:false, invalid path
608 root.getFile(fileName, {
609 create : false
610 }, succeed.bind(null, done, 'root.getFile - Error unexpected callback, file should not exists: ' + fileName), fail);
611 });
612 it("file.spec.23 DirectoryEntry.getDirectory: get Entry for directory that does not exist", function (done) {
613 var dirName = "de.no.dir",
614 fail = function (error) {
615 expect(error).toBeDefined();
616 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
617 done();
618 };
619 // create:false, exclusive:false, directory does not exist
620 root.getDirectory(dirName, {
621 create : false
622 }, succeed.bind(null, done, 'root.getDirectory - Error unexpected callback, directory should not exists: ' + dirName), fail);
623 });
624 it("file.spec.24 DirectoryEntry.getDirectory: create new dir with space then resolveLocalFileSystemURL", function (done) {
625 var dirName = "de create dir";
626
627 function win(directory) {
628 expect(directory).toBeDefined();
629 expect(directory.isFile).toBe(false);
630 expect(directory.isDirectory).toBe(true);
631 expect(directory.name).toCanonicallyMatch(dirName);
632 expect(directory.fullPath).toCanonicallyMatch(joinURL(root.fullPath, dirName));
633 // cleanup
634 deleteEntry(directory.name, done);
635 }
636
637 function getDir(dirEntry) {
638 expect(dirEntry.filesystem).toBeDefined();
639 expect(dirEntry.filesystem).toBe(root.filesystem);
640 var dirURI = dirEntry.toURL();
641 // now encode URI and try to resolve
642 window.resolveLocalFileSystemURL(dirURI, win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - getDir function - Error resolving directory: ' + dirURI));
643 }
644
645 // create:true, exclusive:false, directory does not exist
646 root.getDirectory(dirName, {
647 create : true
648 }, getDir, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));
649 });
650 // This test is excluded, and should probably be removed. Filesystem
651 // should always be properly encoded URLs, and *not* raw paths, and it
652 // doesn't make sense to double-encode the URLs and expect that to be
653 // handled by the implementation.
654 // If a particular platform uses paths internally rather than URLs, // then that platform should careful to pass them correctly to its
655 // backend.
656 xit("file.spec.25 DirectoryEntry.getDirectory: create new dir with space resolveLocalFileSystemURL with encoded URI", function (done) {
657 var dirName = "de create dir2",
658 dirPath = joinURL(root.fullPath, dirName);
659
660 function win(directory) {
661 expect(directory).toBeDefined();
662 expect(directory.isFile).toBe(false);
663 expect(directory.isDirectory).toBe(true);
664 expect(directory.name).toCanonicallyMatch(dirName);
665 expect(directory.fullPath).toCanonicallyMatch(dirPath);
666 // cleanup
667 deleteEntry(directory.name, done);
668 }
669
670 function getDir(dirEntry) {
671 var dirURI = dirEntry.toURL();
672 // now encode URI and try to resolve
673 window.resolveLocalFileSystemURL(encodeURI(dirURI), win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - getDir function - Error resolving directory: ' + dirURI));
674 }
675
676 // create:true, exclusive:false, directory does not exist
677 root.getDirectory(dirName, {
678 create : true
679 }, getDir, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));
680 });
681 it("file.spec.26 DirectoryEntry.getDirectory: create new directory", function (done) {
682 var dirName = "de.create.dir",
683 dirPath = joinURL(root.fullPath, dirName),
684 win = function (directory) {
685 expect(directory).toBeDefined();
686 expect(directory.isFile).toBe(false);
687 expect(directory.isDirectory).toBe(true);
688 expect(directory.name).toCanonicallyMatch(dirName);
689 expect(directory.fullPath).toCanonicallyMatch(dirPath);
690 expect(directory.filesystem).toBeDefined();
691 expect(directory.filesystem).toBe(root.filesystem);
692 // cleanup
693 deleteEntry(directory.name, done);
694 };
695 // create:true, exclusive:false, directory does not exist
696 root.getDirectory(dirName, {
697 create : true
698 }, win, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));
699 });
700 it("file.spec.27 DirectoryEntry.getDirectory: create new directory (exclusive)", function (done) {
701 var dirName = "de.create.exclusive.dir",
702 dirPath = joinURL(root.fullPath, dirName),
703 win = function (directory) {
704 expect(directory).toBeDefined();
705 expect(directory.isFile).toBe(false);
706 expect(directory.isDirectory).toBe(true);
707 expect(directory.name).toCanonicallyMatch(dirName);
708 expect(directory.fullPath).toCanonicallyMatch(dirPath);
709 expect(directory.filesystem).toBeDefined();
710 expect(directory.filesystem).toBe(root.filesystem);
711 // cleanup
712 deleteEntry(directory.name, done);
713 };
714 // create:true, exclusive:true, directory does not exist
715 root.getDirectory(dirName, {
716 create : true,
717 exclusive : true
718 }, win, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));
719 });
720 it("file.spec.28 DirectoryEntry.getDirectory: create directory that already exists", function (done) {
721 var dirName = "de.create.existing.dir",
722 dirPath = joinURL(root.fullPath, dirName),
723 win = function (directory) {
724 expect(directory).toBeDefined();
725 expect(directory.isFile).toBe(false);
726 expect(directory.isDirectory).toBe(true);
727 expect(directory.name).toCanonicallyMatch(dirName);
728 expect(directory.fullPath).toCanonicallyMatch(dirPath);
729 // cleanup
730 deleteEntry(directory.name, done);
731 };
732 // create directory to kick off it
733 root.getDirectory(dirName, {
734 create : true
735 }, function () {
736 root.getDirectory(dirName, {
737 create : true
738 }, win, failed.bind(null, done, 'root.getDirectory - Error creating existent second directory : ' + dirName));
739 }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));
740 });
741 it("file.spec.29 DirectoryEntry.getDirectory: create directory that already exists (exclusive)", function (done) {
742
743 var dirName = "de.create.exclusive.existing.dir",
744 existingDir,
745 fail = function (error) {
746 expect(error).toBeDefined();
747 if (isChrome) {
748 /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of PATH_EXISTS_ERR(code: 12)
749 on trying to exclusively create a file or directory, which already exists (Chrome).*/
750 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
751 } else {
752 expect(error).toBeFileError(FileError.PATH_EXISTS_ERR);
753 }
754 // cleanup
755 deleteEntry(existingDir.name, done);
756 };
757 // create directory to kick off it
758 root.getDirectory(dirName, {
759 create : true
760 }, function (directory) {
761 existingDir = directory;
762 // create:true, exclusive:true, directory exists
763 root.getDirectory(dirName, {
764 create : true,
765 exclusive : true
766 }, failed.bind(null, done, 'root.getDirectory - Unexpected success callback, second directory should not be created : ' + dirName), fail);
767 }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));
768 });
769 it("file.spec.30 DirectoryEntry.getDirectory: get Entry for existing directory", function (done) {
770 var dirName = "de.get.dir",
771 dirPath = joinURL(root.fullPath, dirName),
772 win = function (directory) {
773 expect(directory).toBeDefined();
774 expect(directory.isFile).toBe(false);
775 expect(directory.isDirectory).toBe(true);
776 expect(directory.name).toCanonicallyMatch(dirName);
777 expect(directory.fullPath).toCanonicallyMatch(dirPath);
778 // cleanup
779 deleteEntry(directory.name, done);
780 };
781 // create directory to kick it off
782 root.getDirectory(dirName, {
783 create : true
784 }, function () {
785 root.getDirectory(dirName, {
786 create : false
787 }, win, failed.bind(null, done, 'root.getDirectory - Error getting directory entry : ' + dirName));
788 }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));
789 });
790 it("file.spec.31 DirectoryEntry.getDirectory: get DirectoryEntry for invalid path", function (done) {
791 if (isBrowser) {
792 /*The plugin does not follow to ["8.3 Naming restrictions"]
793 (http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions).*/
794 pending();
795 }
796
797 var dirName = "de:invalid:path",
798 fail = function (error) {
799 expect(error).toBeDefined();
800 expect(error).toBeFileError(FileError.ENCODING_ERR);
801 done();
802 };
803 // create:false, exclusive:false, invalid path
804 root.getDirectory(dirName, {
805 create : false
806 }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, directory should not exists: ' + dirName), fail);
807 });
808 it("file.spec.32 DirectoryEntry.getDirectory: get DirectoryEntry for existing file", function (done) {
809 var fileName = "de.existing.file",
810 existingFile,
811 fail = function (error) {
812 expect(error).toBeDefined();
813 expect(error).toBeFileError(FileError.TYPE_MISMATCH_ERR);
814 // cleanup
815 deleteEntry(existingFile.name, done);
816 };
817 // create file to kick off it
818 root.getFile(fileName, {
819 create : true
820 }, function (file) {
821 existingFile = file;
822 root.getDirectory(fileName, {
823 create : false
824 }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, directory should not exists: ' + fileName), fail);
825 }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName));
826 });
827 it("file.spec.33 DirectoryEntry.getFile: get FileEntry for existing directory", function (done) {
828 var dirName = "de.existing.dir",
829 existingDir,
830 fail = function (error) {
831 expect(error).toBeDefined();
832 expect(error).toBeFileError(FileError.TYPE_MISMATCH_ERR);
833 // cleanup
834 deleteEntry(existingDir.name, done);
835 };
836 // create directory to kick off it
837 root.getDirectory(dirName, {
838 create : true
839 }, function (directory) {
840 existingDir = directory;
841 root.getFile(dirName, {
842 create : false
843 }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, file should not exists: ' + dirName), fail);
844 }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));
845 });
846 it("file.spec.34 DirectoryEntry.removeRecursively on directory", function (done) {
847 var dirName = "de.removeRecursively",
848 subDirName = "dir",
849 dirExists = function (error) {
850 expect(error).toBeDefined();
851 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
852 done();
853 };
854 // create a new directory entry to kick off it
855 root.getDirectory(dirName, {
856 create : true
857 }, function (entry) {
858 entry.getDirectory(subDirName, {
859 create : true
860 }, function (dir) {
861 entry.removeRecursively(function () {
862 root.getDirectory(dirName, {
863 create : false
864 }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, directory should not exists: ' + dirName), dirExists);
865 }, failed.bind(null, done, 'entry.removeRecursively - Error removing directory recursively : ' + dirName));
866 }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + subDirName));
867 }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));
868 });
869 it("file.spec.35 createReader: create reader on existing directory", function () {
870 // create reader for root directory
871 var reader = root.createReader();
872 expect(reader).toBeDefined();
873 expect(typeof reader.readEntries).toBe('function');
874 });
875 it("file.spec.36 removeRecursively on root file system", function (done) {
876
877 var remove = function (error) {
878 expect(error).toBeDefined();
879 if (isChrome) {
880 /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of
881 NO_MODIFICATION_ALLOWED_ERR(code: 6) on trying to call removeRecursively
882 on the root file system (Chrome).*/
883 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
884 } else {
885 expect(error).toBeFileError(FileError.NO_MODIFICATION_ALLOWED_ERR);
886 }
887 done();
888 };
889 // remove root file system
890 root.removeRecursively(succeed.bind(null, done, 'root.removeRecursively - Unexpected success callback, root cannot be removed'), remove);
891 });
892 });
893 describe('DirectoryReader interface', function () {
894 describe("readEntries", function () {
895 it("file.spec.37 should read contents of existing directory", function (done) {
896 var reader,
897 win = function (entries) {
898 expect(entries).toBeDefined();
899 expect(entries instanceof Array).toBe(true);
900 done();
901 };
902 // create reader for root directory
903 reader = root.createReader();
904 // read entries
905 reader.readEntries(win, failed.bind(null, done, 'reader.readEntries - Error reading entries'));
906 });
907 it("file.spec.37.1 should read contents of existing directory", function (done) {
908 var dirName = 'readEntries.dir',
909 fileName = 'readeEntries.file';
910 root.getDirectory(dirName, {
911 create : true
912 }, function (directory) {
913 directory.getFile(fileName, {
914 create : true
915 }, function (fileEntry) {
916 var reader = directory.createReader();
917 reader.readEntries(function (entries) {
918 expect(entries).toBeDefined();
919 expect(entries instanceof Array).toBe(true);
920 expect(entries.length).toBe(1);
921 expect(entries[0].fullPath).toCanonicallyMatch(fileEntry.fullPath);
922 expect(entries[0].filesystem).not.toBe(null);
923 if (isChrome) {
924 // Slicing '[object {type}]' -> '{type}'
925 expect(entries[0].filesystem.toString().slice(8, -1)).toEqual("DOMFileSystem");
926 }
927 else {
928 expect(entries[0].filesystem instanceof FileSystem).toBe(true);
929 }
930
931 // cleanup
932 deleteEntry(directory.name, done);
933 }, failed.bind(null, done, 'reader.readEntries - Error reading entries from directory: ' + dirName));
934 }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + fileName));
935 }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));
936 });
937 it("file.spec.109 should return an empty entry list on the second call", function (done) {
938 var reader,
939 fileName = 'test109.txt';
940 // Add a file to ensure the root directory is non-empty and then read the contents of the directory.
941 root.getFile(fileName, {
942 create : true
943 }, function (entry) {
944 reader = root.createReader();
945 //First read
946 reader.readEntries(function (entries) {
947 expect(entries).toBeDefined();
948 expect(entries instanceof Array).toBe(true);
949 expect(entries.length).not.toBe(0);
950 //Second read
951 reader.readEntries(function (entries_) {
952 expect(entries_).toBeDefined();
953 expect(entries_ instanceof Array).toBe(true);
954 expect(entries_.length).toBe(0);
955 //Clean up
956 deleteEntry(entry.name, done);
957 }, failed.bind(null, done, 'reader.readEntries - Error during SECOND reading of entries from [root] directory'));
958 }, failed.bind(null, done, 'reader.readEntries - Error during FIRST reading of entries from [root] directory'));
959 }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName));
960 });
961 });
962 it("file.spec.38 should read contents of directory that has been removed", function (done) {
963 var dirName = "de.createReader.notfound";
964 // create a new directory entry to kick off it
965 root.getDirectory(dirName, {
966 create : true
967 }, function (directory) {
968 directory.removeRecursively(function () {
969 var reader = directory.createReader();
970 reader.readEntries(succeed.bind(null, done, 'reader.readEntries - Unexpected success callback, it should not read entries from deleted dir: ' + dirName), function (error) {
971 expect(error).toBeDefined();
972 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
973 root.getDirectory(dirName, {
974 create : false
975 }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, it should not get deleted directory: ' + dirName), function (err) {
976 expect(err).toBeDefined();
977 expect(err).toBeFileError(FileError.NOT_FOUND_ERR);
978 done();
979 });
980 });
981 }, failed.bind(null, done, 'directory.removeRecursively - Error removing directory recursively : ' + dirName));
982 }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));
983 });
984 });
985 //DirectoryReader interface
986 describe('File', function () {
987 it("file.spec.39 constructor should be defined", function () {
988 expect(File).toBeDefined();
989 expect(typeof File).toBe('function');
990 });
991 it("file.spec.40 should be define File attributes", function () {
992 var file = new File();
993 expect(file.name).toBeDefined();
994 expect(file.type).toBeDefined();
995 expect(file.lastModifiedDate).toBeDefined();
996 expect(file.size).toBeDefined();
997 });
998 });
999 //File
1000 describe('FileEntry', function () {
1001
1002 it("file.spec.41 should be define FileEntry methods", function (done) {
1003 var fileName = "fe.methods",
1004 testFileEntry = function (fileEntry) {
1005 expect(fileEntry).toBeDefined();
1006 expect(typeof fileEntry.createWriter).toBe('function');
1007 expect(typeof fileEntry.file).toBe('function');
1008 // cleanup
1009 deleteEntry(fileEntry.name, done);
1010 };
1011 // create a new file entry to kick off it
1012 root.getFile(fileName, {
1013 create : true
1014 }, testFileEntry, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName));
1015 });
1016 it("file.spec.42 createWriter should return a FileWriter object", function (done) {
1017 var fileName = "fe.createWriter",
1018 testFile,
1019 testWriter = function (writer) {
1020 expect(writer).toBeDefined();
1021 if (isChrome) {
1022 // Slicing '[object {type}]' -> '{type}'
1023 expect(writer.toString().slice(8, -1)).toEqual("FileWriter");
1024 }
1025 else {
1026 expect(writer instanceof FileWriter).toBe(true);
1027 }
1028
1029 // cleanup
1030 deleteEntry(testFile.name, done);
1031 };
1032 // create a new file entry to kick off it
1033 root.getFile(fileName, {
1034 create : true
1035 }, function (fileEntry) {
1036 testFile = fileEntry;
1037 fileEntry.createWriter(testWriter, failed.bind(null, done, 'fileEntry.createWriter - Error creating Writer from entry'));
1038 }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName));
1039 });
1040 it("file.spec.43 file should return a File object", function (done) {
1041 var fileName = "fe.file",
1042 newFile,
1043 testFile = function (file) {
1044 expect(file).toBeDefined();
1045 if (isChrome) {
1046 // Slicing '[object {type}]' -> '{type}'
1047 expect(file.toString().slice(8, -1)).toEqual("File");
1048 }
1049 else {
1050 expect(file instanceof File).toBe(true);
1051 }
1052
1053 // cleanup
1054 deleteEntry(newFile.name, done);
1055 };
1056 // create a new file entry to kick off it
1057 root.getFile(fileName, {
1058 create : true
1059 }, function (fileEntry) {
1060 newFile = fileEntry;
1061 fileEntry.file(testFile, failed.bind(null, done, 'fileEntry.file - Error reading file using fileEntry: ' + fileEntry.name));
1062 }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName));
1063 });
1064 it("file.spec.44 file: on File that has been removed", function (done) {
1065 var fileName = "fe.no.file";
1066 // create a new file entry to kick off it
1067 root.getFile(fileName, {
1068 create : true
1069 }, function (fileEntry) {
1070 fileEntry.remove(function () {
1071 fileEntry.file(succeed.bind(null, done, 'fileEntry.file - Unexpected success callback, file it should not be created from removed entry'), function (error) {
1072 expect(error).toBeDefined();
1073 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
1074 done();
1075 });
1076 }, failed.bind(null, done, 'fileEntry.remove - Error removing entry : ' + fileName));
1077 }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName));
1078 });
1079 });
1080 //FileEntry
1081 describe('Entry', function () {
1082 it("file.spec.45 Entry object", function (done) {
1083 var fileName = "entry",
1084 fullPath = joinURL(root.fullPath, fileName),
1085 winEntry = function (entry) {
1086 expect(entry).toBeDefined();
1087 expect(entry.isFile).toBe(true);
1088 expect(entry.isDirectory).toBe(false);
1089 expect(entry.name).toCanonicallyMatch(fileName);
1090 expect(entry.fullPath).toCanonicallyMatch(fullPath);
1091 expect(typeof entry.getMetadata).toBe('function');
1092 expect(typeof entry.setMetadata).toBe('function');
1093 expect(typeof entry.moveTo).toBe('function');
1094 expect(typeof entry.copyTo).toBe('function');
1095 expect(typeof entry.toURL).toBe('function');
1096 expect(typeof entry.remove).toBe('function');
1097 expect(typeof entry.getParent).toBe('function');
1098 expect(typeof entry.createWriter).toBe('function');
1099 expect(typeof entry.file).toBe('function');
1100 // Clean up
1101 deleteEntry(fileName, done);
1102 };
1103 // create a new file entry
1104 createFile(fileName, winEntry, failed.bind(null, done, 'createFile - Error creating file : ' + fileName));
1105 });
1106 it("file.spec.46 Entry.getMetadata on file", function (done) {
1107 var fileName = "entry.metadata.file";
1108 // create a new file entry
1109 createFile(fileName, function (entry) {
1110 entry.getMetadata(function (metadata) {
1111 expect(metadata).toBeDefined();
1112 expect(metadata.modificationTime instanceof Date).toBe(true);
1113 expect(typeof metadata.size).toBe("number");
1114 // cleanup
1115 deleteEntry(fileName, done);
1116 }, failed.bind(null, done, 'entry.getMetadata - Error getting metadata from entry : ' + fileName));
1117 }, failed.bind(null, done, 'createFile - Error creating file : ' + fileName));
1118 });
1119 it("file.spec.47 Entry.getMetadata on directory", function (done) {
1120 if (isIndexedDBShim) {
1121 /* Does not support metadata for directories (Firefox, IE) */
1122 pending();
1123 }
1124
1125 var dirName = "entry.metadata.dir";
1126 // create a new directory entry
1127 createDirectory(dirName, function (entry) {
1128 entry.getMetadata(function (metadata) {
1129 expect(metadata).toBeDefined();
1130 expect(metadata.modificationTime instanceof Date).toBe(true);
1131 expect(typeof metadata.size).toBe("number");
1132 expect(metadata.size).toBe(0);
1133 // cleanup
1134 deleteEntry(dirName, done);
1135 }, failed.bind(null, done, 'entry.getMetadata - Error getting metadata from entry : ' + dirName));
1136 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName));
1137 });
1138 it("file.spec.48 Entry.getParent on file in root file system", function (done) {
1139 var fileName = "entry.parent.file",
1140 rootPath = root.fullPath;
1141 // create a new file entry
1142 createFile(fileName, function (entry) {
1143 entry.getParent(function (parent) {
1144 expect(parent).toBeDefined();
1145 expect(parent.fullPath).toCanonicallyMatch(rootPath);
1146 // cleanup
1147 deleteEntry(fileName, done);
1148 }, failed.bind(null, done, 'entry.getParent - Error getting parent directory of file : ' + fileName));
1149 }, failed.bind(null, done, 'createFile - Error creating file : ' + fileName));
1150 });
1151 it("file.spec.49 Entry.getParent on directory in root file system", function (done) {
1152 var dirName = "entry.parent.dir",
1153 rootPath = root.fullPath;
1154 // create a new directory entry
1155 createDirectory(dirName, function (entry) {
1156 entry.getParent(function (parent) {
1157 expect(parent).toBeDefined();
1158 expect(parent.fullPath).toCanonicallyMatch(rootPath);
1159 // cleanup
1160 deleteEntry(dirName, done);
1161 }, failed.bind(null, done, 'entry.getParent - Error getting parent directory of directory : ' + dirName));
1162 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName));
1163 });
1164 it("file.spec.50 Entry.getParent on root file system", function (done) {
1165 var rootPath = root.fullPath,
1166 winParent = function (parent) {
1167 expect(parent).toBeDefined();
1168 expect(parent.fullPath).toCanonicallyMatch(rootPath);
1169 done();
1170 };
1171 // create a new directory entry
1172 root.getParent(winParent, failed.bind(null, done, 'root.getParent - Error getting parent directory of root'));
1173 });
1174 it("file.spec.51 Entry.toURL on file", function (done) {
1175 var fileName = "entry.uri.file",
1176 rootPath = root.fullPath,
1177 winURI = function (entry) {
1178 var uri = entry.toURL();
1179 expect(uri).toBeDefined();
1180 expect(uri.indexOf(rootPath)).not.toBe(-1);
1181 // cleanup
1182 deleteEntry(fileName, done);
1183 };
1184 // create a new file entry
1185 createFile(fileName, winURI, failed.bind(null, done, 'createFile - Error creating file : ' + fileName));
1186 });
1187 it("file.spec.52 Entry.toURL on directory", function (done) {
1188 var dirName_1 = "num 1",
1189 dirName_2 = "num 2",
1190 rootPath = root.fullPath;
1191 createDirectory(dirName_1, function (entry) {
1192 entry.getDirectory(dirName_2, {
1193 create : true
1194 }, function (entryFile) {
1195 var uri = entryFile.toURL();
1196 expect(uri).toBeDefined();
1197 expect(uri).toContain('/num%201/num%202/');
1198 expect(uri.indexOf(rootPath)).not.toBe(-1);
1199 // cleanup
1200 deleteEntry(dirName_1, done);
1201 }, failed.bind(null, done, 'entry.getDirectory - Error creating directory : ' + dirName_2));
1202 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName_1));
1203 });
1204 it("file.spec.53 Entry.remove on file", function (done) {
1205 var fileName = "entr .rm.file";
1206 // create a new file entry
1207 createFile(fileName, function (entry) {
1208 expect(entry).toBeDefined();
1209 entry.remove(function () {
1210 root.getFile(fileName, null, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not get deleted file : ' + fileName), function (error) {
1211 expect(error).toBeDefined();
1212 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
1213 // cleanup
1214 deleteEntry(fileName, done);
1215 });
1216 }, failed.bind(null, done, 'entry.remove - Error removing entry : ' + fileName));
1217 }, failed.bind(null, done, 'createFile - Error creating file : ' + fileName));
1218 });
1219 it("file.spec.53.1 Entry.remove on filename with #s", function (done) {
1220 var fileName = "entry.#rm#.file";
1221 // create a new file entry
1222 createFile(fileName, function (entry) {
1223 expect(entry).toBeDefined();
1224 entry.remove(function () {
1225 root.getFile(fileName, null, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not get deleted file : ' + fileName), function (error) {
1226 expect(error).toBeDefined();
1227 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
1228 // cleanup
1229 deleteEntry(fileName, done);
1230 });
1231 }, failed.bind(null, done, 'entry.remove - Error removing entry : ' + fileName));
1232 }, failed.bind(null, done, 'createFile - Error creating file : ' + fileName));
1233 });
1234 it("file.spec.54 remove on empty directory", function (done) {
1235 var dirName = "entry.rm.dir";
1236 // create a new directory entry
1237 createDirectory(dirName, function (entry) {
1238 expect(entry).toBeDefined();
1239 entry.remove(function () {
1240 root.getDirectory(dirName, null, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, it should not get deleted directory : ' + dirName), function (error) {
1241 expect(error).toBeDefined();
1242 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
1243 // cleanup
1244 deleteEntry(dirName, done);
1245 });
1246 }, failed.bind(null, done, 'entry.remove - Error removing entry : ' + dirName));
1247 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName));
1248 });
1249 it("file.spec.55 remove on non-empty directory", function (done) {
1250 if (isIndexedDBShim) {
1251 /* Both Entry.remove and directoryEntry.removeRecursively don't fail when removing
1252 non-empty directories - directories being removed are cleaned
1253 along with contents instead (Firefox, IE)*/
1254 pending();
1255 }
1256
1257 var dirName = "ent y.rm.dir.not.empty",
1258 fileName = "re ove.txt",
1259 fullPath = joinURL(root.fullPath, dirName);
1260 // create a new directory entry
1261 createDirectory(dirName, function (entry) {
1262 entry.getFile(fileName, {
1263 create : true
1264 }, function (fileEntry) {
1265 entry.remove(succeed.bind(null, done, 'entry.remove - Unexpected success callback, it should not remove a directory that contains files : ' + dirName), function (error) {
1266 expect(error).toBeDefined();
1267 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
1268 root.getDirectory(dirName, null, function (entry) {
1269 expect(entry).toBeDefined();
1270 expect(entry.fullPath).toCanonicallyMatch(fullPath);
1271 // cleanup
1272 deleteEntry(dirName, done);
1273 }, failed.bind(null, done, 'root.getDirectory - Error getting directory : ' + dirName));
1274 });
1275 }, failed.bind(null, done, 'entry.getFile - Error creating file : ' + fileName + ' inside of ' + dirName));
1276 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName));
1277 });
1278 it("file.spec.56 remove on root file system", function (done) {
1279
1280 // remove entry that doesn't exist
1281 root.remove(succeed.bind(null, done, 'entry.remove - Unexpected success callback, it should not remove entry that it does not exists'), function (error) {
1282 expect(error).toBeDefined();
1283 if (isChrome) {
1284 /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of
1285 NO_MODIFICATION_ALLOWED_ERR(code: 6) on trying to call removeRecursively
1286 on the root file system.*/
1287 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
1288 } else {
1289 expect(error).toBeFileError(FileError.NO_MODIFICATION_ALLOWED_ERR);
1290 }
1291 done();
1292 });
1293 });
1294 it("file.spec.57 copyTo: file", function (done) {
1295 var file1 = "entry copy.file1",
1296 file2 = "entry copy.file2",
1297 fullPath = joinURL(root.fullPath, file2);
1298 // create a new file entry to kick off it
1299 deleteEntry(file2, function () {
1300 createFile(file1, function (fileEntry) {
1301 // copy file1 to file2
1302 fileEntry.copyTo(root, file2, function (entry) {
1303 expect(entry).toBeDefined();
1304 expect(entry.isFile).toBe(true);
1305 expect(entry.isDirectory).toBe(false);
1306 expect(entry.fullPath).toCanonicallyMatch(fullPath);
1307 expect(entry.name).toCanonicallyMatch(file2);
1308 root.getFile(file2, {
1309 create : false
1310 }, function (entry2) {
1311 expect(entry2).toBeDefined();
1312 expect(entry2.isFile).toBe(true);
1313 expect(entry2.isDirectory).toBe(false);
1314 expect(entry2.fullPath).toCanonicallyMatch(fullPath);
1315 expect(entry2.name).toCanonicallyMatch(file2);
1316 // cleanup
1317 deleteEntry(file1, function () {
1318 deleteEntry(file2, done);
1319 });
1320 }, failed.bind(null, done, 'root.getFile - Error getting copied file : ' + file2));
1321 }, failed.bind(null, done, 'fileEntry.copyTo - Error copying file : ' + file2));
1322 }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));
1323 }, failed.bind(null, done, 'deleteEntry - Error removing file : ' + file2));
1324 });
1325 it("file.spec.58 copyTo: file onto itself", function (done) {
1326 var file1 = "entry.copy.fos.file1";
1327 // create a new file entry to kick off it
1328 createFile(file1, function (entry) {
1329 // copy file1 onto itself
1330 entry.copyTo(root, null, succeed.bind(null, done, 'entry.copyTo - Unexpected success callback, it should not copy a null file'), function (error) {
1331 expect(error).toBeDefined();
1332 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
1333 // cleanup
1334 deleteEntry(file1, done);
1335 });
1336 }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));
1337 });
1338 it("file.spec.59 copyTo: directory", function (done) {
1339 if (isIndexedDBShim) {
1340 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
1341 pending();
1342 }
1343
1344 var file1 = "file1",
1345 srcDir = "entry.copy.srcDir",
1346 dstDir = "entry.copy.dstDir",
1347 dstPath = joinURL(root.fullPath, dstDir),
1348 filePath = joinURL(dstPath, file1);
1349 // create a new directory entry to kick off it
1350 deleteEntry(dstDir, function () {
1351 createDirectory(srcDir, function (directory) {
1352 // create a file within new directory
1353 directory.getFile(file1, {
1354 create : true
1355 }, function () {
1356 directory.copyTo(root, dstDir, function (directory) {
1357 expect(directory).toBeDefined();
1358 expect(directory.isFile).toBe(false);
1359 expect(directory.isDirectory).toBe(true);
1360 expect(directory.fullPath).toCanonicallyMatch(dstPath);
1361 expect(directory.name).toCanonicallyMatch(dstDir);
1362 root.getDirectory(dstDir, {
1363 create : false
1364 }, function (dirEntry) {
1365 expect(dirEntry).toBeDefined();
1366 expect(dirEntry.isFile).toBe(false);
1367 expect(dirEntry.isDirectory).toBe(true);
1368 expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);
1369 expect(dirEntry.name).toCanonicallyMatch(dstDir);
1370 dirEntry.getFile(file1, {
1371 create : false
1372 }, function (fileEntry) {
1373 expect(fileEntry).toBeDefined();
1374 expect(fileEntry.isFile).toBe(true);
1375 expect(fileEntry.isDirectory).toBe(false);
1376 expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
1377 expect(fileEntry.name).toCanonicallyMatch(file1);
1378 // cleanup
1379 deleteEntry(srcDir, function () {
1380 deleteEntry(dstDir, done);
1381 });
1382 }, failed.bind(null, done, 'dirEntry.getFile - Error getting file : ' + file1));
1383 }, failed.bind(null, done, 'root.getDirectory - Error getting copied directory : ' + dstDir));
1384 }, failed.bind(null, done, 'directory.copyTo - Error copying directory : ' + srcDir + ' to :' + dstDir));
1385 }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1));
1386 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));
1387 }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));
1388 });
1389 it("file.spec.60 copyTo: directory to backup at same root directory", function (done) {
1390 if (isIndexedDBShim) {
1391 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
1392 pending();
1393 }
1394
1395 var file1 = "file1",
1396 srcDir = "entry.copy srcDirSame",
1397 dstDir = "entry.copy srcDirSame-backup",
1398 dstPath = joinURL(root.fullPath, dstDir),
1399 filePath = joinURL(dstPath, file1);
1400 // create a new directory entry to kick off it
1401 deleteEntry(dstDir, function () {
1402 createDirectory(srcDir, function (directory) {
1403 directory.getFile(file1, {
1404 create : true
1405 }, function () {
1406 directory.copyTo(root, dstDir, function (directory) {
1407 expect(directory).toBeDefined();
1408 expect(directory.isFile).toBe(false);
1409 expect(directory.isDirectory).toBe(true);
1410 expect(directory.fullPath).toCanonicallyMatch(dstPath);
1411 expect(directory.name).toCanonicallyMatch(dstDir);
1412 root.getDirectory(dstDir, {
1413 create : false
1414 }, function (dirEntry) {
1415 expect(dirEntry).toBeDefined();
1416 expect(dirEntry.isFile).toBe(false);
1417 expect(dirEntry.isDirectory).toBe(true);
1418 expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);
1419 expect(dirEntry.name).toCanonicallyMatch(dstDir);
1420 dirEntry.getFile(file1, {
1421 create : false
1422 }, function (fileEntry) {
1423 expect(fileEntry).toBeDefined();
1424 expect(fileEntry.isFile).toBe(true);
1425 expect(fileEntry.isDirectory).toBe(false);
1426 expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
1427 expect(fileEntry.name).toCanonicallyMatch(file1);
1428 // cleanup
1429 deleteEntry(srcDir, function () {
1430 deleteEntry(dstDir, done);
1431 });
1432 }, failed.bind(null, done, 'dirEntry.getFile - Error getting file : ' + file1));
1433 }, failed.bind(null, done, 'root.getDirectory - Error getting copied directory : ' + dstDir));
1434 }, failed.bind(null, done, 'directory.copyTo - Error copying directory : ' + srcDir + ' to :' + dstDir));
1435 }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1));
1436 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));
1437 }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));
1438 });
1439 it("file.spec.61 copyTo: directory onto itself", function (done) {
1440 if (isIndexedDBShim) {
1441 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
1442 pending();
1443 }
1444
1445 var file1 = "file1",
1446 srcDir = "entry.copy.dos.srcDir",
1447 srcPath = joinURL(root.fullPath, srcDir),
1448 filePath = joinURL(srcPath, file1);
1449 // create a new directory entry to kick off it
1450 createDirectory(srcDir, function (directory) {
1451 // create a file within new directory
1452 directory.getFile(file1, {
1453 create : true
1454 }, function (fileEntry) {
1455 // copy srcDir onto itself
1456 directory.copyTo(root, null, succeed.bind(null, done, 'directory.copyTo - Unexpected success callback, it should not copy file: ' + srcDir + ' to a null destination'), function (error) {
1457 expect(error).toBeDefined();
1458 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
1459 root.getDirectory(srcDir, {
1460 create : false
1461 }, function (dirEntry) {
1462 expect(dirEntry).toBeDefined();
1463 expect(dirEntry.fullPath).toCanonicallyMatch(srcPath);
1464 dirEntry.getFile(file1, {
1465 create : false
1466 }, function (fileEntry) {
1467 expect(fileEntry).toBeDefined();
1468 expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
1469 // cleanup
1470 deleteEntry(srcDir, done);
1471 }, failed.bind(null, done, 'dirEntry.getFile - Error getting file : ' + file1));
1472 }, failed.bind(null, done, 'root.getDirectory - Error getting directory : ' + srcDir));
1473 });
1474 }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1));
1475 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));
1476 });
1477 it("file.spec.62 copyTo: directory into itself", function (done) {
1478 if (isIndexedDBShim) {
1479 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
1480 pending();
1481 }
1482
1483 var srcDir = "entry.copy.dis.srcDir",
1484 dstDir = "entry.copy.dis.dstDir",
1485 srcPath = joinURL(root.fullPath, srcDir);
1486 // create a new directory entry to kick off it
1487 createDirectory(srcDir, function (directory) {
1488 // copy source directory into itself
1489 directory.copyTo(directory, dstDir, succeed.bind(null, done, 'directory.copyTo - Unexpected success callback, it should not copy a directory ' + srcDir + ' into itself'), function (error) {
1490 expect(error).toBeDefined();
1491 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
1492 root.getDirectory(srcDir, {
1493 create : false
1494 }, function (dirEntry) {
1495 // returning confirms existence so just check fullPath entry
1496 expect(dirEntry).toBeDefined();
1497 expect(dirEntry.fullPath).toCanonicallyMatch(srcPath);
1498 // cleanup
1499 deleteEntry(srcDir, done);
1500 }, failed.bind(null, done, 'root.getDirectory - Error getting directory : ' + srcDir));
1501 });
1502 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));
1503 });
1504 it("file.spec.63 copyTo: directory that does not exist", function (done) {
1505 var file1 = "entry.copy.dnf.file1",
1506 dirName = 'dir-foo';
1507 createFile(file1, function (fileEntry) {
1508 createDirectory(dirName, function (dirEntry) {
1509 dirEntry.remove(function () {
1510 fileEntry.copyTo(dirEntry, null, succeed.bind(null, done, 'fileEntry.copyTo - Unexpected success callback, it should not copy a file ' + file1 + ' into a removed directory'), function (error) {
1511 expect(error).toBeDefined();
1512 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
1513 done();
1514 });
1515 }, failed.bind(null, done, 'dirEntry.remove - Error removing directory : ' + dirName));
1516 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName));
1517 }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));
1518 });
1519 it("file.spec.64 copyTo: invalid target name", function (done) {
1520 if (isBrowser) {
1521 /*The plugin does not follow ["8.3 Naming restrictions"]
1522 (http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions*/
1523 pending();
1524 }
1525
1526 var file1 = "entry.copy.itn.file1",
1527 file2 = "bad:file:name";
1528 // create a new file entry
1529 createFile(file1, function (entry) {
1530 // copy file1 to file2
1531 entry.copyTo(root, file2, succeed.bind(null, done, 'entry.copyTo - Unexpected success callback, it should not copy a file ' + file1 + ' to an invalid file name: ' + file2), function (error) {
1532 expect(error).toBeDefined();
1533 expect(error).toBeFileError(FileError.ENCODING_ERR);
1534 // cleanup
1535 deleteEntry(file1, done);
1536 });
1537 }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));
1538 });
1539 it("file.spec.65 moveTo: file to same parent", function (done) {
1540 var file1 = "entry.move.fsp.file1",
1541 file2 = "entry.move.fsp.file2",
1542 dstPath = joinURL(root.fullPath, file2);
1543 // create a new file entry to kick off it
1544 createFile(file1, function (entry) {
1545 // move file1 to file2
1546 entry.moveTo(root, file2, function (entry) {
1547 expect(entry).toBeDefined();
1548 expect(entry.isFile).toBe(true);
1549 expect(entry.isDirectory).toBe(false);
1550 expect(entry.fullPath).toCanonicallyMatch(dstPath);
1551 expect(entry.name).toCanonicallyMatch(file2);
1552 root.getFile(file2, {
1553 create : false
1554 }, function (fileEntry) {
1555 expect(fileEntry).toBeDefined();
1556 expect(fileEntry.fullPath).toCanonicallyMatch(dstPath);
1557 root.getFile(file1, {
1558 create : false
1559 }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) {
1560 //expect(navigator.fileMgr.testFileExists(srcPath) === false, "original file should not exist.");
1561 expect(error).toBeDefined();
1562 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
1563 // cleanup
1564 deleteEntry(file1, function () {
1565 deleteEntry(file2, done);
1566 });
1567 });
1568 }, failed.bind(null, done, 'root.getFile - Error getting file : ' + file2));
1569 }, failed.bind(null, done, 'entry.moveTo - Error moving file : ' + file1 + ' to root as: ' + file2));
1570 }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));
1571 });
1572 it("file.spec.66 moveTo: file to new parent", function (done) {
1573 var file1 = "entry.move.fnp.file1",
1574 dir = "entry.move.fnp.dir",
1575 dstPath = joinURL(joinURL(root.fullPath, dir), file1);
1576 // ensure destination directory is cleaned up first
1577 deleteEntry(dir, function () {
1578 // create a new file entry to kick off it
1579 createFile(file1, function (entry) {
1580 // create a parent directory to move file to
1581 root.getDirectory(dir, {
1582 create : true
1583 }, function (directory) {
1584 // move file1 to new directory
1585 // move the file
1586 entry.moveTo(directory, null, function (entry) {
1587 expect(entry).toBeDefined();
1588 expect(entry.isFile).toBe(true);
1589 expect(entry.isDirectory).toBe(false);
1590 expect(entry.fullPath).toCanonicallyMatch(dstPath);
1591 expect(entry.name).toCanonicallyMatch(file1);
1592 // test the moved file exists
1593 directory.getFile(file1, {
1594 create : false
1595 }, function (fileEntry) {
1596 expect(fileEntry).toBeDefined();
1597 expect(fileEntry.fullPath).toCanonicallyMatch(dstPath);
1598 root.getFile(file1, {
1599 create : false
1600 }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) {
1601 expect(error).toBeDefined();
1602 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
1603 // cleanup
1604 deleteEntry(file1, function () {
1605 deleteEntry(dir, done);
1606 });
1607 });
1608 }, failed.bind(null, done, 'directory.getFile - Error getting file : ' + file1 + ' from: ' + dir));
1609 }, failed.bind(null, done, 'entry.moveTo - Error moving file : ' + file1 + ' to: ' + dir + ' with the same name'));
1610 }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dir));
1611 }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));
1612 }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dir));
1613 });
1614 it("file.spec.67 moveTo: directory to same parent", function (done) {
1615 if (isIndexedDBShim) {
1616 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
1617 pending();
1618 }
1619
1620 var file1 = "file1",
1621 srcDir = "entry.move.dsp.srcDir",
1622 dstDir = "entry.move.dsp.dstDir",
1623 dstPath = joinURL(root.fullPath, dstDir),
1624 filePath = joinURL(dstPath, file1);
1625 // ensure destination directory is cleaned up before it
1626 deleteEntry(dstDir, function () {
1627 // create a new directory entry to kick off it
1628 createDirectory(srcDir, function (directory) {
1629 // create a file within directory
1630 directory.getFile(file1, {
1631 create : true
1632 }, function () {
1633 // move srcDir to dstDir
1634 directory.moveTo(root, dstDir, function (directory) {
1635 expect(directory).toBeDefined();
1636 expect(directory.isFile).toBe(false);
1637 expect(directory.isDirectory).toBe(true);
1638 expect(directory.fullPath).toCanonicallyMatch(dstPath);
1639 expect(directory.name).toCanonicallyMatch(dstDir);
1640 // test that moved file exists in destination dir
1641 directory.getFile(file1, {
1642 create : false
1643 }, function (fileEntry) {
1644 expect(fileEntry).toBeDefined();
1645 expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
1646 // check that the moved file no longer exists in original dir
1647 root.getFile(file1, {
1648 create : false
1649 }, succeed.bind(null, done, 'directory.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) {
1650 expect(error).toBeDefined();
1651 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
1652 // cleanup
1653 deleteEntry(srcDir, function() {
1654 deleteEntry(dstDir, done);
1655 });
1656 });
1657 }, failed.bind(null, done, 'directory.getFile - Error getting file : ' + file1 + ' from: ' + srcDir));
1658 }, failed.bind(null, done, 'entry.moveTo - Error moving directory : ' + srcDir + ' to root as: ' + dstDir));
1659 }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1));
1660 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));
1661 }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));
1662 });
1663 it("file.spec.68 moveTo: directory to same parent with same name", function (done) {
1664 if (isIndexedDBShim) {
1665 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
1666 pending();
1667 }
1668
1669 var file1 = "file1",
1670 srcDir = "entry.move.dsp.srcDir",
1671 dstDir = "entry.move.dsp.srcDir-backup",
1672 dstPath = joinURL(root.fullPath, dstDir),
1673 filePath = joinURL(dstPath, file1);
1674 // ensure destination directory is cleaned up before it
1675 deleteEntry(dstDir, function () {
1676 // create a new directory entry to kick off it
1677 createDirectory(srcDir, function (directory) {
1678 // create a file within directory
1679 directory.getFile(file1, {
1680 create : true
1681 }, function () {
1682 // move srcDir to dstDir
1683 directory.moveTo(root, dstDir, function (directory) {
1684 expect(directory).toBeDefined();
1685 expect(directory.isFile).toBe(false);
1686 expect(directory.isDirectory).toBe(true);
1687 expect(directory.fullPath).toCanonicallyMatch(dstPath);
1688 expect(directory.name).toCanonicallyMatch(dstDir);
1689 // check that moved file exists in destination dir
1690 directory.getFile(file1, {
1691 create : false
1692 }, function (fileEntry) {
1693 expect(fileEntry).toBeDefined();
1694 expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
1695 // check that the moved file no longer exists in original dir
1696 root.getFile(file1, {
1697 create : false
1698 }, succeed.bind(null, done, 'directory.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) {
1699 expect(error).toBeDefined();
1700 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
1701 // cleanup
1702 deleteEntry(srcDir, function() {
1703 deleteEntry(dstDir, done);
1704 });
1705 });
1706 }, failed.bind(null, done, 'directory.getFile - Error getting file : ' + file1 + ' from: ' + srcDir));
1707 }, failed.bind(null, done, 'entry.moveTo - Error moving directory : ' + srcDir + ' to root as: ' + dstDir));
1708 }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1));
1709 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));
1710 }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));
1711 });
1712 it("file.spec.69 moveTo: directory to new parent", function (done) {
1713 if (isIndexedDBShim) {
1714 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
1715 pending();
1716 }
1717
1718 var file1 = "file1",
1719 srcDir = "entry.move.dnp.srcDir",
1720 dstDir = "entry.move.dnp.dstDir",
1721 dstPath = joinURL(root.fullPath, dstDir),
1722 filePath = joinURL(dstPath, file1);
1723 // ensure destination directory is cleaned up before it
1724 deleteEntry(dstDir, function () {
1725 // create a new directory entry to kick off it
1726 createDirectory(srcDir, function (directory) {
1727 // create a file within directory
1728 directory.getFile(file1, {
1729 create : true
1730 }, function () {
1731 // move srcDir to dstDir
1732 directory.moveTo(root, dstDir, function (dirEntry) {
1733 expect(dirEntry).toBeDefined();
1734 expect(dirEntry.isFile).toBe(false);
1735 expect(dirEntry.isDirectory).toBe(true);
1736 expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);
1737 expect(dirEntry.name).toCanonicallyMatch(dstDir);
1738 // test that moved file exists in destination dir
1739 dirEntry.getFile(file1, {
1740 create : false
1741 }, function (fileEntry) {
1742 expect(fileEntry).toBeDefined();
1743 expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
1744 // test that the moved file no longer exists in original dir
1745 root.getFile(file1, {
1746 create : false
1747 }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) {
1748 expect(error).toBeDefined();
1749 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
1750 // cleanup
1751 deleteEntry(srcDir, function() {
1752 deleteEntry(dstDir, done);
1753 });
1754 });
1755 }, failed.bind(null, done, 'directory.getFile - Error getting file : ' + file1 + ' from: ' + dstDir));
1756 }, failed.bind(null, done, 'directory.moveTo - Error moving directory : ' + srcDir + ' to root as: ' + dstDir));
1757 }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1));
1758 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));
1759 }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));
1760 });
1761
1762 it("file.spec.131 moveTo: directories tree to new parent", function (done) {
1763 if (isIndexedDBShim) {
1764 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
1765 pending();
1766 }
1767
1768 var srcDir = "entry.move.dnp.srcDir";
1769 var srcDirNestedFirst = "entry.move.dnp.srcDir.Nested1";
1770 var srcDirNestedSecond = "entry.move.dnp.srcDir.Nested2";
1771 var dstDir = "entry.move.dnp.dstDir";
1772
1773 createDirectory(dstDir, function (dstDirectory) {
1774 createDirectory(srcDir, function (srcDirectory) {
1775 srcDirectory.getDirectory(srcDirNestedFirst, { create: true }, function () {
1776 srcDirectory.getDirectory(srcDirNestedSecond, { create: true }, function () {
1777 srcDirectory.moveTo(dstDirectory, srcDir, function successMove(transferredDirectory) {
1778 var directoryReader = transferredDirectory.createReader();
1779 directoryReader.readEntries(function successRead(entries) {
1780 expect(entries.length).toBe(2);
1781 expect(entries[0].name).toBe(srcDirNestedFirst);
1782 expect(entries[1].name).toBe(srcDirNestedSecond);
1783 deleteEntry(dstDir, done);
1784 }, failed.bind(null, done, 'Error getting entries from: ' + transferredDirectory));
1785 }, failed.bind(null, done, 'directory.moveTo - Error moving directory : ' + srcDir + ' to root as: ' + dstDir));
1786 }, failed.bind(null, done, 'directory.getDirectory - Error creating directory : ' + srcDirNestedSecond));
1787 }, failed.bind(null, done, 'directory.getDirectory - Error creating directory : ' + srcDirNestedFirst));
1788 }, failed.bind(null, done, 'createDirectory - Error creating source directory : ' + srcDir));
1789 }, failed.bind(null, done, 'createDirectory - Error creating dest directory : ' + dstDir));
1790 });
1791
1792 it("file.spec.70 moveTo: directory onto itself", function (done) {
1793 if (isIndexedDBShim) {
1794 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
1795 pending();
1796 }
1797
1798 var file1 = "file1",
1799 srcDir = "entry.move.dos.srcDir",
1800 srcPath = joinURL(root.fullPath, srcDir),
1801 filePath = joinURL(srcPath, file1);
1802 // create a new directory entry to kick off it
1803 createDirectory(srcDir, function (directory) {
1804 // create a file within new directory
1805 directory.getFile(file1, {
1806 create : true
1807 }, function () {
1808 // move srcDir onto itself
1809 directory.moveTo(root, null, succeed.bind(null, done, 'directory.moveTo - Unexpected success callback, it should not move directory to invalid path'), function (error) {
1810 expect(error).toBeDefined();
1811 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
1812 // test that original dir still exists
1813 root.getDirectory(srcDir, {
1814 create : false
1815 }, function (dirEntry) {
1816 // returning confirms existence so just check fullPath entry
1817 expect(dirEntry).toBeDefined();
1818 expect(dirEntry.fullPath).toCanonicallyMatch(srcPath);
1819 dirEntry.getFile(file1, {
1820 create : false
1821 }, function (fileEntry) {
1822 expect(fileEntry).toBeDefined();
1823 expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
1824 // cleanup
1825 deleteEntry(srcDir, done);
1826 }, failed.bind(null, done, 'dirEntry.getFile - Error getting file : ' + file1 + ' from: ' + srcDir));
1827 }, failed.bind(null, done, 'root.getDirectory - Error getting directory : ' + srcDir));
1828 });
1829 }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1));
1830 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));
1831 });
1832 it("file.spec.71 moveTo: directory into itself", function (done) {
1833 if (isIndexedDBShim) {
1834 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
1835 pending();
1836 }
1837
1838 var srcDir = "entry.move.dis.srcDir",
1839 dstDir = "entry.move.dis.dstDir",
1840 srcPath = joinURL(root.fullPath, srcDir);
1841 // create a new directory entry to kick off it
1842 createDirectory(srcDir, function (directory) {
1843 // move source directory into itself
1844 directory.moveTo(directory, dstDir, succeed.bind(null, done, 'directory.moveTo - Unexpected success callback, it should not move a directory into itself: ' + srcDir), function (error) {
1845 expect(error).toBeDefined();
1846 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
1847 // make sure original directory still exists
1848 root.getDirectory(srcDir, {
1849 create : false
1850 }, function (entry) {
1851 expect(entry).toBeDefined();
1852 expect(entry.fullPath).toCanonicallyMatch(srcPath);
1853 // cleanup
1854 deleteEntry(srcDir, done);
1855 }, failed.bind(null, done, 'root.getDirectory - Error getting directory, making sure that original directory still exists: ' + srcDir));
1856 });
1857 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));
1858 });
1859 it("file.spec.130 moveTo: directory into similar directory", function (done) {
1860 if (isIndexedDBShim) {
1861 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
1862 pending();
1863 }
1864
1865 var srcDir = "entry.move.dis.srcDir",
1866 dstDir = "entry.move.dis.srcDir-backup";
1867 // create a new directory entry to kick off it
1868 createDirectory(srcDir, function (srcDirEntry) {
1869 deleteEntry(dstDir, function () {
1870 createDirectory(dstDir, function (dstDirEntry) {
1871 // move source directory into itself
1872 srcDirEntry.moveTo(dstDirEntry, 'file', function (newDirEntry) {
1873 expect(newDirEntry).toBeDefined();
1874 deleteEntry(dstDir, done);
1875 }, failed.bind(null, done, 'directory.moveTo - Error moving a directory into a similarly-named directory: ' + srcDir));
1876 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dstDir));
1877 }, failed.bind(null, done, 'deleteEntry - Error deleting directory : ' + dstDir));
1878 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));
1879 });
1880 it("file.spec.72 moveTo: file onto itself", function (done) {
1881 var file1 = "entry.move.fos.file1",
1882 filePath = joinURL(root.fullPath, file1);
1883 // create a new file entry to kick off it
1884 createFile(file1, function (entry) {
1885 // move file1 onto itself
1886 entry.moveTo(root, null, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, it should not move a file: ' + file1 + ' into the same parent'), function (error) {
1887 expect(error).toBeDefined();
1888 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
1889 //test that original file still exists
1890 root.getFile(file1, {
1891 create : false
1892 }, function (fileEntry) {
1893 expect(fileEntry).toBeDefined();
1894 expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
1895 // cleanup
1896 deleteEntry(file1, done);
1897 }, failed.bind(null, done, 'root.getFile - Error getting file, making sure that original file still exists: ' + file1));
1898 });
1899 }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));
1900 });
1901 it("file.spec.73 moveTo: file onto existing directory", function (done) {
1902 var file1 = "entry.move.fod.file1",
1903 dstDir = "entry.move.fod.dstDir",
1904 subDir = "subDir",
1905 dirPath = joinURL(joinURL(root.fullPath, dstDir), subDir),
1906 filePath = joinURL(root.fullPath, file1);
1907 // ensure destination directory is cleaned up before it
1908 deleteEntry(dstDir, function () {
1909 // create a new file entry to kick off it
1910 createFile(file1, function (entry) {
1911 // create top level directory
1912 root.getDirectory(dstDir, {
1913 create : true
1914 }, function (directory) {
1915 // create sub-directory
1916 directory.getDirectory(subDir, {
1917 create : true
1918 }, function (subDirectory) {
1919 // move file1 onto sub-directory
1920 entry.moveTo(directory, subDir, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, it should not move a file: ' + file1 + ' into directory: ' + dstDir + '\n' + subDir + ' directory already exists'), function (error) {
1921 expect(error).toBeDefined();
1922 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
1923 // check that original dir still exists
1924 directory.getDirectory(subDir, {
1925 create : false
1926 }, function (dirEntry) {
1927 expect(dirEntry).toBeDefined();
1928 expect(dirEntry.fullPath).toCanonicallyMatch(dirPath);
1929 // check that original file still exists
1930 root.getFile(file1, {
1931 create : false
1932 }, function (fileEntry) {
1933 expect(fileEntry).toBeDefined();
1934 expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
1935 // cleanup
1936 deleteEntry(file1, function () {
1937 deleteEntry(dstDir, done);
1938 });
1939 }, failed.bind(null, done, 'root.getFile - Error getting file, making sure that original file still exists: ' + file1));
1940 }, failed.bind(null, done, 'directory.getDirectory - Error getting directory, making sure that original directory still exists: ' + subDir));
1941 });
1942 }, failed.bind(null, done, 'directory.getDirectory - Error creating directory : ' + subDir));
1943 }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dstDir));
1944 }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));
1945 }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));
1946 });
1947 it("file.spec.74 moveTo: directory onto existing file", function (done) {
1948 if (isIndexedDBShim) {
1949 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
1950 pending();
1951 }
1952
1953 var file1 = "entry.move.dof.file1",
1954 srcDir = "entry.move.dof.srcDir",
1955 dirPath = joinURL(root.fullPath, srcDir),
1956 filePath = joinURL(root.fullPath, file1);
1957 // create a new directory entry to kick off it
1958 createDirectory(srcDir, function (entry) {
1959 // create file
1960 root.getFile(file1, {
1961 create : true
1962 }, function (fileEntry) {
1963 // move directory onto file
1964 entry.moveTo(root, file1, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, it should not move : \n' + srcDir + ' into root directory renamed as ' + file1 + '\n' + file1 + ' file already exists'), function (error) {
1965 expect(error).toBeDefined();
1966 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
1967 // test that original directory exists
1968 root.getDirectory(srcDir, {
1969 create : false
1970 }, function (dirEntry) {
1971 // returning confirms existence so just check fullPath entry
1972 expect(dirEntry).toBeDefined();
1973 expect(dirEntry.fullPath).toCanonicallyMatch(dirPath);
1974 // test that original file exists
1975 root.getFile(file1, {
1976 create : false
1977 }, function (fileEntry) {
1978 expect(fileEntry).toBeDefined();
1979 expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
1980 // cleanup
1981 deleteEntry(file1, function () {
1982 deleteEntry(srcDir, done);
1983 });
1984 }, failed.bind(null, done, 'root.getFile - Error getting file, making sure that original file still exists: ' + file1));
1985 }, failed.bind(null, done, 'directory.getDirectory - Error getting directory, making sure that original directory still exists: ' + srcDir));
1986 });
1987 }, failed.bind(null, done, 'root.getFile - Error creating file : ' + file1));
1988 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));
1989 });
1990 it("file.spec.75 copyTo: directory onto existing file", function (done) {
1991 if (isIndexedDBShim) {
1992 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
1993 pending();
1994 }
1995
1996 var file1 = "entry.copy.dof.file1",
1997 srcDir = "entry.copy.dof.srcDir",
1998 dirPath = joinURL(root.fullPath, srcDir),
1999 filePath = joinURL(root.fullPath, file1);
2000 // create a new directory entry to kick off it
2001 createDirectory(srcDir, function (entry) {
2002 // create file
2003 root.getFile(file1, {
2004 create : true
2005 }, function () {
2006 // copy directory onto file
2007 entry.copyTo(root, file1, succeed.bind(null, done, 'entry.copyTo - Unexpected success callback, it should not copy : \n' + srcDir + ' into root directory renamed as ' + file1 + '\n' + file1 + ' file already exists'), function (error) {
2008 expect(error).toBeDefined();
2009 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
2010 //check that original dir still exists
2011 root.getDirectory(srcDir, {
2012 create : false
2013 }, function (dirEntry) {
2014 // returning confirms existence so just check fullPath entry
2015 expect(dirEntry).toBeDefined();
2016 expect(dirEntry.fullPath).toCanonicallyMatch(dirPath);
2017 // test that original file still exists
2018 root.getFile(file1, {
2019 create : false
2020 }, function (fileEntry) {
2021 expect(fileEntry).toBeDefined();
2022 expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
2023 // cleanup
2024 deleteEntry(file1, function () {
2025 deleteEntry(srcDir, done);
2026 });
2027 }, failed.bind(null, done, 'root.getFile - Error getting file, making sure that original file still exists: ' + file1));
2028 }, failed.bind(null, done, 'root.getDirectory - Error getting directory, making sure that original directory still exists: ' + srcDir));
2029 });
2030 }, failed.bind(null, done, 'root.getFile - Error creating file : ' + file1));
2031 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));
2032 });
2033 it("file.spec.76 moveTo: directory onto directory that is not empty", function (done) {
2034 if (isIndexedDBShim) {
2035 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
2036 pending();
2037 }
2038
2039 var srcDir = "entry.move.dod.srcDir",
2040 dstDir = "entry.move.dod.dstDir",
2041 subDir = "subDir",
2042 srcPath = joinURL(root.fullPath, srcDir),
2043 dstPath = joinURL(joinURL(root.fullPath, dstDir), subDir);
2044 // ensure destination directory is cleaned up before it
2045 deleteEntry(dstDir, function () {
2046 // create a new file entry to kick off it
2047 createDirectory(srcDir, function (entry) {
2048 // create top level directory
2049 root.getDirectory(dstDir, {
2050 create : true
2051 }, function (directory) {
2052 // create sub-directory
2053 directory.getDirectory(subDir, {
2054 create : true
2055 }, function () {
2056 // move srcDir onto dstDir (not empty)
2057 entry.moveTo(root, dstDir, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, it should not copy : \n' + srcDir + ' into root directory renamed as ' + dstDir + '\n' + dstDir + ' directory already exists'), function (error) {
2058 expect(error).toBeDefined();
2059 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
2060 // making sure destination directory still exists
2061 directory.getDirectory(subDir, {
2062 create : false
2063 }, function (dirEntry) {
2064 // returning confirms existence so just check fullPath entry
2065 expect(dirEntry).toBeDefined();
2066 expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);
2067 // making sure source directory exists
2068 root.getDirectory(srcDir, {
2069 create : false
2070 }, function (srcEntry) {
2071 expect(srcEntry).toBeDefined();
2072 expect(srcEntry.fullPath).toCanonicallyMatch(srcPath);
2073 // cleanup
2074 deleteEntry(srcDir, function () {
2075 deleteEntry(dstDir, done);
2076 });
2077 }, failed.bind(null, done, 'root.getDirectory - Error getting directory, making sure that original directory still exists: ' + srcDir));
2078 }, failed.bind(null, done, 'directory.getDirectory - Error getting directory, making sure that original directory still exists: ' + subDir));
2079 });
2080 }, failed.bind(null, done, 'directory.getDirectory - Error creating directory : ' + subDir));
2081 }, failed.bind(null, done, 'directory.getDirectory - Error creating directory : ' + subDir));
2082 }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));
2083 }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));
2084 });
2085 it("file.spec.77 moveTo: file replace existing file", function (done) {
2086 var file1 = "entry.move.frf.file1",
2087 file2 = "entry.move.frf.file2",
2088 file2Path = joinURL(root.fullPath, file2);
2089 // create a new directory entry to kick off it
2090 createFile(file1, function (entry) {
2091 // create file
2092 root.getFile(file2, {
2093 create : true
2094 }, function () {
2095 // replace file2 with file1
2096 entry.moveTo(root, file2, function (entry2) {
2097 expect(entry2).toBeDefined();
2098 expect(entry2.isFile).toBe(true);
2099 expect(entry2.isDirectory).toBe(false);
2100 expect(entry2.fullPath).toCanonicallyMatch(file2Path);
2101 expect(entry2.name).toCanonicallyMatch(file2);
2102 // old file should not exists
2103 root.getFile(file1, {
2104 create : false
2105 }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, file: ' + file1 + ' should not exists'), function (error) {
2106 expect(error).toBeDefined();
2107 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
2108 // test that new file exists
2109 root.getFile(file2, {
2110 create : false
2111 }, function (fileEntry) {
2112 expect(fileEntry).toBeDefined();
2113 expect(fileEntry.fullPath).toCanonicallyMatch(file2Path);
2114 // cleanup
2115 deleteEntry(file1, function () {
2116 deleteEntry(file2, done);
2117 });
2118 }, failed.bind(null, done, 'root.getFile - Error getting moved file: ' + file2));
2119 });
2120 }, failed.bind(null, done, 'entry.moveTo - Error moving file : ' + file1 + ' to root as: ' + file2));
2121 }, failed.bind(null, done, 'root.getFile - Error creating file: ' + file2));
2122 }, failed.bind(null, done, 'createFile - Error creating file: ' + file1));
2123 });
2124 it("file.spec.78 moveTo: directory replace empty directory", function (done) {
2125 if (isIndexedDBShim) {
2126 /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */
2127 pending();
2128 }
2129
2130 var file1 = "file1",
2131 srcDir = "entry.move.drd.srcDir",
2132 dstDir = "entry.move.drd.dstDir",
2133 dstPath = joinURL(root.fullPath, dstDir),
2134 filePath = dstPath + '/' + file1;
2135 // ensure destination directory is cleaned up before it
2136 deleteEntry(dstDir, function () {
2137 // create a new directory entry to kick off it
2138 createDirectory(srcDir, function (directory) {
2139 // create a file within source directory
2140 directory.getFile(file1, {
2141 create : true
2142 }, function () {
2143 // create destination directory
2144 root.getDirectory(dstDir, {
2145 create : true
2146 }, function () {
2147 // move srcDir to dstDir
2148 directory.moveTo(root, dstDir, function (dirEntry) {
2149 expect(dirEntry).toBeDefined();
2150 expect(dirEntry.isFile).toBe(false);
2151 expect(dirEntry.isDirectory).toBe(true);
2152 expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);
2153 expect(dirEntry.name).toCanonicallyMatch(dstDir);
2154 // check that old directory contents have been moved
2155 dirEntry.getFile(file1, {
2156 create : false
2157 }, function (fileEntry) {
2158 expect(fileEntry).toBeDefined();
2159 expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
2160 // check that old directory no longer exists
2161 root.getDirectory(srcDir, {
2162 create : false
2163 }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, directory: ' + srcDir + ' should not exists'), function (error) {
2164 expect(error).toBeDefined();
2165 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
2166 // cleanup
2167 deleteEntry(srcDir, function () {
2168 deleteEntry(dstDir, done);
2169 });
2170 });
2171 }, failed.bind(null, done, 'dirEntry.getFile - Error getting moved file: ' + file1));
2172 }, failed.bind(null, done, 'entry.moveTo - Error moving directory : ' + srcDir + ' to root as: ' + dstDir));
2173 }, failed.bind(null, done, 'root.getDirectory - Error creating directory: ' + dstDir));
2174 }, failed.bind(null, done, 'root.getFile - Error creating file: ' + file1));
2175 }, failed.bind(null, done, 'createDirectory - Error creating directory: ' + srcDir));
2176 }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));
2177 });
2178 it("file.spec.79 moveTo: directory that does not exist", function (done) {
2179
2180 var file1 = "entry.move.dnf.file1",
2181 dstDir = "entry.move.dnf.dstDir",
2182 dstPath = joinURL(root.fullPath, dstDir);
2183 // create a new file entry to kick off it
2184 createFile(file1, function (entry) {
2185 // move file to directory that does not exist
2186 var directory = new DirectoryEntry();
2187 directory.filesystem = root.filesystem;
2188 directory.fullPath = dstPath;
2189 entry.moveTo(directory, null, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, parent directory: ' + dstPath + ' should not exists'), function (error) {
2190 expect(error).toBeDefined();
2191 if (isChrome) {
2192 /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of NOT_FOUND_ERR(code: 1)
2193 on trying to moveTo directory that does not exist.*/
2194 expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
2195 } else {
2196 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
2197 }
2198 // cleanup
2199 deleteEntry(file1, done);
2200 });
2201 }, failed.bind(null, done, 'createFile - Error creating file: ' + file1));
2202 });
2203 it("file.spec.80 moveTo: invalid target name", function (done) {
2204 if (isBrowser) {
2205 /*The plugin does not follow ["8.3 Naming restrictions"]
2206 (http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions*/
2207 pending();
2208 }
2209
2210 var file1 = "entry.move.itn.file1",
2211 file2 = "bad:file:name";
2212 // create a new file entry to kick off it
2213 createFile(file1, function (entry) {
2214 // move file1 to file2
2215 entry.moveTo(root, file2, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, : ' + file1 + ' to root as: ' + file2), function (error) {
2216 expect(error).toBeDefined();
2217 expect(error).toBeFileError(FileError.ENCODING_ERR);
2218 // cleanup
2219 deleteEntry(file1, done);
2220 });
2221 }, failed.bind(null, done, 'createFile - Error creating file: ' + file1));
2222 });
2223 });
2224 //Entry
2225 describe('FileReader', function () {
2226 it("file.spec.81 should have correct methods", function () {
2227 var reader = new FileReader();
2228 expect(reader).toBeDefined();
2229 expect(typeof reader.readAsBinaryString).toBe('function');
2230 expect(typeof reader.readAsDataURL).toBe('function');
2231 expect(typeof reader.readAsText).toBe('function');
2232 expect(typeof reader.readAsArrayBuffer).toBe('function');
2233 expect(typeof reader.abort).toBe('function');
2234 expect(reader.result).toBe(null);
2235 });
2236 });
2237 //FileReader
2238 describe('Read method', function () {
2239 it("file.spec.82 should error out on non-existent file", function (done) {
2240 var fileName = cordova.platformId === 'windowsphone' ? root.toURL() + "/" + "somefile.txt" : "somefile.txt",
2241 verifier = function (evt) {
2242 expect(evt).toBeDefined();
2243 expect(evt.target.error).toBeFileError(FileError.NOT_FOUND_ERR);
2244 done();
2245 };
2246 root.getFile(fileName, {
2247 create : true
2248 }, function (entry) {
2249 entry.file(function (file) {
2250 deleteEntry(fileName, function () {
2251 //Create FileReader
2252 var reader = new FileReader();
2253 reader.onerror = verifier;
2254 reader.onload = succeed.bind(null, done, 'reader.onload - Unexpected success callback, file: ' + fileName + ' it should not exists');
2255 reader.readAsText(file);
2256 }, failed.bind(null, done, 'deleteEntry - Error removing file: ' + fileName));
2257 }, failed.bind(null, done, 'entry.file - Error reading file: ' + fileName));
2258 }, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName));
2259 });
2260 it("file.spec.83 should be able to read native blob objects", function (done) {
2261 // Skip test if blobs are not supported (e.g.: Android 2.3).
2262 if (typeof window.Blob == 'undefined' || typeof window.Uint8Array == 'undefined') {
2263 expect(true).toFailWithMessage('Platform does not supported this feature');
2264 done();
2265 }
2266 var contents = 'asdf';
2267 var uint8Array = new Uint8Array(contents.length);
2268 for (var i = 0; i < contents.length; ++i) {
2269 uint8Array[i] = contents.charCodeAt(i);
2270 }
2271 var Builder = window.BlobBuilder || window.WebKitBlobBuilder;
2272 var blob;
2273 if (Builder) {
2274 var builder = new Builder();
2275 builder.append(uint8Array.buffer);
2276 builder.append(contents);
2277 blob = builder.getBlob("text/plain");
2278 } else {
2279 try {
2280 // iOS 6 does not support Views, so pass in the buffer.
2281 blob = new Blob([uint8Array.buffer, contents]);
2282 } catch (e) {
2283 // Skip the test if we can't create a blob (e.g.: iOS 5).
2284 if (e instanceof TypeError) {
2285 expect(true).toFailWithMessage('Platform does not supported this feature');
2286 done();
2287 }
2288 throw e;
2289 }
2290 }
2291 var verifier = function (evt) {
2292 expect(evt).toBeDefined();
2293 expect(evt.target.result).toBe('asdfasdf');
2294 done();
2295 };
2296 var reader = new FileReader();
2297 reader.onloadend = verifier;
2298 reader.readAsText(blob);
2299 });
2300 function writeDummyFile(writeBinary, callback, done, fileContents) {
2301 var fileName = "dummy.txt",
2302 fileEntry = null,
2303 // use default string if file data is not provided
2304 fileData = fileContents !== undefined ? fileContents :
2305 '\u20AC\xEB - There is an exception to every rule. Except this one.',
2306 fileDataAsBinaryString = fileContents !== undefined ? fileContents :
2307 '\xe2\x82\xac\xc3\xab - There is an exception to every rule. Except this one.';
2308
2309 function createWriter(fe) {
2310 fileEntry = fe;
2311 fileEntry.createWriter(writeFile, failed.bind(null, done, 'fileEntry.createWriter - Error reading file: ' + fileName));
2312 }
2313
2314 // writes file and reads it back in
2315 function writeFile(writer) {
2316 writer.onwriteend = function () {
2317 fileEntry.file(function (f) {
2318 callback(fileEntry, f, fileData, fileDataAsBinaryString);
2319 }, failed.bind(null, done, 'writer.onwriteend - Error writing data on file: ' + fileName));
2320 };
2321 writer.write(fileData);
2322 }
2323
2324 fileData += writeBinary ? 'bin:\x01\x00' : '';
2325 fileDataAsBinaryString += writeBinary ? 'bin:\x01\x00' : '';
2326 // create a file, write to it, and read it in again
2327 createFile(fileName, createWriter, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
2328 }
2329 function runReaderTest(funcName, writeBinary, done, progressFunc, verifierFunc, sliceStart, sliceEnd, fileContents) {
2330 writeDummyFile(writeBinary, function (fileEntry, file, fileData, fileDataAsBinaryString) {
2331 var verifier = function (evt) {
2332 expect(evt).toBeDefined();
2333 verifierFunc(evt, fileData, fileDataAsBinaryString);
2334 };
2335 var reader = new FileReader();
2336 reader.onprogress = progressFunc;
2337 reader.onload = verifier;
2338 reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + file + ' using function: ' + funcName);
2339 if (sliceEnd !== undefined) {
2340 // 'type' is specified so that is will be preserved in the resulting file:
2341 // http://www.w3.org/TR/FileAPI/#slice-method-algo -> "6.4.1. The slice method" -> 4. A), 6. c)
2342 file = file.slice(sliceStart, sliceEnd, file.type);
2343 } else if (sliceStart !== undefined) {
2344 file = file.slice(sliceStart, file.size, file.type);
2345 }
2346 reader[funcName](file);
2347 }, done, fileContents);
2348 }
2349 function arrayBufferEqualsString(ab, str) {
2350 var buf = new Uint8Array(ab);
2351 var match = buf.length == str.length;
2352 for (var i = 0; match && i < buf.length; i++) {
2353 match = buf[i] == str.charCodeAt(i);
2354 }
2355 return match;
2356 }
2357 it("file.spec.84 should read file properly, readAsText", function (done) {
2358 runReaderTest('readAsText', false, done, null, function (evt, fileData, fileDataAsBinaryString) {
2359 expect(evt.target.result).toBe(fileData);
2360 done();
2361 });
2362 });
2363 it("file.spec.84.1 should read JSON file properly, readAsText", function (done) {
2364 var testObject = {key1: "value1", key2: 2};
2365 runReaderTest('readAsText', false, done, null, function (evt, fileData, fileDataAsBinaryString) {
2366 expect(evt.target.result).toEqual(JSON.stringify(testObject));
2367 done();
2368 }, undefined, undefined, JSON.stringify(testObject));
2369 });
2370 it("file.spec.85 should read file properly, Data URI", function (done) {
2371 runReaderTest('readAsDataURL', true, done, null, function (evt, fileData, fileDataAsBinaryString) {
2372 /* `readAsDataURL` function is supported, but the mediatype in Chrome depends on entry name extension,
2373 mediatype in IE is always empty (which is the same as `text-plain` according the specification),
2374 the mediatype in Firefox is always `application/octet-stream`.
2375 For example, if the content is `abcdefg` then Firefox returns `data:application/octet-stream;base64,YWJjZGVmZw==`,
2376 IE returns `data:;base64,YWJjZGVmZw==`, Chrome returns `data:<mediatype depending on extension of entry name>;base64,YWJjZGVmZw==`. */
2377 expect(evt.target.result).toBeDataUrl();
2378
2379 //The atob function it is completely ignored during mobilespec execution, besides the returned object: evt
2380 //it is encoded and the atob function is aimed to decode a string. Even with btoa (encode) the function it gets stucked
2381 //because of the Unicode characters that contains the fileData object.
2382 //Issue reported at JIRA with all the details: CB-7095
2383
2384 //expect(evt.target.result.slice(23)).toBe(atob(fileData));
2385
2386 done();
2387 });
2388 });
2389 it("file.spec.86 should read file properly, readAsBinaryString", function (done) {
2390 if (isIE) {
2391 /*`readAsBinaryString` function is not supported by IE and has not the stub.*/
2392 pending();
2393 }
2394
2395 runReaderTest('readAsBinaryString', true, done, null, function (evt, fileData, fileDataAsBinaryString) {
2396 expect(evt.target.result).toBe(fileDataAsBinaryString);
2397 done();
2398 });
2399 });
2400 it("file.spec.87 should read file properly, readAsArrayBuffer", function (done) {
2401 // Skip test if ArrayBuffers are not supported (e.g.: Android 2.3).
2402 if (typeof window.ArrayBuffer == 'undefined') {
2403 expect(true).toFailWithMessage('Platform does not supported this feature');
2404 done();
2405 }
2406 runReaderTest('readAsArrayBuffer', true, done, null, function (evt, fileData, fileDataAsBinaryString) {
2407 expect(arrayBufferEqualsString(evt.target.result, fileDataAsBinaryString)).toBe(true);
2408 done();
2409 });
2410 });
2411 it("file.spec.88 should read sliced file: readAsText", function (done) {
2412 runReaderTest('readAsText', false, done, null, function (evt, fileData, fileDataAsBinaryString) {
2413 expect(evt.target.result).toBe(fileDataAsBinaryString.slice(10, 40));
2414 done();
2415 }, 10, 40);
2416 });
2417 it("file.spec.89 should read sliced file: slice past eof", function (done) {
2418 runReaderTest('readAsText', false, done, null, function (evt, fileData, fileDataAsBinaryString) {
2419 expect(evt.target.result).toBe(fileData.slice(-5, 9999));
2420 done();
2421 }, -5, 9999);
2422 });
2423 it("file.spec.90 should read sliced file: slice to eof", function (done) {
2424 runReaderTest('readAsText', false, done, null, function (evt, fileData, fileDataAsBinaryString) {
2425 expect(evt.target.result).toBe(fileData.slice(-5));
2426 done();
2427 }, -5);
2428 });
2429 it("file.spec.91 should read empty slice", function (done) {
2430 runReaderTest('readAsText', false, done, null, function (evt, fileData, fileDataAsBinaryString) {
2431 expect(evt.target.result).toBe('');
2432 done();
2433 }, 0, 0);
2434 });
2435 it("file.spec.92 should read sliced file properly, readAsDataURL", function (done) {
2436 runReaderTest('readAsDataURL', true, done, null, function (evt, fileData, fileDataAsBinaryString) {
2437 /* `readAsDataURL` function is supported, but the mediatype in Chrome depends on entry name extension,
2438 mediatype in IE is always empty (which is the same as `text-plain` according the specification),
2439 the mediatype in Firefox is always `application/octet-stream`.
2440 For example, if the content is `abcdefg` then Firefox returns `data:application/octet-stream;base64,YWJjZGVmZw==`,
2441 IE returns `data:;base64,YWJjZGVmZw==`, Chrome returns `data:<mediatype depending on extension of entry name>;base64,YWJjZGVmZw==`. */
2442 expect(evt.target.result).toBeDataUrl();
2443
2444 //The atob function it is completely ignored during mobilespec execution, besides the returned object: evt
2445 //it is encoded and the atob function is aimed to decode a string. Even with btoa (encode) the function it gets stucked
2446 //because of the Unicode characters that contains the fileData object.
2447 //Issue reported at JIRA with all the details: CB-7095
2448
2449 //expect(evt.target.result.slice(23)).toBe(atob(fileDataAsBinaryString.slice(10, -3)));
2450
2451 done();
2452 }, 10, -3);
2453 });
2454 it("file.spec.93 should read sliced file properly, readAsBinaryString", function (done) {
2455 if (isIE) {
2456 /*`readAsBinaryString` function is not supported by IE and has not the stub.*/
2457 pending();
2458 }
2459
2460 runReaderTest('readAsBinaryString', true, done, null, function (evt, fileData, fileDataAsBinaryString) {
2461 expect(evt.target.result).toBe(fileDataAsBinaryString.slice(-10, -5));
2462 done();
2463 }, -10, -5);
2464 });
2465 it("file.spec.94 should read sliced file properly, readAsArrayBuffer", function (done) {
2466 // Skip test if ArrayBuffers are not supported (e.g.: Android 2.3).
2467 if (typeof window.ArrayBuffer == 'undefined') {
2468 expect(true).toFailWithMessage('Platform does not supported this feature');
2469 done();
2470 }
2471 runReaderTest('readAsArrayBuffer', true, done, null, function (evt, fileData, fileDataAsBinaryString) {
2472 expect(arrayBufferEqualsString(evt.target.result, fileDataAsBinaryString.slice(0, -1))).toBe(true);
2473 done();
2474 }, 0, -1);
2475 });
2476 it("file.spec.94.5 should read large file in multiple chunks, readAsArrayBuffer", function (done) {
2477 // Skip test if ArrayBuffers are not supported (e.g.: Android 2.3).
2478 if (typeof window.ArrayBuffer == 'undefined') {
2479 expect(true).toFailWithMessage('Platform does not supported this feature');
2480 done();
2481 }
2482
2483 var largeText = "";
2484 for (var i = 0; i < 1000; i++) {
2485 largeText += "Test " + i + "\n";
2486 }
2487
2488 // Set the chunk size so that the read will take 5 chunks
2489 FileReader.READ_CHUNK_SIZE = Math.floor(largeText.length / 4) + 1;
2490
2491 var chunkCount = 0;
2492 var lastProgressValue = -1;
2493 var progressFunc = function (evt) {
2494 expect(evt.loaded).toBeDefined();
2495 expect(evt.total).toBeDefined();
2496
2497 expect(evt.total >= largeText.length).toBe(true);
2498 expect(evt.total <= largeText.length + 5).toBe(true);
2499 expect(evt.loaded > lastProgressValue).toBe(true);
2500 expect(evt.loaded <= evt.total).toBe(true);
2501
2502 lastProgressValue = evt.loaded;
2503 chunkCount++;
2504 };
2505
2506 runReaderTest(
2507 'readAsArrayBuffer', true, done, progressFunc,
2508 function (evt, fileData, fileDataAsBinaryString) {
2509 expect(arrayBufferEqualsString(evt.target.result, fileDataAsBinaryString.slice(0, -1))).toBe(true);
2510 expect(lastProgressValue >= largeText.length).toBe(true);
2511 expect(lastProgressValue <= largeText.length + 5).toBe(true);
2512 expect(chunkCount).toBe(5);
2513 done();
2514 },
2515 0, -1, largeText);
2516 });
2517 it("file.spec.94.6 should read large file in multiple chunks, readAsDataURL", function (done) {
2518 var largeText = "";
2519 for (var i = 0; i < 10; i++) {
2520 largeText += "Test " + i + "\n";
2521 }
2522
2523 // Set the chunk size so that the read will take 5 chunks
2524 FileReader.READ_CHUNK_SIZE = Math.floor(largeText.length / 4) + 1;
2525
2526 var lastProgressValue = 0;
2527 var progressFunc = function (evt) {
2528 expect(evt.total).toBeDefined();
2529 expect(evt.total).toEqual(largeText.length);
2530
2531 expect(evt.loaded).toBeDefined();
2532 expect(evt.loaded).toBeGreaterThan(lastProgressValue);
2533 expect(evt.loaded).toBeLessThan(evt.total + 1);
2534
2535 lastProgressValue = evt.loaded;
2536 };
2537
2538 runReaderTest('readAsDataURL', false, done, progressFunc,
2539 function (evt, fileData, fileDataAsBinaryString) {
2540 expect(function () {
2541 // Cut off data uri prefix
2542 var base64Data = evt.target.result.substring(evt.target.result.indexOf(',') + 1);
2543 expect(window.atob(base64Data)).toEqual(fileData);
2544 }).not.toThrow();
2545
2546 expect(lastProgressValue).toEqual(largeText.length);
2547 done();
2548 },
2549 undefined, undefined, largeText);
2550 });
2551 });
2552 //Read method
2553 describe('FileWriter', function () {
2554 it("file.spec.95 should have correct methods", function (done) {
2555 // retrieve a FileWriter object
2556 var fileName = "writer.methods";
2557 // FileWriter
2558 root.getFile(fileName, {
2559 create : true
2560 }, function (fileEntry) {
2561 fileEntry.createWriter(function (writer) {
2562 expect(writer).toBeDefined();
2563 expect(typeof writer.write).toBe('function');
2564 expect(typeof writer.seek).toBe('function');
2565 expect(typeof writer.truncate).toBe('function');
2566 expect(typeof writer.abort).toBe('function');
2567 // cleanup
2568 deleteFile(fileName, done);
2569 }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));
2570 }, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName));
2571 });
2572 it("file.spec.96 should be able to write and append to file, createWriter", function (done) {
2573 var fileName = "writer.append.createWriter", // file content
2574 content = "There is an exception to every rule.", // for checkin file length
2575 exception = " Except this one.",
2576 length = content.length;
2577 // create file, then write and append to it
2578 createFile(fileName, function (fileEntry) {
2579 // writes initial file content
2580 fileEntry.createWriter(function (writer) {
2581 //Verifiers declaration
2582 function verifier(evt) {
2583 expect(writer.length).toBe(length);
2584 expect(writer.position).toBe(length);
2585 // Append some more data
2586 writer.onwriteend = secondVerifier;
2587 length += exception.length;
2588 writer.seek(writer.length);
2589 writer.write(exception);
2590 }
2591 function secondVerifier(evt) {
2592 expect(writer.length).toBe(length);
2593 expect(writer.position).toBe(length);
2594 var reader = new FileReader();
2595 reader.onloadend = thirdVerifier;
2596 reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + fileName);
2597 fileEntry.file(function(f){reader.readAsText(f);});
2598 }
2599 function thirdVerifier(evt) {
2600 expect(evt.target.result).toBe(content+exception);
2601 // cleanup
2602 deleteFile(fileName, done);
2603 }
2604
2605 //Write process
2606 writer.onwriteend = verifier;
2607 writer.write(content);
2608 }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));
2609 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
2610 });
2611 it("file.spec.97 should be able to write and append to file, File object", function (done) {
2612 var fileName = "writer.append.File", // file content
2613 content = "There is an exception to every rule.", // for checkin file length
2614 exception = " Except this one.",
2615 length = content.length;
2616 root.getFile(fileName, {
2617 create : true
2618 }, function (fileEntry) {
2619 fileEntry.createWriter(function (writer) {
2620 //Verifiers declaration
2621 function verifier() {
2622 expect(writer.length).toBe(length);
2623 expect(writer.position).toBe(length);
2624 // Append some more data
2625 writer.onwriteend = secondVerifier;
2626 length += exception.length;
2627 writer.seek(writer.length);
2628 writer.write(exception);
2629 }
2630 function secondVerifier() {
2631 expect(writer.length).toBe(length);
2632 expect(writer.position).toBe(length);
2633 var reader = new FileReader();
2634 reader.onloadend = thirdVerifier;
2635 reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + fileName);
2636 fileEntry.file(function(f){reader.readAsText(f);});
2637 }
2638 function thirdVerifier(evt) {
2639 expect(evt.target.result).toBe(content+exception);
2640 // cleanup
2641 deleteFile(fileName, done);
2642 }
2643
2644 //Write process
2645 writer.onwriteend = verifier;
2646 writer.write(content);
2647 }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));
2648 }, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName));
2649 });
2650 it("file.spec.98 should be able to seek to the middle of the file and write more data than file.length", function (done) {
2651 var fileName = "writer.seek.write", // file content
2652 content = "This is our sentence.", // for checking file length
2653 exception = "newer sentence.",
2654 length = content.length;
2655 // create file, then write and append to it
2656 createFile(fileName, function (fileEntry) {
2657 fileEntry.createWriter(function (writer) {
2658 //Verifiers declaration
2659 function verifier(evt) {
2660 expect(writer.length).toBe(length);
2661 expect(writer.position).toBe(length);
2662 // Append some more data
2663 writer.onwriteend = secondVerifier;
2664 length = 12 + exception.length;
2665 writer.seek(12);
2666 writer.write(exception);
2667 }
2668 function secondVerifier(evt) {
2669 expect(writer.length).toBe(length);
2670 expect(writer.position).toBe(length);
2671 var reader = new FileReader();
2672 reader.onloadend = thirdVerifier;
2673 reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + fileName);
2674 fileEntry.file(function(f){reader.readAsText(f);});
2675 }
2676 function thirdVerifier(evt) {
2677 expect(evt.target.result).toBe(content.substr(0,12)+exception);
2678 // cleanup
2679 deleteFile(fileName, done);
2680 }
2681
2682 //Write process
2683 writer.onwriteend = verifier;
2684 writer.write(content);
2685 }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));
2686 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
2687 });
2688 it("file.spec.99 should be able to seek to the middle of the file and write less data than file.length", function (done) {
2689 if (isChrome) {
2690 /* Chrome (re)writes as follows: "This is our sentence." -> "This is new.sentence.",
2691 i.e. the length is not being changed from content.length and writer length will be equal 21 */
2692 pending();
2693 }
2694
2695 var fileName = "writer.seek.write2", // file content
2696 content = "This is our sentence.", // for checking file length
2697 exception = "new.",
2698 length = content.length;
2699 // create file, then write and append to it
2700 createFile(fileName, function (fileEntry) {
2701 fileEntry.createWriter(function (writer) {
2702 // Verifiers declaration
2703 function verifier(evt) {
2704 expect(writer.length).toBe(length);
2705 expect(writer.position).toBe(length);
2706 // Append some more data
2707 writer.onwriteend = secondVerifier;
2708 length = 8 + exception.length;
2709 writer.seek(8);
2710 writer.write(exception);
2711 }
2712 function secondVerifier(evt) {
2713 expect(writer.length).toBe(length);
2714 expect(writer.position).toBe(length);
2715 var reader = new FileReader();
2716 reader.onloadend = thirdVerifier;
2717 reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + fileName);
2718 fileEntry.file(function(f){reader.readAsText(f);});
2719 }
2720 function thirdVerifier(evt) {
2721 expect(evt.target.result).toBe(content.substr(0,8)+exception);
2722 // cleanup
2723 deleteFile(fileName, done);
2724 }
2725
2726 //Write process
2727 writer.onwriteend = verifier;
2728 writer.write(content);
2729 }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));
2730 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
2731 });
2732 it("file.spec.100 should be able to write XML data", function (done) {
2733 var fileName = "writer.xml", // file content
2734 content = '<?xml version="1.0" encoding="UTF-8"?>\n<test prop="ack">\nData\n</test>\n', // for testing file length
2735 length = content.length;
2736 // creates file, then write XML data
2737 createFile(fileName, function (fileEntry) {
2738 fileEntry.createWriter(function (writer) {
2739 //Verifier content
2740 var verifier = function (evt) {
2741 expect(writer.length).toBe(length);
2742 expect(writer.position).toBe(length);
2743 // cleanup
2744 deleteFile(fileName, done);
2745 };
2746 //Write process
2747 writer.onwriteend = verifier;
2748 writer.write(content);
2749 }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));
2750 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
2751 });
2752 it("file.spec.101 should be able to write JSON data", function (done) {
2753 var fileName = "writer.json", // file content
2754 content = '{ "name": "Guy Incognito", "email": "here@there.com" }', // for testing file length
2755 length = content.length;
2756 // creates file, then write JSON content
2757 createFile(fileName, function (fileEntry) {
2758 fileEntry.createWriter(function (writer) {
2759 //Verifier declaration
2760 var verifier = function (evt) {
2761 expect(writer.length).toBe(length);
2762 expect(writer.position).toBe(length);
2763 // cleanup
2764 deleteFile(fileName, done);
2765 };
2766 //Write process
2767 writer.onwriteend = verifier;
2768 writer.write(content);
2769 }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));
2770 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
2771 });
2772 it("file.spec.102 should be able to seek", function (done) {
2773 var fileName = "writer.seek", // file content
2774 content = "There is an exception to every rule. Except this one.", // for testing file length
2775 length = content.length;
2776 // creates file, then write JSON content
2777 createFile(fileName, function (fileEntry) {
2778 // writes file content and tests writer.seek
2779 fileEntry.createWriter(function (writer) {
2780 //Verifier declaration
2781 var verifier = function () {
2782 expect(writer.position).toBe(length);
2783 writer.seek(-5);
2784 expect(writer.position).toBe(length - 5);
2785 writer.seek(length + 100);
2786 expect(writer.position).toBe(length);
2787 writer.seek(10);
2788 expect(writer.position).toBe(10);
2789 // cleanup
2790 deleteFile(fileName, done);
2791 };
2792 //Write process
2793 writer.onwriteend = verifier;
2794 writer.seek(-100);
2795 expect(writer.position).toBe(0);
2796 writer.write(content);
2797 }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));
2798 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
2799 });
2800 it("file.spec.103 should be able to truncate", function (done) {
2801 if (isIndexedDBShim) {
2802 /* `abort` and `truncate` functions are not supported (Firefox, IE) */
2803 pending();
2804 }
2805
2806 var fileName = "writer.truncate",
2807 content = "There is an exception to every rule. Except this one.";
2808 // creates file, writes to it, then truncates it
2809 createFile(fileName, function (fileEntry) {
2810 fileEntry.createWriter(function (writer) {
2811 // Verifier declaration
2812 var verifier = function () {
2813 expect(writer.length).toBe(36);
2814 expect(writer.position).toBe(36);
2815 // cleanup
2816 deleteFile(fileName, done);
2817 };
2818 //Write process
2819 writer.onwriteend = function () {
2820 //Truncate process after write
2821 writer.onwriteend = verifier;
2822 writer.truncate(36);
2823 };
2824 writer.write(content);
2825 }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));
2826 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
2827 });
2828 it("file.spec.104 should be able to write binary data from an ArrayBuffer", function (done) {
2829 // Skip test if ArrayBuffers are not supported (e.g.: Android 2.3).
2830 if (typeof window.ArrayBuffer == 'undefined') {
2831 expect(true).toFailWithMessage('Platform does not supported this feature');
2832 done();
2833 return;
2834 }
2835 var fileName = "bufferwriter.bin", // file content
2836 data = new ArrayBuffer(32),
2837 dataView = new Int8Array(data), // for verifying file length
2838 length = 32;
2839 for (var i = 0; i < dataView.length; i++) {
2840 dataView[i] = i;
2841 }
2842 // creates file, then write content
2843 createFile(fileName, function (fileEntry) {
2844 // writes file content
2845 fileEntry.createWriter(function (writer) {
2846 //Verifier declaration
2847 var verifier = function () {
2848 expect(writer.length).toBe(length);
2849 expect(writer.position).toBe(length);
2850 // cleanup
2851 deleteFile(fileName, done);
2852 };
2853 //Write process
2854 writer.onwriteend = verifier;
2855 writer.write(data);
2856 }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));
2857 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
2858 });
2859 it("file.spec.105 should be able to write binary data from a Blob", function (done) {
2860 // Skip test if Blobs are not supported (e.g.: Android 2.3).
2861 if ((typeof window.Blob == 'undefined' && typeof window.WebKitBlobBuilder == 'undefined') || typeof window.ArrayBuffer == 'undefined') {
2862 expect(true).toFailWithMessage('Platform does not supported this feature');
2863 done();
2864 return;
2865 }
2866 var fileName = "blobwriter.bin", // file content
2867 data = new ArrayBuffer(32),
2868 dataView = new Int8Array(data),
2869 blob, // for verifying file length
2870 length = 32;
2871 for (var i = 0; i < dataView.length; i++) {
2872 dataView[i] = i;
2873 }
2874 try {
2875 // Mobile Safari: Use Blob constructor
2876 blob = new Blob([data], {
2877 "type" : "application/octet-stream"
2878 });
2879 } catch (e) {
2880 if (window.WebKitBlobBuilder) {
2881 // Android Browser: Use deprecated BlobBuilder
2882 var builder = new WebKitBlobBuilder();
2883 builder.append(data);
2884 blob = builder.getBlob('application/octet-stream');
2885 } else {
2886 // We have no way defined to create a Blob, so fail
2887 fail();
2888 }
2889 }
2890 if (typeof blob !== 'undefined') {
2891 // creates file, then write content
2892 createFile(fileName, function (fileEntry) {
2893 fileEntry.createWriter(function (writer) {
2894 //Verifier declaration
2895 var verifier = function () {
2896 expect(writer.length).toBe(length);
2897 expect(writer.position).toBe(length);
2898 // cleanup
2899 deleteFile(fileName, done);
2900 };
2901 //Write process
2902 writer.onwriteend = verifier;
2903 writer.write(blob);
2904 }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));
2905 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
2906 }
2907 });
2908 it("file.spec.106 should be able to write a File to a FileWriter", function (done) {
2909 var dummyFileName = 'dummy.txt',
2910 outputFileName = 'verify.txt',
2911 dummyFileText = 'This text should be written to two files',
2912 verifier = function (outputFileWriter) {
2913 expect(outputFileWriter.length).toBe(dummyFileText.length);
2914 expect(outputFileWriter.position).toBe(dummyFileText.length);
2915 deleteFile(outputFileName, done);
2916 },
2917 writeFile = function (fileName, fileData, win) {
2918 var theWriter,
2919 write_file = function (fileEntry) {
2920 // writes file content to new file
2921 fileEntry.createWriter(function (writer) {
2922 theWriter = writer;
2923 writer.onwriteend = function (ev) {
2924 if (typeof fileData.length !== "undefined") {
2925 expect(theWriter.length).toBe(fileData.length);
2926 expect(theWriter.position).toBe(fileData.length);
2927 }
2928 win(theWriter);
2929 };
2930 writer.onerror = failed.bind(null, done, 'writer.onerror - Error writing content on file: ' + fileName);
2931 writer.write(fileData);
2932 }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));
2933 };
2934 createFile(fileName, write_file, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
2935 },
2936 openFile = function (fileName, callback) {
2937 root.getFile(fileName, {
2938 create : false
2939 }, function (fileEntry) {
2940 fileEntry.file(callback, failed.bind(null, done, 'fileEntry.file - Error reading file using fileEntry: ' + fileEntry.name));
2941 }, failed.bind(null, done, 'root.getFile - Error getting file: ' + fileName));
2942 };
2943 writeFile(dummyFileName, dummyFileText, function (dummyFileWriter) {
2944 openFile(dummyFileName, function (file) {
2945 writeFile(outputFileName, file, verifier);
2946 });
2947 });
2948 });
2949 it("file.spec.107 should be able to write a sliced File to a FileWriter", function (done) {
2950 var dummyFileName = 'dummy2.txt',
2951 outputFileName = 'verify2.txt',
2952 dummyFileText = 'This text should be written to two files',
2953 verifier = function (outputFileWriter) {
2954 expect(outputFileWriter.length).toBe(10);
2955 expect(outputFileWriter.position).toBe(10);
2956 deleteFile(outputFileName, done);
2957 },
2958 writeFile = function (fileName, fileData, win) {
2959 var theWriter,
2960 write_file = function (fileEntry) {
2961 // writes file content to new file
2962 fileEntry.createWriter(function (writer) {
2963 theWriter = writer;
2964 writer.onwriteend = function (ev) {
2965 if (typeof fileData.length !== "undefined") {
2966 expect(theWriter.length).toBe(fileData.length);
2967 expect(theWriter.position).toBe(fileData.length);
2968 }
2969 win(theWriter);
2970 };
2971 writer.onerror = failed.bind(null, done, 'writer.onerror - Error writing content on file: ' + fileName);
2972 writer.write(fileData);
2973 }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));
2974 };
2975 createFile(fileName, write_file, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
2976 },
2977 openFile = function (fileName, callback) {
2978 root.getFile(fileName, {
2979 create : false
2980 }, function (fileEntry) {
2981 fileEntry.file(callback, failed.bind(null, done, 'fileEntry.file - Error reading file using fileEntry: ' + fileEntry.name));
2982 }, failed.bind(null, done, 'root.getFile - Error getting file: ' + fileName));
2983 };
2984 writeFile(dummyFileName, dummyFileText, function (dummyFileWriter) {
2985 openFile(dummyFileName, function (file) {
2986 writeFile(outputFileName, file.slice(10, 20), verifier);
2987 });
2988 });
2989 });
2990 it("file.spec.108 should be able to write binary data from a File", function (done) {
2991 // Skip test if Blobs are not supported (e.g.: Android 2.3).
2992 if (typeof window.Blob == 'undefined' && typeof window.WebKitBlobBuilder == 'undefined') {
2993 expect(true).toFailWithMessage('Platform does not supported this feature');
2994 done();
2995 }
2996 var dummyFileName = "blobwriter.bin",
2997 outputFileName = 'verify.bin', // file content
2998 data = new ArrayBuffer(32),
2999 dataView = new Int8Array(data),
3000 blob, // for verifying file length
3001 length = 32,
3002 verifier = function (outputFileWriter) {
3003 expect(outputFileWriter.length).toBe(length);
3004 expect(outputFileWriter.position).toBe(length);
3005 // cleanup
3006 deleteFile(outputFileName);
3007 done();
3008 },
3009 writeFile = function (fileName, fileData, win) {
3010 var theWriter,
3011 write_file = function (fileEntry) {
3012 // writes file content to new file
3013 fileEntry.createWriter(function (writer) {
3014 theWriter = writer;
3015 writer.onwriteend = function (ev) {
3016 if (typeof fileData.length !== "undefined") {
3017 expect(theWriter.length).toBe(fileData.length);
3018 expect(theWriter.position).toBe(fileData.length);
3019 }
3020 win(theWriter);
3021 };
3022 writer.onerror = failed.bind(null, done, 'writer.onerror - Error writing content on file: ' + fileName);
3023 writer.write(fileData);
3024 }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));
3025 };
3026 createFile(fileName, write_file, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
3027 },
3028 openFile = function (fileName, callback) {
3029 root.getFile(fileName, {
3030 create : false
3031 }, function (fileEntry) {
3032 fileEntry.file(callback, failed.bind(null, done, 'fileEntry.file - Error reading file using fileEntry: ' + fileEntry.name));
3033 }, failed.bind(null, done, 'root.getFile - Error getting file: ' + fileName));
3034 };
3035 for (var i = 0; i < dataView.length; i++) {
3036 dataView[i] = i;
3037 }
3038 try {
3039 // Mobile Safari: Use Blob constructor
3040 blob = new Blob([data], {
3041 "type" : "application/octet-stream"
3042 });
3043 } catch (e) {
3044 if (window.WebKitBlobBuilder) {
3045 // Android Browser: Use deprecated BlobBuilder
3046 var builder = new WebKitBlobBuilder();
3047 builder.append(data);
3048 blob = builder.getBlob('application/octet-stream');
3049 } else {
3050 // We have no way defined to create a Blob, so fail
3051 fail();
3052 }
3053 }
3054 if (typeof blob !== 'undefined') {
3055 // creates file, then write content
3056 writeFile(dummyFileName, blob, function (dummyFileWriter) {
3057 openFile(dummyFileName, function (file) {
3058 writeFile(outputFileName, file, verifier);
3059 });
3060 });
3061 }
3062 });
3063 });
3064 //FileWritter
3065 describe('Backwards compatibility', function () {
3066 /* These specs exist to test that the File plugin can still recognize file:///
3067 * URLs, and can resolve them to FileEntry and DirectoryEntry objects.
3068 * They rely on an undocumented interface to File which provides absolute file
3069 * paths, which are not used internally anymore.
3070 * If that interface is not present, then these tests will silently succeed.
3071 */
3072 it("file.spec.109 should be able to resolve a file:/// URL", function (done) {
3073 var localFilename = 'file.txt';
3074 var originalEntry;
3075 root.getFile(localFilename, {
3076 create : true
3077 }, function (entry) {
3078 originalEntry = entry;
3079 /* This is an undocumented interface to File which exists only for testing
3080 * backwards compatibilty. By obtaining the raw filesystem path of the download
3081 * location, we can pass that to ft.download() to make sure that previously-stored
3082 * paths are still valid.
3083 */
3084 cordova.exec(function (localPath) {
3085 window.resolveLocalFileSystemURL("file://" + encodeURI(localPath), function (fileEntry) {
3086 expect(fileEntry.toURL()).toEqual(originalEntry.toURL());
3087 // cleanup
3088 deleteFile(localFilename);
3089 done();
3090 }, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving URI: file://' + encodeURI(localPath)));
3091 }, done, 'File', '_getLocalFilesystemPath', [entry.toURL()]);
3092 }, failed.bind(null, done, 'root.getFile - Error creating file: ' + localFilename));
3093 });
3094 });
3095 //Backwards Compatibility
3096 describe('Parent References', function () {
3097 /* These specs verify that paths with parent references i("..") in them
3098 * work correctly, and do not cause the application to crash.
3099 */
3100 it("file.spec.110 should not throw exception resolving parent refefences", function (done) {
3101 /* This is a direct copy of file.spec.9, with the filename changed, * as reported in CB-5721.
3102 */
3103 var fileName = "resolve.file.uri";
3104 var dirName = "resolve.dir.uri";
3105 // create a new file entry
3106 createDirectory(dirName, function () {
3107 createFile(dirName+"/../" + fileName, function (entry) {
3108 // lookup file system entry
3109 window.resolveLocalFileSystemURL(entry.toURL(), function (fileEntry) {
3110 expect(fileEntry).toBeDefined();
3111 expect(fileEntry.name).toCanonicallyMatch(fileName);
3112 // cleanup
3113 deleteEntry(fileName, done);
3114 }, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving URI: ' + entry.toURL()));
3115 }, failed.bind(null, done, 'createFile - Error creating file: ../' + fileName));
3116 }, failed.bind(null, done, 'createDirectory - Error creating directory: ' + dirName));
3117 });
3118 it("file.spec.111 should not traverse above above the root directory", function (done) {
3119 var fileName = "traverse.file.uri";
3120 // create a new file entry
3121 createFile(fileName, function (entry) {
3122 // lookup file system entry
3123 root.getFile('../' + fileName, {
3124 create : false
3125 }, function (fileEntry) {
3126 // Note: we expect this to still resolve, as the correct behaviour is to ignore the ../, not to fail out.
3127 expect(fileEntry).toBeDefined();
3128 expect(fileEntry.name).toBe(fileName);
3129 expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath +'/' + fileName);
3130 // cleanup
3131 deleteEntry(fileName, done);
3132 }, failed.bind(null, done, 'root.getFile - Error getting file: ../' + fileName));
3133 }, failed.bind(null, done, 'createFile - Error creating file: ../' + fileName));
3134 });
3135 it("file.spec.112 should traverse above above the current directory", function (done) {
3136 var fileName = "traverse2.file.uri",
3137 dirName = "traverse2.subdir";
3138 // create a new directory and a file entry
3139 createFile(fileName, function () {
3140 createDirectory(dirName, function (entry) {
3141 // lookup file system entry
3142 entry.getFile('../' + fileName, {
3143 create : false
3144 }, function (fileEntry) {
3145 expect(fileEntry).toBeDefined();
3146 expect(fileEntry.name).toBe(fileName);
3147 expect(fileEntry.fullPath).toCanonicallyMatch('/' + fileName);
3148 // cleanup
3149 deleteEntry(fileName, function () {
3150 deleteEntry(dirName, done);
3151 });
3152 }, failed.bind(null, done, 'entry.getFile - Error getting file: ' + fileName + ' recently created above: ' + dirName));
3153 }, failed.bind(null, done, 'createDirectory - Error creating directory: ' + dirName));
3154 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
3155 });
3156 it("file.spec.113 getFile: get Entry should error for missing file above root directory", function (done) {
3157 var fileName = "../missing.file";
3158 // create:false, exclusive:false, file does not exist
3159 root.getFile(fileName, {
3160 create : false
3161 }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not locate nonexistent file: ' + fileName), function (error) {
3162 expect(error).toBeDefined();
3163 expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
3164 done();
3165 });
3166 });
3167 });
3168 //Parent References
3169 describe('toNativeURL interface', function () {
3170 /* These specs verify that FileEntries have a toNativeURL method
3171 * which appears to be sane.
3172 */
3173 var pathExpect = cordova.platformId === 'windowsphone' ? "//nativ" : "file://";
3174 if (isChrome) {
3175 pathExpect = 'filesystem:file://';
3176 }
3177 it("file.spec.114 fileEntry should have a toNativeURL method", function (done) {
3178 var fileName = "native.file.uri";
3179 if (isWindows) {
3180 var rootPath = root.fullPath;
3181 pathExpect = rootPath.substr(0, rootPath.indexOf(":"));
3182 }
3183 // create a new file entry
3184 createFile(fileName, function (entry) {
3185 expect(entry.toNativeURL).toBeDefined();
3186 expect(entry.name).toCanonicallyMatch(fileName);
3187 expect(typeof entry.toNativeURL).toBe('function');
3188 var nativeURL = entry.toNativeURL();
3189 expect(typeof nativeURL).toBe("string");
3190 expect(nativeURL.substring(0, pathExpect.length)).toEqual(pathExpect);
3191 expect(nativeURL.substring(nativeURL.length - fileName.length)).toEqual(fileName);
3192 // cleanup
3193 deleteEntry(fileName, done);
3194 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
3195 });
3196 it("file.spec.115 DirectoryReader should return entries with toNativeURL method", function (done) {
3197 var dirName = 'nativeEntries.dir',
3198 fileName = 'nativeEntries.file',
3199 directory,
3200 checkEntries = function (entries) {
3201 expect(entries).toBeDefined();
3202 expect(entries instanceof Array).toBe(true);
3203 expect(entries.length).toBe(1);
3204 expect(entries[0].toNativeURL).toBeDefined();
3205 expect(typeof entries[0].toNativeURL).toBe('function');
3206 var nativeURL = entries[0].toNativeURL();
3207 expect(typeof nativeURL).toBe("string");
3208 expect(nativeURL.substring(0, pathExpect.length)).toEqual(pathExpect);
3209 expect(nativeURL.substring(nativeURL.length - fileName.length)).toEqual(fileName);
3210 // cleanup
3211 directory.removeRecursively(null, null);
3212 done();
3213 };
3214 // create a new file entry
3215 root.getDirectory(dirName, {
3216 create : true
3217 }, function (dir) {
3218 directory = dir;
3219 directory.getFile(fileName, {
3220 create : true
3221 }, function (fileEntry) {
3222 var reader = directory.createReader();
3223 reader.readEntries(checkEntries, failed.bind(null, done, 'reader.readEntries - Error reading entries from directory: ' + dirName));
3224 }, failed.bind(null, done, 'directory.getFile - Error creating file: ' + fileName));
3225 }, failed.bind(null, done, 'root.getDirectory - Error creating directory: ' + dirName));
3226 });
3227 it("file.spec.116 resolveLocalFileSystemURL should return entries with toNativeURL method", function (done) {
3228 var fileName = "native.resolve.uri";
3229 // create a new file entry
3230 createFile(fileName, function (entry) {
3231 resolveLocalFileSystemURL(entry.toURL(), function (entry) {
3232 expect(entry.toNativeURL).toBeDefined();
3233 expect(entry.name).toCanonicallyMatch(fileName);
3234 expect(typeof entry.toNativeURL).toBe('function');
3235 var nativeURL = entry.toNativeURL();
3236 expect(typeof nativeURL).toBe("string");
3237 expect(nativeURL.substring(0, pathExpect.length)).toEqual(pathExpect);
3238 expect(nativeURL.substring(nativeURL.length - fileName.length)).toEqual(fileName);
3239 // cleanup
3240 deleteEntry(fileName, done);
3241 }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + entry.toURL()));
3242 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
3243 });
3244 });
3245 //toNativeURL interface
3246 describe('resolveLocalFileSystemURL on file://', function () {
3247 /* These specs verify that window.resolveLocalFileSystemURL works correctly on file:// URLs
3248 */
3249 it("file.spec.117 should not resolve native URLs outside of FS roots", function (done) {
3250 // lookup file system entry
3251 window.resolveLocalFileSystemURL("file:///this.is.an.invalid.url", succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Unexpected success callback, it should not resolve invalid URL: file:///this.is.an.invalid.url'), function (error) {
3252 expect(error).toBeDefined();
3253 done();
3254 });
3255 });
3256 it("file.spec.118 should not resolve native URLs outside of FS roots", function (done) {
3257 // lookup file system entry
3258 window.resolveLocalFileSystemURL("file://localhost/this.is.an.invalid.url", succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Unexpected success callback, it should not resolve invalid URL: file://localhost/this.is.an.invalid.url'), function (error) {
3259 expect(error).toBeDefined();
3260 done();
3261 });
3262 });
3263 it("file.spec.119 should not resolve invalid native URLs", function (done) {
3264 // lookup file system entry
3265 window.resolveLocalFileSystemURL("file://localhost", succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Unexpected success callback, it should not resolve invalid URL: file://localhost'), function (error) {
3266 expect(error).toBeDefined();
3267 done();
3268 });
3269 });
3270 it("file.spec.120 should not resolve invalid native URLs with query strings", function (done) {
3271 // lookup file system entry
3272 window.resolveLocalFileSystemURL("file://localhost?test/test", succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Unexpected success callback, it should not resolve invalid URL: file://localhost?test/test'), function (error) {
3273 expect(error).toBeDefined();
3274 done();
3275 });
3276 });
3277 it("file.spec.121 should resolve native URLs returned by API", function (done) {
3278 var fileName = "native.resolve.uri1";
3279 // create a new file entry
3280 createFile(fileName, function (entry) {
3281 resolveLocalFileSystemURL(entry.toNativeURL(), function (fileEntry) {
3282 expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath + "/" + fileName);
3283 // cleanup
3284 deleteEntry(fileName, done);
3285 }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + entry.toNativeURL()));
3286 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
3287 });
3288 it("file.spec.122 should resolve native URLs returned by API with localhost", function (done) {
3289 var fileName = "native.resolve.uri2";
3290 // create a new file entry
3291 createFile(fileName, function (entry) {
3292 var url = entry.toNativeURL();
3293 url = url.replace("///", "//localhost/");
3294 resolveLocalFileSystemURL(url, function (fileEntry) {
3295 expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath + "/" + fileName);
3296 // cleanup
3297 deleteEntry(fileName, done);
3298 }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + url));
3299 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
3300 });
3301 it("file.spec.123 should resolve native URLs returned by API with query string", function (done) {
3302 var fileName = "native.resolve.uri3";
3303 // create a new file entry
3304 createFile(fileName, function (entry) {
3305 var url = entry.toNativeURL();
3306 url = url + "?test/test";
3307 resolveLocalFileSystemURL(url, function (fileEntry) {
3308 expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath + "/" + fileName);
3309 // cleanup
3310 deleteEntry(fileName, done);
3311 }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + url));
3312 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
3313 });
3314 it("file.spec.124 should resolve native URLs returned by API with localhost and query string", function (done) {
3315 var fileName = "native.resolve.uri4";
3316 // create a new file entry
3317 createFile(fileName, function (entry) {
3318 var url = entry.toNativeURL();
3319 url = url.replace("///", "//localhost/") + "?test/test";
3320 resolveLocalFileSystemURL(url, function (fileEntry) {
3321 expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath + "/" + fileName);
3322 // cleanup
3323 deleteEntry(fileName, done);
3324 }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + url));
3325 }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));
3326 });
3327 });
3328 //resolveLocalFileSystemURL on file://
3329 describe('cross-file-system copy and move', function () {
3330 /* These specs verify that Entry.copyTo and Entry.moveTo work correctly
3331 * when crossing filesystem boundaries.
3332 */
3333 it("file.spec.125 copyTo: temporary -> persistent", function (done) {
3334 var file1 = "entry.copy.file1a",
3335 file2 = "entry.copy.file2a",
3336 sourceEntry,
3337 fullPath = joinURL(root.fullPath, file2),
3338 validateFile = function (entry) {
3339 // a bit redundant since copy returned this entry already
3340 expect(entry).toBeDefined();
3341 expect(entry.isFile).toBe(true);
3342 expect(entry.isDirectory).toBe(false);
3343 expect(entry.name).toCanonicallyMatch(file2);
3344 expect(entry.fullPath).toCanonicallyMatch(fullPath);
3345 expect(entry.filesystem).toBeDefined();
3346 if (isChrome) {
3347 expect(entry.filesystem.name).toContain("Persistent");
3348 } else {
3349 expect(entry.filesystem.name).toEqual("persistent");
3350 }
3351 // cleanup
3352 deleteEntry(entry.name);
3353 deleteEntry(sourceEntry.name, done);
3354 },
3355 createSourceAndTransfer = function () {
3356 temp_root.getFile(file1, {
3357 create : true
3358 }, function (entry) {
3359 expect(entry.filesystem).toBeDefined();
3360 if (isChrome) {
3361 expect(entry.filesystem.name).toContain("Temporary");
3362 } else {
3363 expect(entry.filesystem.name).toEqual("temporary");
3364 }
3365 sourceEntry = entry;
3366 // Save for later cleanup
3367 entry.copyTo(persistent_root, file2, validateFile, failed.bind(null, done, 'entry.copyTo - Error copying file: ' + file1 + ' to PERSISTENT root as: ' + file2));
3368 }, failed.bind(null, done, 'temp_root.getFile - Error creating file: ' + file1 + 'at TEMPORAL root'));
3369 };
3370 // Delete any existing file to start things off
3371 persistent_root.getFile(file2, {}, function (entry) {
3372 entry.remove(createSourceAndTransfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2));
3373 }, createSourceAndTransfer);
3374 });
3375 it("file.spec.126 copyTo: persistent -> temporary", function (done) {
3376 var file1 = "entry.copy.file1b",
3377 file2 = "entry.copy.file2b",
3378 sourceEntry,
3379 fullPath = joinURL(temp_root.fullPath, file2),
3380 validateFile = function (entry) {
3381 expect(entry).toBeDefined();
3382 expect(entry.isFile).toBe(true);
3383 expect(entry.isDirectory).toBe(false);
3384 expect(entry.name).toCanonicallyMatch(file2);
3385 expect(entry.fullPath).toCanonicallyMatch(fullPath);
3386 if (isChrome) {
3387 expect(entry.filesystem.name).toContain("Temporary");
3388 } else {
3389 expect(entry.filesystem.name).toEqual("temporary");
3390 }
3391 // cleanup
3392 deleteEntry(entry.name);
3393 deleteEntry(sourceEntry.name, done);
3394 },
3395 createSourceAndTransfer = function () {
3396 persistent_root.getFile(file1, {
3397 create : true
3398 }, function (entry) {
3399 expect(entry).toBeDefined();
3400 expect(entry.filesystem).toBeDefined();
3401 if (isChrome) {
3402 expect(entry.filesystem.name).toContain("Persistent");
3403 } else {
3404 expect(entry.filesystem.name).toEqual("persistent");
3405 }
3406 sourceEntry = entry;
3407 // Save for later cleanup
3408 entry.copyTo(temp_root, file2, validateFile, failed.bind(null, done, 'entry.copyTo - Error copying file: ' + file1 + ' to TEMPORAL root as: ' + file2));
3409 }, failed.bind(null, done, 'persistent_root.getFile - Error creating file: ' + file1 + 'at PERSISTENT root'));
3410 };
3411 // Delete any existing file to start things off
3412 temp_root.getFile(file2, {}, function (entry) {
3413 entry.remove(createSourceAndTransfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2));
3414 }, createSourceAndTransfer);
3415 });
3416 it("file.spec.127 moveTo: temporary -> persistent", function (done) {
3417 var file1 = "entry.copy.file1a",
3418 file2 = "entry.copy.file2a",
3419 sourceEntry,
3420 fullPath = joinURL(root.fullPath, file2),
3421 validateFile = function (entry) {
3422 // a bit redundant since copy returned this entry already
3423 expect(entry).toBeDefined();
3424 expect(entry.isFile).toBe(true);
3425 expect(entry.isDirectory).toBe(false);
3426 expect(entry.name).toCanonicallyMatch(file2);
3427 expect(entry.fullPath).toCanonicallyMatch(fullPath);
3428 expect(entry.filesystem).toBeDefined();
3429 if (isChrome) {
3430 expect(entry.filesystem.name).toContain("Persistent");
3431 } else {
3432 expect(entry.filesystem.name).toEqual("persistent");
3433 }
3434 // cleanup
3435 deleteEntry(entry.name);
3436 deleteEntry(sourceEntry.name, done);
3437 },
3438 createSourceAndTransfer = function () {
3439 temp_root.getFile(file1, {
3440 create : true
3441 }, function (entry) {
3442 expect(entry.filesystem).toBeDefined();
3443 if (isChrome) {
3444 expect(entry.filesystem.name).toContain("Temporary");
3445 } else {
3446 expect(entry.filesystem.name).toEqual("temporary");
3447 }
3448 sourceEntry = entry;
3449 // Save for later cleanup
3450 entry.moveTo(persistent_root, file2, validateFile, failed.bind(null, done, 'entry.moveTo - Error moving file: ' + file1 + ' to PERSISTENT root as: ' + file2));
3451 }, failed.bind(null, done, 'temp_root.getFile - Error creating file: ' + file1 + 'at TEMPORAL root'));
3452 };
3453 // Delete any existing file to start things off
3454 persistent_root.getFile(file2, {}, function (entry) {
3455 entry.remove(createSourceAndTransfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2));
3456 }, createSourceAndTransfer);
3457 });
3458 it("file.spec.128 moveTo: persistent -> temporary", function (done) {
3459 var file1 = "entry.copy.file1b",
3460 file2 = "entry.copy.file2b",
3461 sourceEntry,
3462 fullPath = joinURL(temp_root.fullPath, file2),
3463 validateFile = function (entry) {
3464 expect(entry).toBeDefined();
3465 expect(entry.isFile).toBe(true);
3466 expect(entry.isDirectory).toBe(false);
3467 expect(entry.name).toCanonicallyMatch(file2);
3468 expect(entry.fullPath).toCanonicallyMatch(fullPath);
3469 if(isChrome) {
3470 expect(entry.filesystem.name).toContain("Temporary");
3471 } else {
3472 expect(entry.filesystem.name).toEqual("temporary");
3473 }
3474 // cleanup
3475 deleteEntry(entry.name);
3476 deleteEntry(sourceEntry.name, done);
3477 },
3478 createSourceAndTransfer = function () {
3479 persistent_root.getFile(file1, {
3480 create : true
3481 }, function (entry) {
3482 expect(entry).toBeDefined();
3483 expect(entry.filesystem).toBeDefined();
3484 if (isChrome) {
3485 expect(entry.filesystem.name).toContain("Persistent");
3486 } else {
3487 expect(entry.filesystem.name).toEqual("persistent");
3488 }
3489 sourceEntry = entry;
3490 // Save for later cleanup
3491 entry.moveTo(temp_root, file2, validateFile, failed.bind(null, done, 'entry.moveTo - Error moving file: ' + file1 + ' to TEMPORAL root as: ' + file2));
3492 }, failed.bind(null, done, 'persistent_root.getFile - Error creating file: ' + file1 + 'at PERSISTENT root'));
3493 };
3494 // Delete any existing file to start things off
3495 temp_root.getFile(file2, {}, function (entry) {
3496 entry.remove(createSourceAndTransfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2));
3497 }, createSourceAndTransfer);
3498 });
3499 it("file.spec.129 cordova.file.*Directory are set", function () {
3500 var expectedPaths = ['applicationDirectory', 'applicationStorageDirectory', 'dataDirectory', 'cacheDirectory'];
3501 if (cordova.platformId == 'android' || cordova.platformId == 'amazon-fireos') {
3502 if (cordova.file.externalApplicationStorageDirectory !== null) {
3503 // https://issues.apache.org/jira/browse/CB-10411
3504 // If external storage can't be mounted, the cordova.file.external* properties are null.
3505 expectedPaths.push('externalApplicationStorageDirectory', 'externalRootDirectory', 'externalCacheDirectory', 'externalDataDirectory');
3506 }
3507 } else if (cordova.platformId == 'blackberry10') {
3508 expectedPaths.push('externalRootDirectory', 'sharedDirectory');
3509 } else if (cordova.platformId == 'ios') {
3510 expectedPaths.push('syncedDataDirectory', 'documentsDirectory', 'tempDirectory');
3511 } else if (cordova.platformId == 'osx') {
3512 expectedPaths.push('documentsDirectory', 'tempDirectory', 'rootDirectory');
3513 } else {
3514 console.log('Skipping test due on unsupported platform.');
3515 return;
3516 }
3517 for (var i = 0; i < expectedPaths.length; ++i) {
3518 expect(typeof cordova.file[expectedPaths[i]]).toBe('string');
3519 expect(cordova.file[expectedPaths[i]]).toMatch(/\/$/, 'Path should end with a slash');
3520 }
3521 });
3522 });
3523 describe('resolveLocalFileSystemURL on cdvfile://', function () {
3524 it("file.spec.147 should be able to resolve cdvfile applicationDirectory fs root", function(done) {
3525 var cdvfileApplicationDirectoryFsRootName;
3526 if (cordova.platformId === 'android') {
3527 cdvfileApplicationDirectoryFsRootName = 'assets';
3528 } else if (cordova.platformId === 'ios') {
3529 cdvfileApplicationDirectoryFsRootName = 'bundle';
3530 } else {
3531 pending();
3532 }
3533
3534 resolveLocalFileSystemURL('cdvfile://localhost/' + cdvfileApplicationDirectoryFsRootName + '/', function(applicationDirectoryRoot) {
3535 expect(applicationDirectoryRoot.isFile).toBe(false);
3536 expect(applicationDirectoryRoot.isDirectory).toBe(true);
3537 expect(applicationDirectoryRoot.name).toCanonicallyMatch('');
3538 expect(applicationDirectoryRoot.fullPath).toCanonicallyMatch('/');
3539 expect(applicationDirectoryRoot.filesystem.name).toEqual(cdvfileApplicationDirectoryFsRootName);
3540
3541 // Requires HelloCordova www assets, <allow-navigation href="cdvfile:*" /> in config.xml or
3542 // cdvfile: in CSP and <access origin="cdvfile://*" /> in config.xml
3543 resolveLocalFileSystemURL('cdvfile://localhost/' + cdvfileApplicationDirectoryFsRootName + '/www/img/logo.png', function(entry) {
3544 expect(entry.isFile).toBe(true);
3545 expect(entry.isDirectory).toBe(false);
3546 expect(entry.name).toCanonicallyMatch('logo.png');
3547 expect(entry.fullPath).toCanonicallyMatch('/www/img/logo.png');
3548 expect(entry.filesystem.name).toEqual(cdvfileApplicationDirectoryFsRootName);
3549
3550 var img = new Image();
3551 img.onerror = function(err) {
3552 expect(err).not.toBeDefined();
3553 done();
3554 };
3555 img.onload = function() {
3556 done();
3557 };
3558 img.src = entry.toInternalURL();
3559 }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for cdvfile applicationDirectory'));
3560 }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for cdvfile applicationDirectory'));
3561 });
3562 });
3563 //cross-file-system copy and move
3564 describe('IndexedDB-based impl', function () {
3565 it("file.spec.131 Nested file or nested directory should be removed when removing a parent directory", function (done) {
3566 var parentDirName = 'deletedDir131',
3567 nestedDirName = 'nestedDir131',
3568 nestedFileName = 'nestedFile131.txt';
3569
3570 createDirectory(parentDirName, function (parent) {
3571 parent.getDirectory(nestedDirName, { create: true}, function () {
3572 parent.getFile(nestedFileName, { create: true}, function () {
3573 parent.removeRecursively(function() {
3574 root.getDirectory(parentDirName,{ create: false}, failed.bind(this, done, 'root.getDirectory - unexpected success callback : ' + parentDirName), function(){
3575 parent.getFile(nestedFileName,{ create: false}, failed.bind(this, done, 'getFile - unexpected success callback : ' + nestedFileName), function(){
3576 parent.getDirectory(nestedDirName, { create: false}, failed.bind(this, done, 'getDirectory - unexpected success callback : ' + nestedDirName), done);
3577 });
3578 });
3579 }, failed.bind(this, done, 'removeRecursively - Error removing directory : ' + parentDirName));
3580 }, failed.bind(this, done, 'getFile - Error creating file : ' + nestedFileName));
3581 },failed.bind(this, done, 'getDirectory - Error creating directory : ' + nestedDirName));
3582 }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + parentDirName));
3583 });
3584 it("file.spec.132 Entry should be created succesfully when using relative paths if its parent directory exists", function (done) {
3585 /* Directory entries have to be created successively.
3586 For example, the call `fs.root.getDirectory('dir1/dir2', {create:true}, successCallback, errorCallback)`
3587 will fail if dir1 did not exist. */
3588 var parentName = 'parentName132';
3589 var nestedName = 'nestedName132';
3590 var path = parentName + '/' + nestedName;
3591
3592 var win = function(directory){
3593 expect(directory).toBeDefined();
3594 expect(directory.isFile).toBe(false);
3595 expect(directory.isDirectory).toBe(true);
3596 expect(directory.name).toCanonicallyMatch(nestedName);
3597 expect(directory.fullPath).toCanonicallyMatch('/' + path + '/');
3598 deleteEntry(directory.name);
3599 deleteEntry(parentName, done);
3600 };
3601
3602 createDirectory(parentName, function() {
3603 root.getDirectory(parentName + '/' + nestedName, {create:true}, win,
3604 failed.bind(this, done, 'root.getDirectory - Error getting directory : ' + path));
3605 }, failed.bind(this, done, 'root.getDirectory - Error getting directory : ' + parentName));
3606 });
3607 it("file.spec.133 A file being removed should not affect another file with name being a prefix of the removed file name.", function (done) {
3608
3609 // Names include special symbols so that we check the IndexedDB range used
3610 var deletedFileName = 'deletedFile.0',
3611 secondFileName = 'deletedFile.0.1';
3612
3613 var win = function(fileEntry){
3614 expect(fileEntry).toBeDefined();
3615 expect(fileEntry.isFile).toBe(true);
3616 expect(fileEntry.isDirectory).toBe(false);
3617 expect(fileEntry.name).toCanonicallyMatch(secondFileName);
3618 deleteEntry(fileEntry.name, done);
3619 };
3620
3621 createFile(deletedFileName, function (deletedFile) {
3622 createFile(secondFileName, function () {
3623 deletedFile.remove(function() {
3624 root.getFile(deletedFileName, {create: false}, failed.bind(this, done, 'getFile - unexpected success callback getting deleted file : ' + deletedFileName), function(){
3625 root.getFile(secondFileName, {create: false}, win, failed.bind(this, done, 'getFile - Error getting file after deleting deletedFile : ' + secondFileName));
3626 });
3627 }, failed.bind(this, done, 'remove - Error removing file : ' + deletedFileName));
3628 }, failed.bind(this, done, 'getFile - Error creating file : ' + secondFileName));
3629 }, failed.bind(this, done, 'getFile - Error creating file : ' + deletedFileName));
3630 });
3631 it("file.spec.134 A directory being removed should not affect another directory with name being a prefix of the removed directory name.", function (done) {
3632
3633 // Names include special symbols so that we check the IndexedDB range used
3634 var deletedDirName = 'deletedDir.0',
3635 secondDirName = 'deletedDir.0.1';
3636
3637 var win = function(directory){
3638 expect(directory).toBeDefined();
3639 expect(directory.isFile).toBe(false);
3640 expect(directory.isDirectory).toBe(true);
3641 expect(directory.name).toCanonicallyMatch(secondDirName);
3642 deleteEntry(directory.name, done);
3643 };
3644
3645 createDirectory(deletedDirName, function (deletedDir) {
3646 createDirectory(secondDirName, function () {
3647 deletedDir.remove(function() {
3648 root.getDirectory(deletedDirName, {create: false}, failed.bind(this, done, 'getDirectory - unexpected success callback getting deleted directory : ' + deletedDirName), function() {
3649 root.getDirectory(secondDirName, {create: false}, win, failed.bind(this, done, 'getDirectory - Error getting directory after deleting deletedDirectory : ' + secondDirName));
3650 });
3651 }, failed.bind(this, done, 'remove - Error removing directory : ' + deletedDirName));
3652 }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + secondDirName));
3653 }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + deletedDirName));
3654 });
3655 it("file.spec.135 Deletion of a child directory should not affect the parent directory.", function (done) {
3656
3657 var parentName = 'parentName135';
3658 var childName = 'childName135';
3659
3660 var win = function(directory){
3661 expect(directory).toBeDefined();
3662 expect(directory.isFile).toBe(false);
3663 expect(directory.isDirectory).toBe(true);
3664 expect(directory.name).toCanonicallyMatch(parentName);
3665 deleteEntry(directory.name, done);
3666 };
3667
3668 createDirectory(parentName, function(parent){
3669 parent.getDirectory(childName, {create: true}, function(child){
3670 child.removeRecursively(function(){
3671 root.getDirectory(parentName, {create: false}, win, failed.bind(this, done, 'root.getDirectory - Error getting parent directory : ' + parentName));
3672 },
3673 failed.bind(this, done, 'getDirectory - Error removing directory : ' + childName));
3674 }, failed.bind(this, done, 'getDirectory - Error creating directory : ' + childName));
3675 }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + parentName));
3676 });
3677 it("file.spec.136 Paths should support Unicode symbols.", function (done) {
3678
3679 var dirName = '文件插件';
3680
3681 var win = function(directory){
3682 expect(directory).toBeDefined();
3683 expect(directory.isFile).toBe(false);
3684 expect(directory.isDirectory).toBe(true);
3685 expect(directory.name).toCanonicallyMatch(dirName);
3686 deleteEntry(directory.name, done);
3687 };
3688
3689 createDirectory(dirName, function(){
3690 root.getDirectory(dirName, {create: false}, win,
3691 failed.bind(this, done, 'root.getDirectory - Error getting directory : ' + dirName));
3692 }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + dirName));
3693 });
3694 });
3695 // Content and Asset URLs
3696 if (cordova.platformId == 'android') {
3697 describe('content: URLs', function() {
3698 // Warning: Default HelloWorld www directory structure is required for these tests (www/index.html at least)
3699 function testContentCopy(src, done) {
3700 var file2 = "entry.copy.file2b",
3701 fullPath = joinURL(temp_root.fullPath, file2),
3702 validateFile = function (entry) {
3703 expect(entry.isFile).toBe(true);
3704 expect(entry.isDirectory).toBe(false);
3705 expect(entry.name).toCanonicallyMatch(file2);
3706 expect(entry.fullPath).toCanonicallyMatch(fullPath);
3707 expect(entry.filesystem.name).toEqual("temporary");
3708 // cleanup
3709 deleteEntry(entry.name, done);
3710 },
3711 transfer = function () {
3712 resolveLocalFileSystemURL(src, function(entry) {
3713 expect(entry).toBeDefined();
3714 expect(entry.filesystem.name).toEqual("content");
3715 entry.copyTo(temp_root, file2, validateFile, failed.bind(null, done, 'entry.copyTo - Error copying file: ' + entry.toURL() + ' to TEMPORAL root as: ' + file2));
3716 }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for content provider'));
3717 };
3718 // Delete any existing file to start things off
3719 temp_root.getFile(file2, {}, function (entry) {
3720 entry.remove(transfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2));
3721 }, transfer);
3722 }
3723 it("file.spec.138 copyTo: content", function(done) {
3724 testContentCopy('content://org.apache.cordova.file.testprovider/www/index.html', done);
3725 });
3726 it("file.spec.139 copyTo: content /w space and query", function(done) {
3727 testContentCopy('content://org.apache.cordova.file.testprovider/?name=foo%20bar&realPath=%2Fwww%2Findex.html', done);
3728 });
3729 it("file.spec.140 delete: content should fail", function(done) {
3730 resolveLocalFileSystemURL('content://org.apache.cordova.file.testprovider/www/index.html', function(entry) {
3731 entry.remove(failed.bind(null, done, 'expected delete to fail'), done);
3732 }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for content provider'));
3733 });
3734 });
3735
3736 // these tests ensure that you can read and copy from android_asset folder
3737 // for details see https://issues.apache.org/jira/browse/CB-6428
3738 // and https://mail-archives.apache.org/mod_mbox/cordova-dev/201508.mbox/%3C782154441.8406572.1440182722528.JavaMail.yahoo%40mail.yahoo.com%3E
3739 describe('asset: URLs', function() {
3740 it("file.spec.141 filePaths.applicationStorage", function() {
3741 expect(cordova.file.applicationDirectory).toEqual('file:///android_asset/');
3742 }, MEDIUM_TIMEOUT);
3743 it("file.spec.142 assets should be enumerable", function(done) {
3744 resolveLocalFileSystemURL('file:///android_asset/www/fixtures/asset-test', function(entry) {
3745 var reader = entry.createReader();
3746 reader.readEntries(function (entries) {
3747 expect(entries.length).not.toBe(0);
3748 done();
3749 }, failed.bind(null, done, 'reader.readEntries - Error during reading of entries from assets directory'));
3750 }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for assets'));
3751 }, MEDIUM_TIMEOUT);
3752 it("file.spec.145 asset subdirectories should be obtainable", function(done) {
3753 resolveLocalFileSystemURL('file:///android_asset/www/fixtures', function(entry) {
3754 entry.getDirectory('asset-test', { create: false }, function (subDir) {
3755 expect(subDir).toBeDefined();
3756 expect(subDir.isFile).toBe(false);
3757 expect(subDir.isDirectory).toBe(true);
3758 expect(subDir.name).toCanonicallyMatch('asset-test');
3759 done();
3760 }, failed.bind(null, done, 'entry.getDirectory - Error getting asset subdirectory'));
3761 }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for assets'));
3762 }, MEDIUM_TIMEOUT);
3763 it("file.spec.146 asset files should be readable", function(done) {
3764 resolveLocalFileSystemURL('file:///android_asset/www/fixtures/asset-test/asset-test.txt', function(entry) {
3765 expect(entry.isFile).toBe(true);
3766 entry.file(function (file) {
3767 expect(file).toBeDefined();
3768 var reader = new FileReader();
3769 reader.onerror = failed.bind(null, done, 'reader.readAsText - Error reading asset text file');
3770 reader.onloadend = function () {
3771 expect(this.result).toBeDefined();
3772 expect(this.result.length).not.toBe(0);
3773 done();
3774 };
3775 reader.readAsText(file);
3776 }, failed.bind(null, done, 'entry.file - Error reading asset file'));
3777 }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for assets'));
3778 }, MEDIUM_TIMEOUT);
3779 it("file.spec.143 copyTo: asset -> temporary", function(done) {
3780 var file2 = "entry.copy.file2b",
3781 fullPath = joinURL(temp_root.fullPath, file2),
3782 validateFile = function (entry) {
3783 expect(entry.isFile).toBe(true);
3784 expect(entry.isDirectory).toBe(false);
3785 expect(entry.name).toCanonicallyMatch(file2);
3786 expect(entry.fullPath).toCanonicallyMatch(fullPath);
3787 expect(entry.filesystem.name).toEqual("temporary");
3788 // cleanup
3789 deleteEntry(entry.name, done);
3790 },
3791 transfer = function () {
3792 resolveLocalFileSystemURL('file:///android_asset/www/index.html', function(entry) {
3793 expect(entry.filesystem.name).toEqual('assets');
3794 entry.copyTo(temp_root, file2, validateFile, failed.bind(null, done, 'entry.copyTo - Error copying file: ' + entry.toURL() + ' to TEMPORAL root as: ' + file2));
3795 }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for assets'));
3796 };
3797 // Delete any existing file to start things off
3798 temp_root.getFile(file2, {}, function (entry) {
3799 entry.remove(transfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2));
3800 }, transfer);
3801 }, MEDIUM_TIMEOUT);
3802 });
3803 it("file.spec.144 copyTo: asset directory", function (done) {
3804 var srcUrl = 'file:///android_asset/www/fixtures/asset-test';
3805 var dstDir = "entry.copy.dstDir";
3806 var dstPath = joinURL(root.fullPath, dstDir);
3807 // create a new directory entry to kick off it
3808 deleteEntry(dstDir, function () {
3809 resolveLocalFileSystemURL(srcUrl, function(directory) {
3810 directory.copyTo(root, dstDir, function (directory) {
3811 expect(directory).toBeDefined();
3812 expect(directory.isFile).toBe(false);
3813 expect(directory.isDirectory).toBe(true);
3814 expect(directory.fullPath).toCanonicallyMatch(dstPath);
3815 expect(directory.name).toCanonicallyMatch(dstDir);
3816 root.getDirectory(dstDir, {
3817 create : false
3818 }, function (dirEntry) {
3819 expect(dirEntry).toBeDefined();
3820 expect(dirEntry.isFile).toBe(false);
3821 expect(dirEntry.isDirectory).toBe(true);
3822 expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);
3823 expect(dirEntry.name).toCanonicallyMatch(dstDir);
3824 dirEntry.getFile('asset-test.txt', {
3825 create : false
3826 }, function (fileEntry) {
3827 expect(fileEntry).toBeDefined();
3828 expect(fileEntry.isFile).toBe(true);
3829 // cleanup
3830 deleteEntry(dstDir, done);
3831 }, failed.bind(null, done, 'dirEntry.getFile - Error getting subfile'));
3832 }, failed.bind(null, done, 'root.getDirectory - Error getting copied directory'));
3833 }, failed.bind(null, done, 'directory.copyTo - Error copying directory'));
3834 }, failed.bind(null, done, 'resolving src dir'));
3835 }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));
3836 }, MEDIUM_TIMEOUT);
3837 }
3838 });
3839
3840};
3841//******************************************************************************************
3842//***************************************Manual Tests***************************************
3843//******************************************************************************************
3844
3845exports.defineManualTests = function (contentEl, createActionButton) {
3846
3847 function resolveFs(fsname) {
3848 var fsURL = "cdvfile://localhost/" + fsname + "/";
3849 logMessage("Resolving URL: " + fsURL);
3850 resolveLocalFileSystemURL(fsURL, function (entry) {
3851 logMessage("Success", 'green');
3852 logMessage(entry.toURL(), 'blue');
3853 logMessage(entry.toInternalURL(), 'blue');
3854 logMessage("Resolving URL: " + entry.toURL());
3855 resolveLocalFileSystemURL(entry.toURL(), function (entry2) {
3856 logMessage("Success", 'green');
3857 logMessage(entry2.toURL(), 'blue');
3858 logMessage(entry2.toInternalURL(), 'blue');
3859 }, logError("resolveLocalFileSystemURL"));
3860 }, logError("resolveLocalFileSystemURL"));
3861 }
3862
3863 function testPrivateURL() {
3864 requestFileSystem(LocalFileSystem.TEMPORARY, 0, function (fileSystem) {
3865 logMessage("Temporary root is at " + fileSystem.root.toNativeURL());
3866 fileSystem.root.getFile("testfile", {
3867 create : true
3868 }, function (entry) {
3869 logMessage("Temporary file is at " + entry.toNativeURL());
3870 if (entry.toNativeURL().substring(0, 12) == "file:///var/") {
3871 logMessage("File starts with /var/, trying /private/var");
3872 var newURL = "file://localhost/private/var/" + entry.toNativeURL().substring(12) + "?and=another_thing";
3873 //var newURL = entry.toNativeURL();
3874 logMessage(newURL, 'blue');
3875 resolveLocalFileSystemURL(newURL, function (newEntry) {
3876 logMessage("Successfully resolved.", 'green');
3877 logMessage(newEntry.toURL(), 'blue');
3878 logMessage(newEntry.toNativeURL(), 'blue');
3879 }, logError("resolveLocalFileSystemURL"));
3880 }
3881 }, logError("getFile"));
3882 }, logError("requestFileSystem"));
3883 }
3884
3885 function resolveFsContactImage() {
3886 navigator.contacts.pickContact(function(contact) {
3887 var logBox = document.getElementById("logContactBox");
3888 logBox.innerHTML = "";
3889 var resolveResult = document.createElement("p");
3890 if (contact.photos) {
3891 var photoURL = contact.photos[0].value;
3892 resolveLocalFileSystemURL(photoURL, function(entry) {
3893 var contactImage = document.createElement("img");
3894 var contactLabelImage = document.createElement("p");
3895 contactLabelImage.innerHTML = "Result contact image";
3896 contactImage.setAttribute("src", entry.toURL());
3897 resolveResult.innerHTML = "Success resolve\n" + entry.toURL();
3898 logBox.appendChild(contactLabelImage);
3899 logBox.appendChild(contactImage);
3900 logBox.appendChild(resolveResult);
3901 },
3902 function(err) {
3903 console.log("resolve error" + err);
3904 });
3905 }
3906 else {
3907 resolveResult.innerHTML = "Contact has no photos";
3908 logBox.appendChild(resolveResult);
3909 }
3910 },
3911 function(err) {
3912 console.log("contact pick error" + err);
3913 });
3914 }
3915
3916 function clearLog() {
3917 var log = document.getElementById("info");
3918 log.innerHTML = "";
3919 }
3920
3921 function logMessage(message, color) {
3922 var log = document.getElementById("info");
3923 var logLine = document.createElement('div');
3924 if (color) {
3925 logLine.style.color = color;
3926 }
3927 logLine.innerHTML = message;
3928 log.appendChild(logLine);
3929 }
3930
3931 function logError(serviceName) {
3932 return function (err) {
3933 logMessage("ERROR: " + serviceName + " " + JSON.stringify(err), "red");
3934 };
3935 }
3936
3937 var fsRoots = {
3938 "ios" : "library,library-nosync,documents,documents-nosync,cache,bundle,root,private",
3939 "osx" : "library,library-nosync,documents,documents-nosync,cache,bundle,root,private",
3940 "android" : "files,files-external,documents,sdcard,cache,cache-external,assets,root",
3941 "amazon-fireos" : "files,files-external,documents,sdcard,cache,cache-external,root",
3942 "windows": "temporary,persistent"
3943 };
3944
3945 //Add title and align to content
3946 var div = document.createElement('h2');
3947 div.appendChild(document.createTextNode('File Systems'));
3948 div.setAttribute("align", "center");
3949 contentEl.appendChild(div);
3950
3951 div = document.createElement('h3');
3952 div.appendChild(document.createTextNode('Results are displayed in yellow status box below with expected results noted under that'));
3953 div.setAttribute("align", "center");
3954 contentEl.appendChild(div);
3955
3956 div = document.createElement('div');
3957 div.setAttribute("id", "button");
3958 div.setAttribute("align", "center");
3959 contentEl.appendChild(div);
3960 if (fsRoots.hasOwnProperty(cordova.platformId)) {
3961 (fsRoots[cordova.platformId].split(',')).forEach(function (fs) {
3962 if (cordova.platformId === 'ios' && fs === 'private') {
3963 createActionButton("Test private URL (iOS)", function () {
3964 clearLog();
3965 testPrivateURL();
3966 }, 'button');
3967 } else {
3968 createActionButton(fs, function () {
3969 clearLog();
3970 resolveFs(fs);
3971 }, 'button');
3972 }
3973 });
3974 }
3975
3976
3977 div = document.createElement('div');
3978 div.setAttribute("id", "info");
3979 div.setAttribute("align", "center");
3980 contentEl.appendChild(div);
3981
3982 div = document.createElement('h3');
3983 div.appendChild(document.createTextNode('For each test above, file or directory should be successfully found. ' +
3984 'Status box should say Resolving URL was Success. The first URL resolved is the internal URL. ' +
3985 'The second URL resolved is the absolute URL. Blue URLs must match.'));
3986 contentEl.appendChild(div);
3987
3988 div = document.createElement('h3');
3989 div.appendChild(document.createTextNode('For Test private URL (iOS), the private URL (first blue URL in status box) ' +
3990 'should be successfully resolved. Status box should say Successfully resolved. Both blue URLs below ' +
3991 'that should match.'));
3992 contentEl.appendChild(div);
3993
3994 div = document.createElement('h2');
3995 div.appendChild(document.createTextNode('Resolving content urls'));
3996 div.setAttribute("align", "center");
3997 contentEl.appendChild(div);
3998
3999 div = document.createElement('div');
4000 div.setAttribute("id", "contactButton");
4001 div.setAttribute("align", "center");
4002 contentEl.appendChild(div);
4003
4004 div = document.createElement('div');
4005 div.setAttribute("id", "logContactBox");
4006 div.setAttribute("align", "center");
4007 contentEl.appendChild(div);
4008
4009 createActionButton('show-contact-image', function () {
4010 resolveFsContactImage();
4011 }, 'contactButton');
4012};