1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/osfile/tests/mochi/worker_test_osfile_front.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,798 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + * http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +importScripts('worker_test_osfile_shared.js'); 1.8 +importScripts("resource://gre/modules/workers/require.js"); 1.9 + 1.10 +let SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm"); 1.11 +SharedAll.Config.DEBUG = true; 1.12 + 1.13 +function should_throw(f) { 1.14 + try { 1.15 + f(); 1.16 + } catch (x) { 1.17 + return x; 1.18 + } 1.19 + return null; 1.20 +} 1.21 + 1.22 +self.onmessage = function onmessage_start(msg) { 1.23 + self.onmessage = function onmessage_ignored(msg) { 1.24 + log("ignored message " + JSON.stringify(msg.data)); 1.25 + }; 1.26 + try { 1.27 + test_init(); 1.28 + test_offsetby(); 1.29 + test_open_existing_file(); 1.30 + test_open_non_existing_file(); 1.31 + test_flush_open_file(); 1.32 + test_copy_existing_file(); 1.33 + test_readall_writeall_file(); 1.34 + test_position(); 1.35 + test_move_file(); 1.36 + test_iter_dir(); 1.37 + test_info(); 1.38 + test_path(); 1.39 + test_exists_file(); 1.40 + test_remove_file(); 1.41 + } catch (x) { 1.42 + log("Catching error: " + x); 1.43 + log("Stack: " + x.stack); 1.44 + log("Source: " + x.toSource()); 1.45 + ok(false, x.toString() + "\n" + x.stack); 1.46 + } 1.47 + finish(); 1.48 +}; 1.49 + 1.50 +function test_init() { 1.51 + info("Starting test_init"); 1.52 + importScripts("resource://gre/modules/osfile.jsm"); 1.53 +} 1.54 + 1.55 +function test_offsetby() { 1.56 + info("Starting test_offsetby"); 1.57 + 1.58 + // Initialize one array 1.59 + let LENGTH = 1024; 1.60 + let buf = new ArrayBuffer(LENGTH); 1.61 + let view = new Uint8Array(buf); 1.62 + let i; 1.63 + for (i = 0; i < LENGTH; ++i) { 1.64 + view[i] = i; 1.65 + } 1.66 + 1.67 + // Walk through the array with offsetBy by 8 bits 1.68 + let uint8 = SharedAll.Type.uint8_t.in_ptr.implementation(buf); 1.69 + for (i = 0; i < LENGTH; ++i) { 1.70 + let value = SharedAll.offsetBy(uint8, i).contents; 1.71 + if (value != i%256) { 1.72 + is(value, i % 256, "test_offsetby: Walking through array with offsetBy (8 bits)"); 1.73 + break; 1.74 + } 1.75 + } 1.76 + 1.77 + // Walk again by 16 bits 1.78 + let uint16 = SharedAll.Type.uint16_t.in_ptr.implementation(buf); 1.79 + let view2 = new Uint16Array(buf); 1.80 + for (i = 0; i < LENGTH/2; ++i) { 1.81 + let value = SharedAll.offsetBy(uint16, i).contents; 1.82 + if (value != view2[i]) { 1.83 + is(value, view2[i], "test_offsetby: Walking through array with offsetBy (16 bits)"); 1.84 + break; 1.85 + } 1.86 + } 1.87 + 1.88 + // Ensure that offsetBy(..., 0) is idempotent 1.89 + let startptr = SharedAll.offsetBy(uint8, 0); 1.90 + let startptr2 = SharedAll.offsetBy(startptr, 0); 1.91 + is(startptr.toString(), startptr2.toString(), "test_offsetby: offsetBy(..., 0) is idmpotent"); 1.92 + 1.93 + // Ensure that offsetBy(ptr, ...) does not work if ptr is a void* 1.94 + let ptr = ctypes.voidptr_t(0); 1.95 + let exn; 1.96 + try { 1.97 + SharedAll.offsetBy(ptr, 1); 1.98 + } catch (x) { 1.99 + exn = x; 1.100 + } 1.101 + ok(!!exn, "test_offsetby: rejected offsetBy with void*"); 1.102 + 1.103 + info("test_offsetby: complete"); 1.104 +} 1.105 + 1.106 + 1.107 +/** 1.108 + * Test that we can open an existing file. 1.109 + */ 1.110 +function test_open_existing_file() 1.111 +{ 1.112 + info("Starting test_open_existing"); 1.113 + let file = OS.File.open("chrome/toolkit/components/osfile/tests/mochi/worker_test_osfile_unix.js"); 1.114 + file.close(); 1.115 +} 1.116 + 1.117 +/** 1.118 + * Test that opening a file that does not exist fails with the right error. 1.119 + */ 1.120 +function test_open_non_existing_file() 1.121 +{ 1.122 + info("Starting test_open_non_existing"); 1.123 + let exn; 1.124 + try { 1.125 + let file = OS.File.open("/I do not exist"); 1.126 + } catch (x) { 1.127 + exn = x; 1.128 + info("test_open_non_existing_file: Exception detail " + exn); 1.129 + } 1.130 + ok(!!exn, "test_open_non_existing_file: Exception was raised "); 1.131 + ok(exn instanceof OS.File.Error, "test_open_non_existing_file: Exception was a OS.File.Error"); 1.132 + ok(exn.becauseNoSuchFile, "test_open_non_existing_file: Exception confirms that the file does not exist"); 1.133 +} 1.134 + 1.135 +/** 1.136 + * Test that to ensure that |foo.flush()| does not 1.137 + * cause an error, where |foo| is an open file. 1.138 + */ 1.139 +function test_flush_open_file() 1.140 +{ 1.141 + info("Starting test_flush_open_file"); 1.142 + let tmp = "test_flush.tmp"; 1.143 + let file = OS.File.open(tmp, {create: true, write: true}); 1.144 + file.flush(); 1.145 + file.close(); 1.146 + OS.File.remove(tmp); 1.147 +} 1.148 + 1.149 +/** 1.150 + * Utility function for comparing two files (or a prefix of two files). 1.151 + * 1.152 + * This function returns nothing but fails of both files (or prefixes) 1.153 + * are not identical. 1.154 + * 1.155 + * @param {string} test The name of the test (used for logging). 1.156 + * @param {string} sourcePath The name of the first file. 1.157 + * @param {string} destPath The name of the second file. 1.158 + * @param {number=} prefix If specified, only compare the |prefix| 1.159 + * first bytes of |sourcePath| and |destPath|. 1.160 + */ 1.161 +function compare_files(test, sourcePath, destPath, prefix) 1.162 +{ 1.163 + info(test + ": Comparing " + sourcePath + " and " + destPath); 1.164 + let source = OS.File.open(sourcePath); 1.165 + let dest = OS.File.open(destPath); 1.166 + info("Files are open"); 1.167 + let sourceResult, destResult; 1.168 + try { 1.169 + if (prefix != undefined) { 1.170 + sourceResult = source.read(prefix); 1.171 + destResult = dest.read(prefix); 1.172 + } else { 1.173 + sourceResult = source.read(); 1.174 + destResult = dest.read(); 1.175 + } 1.176 + is(sourceResult.length, destResult.length, test + ": Both files have the same size"); 1.177 + for (let i = 0; i < sourceResult.length; ++i) { 1.178 + if (sourceResult[i] != destResult[i]) { 1.179 + is(sourceResult[i] != destResult[i], test + ": Comparing char " + i); 1.180 + break; 1.181 + } 1.182 + } 1.183 + } finally { 1.184 + source.close(); 1.185 + dest.close(); 1.186 + } 1.187 + info(test + ": Comparison complete"); 1.188 +} 1.189 + 1.190 +function test_readall_writeall_file() 1.191 +{ 1.192 + let src_file_name = 1.193 + OS.Path.join("chrome", "toolkit", "components", "osfile", "tests", "mochi", 1.194 + "worker_test_osfile_front.js"); 1.195 + let tmp_file_name = 1.196 + OS.Path.join(OS.Constants.Path.tmpDir, "test_osfile_front.tmp"); 1.197 + info("Starting test_readall_writeall_file"); 1.198 + 1.199 + // read, ArrayBuffer 1.200 + 1.201 + let source = OS.File.open(src_file_name); 1.202 + let dest = OS.File.open(tmp_file_name, {write: true, trunc:true}); 1.203 + let size = source.stat().size; 1.204 + 1.205 + let buf = new Uint8Array(size); 1.206 + let readResult = source.readTo(buf); 1.207 + is(readResult, size, "test_readall_writeall_file: read the right number of bytes"); 1.208 + 1.209 + dest.write(buf); 1.210 + 1.211 + info("test_readall_writeall_file: copy complete (manual allocation)"); 1.212 + source.close(); 1.213 + dest.close(); 1.214 + 1.215 + compare_files("test_readall_writeall_file (manual allocation)", src_file_name, tmp_file_name); 1.216 + OS.File.remove(tmp_file_name); 1.217 + 1.218 + // read, C buffer 1.219 + source = OS.File.open(src_file_name); 1.220 + dest = OS.File.open(tmp_file_name, {write: true, trunc:true}); 1.221 + buf = new ArrayBuffer(size); 1.222 + let ptr = OS.Shared.Type.voidptr_t.implementation(buf); 1.223 + readResult = source.readTo(ptr, {bytes: size}); 1.224 + is(readResult, size, "test_readall_writeall_file: read the right number of bytes (C buffer)"); 1.225 + 1.226 + dest.write(ptr, {bytes: size}); 1.227 + 1.228 + info("test_readall_writeall_file: copy complete (C buffer)"); 1.229 + source.close(); 1.230 + dest.close(); 1.231 + 1.232 + compare_files("test_readall_writeall_file (C buffer)", src_file_name, tmp_file_name); 1.233 + OS.File.remove(tmp_file_name); 1.234 + 1.235 + // read/write, C buffer, missing |bytes| option 1.236 + source = OS.File.open(src_file_name); 1.237 + dest = OS.File.open(tmp_file_name, {write: true, trunc:true}); 1.238 + let exn = should_throw(function() { source.readTo(ptr); }); 1.239 + ok(exn != null && exn instanceof TypeError, "test_readall_writeall_file: read with C pointer and without bytes fails with the correct error"); 1.240 + exn = should_throw(function() { dest.write(ptr); }); 1.241 + ok(exn != null && exn instanceof TypeError, "test_readall_writeall_file: write with C pointer and without bytes fails with the correct error"); 1.242 + 1.243 + source.close(); 1.244 + dest.close(); 1.245 + 1.246 + // readTo, ArrayBuffer + offset 1.247 + let OFFSET = 12; 1.248 + let LEFT = size - OFFSET; 1.249 + buf = new ArrayBuffer(size); 1.250 + let offset_view = new Uint8Array(buf, OFFSET); 1.251 + source = OS.File.open(src_file_name); 1.252 + dest = OS.File.open(tmp_file_name, {write: true, trunc:true}); 1.253 + 1.254 + readResult = source.readTo(offset_view); 1.255 + is(readResult, LEFT, "test_readall_writeall_file: read the right number of bytes (with offset)"); 1.256 + 1.257 + dest.write(offset_view); 1.258 + is(dest.stat().size, LEFT, "test_readall_writeall_file: wrote the right number of bytes (with offset)"); 1.259 + 1.260 + info("test_readall_writeall_file: copy complete (with offset)"); 1.261 + source.close(); 1.262 + dest.close(); 1.263 + 1.264 + compare_files("test_readall_writeall_file (with offset)", src_file_name, tmp_file_name, LEFT); 1.265 + OS.File.remove(tmp_file_name); 1.266 + 1.267 + // read 1.268 + buf = new Uint8Array(size); 1.269 + source = OS.File.open(src_file_name); 1.270 + dest = OS.File.open(tmp_file_name, {write: true, trunc:true}); 1.271 + 1.272 + readResult = source.read(); 1.273 + is(readResult.length, size, "test_readall_writeall_file: read the right number of bytes (auto allocation)"); 1.274 + 1.275 + dest.write(readResult); 1.276 + 1.277 + info("test_readall_writeall_file: copy complete (auto allocation)"); 1.278 + source.close(); 1.279 + dest.close(); 1.280 + 1.281 + compare_files("test_readall_writeall_file (auto allocation)", src_file_name, tmp_file_name); 1.282 + OS.File.remove(tmp_file_name); 1.283 + 1.284 + // File.readAll 1.285 + readResult = OS.File.read(src_file_name); 1.286 + is(readResult.length, size, "test_readall_writeall_file: read the right number of bytes (OS.File.readAll)"); 1.287 + 1.288 + // File.writeAtomic on top of nothing 1.289 + OS.File.writeAtomic(tmp_file_name, readResult, 1.290 + {tmpPath: tmp_file_name + ".tmp"}); 1.291 + try { 1.292 + let stat = OS.File.stat(tmp_file_name); 1.293 + info("readAll + writeAtomic created a file"); 1.294 + is(stat.size, size, "readAll + writeAtomic created a file of the right size"); 1.295 + } catch (x) { 1.296 + ok(false, "readAll + writeAtomic somehow failed"); 1.297 + if(x.becauseNoSuchFile) { 1.298 + ok(false, "readAll + writeAtomic did not create file"); 1.299 + } 1.300 + } 1.301 + compare_files("test_readall_writeall_file (OS.File.readAll + writeAtomic)", 1.302 + src_file_name, tmp_file_name); 1.303 + exn = null; 1.304 + try { 1.305 + let stat = OS.File.stat(tmp_file_name + ".tmp"); 1.306 + } catch (x) { 1.307 + exn = x; 1.308 + } 1.309 + ok(!!exn, "readAll + writeAtomic cleaned up after itself"); 1.310 + 1.311 + // File.writeAtomic on top of existing file 1.312 + // Remove content and set arbitrary size, to avoid potential false negatives 1.313 + dest = OS.File.open(tmp_file_name, {write: true, trunc:true}); 1.314 + dest.setPosition(1234); 1.315 + dest.close(); 1.316 + 1.317 + OS.File.writeAtomic(tmp_file_name, readResult, 1.318 + {tmpPath: tmp_file_name + ".tmp"}); 1.319 + compare_files("test_readall_writeall_file (OS.File.readAll + writeAtomic 2)", 1.320 + src_file_name, tmp_file_name); 1.321 + 1.322 + // File.writeAtomic on top of existing file but without overwritten the file 1.323 + exn = null; 1.324 + try { 1.325 + let view = new Uint8Array(readResult.buffer, 10, 200); 1.326 + OS.File.writeAtomic(tmp_file_name, view, 1.327 + { tmpPath: tmp_file_name + ".tmp", noOverwrite: true}); 1.328 + } catch (x) { 1.329 + exn = x; 1.330 + } 1.331 + ok(exn && exn instanceof OS.File.Error && exn.becauseExists, "writeAtomic fails if file already exists with noOverwrite option"); 1.332 + // Check file was not overwritten. 1.333 + compare_files("test_readall_writeall_file (OS.File.readAll + writeAtomic check file was not overwritten)", 1.334 + src_file_name, tmp_file_name); 1.335 + 1.336 + // Ensure that File.writeAtomic fails if no temporary file name is provided 1.337 + // (FIXME: Remove this test as part of bug 793660) 1.338 + 1.339 + exn = null; 1.340 + try { 1.341 + OS.File.writeAtomic(tmp_file_name, readResult.buffer, 1.342 + {bytes: readResult.length}); 1.343 + } catch (x) { 1.344 + exn = x; 1.345 + } 1.346 + ok(!!exn && exn instanceof TypeError, "writeAtomic fails if tmpPath is not provided"); 1.347 + 1.348 + // Check that writeAtomic fails when destination path is undefined 1.349 + exn = null; 1.350 + try { 1.351 + let path = undefined; 1.352 + let options = {tmpPath: tmp_file_name}; 1.353 + OS.File.writeAtomic(path, readResult.buffer, options); 1.354 + } catch (x) { 1.355 + exn = x; 1.356 + } 1.357 + ok(!!exn && exn instanceof TypeError, "writeAtomic fails if path is undefined"); 1.358 + 1.359 + // Check that writeAtomic fails when destination path is an empty string 1.360 + exn = null; 1.361 + try { 1.362 + let path = ""; 1.363 + let options = {tmpPath: tmp_file_name}; 1.364 + OS.File.writeAtomic(path, readResult.buffer, options); 1.365 + } catch (x) { 1.366 + exn = x; 1.367 + } 1.368 + ok(!!exn && exn instanceof TypeError, "writeAtomic fails if path is an empty string"); 1.369 + 1.370 + // Cleanup. 1.371 + OS.File.remove(tmp_file_name); 1.372 +} 1.373 + 1.374 +/** 1.375 + * Test that copying a file using |copy| works. 1.376 + */ 1.377 +function test_copy_existing_file() 1.378 +{ 1.379 + let src_file_name = 1.380 + OS.Path.join("chrome", "toolkit", "components", "osfile", "tests", "mochi", 1.381 + "worker_test_osfile_front.js"); 1.382 + let tmp_file_name = "test_osfile_front.tmp"; 1.383 + info("Starting test_copy_existing"); 1.384 + OS.File.copy(src_file_name, tmp_file_name); 1.385 + 1.386 + info("test_copy_existing: Copy complete"); 1.387 + compare_files("test_copy_existing", src_file_name, tmp_file_name); 1.388 + 1.389 + // Create a bogus file with arbitrary content, then attempt to overwrite 1.390 + // it with |copy|. 1.391 + let dest = OS.File.open(tmp_file_name, {trunc: true}); 1.392 + let buf = new Uint8Array(50); 1.393 + dest.write(buf); 1.394 + dest.close(); 1.395 + 1.396 + OS.File.copy(src_file_name, tmp_file_name); 1.397 + 1.398 + compare_files("test_copy_existing 2", src_file_name, tmp_file_name); 1.399 + 1.400 + // Attempt to overwrite with noOverwrite 1.401 + let exn; 1.402 + try { 1.403 + OS.File.copy(src_file_name, tmp_file_name, {noOverwrite: true}); 1.404 + } catch(x) { 1.405 + exn = x; 1.406 + } 1.407 + ok(!!exn, "test_copy_existing: noOverwrite prevents overwriting existing files"); 1.408 + 1.409 + info("test_copy_existing: Cleaning up"); 1.410 + OS.File.remove(tmp_file_name); 1.411 +} 1.412 + 1.413 +/** 1.414 + * Test that moving a file works. 1.415 + */ 1.416 +function test_move_file() 1.417 +{ 1.418 + info("test_move_file: Starting"); 1.419 + // 1. Copy file into a temporary file 1.420 + let src_file_name = 1.421 + OS.Path.join("chrome", "toolkit", "components", "osfile", "tests", "mochi", 1.422 + "worker_test_osfile_front.js"); 1.423 + let tmp_file_name = "test_osfile_front.tmp"; 1.424 + let tmp2_file_name = "test_osfile_front.tmp2"; 1.425 + OS.File.copy(src_file_name, tmp_file_name); 1.426 + 1.427 + info("test_move_file: Copy complete"); 1.428 + 1.429 + // 2. Move 1.430 + OS.File.move(tmp_file_name, tmp2_file_name); 1.431 + 1.432 + info("test_move_file: Move complete"); 1.433 + 1.434 + // 3. Check that destination exists 1.435 + compare_files("test_move_file", src_file_name, tmp2_file_name); 1.436 + 1.437 + // 4. Check that original file does not exist anymore 1.438 + let exn; 1.439 + try { 1.440 + OS.File.open(tmp_file_name); 1.441 + } catch (x) { 1.442 + exn = x; 1.443 + } 1.444 + ok(!!exn, "test_move_file: Original file has been removed"); 1.445 + 1.446 + info("test_move_file: Cleaning up"); 1.447 + OS.File.remove(tmp2_file_name); 1.448 +} 1.449 + 1.450 +function test_iter_dir() 1.451 +{ 1.452 + info("test_iter_dir: Starting"); 1.453 + 1.454 + // Create a file, to be sure that it exists 1.455 + let tmp_file_name = "test_osfile_front.tmp"; 1.456 + let tmp_file = OS.File.open(tmp_file_name, {write: true, trunc:true}); 1.457 + tmp_file.close(); 1.458 + 1.459 + let parent = OS.File.getCurrentDirectory(); 1.460 + info("test_iter_dir: directory " + parent); 1.461 + let iterator = new OS.File.DirectoryIterator(parent); 1.462 + info("test_iter_dir: iterator created"); 1.463 + let encountered_tmp_file = false; 1.464 + for (let entry in iterator) { 1.465 + // Checking that |name| can be decoded properly 1.466 + info("test_iter_dir: encountering entry " + entry.name); 1.467 + 1.468 + if (entry.name == tmp_file_name) { 1.469 + encountered_tmp_file = true; 1.470 + isnot(entry.isDir, "test_iter_dir: The temporary file is not a directory"); 1.471 + isnot(entry.isSymLink, "test_iter_dir: The temporary file is not a link"); 1.472 + } 1.473 + 1.474 + let file; 1.475 + let success = true; 1.476 + try { 1.477 + file = OS.File.open(entry.path); 1.478 + } catch (x) { 1.479 + if (x.becauseNoSuchFile) { 1.480 + success = false; 1.481 + } 1.482 + } 1.483 + if (file) { 1.484 + file.close(); 1.485 + } 1.486 + ok(success, "test_iter_dir: Entry " + entry.path + " exists"); 1.487 + 1.488 + if (OS.Win) { 1.489 + let year = new Date().getFullYear(); 1.490 + let creation = entry.winCreationDate; 1.491 + ok(creation, "test_iter_dir: Windows creation date exists: " + creation); 1.492 + ok(creation.getFullYear() >= year - 1 && creation.getFullYear() <= year, "test_iter_dir: consistent creation date"); 1.493 + 1.494 + let lastWrite = entry.winLastWriteDate; 1.495 + ok(lastWrite, "test_iter_dir: Windows lastWrite date exists: " + lastWrite); 1.496 + ok(lastWrite.getFullYear() >= year - 1 && lastWrite.getFullYear() <= year, "test_iter_dir: consistent lastWrite date"); 1.497 + 1.498 + let lastAccess = entry.winLastAccessDate; 1.499 + ok(lastAccess, "test_iter_dir: Windows lastAccess date exists: " + lastAccess); 1.500 + ok(lastAccess.getFullYear() >= year - 1 && lastAccess.getFullYear() <= year, "test_iter_dir: consistent lastAccess date"); 1.501 + } 1.502 + 1.503 + } 1.504 + ok(encountered_tmp_file, "test_iter_dir: We have found the temporary file"); 1.505 + 1.506 + info("test_iter_dir: Cleaning up"); 1.507 + iterator.close(); 1.508 + 1.509 + // Testing nextBatch() 1.510 + iterator = new OS.File.DirectoryIterator(parent); 1.511 + let allentries = [x for(x in iterator)]; 1.512 + iterator.close(); 1.513 + 1.514 + ok(allentries.length >= 14, "test_iter_dir: Meta-check: the test directory should contain at least 14 items"); 1.515 + 1.516 + iterator = new OS.File.DirectoryIterator(parent); 1.517 + let firstten = iterator.nextBatch(10); 1.518 + is(firstten.length, 10, "test_iter_dir: nextBatch(10) returns 10 items"); 1.519 + for (let i = 0; i < firstten.length; ++i) { 1.520 + is(allentries[i].path, firstten[i].path, "test_iter_dir: Checking that batch returns the correct entries"); 1.521 + } 1.522 + let nextthree = iterator.nextBatch(3); 1.523 + is(nextthree.length, 3, "test_iter_dir: nextBatch(3) returns 3 items"); 1.524 + for (let i = 0; i < nextthree.length; ++i) { 1.525 + is(allentries[i + firstten.length].path, nextthree[i].path, "test_iter_dir: Checking that batch 2 returns the correct entries"); 1.526 + } 1.527 + let everythingelse = iterator.nextBatch(); 1.528 + ok(everythingelse.length >= 1, "test_iter_dir: nextBatch() returns at least one item"); 1.529 + for (let i = 0; i < everythingelse.length; ++i) { 1.530 + is(allentries[i + firstten.length + nextthree.length].path, everythingelse[i].path, "test_iter_dir: Checking that batch 3 returns the correct entries"); 1.531 + } 1.532 + is(iterator.nextBatch().length, 0, "test_iter_dir: Once there is nothing left, nextBatch returns an empty array"); 1.533 + iterator.close(); 1.534 + 1.535 + iterator = new OS.File.DirectoryIterator(parent); 1.536 + iterator.close(); 1.537 + is(iterator.nextBatch().length, 0, "test_iter_dir: nextBatch on closed iterator returns an empty array"); 1.538 + 1.539 + iterator = new OS.File.DirectoryIterator(parent); 1.540 + let allentries2 = iterator.nextBatch(); 1.541 + is(allentries.length, allentries2.length, "test_iter_dir: Checking that getBatch(null) returns the right number of entries"); 1.542 + for (let i = 0; i < allentries.length; ++i) { 1.543 + is(allentries[i].path, allentries2[i].path, "test_iter_dir: Checking that getBatch(null) returns everything in the right order"); 1.544 + } 1.545 + iterator.close(); 1.546 + 1.547 + // Test forEach 1.548 + iterator = new OS.File.DirectoryIterator(parent); 1.549 + let index = 0; 1.550 + iterator.forEach( 1.551 + function cb(entry, aIndex, aIterator) { 1.552 + is(index, aIndex, "test_iter_dir: Checking that forEach index is correct"); 1.553 + ok(iterator == aIterator, "test_iter_dir: Checking that right iterator is passed"); 1.554 + if (index < 10) { 1.555 + is(allentries[index].path, entry.path, "test_iter_dir: Checking that forEach entry is correct"); 1.556 + } else if (index == 10) { 1.557 + iterator.close(); 1.558 + } else { 1.559 + ok(false, "test_iter_dir: Checking that forEach can be stopped early"); 1.560 + } 1.561 + ++index; 1.562 + }); 1.563 + iterator.close(); 1.564 + 1.565 + //test for prototype |OS.File.DirectoryIterator.unixAsFile| 1.566 + if ("unixAsFile" in OS.File.DirectoryIterator.prototype) { 1.567 + info("testing property unixAsFile"); 1.568 + let path = OS.Path.join("chrome", "toolkit", "components", "osfile", "tests", "mochi"); 1.569 + iterator = new OS.File.DirectoryIterator(path); 1.570 + 1.571 + let dir_file = iterator.unixAsFile();// return |File| 1.572 + let stat0 = dir_file.stat(); 1.573 + let stat1 = OS.File.stat(path); 1.574 + 1.575 + let unix_info_to_string = function unix_info_to_string(info) { 1.576 + return "| " + info.unixMode + " | " + info.unixOwner + " | " + info.unixGroup + " | " + info.creationDate + " | " + info.lastModificationDate + " | " + info.lastAccessDate + " | " + info.size + " |"; 1.577 + }; 1.578 + 1.579 + let s0_string = unix_info_to_string(stat0); 1.580 + let s1_string = unix_info_to_string(stat1); 1.581 + 1.582 + ok(stat0.isDir, "unixAsFile returned a directory"); 1.583 + is(s0_string, s1_string, "unixAsFile returned the correct file"); 1.584 + dir_file.close(); 1.585 + iterator.close(); 1.586 + } 1.587 + info("test_iter_dir: Complete"); 1.588 +} 1.589 + 1.590 +function test_position() { 1.591 + info("test_position: Starting"); 1.592 + 1.593 + ok("POS_START" in OS.File, "test_position: POS_START exists"); 1.594 + ok("POS_CURRENT" in OS.File, "test_position: POS_CURRENT exists"); 1.595 + ok("POS_END" in OS.File, "test_position: POS_END exists"); 1.596 + 1.597 + let ARBITRARY_POSITION = 321; 1.598 + let src_file_name = 1.599 + OS.Path.join("chrome", "toolkit", "components", "osfile", "tests", "mochi", 1.600 + "worker_test_osfile_front.js"); 1.601 + 1.602 + let file = OS.File.open(src_file_name); 1.603 + is(file.getPosition(), 0, "test_position: Initial position is 0"); 1.604 + 1.605 + let size = 0 + file.stat().size; // Hack: We can remove this 0 + once 776259 has landed 1.606 + 1.607 + file.setPosition(ARBITRARY_POSITION, OS.File.POS_START); 1.608 + is(file.getPosition(), ARBITRARY_POSITION, "test_position: Setting position from start"); 1.609 + 1.610 + file.setPosition(0, OS.File.POS_START); 1.611 + is(file.getPosition(), 0, "test_position: Setting position from start back to 0"); 1.612 + 1.613 + file.setPosition(ARBITRARY_POSITION); 1.614 + is(file.getPosition(), ARBITRARY_POSITION, "test_position: Setting position without argument"); 1.615 + 1.616 + file.setPosition(-ARBITRARY_POSITION, OS.File.POS_END); 1.617 + is(file.getPosition(), size - ARBITRARY_POSITION, "test_position: Setting position from end"); 1.618 + 1.619 + file.setPosition(ARBITRARY_POSITION, OS.File.POS_CURRENT); 1.620 + is(file.getPosition(), size, "test_position: Setting position from current"); 1.621 + 1.622 + file.close(); 1.623 + info("test_position: Complete"); 1.624 +} 1.625 + 1.626 +function test_info() { 1.627 + info("test_info: Starting"); 1.628 + 1.629 + let filename = "test_info.tmp"; 1.630 + let size = 261;// An arbitrary file length 1.631 + let start = new Date(); 1.632 + 1.633 + // Cleanup any leftover from previous tests 1.634 + try { 1.635 + OS.File.remove(filename); 1.636 + info("test_info: Cleaned up previous garbage"); 1.637 + } catch (x) { 1.638 + if (!x.becauseNoSuchFile) { 1.639 + throw x; 1.640 + } 1.641 + info("test_info: No previous garbage"); 1.642 + } 1.643 + 1.644 + let file = OS.File.open(filename, {trunc: true}); 1.645 + let buf = new ArrayBuffer(size); 1.646 + file._write(buf, size); 1.647 + file.close(); 1.648 + 1.649 + // Test OS.File.stat on new file 1.650 + let stat = OS.File.stat(filename); 1.651 + ok(!!stat, "test_info: info acquired"); 1.652 + ok(!stat.isDir, "test_info: file is not a directory"); 1.653 + is(stat.isSymLink, false, "test_info: file is not a link"); 1.654 + is(stat.size.toString(), size, "test_info: correct size"); 1.655 + 1.656 + let stop = new Date(); 1.657 + 1.658 + // We round down/up by 1s as file system precision is lower than 1.659 + // Date precision (no clear specifications about that, but it seems 1.660 + // that this can be a little over 1 second under ext3 and 2 seconds 1.661 + // under FAT). 1.662 + let SLOPPY_FILE_SYSTEM_ADJUSTMENT = 3000; 1.663 + let startMs = start.getTime() - SLOPPY_FILE_SYSTEM_ADJUSTMENT; 1.664 + let stopMs = stop.getTime() + SLOPPY_FILE_SYSTEM_ADJUSTMENT; 1.665 + info("Testing stat with bounds [ " + startMs + ", " + stopMs +" ]"); 1.666 + 1.667 + (function() { 1.668 + let birth; 1.669 + if ("winBirthDate" in stat) { 1.670 + birth = stat.winBirthDate; 1.671 + } else if ("macBirthDate" in stat) { 1.672 + birth = stat.macBirthDate; 1.673 + } else { 1.674 + ok(true, "Skipping birthdate test"); 1.675 + return; 1.676 + } 1.677 + ok(birth.getTime() <= stopMs, 1.678 + "test_info: platformBirthDate is consistent"); 1.679 + // Note: Previous versions of this test checked whether the file 1.680 + // has been created after the start of the test. Unfortunately, 1.681 + // this sometimes failed under Windows, in specific circumstances: 1.682 + // if the file has been removed at the start of the test and 1.683 + // recreated immediately, the Windows file system detects this and 1.684 + // decides that the file was actually truncated rather than 1.685 + // recreated, hence that it should keep its previous creation 1.686 + // date. Debugging hilarity ensues. 1.687 + }); 1.688 + 1.689 + let change = stat.lastModificationDate; 1.690 + info("Testing lastModificationDate: " + change); 1.691 + ok(change.getTime() >= startMs && change.getTime() <= stopMs, 1.692 + "test_info: lastModificationDate is consistent"); 1.693 + 1.694 + // Test OS.File.prototype.stat on new file 1.695 + file = OS.File.open(filename); 1.696 + try { 1.697 + stat = file.stat(); 1.698 + } finally { 1.699 + file.close(); 1.700 + } 1.701 + 1.702 + ok(!!stat, "test_info: info acquired 2"); 1.703 + ok(!stat.isDir, "test_info: file is not a directory 2"); 1.704 + ok(!stat.isSymLink, "test_info: file is not a link 2"); 1.705 + is(stat.size.toString(), size, "test_info: correct size 2"); 1.706 + 1.707 + stop = new Date(); 1.708 + 1.709 + // Round up/down as above 1.710 + startMs = start.getTime() - SLOPPY_FILE_SYSTEM_ADJUSTMENT; 1.711 + stopMs = stop.getTime() + SLOPPY_FILE_SYSTEM_ADJUSTMENT; 1.712 + info("Testing stat 2 with bounds [ " + startMs + ", " + stopMs +" ]"); 1.713 + 1.714 + let access = stat.lastAccessDate; 1.715 + info("Testing lastAccessDate: " + access); 1.716 + ok(access.getTime() >= startMs && access.getTime() <= stopMs, 1.717 + "test_info: lastAccessDate is consistent"); 1.718 + 1.719 + change = stat.lastModificationDate; 1.720 + info("Testing lastModificationDate 2: " + change); 1.721 + ok(change.getTime() >= startMs && change.getTime() <= stopMs, 1.722 + "test_info: lastModificationDate 2 is consistent"); 1.723 + 1.724 + // Test OS.File.stat on directory 1.725 + stat = OS.File.stat(OS.File.getCurrentDirectory()); 1.726 + ok(!!stat, "test_info: info on directory acquired"); 1.727 + ok(stat.isDir, "test_info: directory is a directory"); 1.728 + 1.729 + info("test_info: Complete"); 1.730 +} 1.731 + 1.732 +// Note that most of the features of path are tested in 1.733 +// worker_test_osfile_{unix, win}.js 1.734 +function test_path() 1.735 +{ 1.736 + info("test_path: starting"); 1.737 + let abcd = OS.Path.join("a", "b", "c", "d"); 1.738 + is(OS.Path.basename(abcd), "d", "basename of a/b/c/d"); 1.739 + 1.740 + let abc = OS.Path.join("a", "b", "c"); 1.741 + is(OS.Path.dirname(abcd), abc, "dirname of a/b/c/d"); 1.742 + 1.743 + let abdotsc = OS.Path.join("a", "b", "..", "c"); 1.744 + is(OS.Path.normalize(abdotsc), OS.Path.join("a", "c"), "normalize a/b/../c"); 1.745 + 1.746 + let adotsdotsdots = OS.Path.join("a", "..", "..", ".."); 1.747 + is(OS.Path.normalize(adotsdotsdots), OS.Path.join("..", ".."), "normalize a/../../.."); 1.748 + 1.749 + info("test_path: Complete"); 1.750 +} 1.751 + 1.752 +/** 1.753 + * Test the file |exists| method. 1.754 + */ 1.755 +function test_exists_file() 1.756 +{ 1.757 + let file_name = OS.Path.join("chrome", "toolkit", "components" ,"osfile", 1.758 + "tests", "mochi", "test_osfile_front.xul"); 1.759 + info("test_exists_file: starting"); 1.760 + ok(OS.File.exists(file_name), "test_exists_file: file exists (OS.File.exists)"); 1.761 + ok(!OS.File.exists(file_name + ".tmp"), "test_exists_file: file does not exists (OS.File.exists)"); 1.762 + 1.763 + let dir_name = OS.Path.join("chrome", "toolkit", "components" ,"osfile", 1.764 + "tests", "mochi"); 1.765 + ok(OS.File.exists(dir_name), "test_exists_file: directory exists"); 1.766 + ok(!OS.File.exists(dir_name) + ".tmp", "test_exists_file: directory does not exist"); 1.767 + 1.768 + info("test_exists_file: complete"); 1.769 +} 1.770 + 1.771 +/** 1.772 + * Test the file |remove| method. 1.773 + */ 1.774 +function test_remove_file() 1.775 +{ 1.776 + let absent_file_name = "test_osfile_front_absent.tmp"; 1.777 + 1.778 + // Check that removing absent files is handled correctly 1.779 + let exn = should_throw(function() { 1.780 + OS.File.remove(absent_file_name, {ignoreAbsent: false}); 1.781 + }); 1.782 + ok(!!exn, "test_remove_file: throws if there is no such file"); 1.783 + 1.784 + exn = should_throw(function() { 1.785 + OS.File.remove(absent_file_name, {ignoreAbsent: true}); 1.786 + OS.File.remove(absent_file_name); 1.787 + }); 1.788 + ok(!exn, "test_remove_file: ignoreAbsent works"); 1.789 + 1.790 + if (OS.Win) { 1.791 + let file_name = "test_osfile_front_file_to_remove.tmp"; 1.792 + let file = OS.File.open(file_name, {write: true}); 1.793 + file.close(); 1.794 + ok(OS.File.exists(file_name), "test_remove_file: test file exists"); 1.795 + OS.Win.File.SetFileAttributes(file_name, 1.796 + OS.Constants.Win.FILE_ATTRIBUTE_READONLY); 1.797 + OS.File.remove(file_name); 1.798 + ok(!OS.File.exists(file_name), 1.799 + "test_remove_file: test file has been removed"); 1.800 + } 1.801 +}