content/base/test/test_fileapi.html

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 <!DOCTYPE HTML>
     2 <html>
     3 <head>
     4 <!--
     5 https://bugzilla.mozilla.org/show_bug.cgi?id=414796
     6 -->
     7   <title>Test for Bug 414796</title>
     8   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
     9   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
    10 </head>
    12 <body>
    13 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=414796">Mozilla Bug 414796</a>
    14 <p id="display">
    15   <input id="fileList" type="file"></input>
    16 </p>
    17 <div id="content" style="display: none">
    18 </div>
    20 <pre id="test">
    21 <script class="testbody" type="text/javascript">
    23 // File constructors should not work from non-chrome code
    24 try {
    25   var file = File("/etc/passwd");
    26   ok(false, "Did not throw on unprivileged attempt to construct a File");
    27 } catch (e) {
    28   ok(true, "Threw on an unprivileged attempt to construct a File");
    29 }
    31 const minFileSize = 20000;
    32 var fileNum = 1;
    33 var testRanCounter = 0;
    34 var expectedTestCount = 0;
    35 SimpleTest.waitForExplicitFinish();
    37 is(FileReader.EMPTY, 0, "correct EMPTY value");
    38 is(FileReader.LOADING, 1, "correct LOADING value");
    39 is(FileReader.DONE, 2, "correct DONE value");
    41 // Create strings containing data we'll test with. We'll want long
    42 // strings to ensure they span multiple buffers while loading
    43 var testTextData = "asd b\tlah\u1234w\u00a0r";
    44 while (testTextData.length < minFileSize) {
    45   testTextData = testTextData + testTextData;
    46 }
    48 var testASCIIData = "abcdef 123456\n";
    49 while (testASCIIData.length < minFileSize) {
    50   testASCIIData = testASCIIData + testASCIIData;
    51 }
    53 var testBinaryData = "";
    54 for (var i = 0; i < 256; i++) {
    55   testBinaryData += String.fromCharCode(i);
    56 }
    57 while (testBinaryData.length < minFileSize) {
    58   testBinaryData = testBinaryData + testBinaryData;
    59 }
    62 //Set up files for testing
    63 var asciiFile = createFileWithData(testASCIIData);
    64 var binaryFile = createFileWithData(testBinaryData);
    66 var fileList = document.getElementById('fileList');
    67 SpecialPowers.wrap(fileList).value = "/none/existing/path/fileAPI/testing";
    68 var nonExistingFile = fileList.files[0];
    70 // Test that plain reading works and fires events as expected, both
    71 // for text and binary reading
    73 var onloadHasRunText = false;
    74 var onloadStartHasRunText = false;
    75 r = new FileReader();
    76 is(r.readyState, FileReader.EMPTY, "correct initial text readyState");
    77 r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "plain reading");
    78 r.addEventListener("load", function() { onloadHasRunText = true }, false);
    79 r.addEventListener("loadstart", function() { onloadStartHasRunText = true }, false);
    80 r.readAsText(asciiFile);
    81 is(r.readyState, FileReader.LOADING, "correct loading text readyState");
    82 is(onloadHasRunText, false, "text loading must be async");
    83 is(onloadStartHasRunText, true, "text loadstart should fire sync");
    84 expectedTestCount++;
    86 var onloadHasRunBinary = false;
    87 var onloadStartHasRunBinary = false;
    88 r = new FileReader();
    89 is(r.readyState, FileReader.EMPTY, "correct initial binary readyState");
    90 r.addEventListener("load", function() { onloadHasRunBinary = true }, false);
    91 r.addEventListener("loadstart", function() { onloadStartHasRunBinary = true }, false);
    92 r.readAsBinaryString(binaryFile);
    93 r.onload = getLoadHandler(testBinaryData, testBinaryData.length, "binary reading");
    94 is(r.readyState, FileReader.LOADING, "correct loading binary readyState");
    95 is(onloadHasRunBinary, false, "binary loading must be async");
    96 is(onloadStartHasRunBinary, true, "binary loadstart should fire sync");
    97 expectedTestCount++;
    99 var onloadHasRunArrayBuffer = false;
   100 var onloadStartHasRunArrayBuffer = false;
   101 r = new FileReader();
   102 is(r.readyState, FileReader.EMPTY, "correct initial arrayBuffer readyState");
   103 r.addEventListener("load", function() { onloadHasRunArrayBuffer = true }, false);
   104 r.addEventListener("loadstart", function() { onloadStartHasRunArrayBuffer = true }, false);
   105 r.readAsArrayBuffer(binaryFile);
   106 r.onload = getLoadHandlerForArrayBuffer(testBinaryData, testBinaryData.length, "array buffer reading");
   107 is(r.readyState, FileReader.LOADING, "correct loading arrayBuffer readyState");
   108 is(onloadHasRunArrayBuffer, false, "arrayBuffer loading must be async");
   109 is(onloadStartHasRunArrayBuffer, true, "arrayBuffer loadstart should fire sync");
   110 expectedTestCount++;
   112 // Test a variety of encodings, and make sure they work properly
   113 r = new FileReader();
   114 r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "no encoding reading");
   115 r.readAsText(asciiFile, "");
   116 expectedTestCount++;
   118 r = new FileReader();
   119 r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "iso8859 reading");
   120 r.readAsText(asciiFile, "iso-8859-1");
   121 expectedTestCount++;
   123 r = new FileReader();
   124 r.onload = getLoadHandler(testTextData,
   125                           convertToUTF8(testTextData).length,
   126                           "utf8 reading");
   127 r.readAsText(createFileWithData(convertToUTF8(testTextData)), "utf8");
   128 expectedTestCount++;
   130 r = new FileReader();
   131 r.readAsText(createFileWithData(convertToUTF16(testTextData)), "utf-16");
   132 r.onload = getLoadHandler(testTextData,
   133                           convertToUTF16(testTextData).length,
   134                           "utf16 reading");
   135 expectedTestCount++;
   137 // Test get result without reading
   138 r = new FileReader();
   139 is(r.readyState, FileReader.EMPTY,
   140   "readyState in test reader get result without reading");
   141 is(r.error, null,
   142   "no error in test reader get result without reading");
   143 is(r.result, null,
   144   "result in test reader get result without reading");
   146 // Test loading an empty file works (and doesn't crash!)
   147 var emptyFile = createFileWithData("");
   148 dump("hello nurse");
   149 r = new FileReader();
   150 r.onload = getLoadHandler("", 0, "empty no encoding reading");
   151 r.readAsText(emptyFile, "");
   152 expectedTestCount++;
   154 r = new FileReader();
   155 r.onload = getLoadHandler("", 0, "empty utf8 reading");
   156 r.readAsText(emptyFile, "utf8");
   157 expectedTestCount++;
   159 r = new FileReader();
   160 r.onload = getLoadHandler("", 0, "empty utf16 reading");
   161 r.readAsText(emptyFile, "utf-16");
   162 expectedTestCount++;
   164 r = new FileReader();
   165 r.onload = getLoadHandler("", 0, "empty binary string reading");
   166 r.readAsBinaryString(emptyFile);
   167 expectedTestCount++;
   169 r = new FileReader();
   170 r.onload = getLoadHandlerForArrayBuffer("", 0, "empty array buffer reading");
   171 r.readAsArrayBuffer(emptyFile);
   172 expectedTestCount++;
   174 r = new FileReader();
   175 r.onload = getLoadHandler(convertToDataURL(""), 0, "empt binary string reading");
   176 r.readAsDataURL(emptyFile);
   177 expectedTestCount++;
   179 // Test reusing a FileReader to read multiple times
   180 r = new FileReader();
   181 r.onload = getLoadHandler(testASCIIData,
   182                           testASCIIData.length,
   183                           "to-be-reused reading text")
   184 var makeAnotherReadListener = function(event) {
   185   r = event.target;
   186   r.removeEventListener("load", makeAnotherReadListener, false);
   187   r.onload = getLoadHandler(testASCIIData,
   188                             testASCIIData.length,
   189                             "reused reading text");
   190   r.readAsText(asciiFile);
   191 };
   192 r.addEventListener("load", makeAnotherReadListener, false);
   193 r.readAsText(asciiFile);
   194 expectedTestCount += 2;
   196 r = new FileReader();
   197 r.onload = getLoadHandler(testBinaryData,
   198                           testBinaryData.length,
   199                           "to-be-reused reading binary")
   200 var makeAnotherReadListener2 = function(event) {
   201   r = event.target;
   202   r.removeEventListener("load", makeAnotherReadListener2, false);
   203   r.onload = getLoadHandler(testBinaryData,
   204                             testBinaryData.length,
   205                             "reused reading binary");
   206   r.readAsBinaryString(binaryFile);
   207 };
   208 r.addEventListener("load", makeAnotherReadListener2, false);
   209 r.readAsBinaryString(binaryFile);
   210 expectedTestCount += 2;
   212 r = new FileReader();
   213 r.onload = getLoadHandler(convertToDataURL(testBinaryData),
   214                           testBinaryData.length,
   215                           "to-be-reused reading data url")
   216 var makeAnotherReadListener3 = function(event) {
   217   r = event.target;
   218   r.removeEventListener("load", makeAnotherReadListener3, false);
   219   r.onload = getLoadHandler(convertToDataURL(testBinaryData),
   220                             testBinaryData.length,
   221                             "reused reading data url");
   222   r.readAsDataURL(binaryFile);
   223 };
   224 r.addEventListener("load", makeAnotherReadListener3, false);
   225 r.readAsDataURL(binaryFile);
   226 expectedTestCount += 2;
   228 r = new FileReader();
   229 r.onload = getLoadHandlerForArrayBuffer(testBinaryData,
   230                           testBinaryData.length,
   231                           "to-be-reused reading arrayBuffer")
   232 var makeAnotherReadListener4 = function(event) {
   233   r = event.target;
   234   r.removeEventListener("load", makeAnotherReadListener4, false);
   235   r.onload = getLoadHandlerForArrayBuffer(testBinaryData,
   236                             testBinaryData.length,
   237                             "reused reading arrayBuffer");
   238   r.readAsArrayBuffer(binaryFile);
   239 };
   240 r.addEventListener("load", makeAnotherReadListener4, false);
   241 r.readAsArrayBuffer(binaryFile);
   242 expectedTestCount += 2;
   244 // Test first reading as ArrayBuffer then read as something else
   245 // (BinaryString) and doesn't crash
   246 r = new FileReader();
   247 r.onload = getLoadHandlerForArrayBuffer(testBinaryData,
   248                           testBinaryData.length,
   249                           "to-be-reused reading arrayBuffer")
   250 var makeAnotherReadListener5 = function(event) {
   251   r = event.target;
   252   r.removeEventListener("load", makeAnotherReadListener5, false);
   253   r.onload = getLoadHandler(testBinaryData,
   254                             testBinaryData.length,
   255                             "reused reading binary string");
   256   r.readAsBinaryString(binaryFile);
   257 };
   258 r.addEventListener("load", makeAnotherReadListener5, false);
   259 r.readAsArrayBuffer(binaryFile);
   260 expectedTestCount += 2;
   262 //Test data-URI encoding on differing file sizes
   263 dataurldata = testBinaryData.substr(0, testBinaryData.length -
   264                                        testBinaryData.length % 3);
   265 is(dataurldata.length % 3, 0, "Want to test data with length % 3 == 0");
   266 r = new FileReader();
   267 r.onload = getLoadHandler(convertToDataURL(dataurldata),
   268                           dataurldata.length,
   269                           "dataurl reading, %3 = 0");
   270 r.readAsDataURL(createFileWithData(dataurldata));
   271 expectedTestCount++;
   273 dataurldata = testBinaryData.substr(0, testBinaryData.length - 2 -
   274                                        testBinaryData.length % 3);
   275 is(dataurldata.length % 3, 1, "Want to test data with length % 3 == 1");
   276 r = new FileReader();
   277 r.onload = getLoadHandler(convertToDataURL(dataurldata),
   278                           dataurldata.length,
   279                           "dataurl reading, %3 = 1");
   280 r.readAsDataURL(createFileWithData(dataurldata));
   281 expectedTestCount++;
   283 dataurldata = testBinaryData.substr(0, testBinaryData.length - 1 -
   284                                        testBinaryData.length % 3);
   285 is(dataurldata.length % 3, 2, "Want to test data with length % 3 == 2");
   286 r = new FileReader();
   287 r.onload = getLoadHandler(convertToDataURL(dataurldata),
   288                           dataurldata.length,
   289                           "dataurl reading, %3 = 2");
   290 r.readAsDataURL(createFileWithData(dataurldata));
   291 expectedTestCount++;
   294 // Test abort()
   295 var abortHasRun = false;
   296 var loadEndHasRun = false;
   297 r = new FileReader();
   298 r.onabort = function (event) {
   299   is(abortHasRun, false, "abort should only fire once");
   300   is(loadEndHasRun, false, "loadend shouldn't have fired yet");
   301   abortHasRun = true;
   302   is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort");
   303   is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads");
   304   is(event.target.result, null, "file data should be null on aborted reads");
   305 }
   306 r.onloadend = function (event) {
   307   is(abortHasRun, true, "abort should fire before loadend");
   308   is(loadEndHasRun, false, "loadend should only fire once");
   309   loadEndHasRun = true;
   310   is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort");
   311   is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads");
   312   is(event.target.result, null, "file data should be null on aborted reads");
   313 }
   314 r.onload = function() { ok(false, "load should not fire for aborted reads") };
   315 r.onerror = function() { ok(false, "error should not fire for aborted reads") };
   316 r.onprogress = function() { ok(false, "progress should not fire for aborted reads") };
   317 var abortThrew = false;
   318 try {
   319   r.abort();
   320 } catch(e) {
   321   abortThrew = true;
   322 }
   323 is(abortThrew, true, "abort() must throw if not loading");
   324 is(abortHasRun, false, "abort() is a no-op unless loading");
   325 r.readAsText(asciiFile);
   326 r.abort();
   327 is(abortHasRun, true, "abort should fire sync");
   328 is(loadEndHasRun, true, "loadend should fire sync");
   330 // Test calling readAsX to cause abort()
   331 var reuseAbortHasRun = false;
   332 r = new FileReader();
   333 r.onabort = function (event) {
   334   is(reuseAbortHasRun, false, "abort should only fire once");
   335   reuseAbortHasRun = true;
   336   is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort");
   337   is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads");
   338   is(event.target.result, null, "file data should be null on aborted reads");
   339 }
   340 r.onload = function() { ok(false, "load should not fire for aborted reads") };
   341 var abortThrew = false;
   342 try {
   343   r.abort();
   344 } catch(e) {
   345   abortThrew = true;
   346 }
   347 is(abortThrew, true, "abort() must throw if not loading");
   348 is(reuseAbortHasRun, false, "abort() is a no-op unless loading");
   349 r.readAsText(asciiFile);
   350 r.readAsText(asciiFile);
   351 is(reuseAbortHasRun, true, "abort should fire sync");
   352 r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "reuse-as-abort reading");
   353 expectedTestCount++;
   356 // Test reading from nonexistent files
   357 r = new FileReader();
   358 var didThrow = false;
   359 try {
   360   r.readAsDataURL(nonExistingFile);
   361 } catch(ex) {
   362   didThrow = true;
   363 }
   364 // Once this test passes, we should test that onerror gets called and
   365 // that the FileReader object is in the right state during that call.
   366 todo(!didThrow, "shouldn't throw when opening nonexistent file, should fire error instead");
   369 function getLoadHandler(expectedResult, expectedLength, testName) {
   370   return function (event) {
   371     is(event.target.readyState, FileReader.DONE,
   372        "readyState in test " + testName);
   373     is(event.target.error, null,
   374        "no error in test " + testName);
   375     is(event.target.result, expectedResult,
   376        "result in test " + testName);
   377     is(event.lengthComputable, true,
   378        "lengthComputable in test " + testName);
   379     is(event.loaded, expectedLength,
   380        "loaded in test " + testName);
   381     is(event.total, expectedLength,
   382        "total in test " + testName);
   383     testHasRun();
   384   }
   385 }
   387 function getLoadHandlerForArrayBuffer(expectedResult, expectedLength, testName) {
   388   return function (event) {
   389     is(event.target.readyState, FileReader.DONE,
   390        "readyState in test " + testName);
   391     is(event.target.error, null,
   392        "no error in test " +  testName);
   393     is(event.lengthComputable, true,
   394        "lengthComputable in test " + testName);
   395     is(event.loaded, expectedLength,
   396        "loaded in test " + testName);
   397     is(event.total, expectedLength,
   398        "total in test " + testName);
   399     is(event.target.result.byteLength, expectedLength,
   400        "array buffer size in test " + testName);
   401     var u8v = new Uint8Array(event.target.result);
   402     is(String.fromCharCode.apply(String, u8v), expectedResult,
   403        "array buffer contents in test " + testName);
   404     u8v = null;
   405     SpecialPowers.gc();
   406     is(event.target.result.byteLength, expectedLength,
   407        "array buffer size after gc in test " + testName);
   408     u8v = new Uint8Array(event.target.result);
   409     is(String.fromCharCode.apply(String, u8v), expectedResult,
   410        "array buffer contents after gc in test " + testName);
   411     testHasRun();
   412   }
   413 }
   415 function testHasRun() {
   416  //alert(testRanCounter);
   417  ++testRanCounter;
   418  if (testRanCounter == expectedTestCount) {
   419     is(onloadHasRunText, true, "onload text should have fired by now"); 
   420     is(onloadHasRunBinary, true, "onload binary should have fired by now"); 
   421     SimpleTest.finish();
   422   }
   423 }
   425 function createFileWithData(fileData) {
   426   var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"].getService(SpecialPowers.Ci.nsIProperties);
   427   var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
   428   testFile.append("fileAPItestfile" + fileNum);
   429   fileNum++;
   430   var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].createInstance(SpecialPowers.Ci.nsIFileOutputStream);
   431   outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
   432                  0666, 0);
   433   outStream.write(fileData, fileData.length);
   434   outStream.close();
   436   var fileList = document.getElementById('fileList');
   437   SpecialPowers.wrap(fileList).value = testFile.path;
   439   return fileList.files[0];
   440 }
   442 function convertToUTF16(s) {
   443   res = "";
   444   for (var i = 0; i < s.length; ++i) {
   445     c = s.charCodeAt(i);
   446     res += String.fromCharCode(c & 255, c >>> 8);
   447   }
   448   return res;
   449 }
   451 function convertToUTF8(s) {
   452   return unescape(encodeURIComponent(s));
   453 }
   455 function convertToDataURL(s) {
   456   return "data:application/octet-stream;base64," + btoa(s);
   457 }
   459 </script>
   460 </pre>
   461 </body> </html>

mercurial