"use strict"; Components.utils.import("resource://gre/modules/osfile.jsm"); Components.utils.import("resource://gre/modules/Task.jsm"); /** * A test to ensure that OS.File.setDates and OS.File.prototype.setDates are * working correctly. * (see bug 924916) */ function run_test() { run_next_test(); } // Non-prototypical tests, operating on path names. add_task(function* test_nonproto() { // First, create a file we can mess with. let path = OS.Path.join(OS.Constants.Path.tmpDir, "test_osfile_async_setDates_nonproto.tmp"); yield OS.File.writeAtomic(path, new Uint8Array(1)); try { // 1. Try to set some well known dates. // We choose multiples of 2000ms, because the time stamp resolution of // the underlying OS might not support something more precise. const accDate = 2000; const modDate = 4000; { yield OS.File.setDates(path, accDate, modDate); let stat = yield OS.File.stat(path); do_check_eq(accDate, stat.lastAccessDate.getTime()); do_check_eq(modDate, stat.lastModificationDate.getTime()); } // 2.1 Try to omit modificationDate (which should then default to // |Date.now()|, expect for resolution differences). { yield OS.File.setDates(path, accDate); let stat = yield OS.File.stat(path); do_check_eq(accDate, stat.lastAccessDate.getTime()); do_check_neq(modDate, stat.lastModificationDate.getTime()); } // 2.2 Try to omit accessDate as well (which should then default to // |Date.now()|, expect for resolution differences). { yield OS.File.setDates(path); let stat = yield OS.File.stat(path); do_check_neq(accDate, stat.lastAccessDate.getTime()); do_check_neq(modDate, stat.lastModificationDate.getTime()); } // 3. Repeat 1., but with Date objects this time { yield OS.File.setDates(path, new Date(accDate), new Date(modDate)); let stat = yield OS.File.stat(path); do_check_eq(accDate, stat.lastAccessDate.getTime()); do_check_eq(modDate, stat.lastModificationDate.getTime()); } // 4. Check that invalid params will cause an exception/rejection. { for (let p of ["invalid", new Uint8Array(1), NaN]) { try { yield OS.File.setDates(path, p, modDate); do_throw("Invalid access date should have thrown for: " + p); } catch (ex) { let stat = yield OS.File.stat(path); do_check_eq(accDate, stat.lastAccessDate.getTime()); do_check_eq(modDate, stat.lastModificationDate.getTime()); } try { yield OS.File.setDates(path, accDate, p); do_throw("Invalid modification date should have thrown for: " + p); } catch (ex) { let stat = yield OS.File.stat(path); do_check_eq(accDate, stat.lastAccessDate.getTime()); do_check_eq(modDate, stat.lastModificationDate.getTime()); } try { yield OS.File.setDates(path, p, p); do_throw("Invalid dates should have thrown for: " + p); } catch (ex) { let stat = yield OS.File.stat(path); do_check_eq(accDate, stat.lastAccessDate.getTime()); do_check_eq(modDate, stat.lastModificationDate.getTime()); } } } } finally { // Remove the temp file again yield OS.File.remove(path); } }); // Prototypical tests, operating on |File| handles. add_task(function* test_proto() { if (OS.Constants.Sys.Name == "Android" || OS.Constants.Sys.Name == "Gonk") { do_print("File.prototype.setDates is not implemented for Android/B2G"); do_check_eq(OS.File.prototype.setDates, undefined); return; } // First, create a file we can mess with. let path = OS.Path.join(OS.Constants.Path.tmpDir, "test_osfile_async_setDates_proto.tmp"); yield OS.File.writeAtomic(path, new Uint8Array(1)); try { let fd = yield OS.File.open(path, {write: true}); try { // 1. Try to set some well known dates. // We choose multiples of 2000ms, because the time stamp resolution of // the underlying OS might not support something more precise. const accDate = 2000; const modDate = 4000; { yield fd.setDates(accDate, modDate); let stat = yield fd.stat(); do_check_eq(accDate, stat.lastAccessDate.getTime()); do_check_eq(modDate, stat.lastModificationDate.getTime()); } // 2.1 Try to omit modificationDate (which should then default to // |Date.now()|, expect for resolution differences). { yield fd.setDates(accDate); let stat = yield fd.stat(); do_check_eq(accDate, stat.lastAccessDate.getTime()); do_check_neq(modDate, stat.lastModificationDate.getTime()); } // 2.2 Try to omit accessDate as well (which should then default to // |Date.now()|, expect for resolution differences). { yield fd.setDates(); let stat = yield fd.stat(); do_check_neq(accDate, stat.lastAccessDate.getTime()); do_check_neq(modDate, stat.lastModificationDate.getTime()); } // 3. Repeat 1., but with Date objects this time { yield fd.setDates(new Date(accDate), new Date(modDate)); let stat = yield fd.stat(); do_check_eq(accDate, stat.lastAccessDate.getTime()); do_check_eq(modDate, stat.lastModificationDate.getTime()); } // 4. Check that invalid params will cause an exception/rejection. { for (let p of ["invalid", new Uint8Array(1), NaN]) { try { yield fd.setDates(p, modDate); do_throw("Invalid access date should have thrown for: " + p); } catch (ex) { let stat = yield fd.stat(); do_check_eq(accDate, stat.lastAccessDate.getTime()); do_check_eq(modDate, stat.lastModificationDate.getTime()); } try { yield fd.setDates(accDate, p); do_throw("Invalid modification date should have thrown for: " + p); } catch (ex) { let stat = yield fd.stat(); do_check_eq(accDate, stat.lastAccessDate.getTime()); do_check_eq(modDate, stat.lastModificationDate.getTime()); } try { yield fd.setDates(p, p); do_throw("Invalid dates should have thrown for: " + p); } catch (ex) { let stat = yield fd.stat(); do_check_eq(accDate, stat.lastAccessDate.getTime()); do_check_eq(modDate, stat.lastModificationDate.getTime()); } } } } finally { yield fd.close(); } } finally { // Remove the temp file again yield OS.File.remove(path); } }); // Tests setting dates on directories. add_task(function* test_dirs() { let path = OS.Path.join(OS.Constants.Path.tmpDir, "test_osfile_async_setDates_dir"); yield OS.File.makeDir(path); try { // 1. Try to set some well known dates. // We choose multiples of 2000ms, because the time stamp resolution of // the underlying OS might not support something more precise. const accDate = 2000; const modDate = 4000; { yield OS.File.setDates(path, accDate, modDate); let stat = yield OS.File.stat(path); do_check_eq(accDate, stat.lastAccessDate.getTime()); do_check_eq(modDate, stat.lastModificationDate.getTime()); } } finally { yield OS.File.removeEmptyDir(path); } });