content/base/test/test_fileapi.html

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/base/test/test_fileapi.html	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,461 @@
     1.4 +<!DOCTYPE HTML>
     1.5 +<html>
     1.6 +<head>
     1.7 +<!--
     1.8 +https://bugzilla.mozilla.org/show_bug.cgi?id=414796
     1.9 +-->
    1.10 +  <title>Test for Bug 414796</title>
    1.11 +  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
    1.12 +  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
    1.13 +</head>
    1.14 +
    1.15 +<body>
    1.16 +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=414796">Mozilla Bug 414796</a>
    1.17 +<p id="display">
    1.18 +  <input id="fileList" type="file"></input>
    1.19 +</p>
    1.20 +<div id="content" style="display: none">
    1.21 +</div>
    1.22 +
    1.23 +<pre id="test">
    1.24 +<script class="testbody" type="text/javascript">
    1.25 +
    1.26 +// File constructors should not work from non-chrome code
    1.27 +try {
    1.28 +  var file = File("/etc/passwd");
    1.29 +  ok(false, "Did not throw on unprivileged attempt to construct a File");
    1.30 +} catch (e) {
    1.31 +  ok(true, "Threw on an unprivileged attempt to construct a File");
    1.32 +}
    1.33 +
    1.34 +const minFileSize = 20000;
    1.35 +var fileNum = 1;
    1.36 +var testRanCounter = 0;
    1.37 +var expectedTestCount = 0;
    1.38 +SimpleTest.waitForExplicitFinish();
    1.39 +
    1.40 +is(FileReader.EMPTY, 0, "correct EMPTY value");
    1.41 +is(FileReader.LOADING, 1, "correct LOADING value");
    1.42 +is(FileReader.DONE, 2, "correct DONE value");
    1.43 +
    1.44 +// Create strings containing data we'll test with. We'll want long
    1.45 +// strings to ensure they span multiple buffers while loading
    1.46 +var testTextData = "asd b\tlah\u1234w\u00a0r";
    1.47 +while (testTextData.length < minFileSize) {
    1.48 +  testTextData = testTextData + testTextData;
    1.49 +}
    1.50 +
    1.51 +var testASCIIData = "abcdef 123456\n";
    1.52 +while (testASCIIData.length < minFileSize) {
    1.53 +  testASCIIData = testASCIIData + testASCIIData;
    1.54 +}
    1.55 +
    1.56 +var testBinaryData = "";
    1.57 +for (var i = 0; i < 256; i++) {
    1.58 +  testBinaryData += String.fromCharCode(i);
    1.59 +}
    1.60 +while (testBinaryData.length < minFileSize) {
    1.61 +  testBinaryData = testBinaryData + testBinaryData;
    1.62 +}
    1.63 +
    1.64 +
    1.65 +//Set up files for testing
    1.66 +var asciiFile = createFileWithData(testASCIIData);
    1.67 +var binaryFile = createFileWithData(testBinaryData);
    1.68 +
    1.69 +var fileList = document.getElementById('fileList');
    1.70 +SpecialPowers.wrap(fileList).value = "/none/existing/path/fileAPI/testing";
    1.71 +var nonExistingFile = fileList.files[0];
    1.72 +
    1.73 +// Test that plain reading works and fires events as expected, both
    1.74 +// for text and binary reading
    1.75 +
    1.76 +var onloadHasRunText = false;
    1.77 +var onloadStartHasRunText = false;
    1.78 +r = new FileReader();
    1.79 +is(r.readyState, FileReader.EMPTY, "correct initial text readyState");
    1.80 +r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "plain reading");
    1.81 +r.addEventListener("load", function() { onloadHasRunText = true }, false);
    1.82 +r.addEventListener("loadstart", function() { onloadStartHasRunText = true }, false);
    1.83 +r.readAsText(asciiFile);
    1.84 +is(r.readyState, FileReader.LOADING, "correct loading text readyState");
    1.85 +is(onloadHasRunText, false, "text loading must be async");
    1.86 +is(onloadStartHasRunText, true, "text loadstart should fire sync");
    1.87 +expectedTestCount++;
    1.88 +
    1.89 +var onloadHasRunBinary = false;
    1.90 +var onloadStartHasRunBinary = false;
    1.91 +r = new FileReader();
    1.92 +is(r.readyState, FileReader.EMPTY, "correct initial binary readyState");
    1.93 +r.addEventListener("load", function() { onloadHasRunBinary = true }, false);
    1.94 +r.addEventListener("loadstart", function() { onloadStartHasRunBinary = true }, false);
    1.95 +r.readAsBinaryString(binaryFile);
    1.96 +r.onload = getLoadHandler(testBinaryData, testBinaryData.length, "binary reading");
    1.97 +is(r.readyState, FileReader.LOADING, "correct loading binary readyState");
    1.98 +is(onloadHasRunBinary, false, "binary loading must be async");
    1.99 +is(onloadStartHasRunBinary, true, "binary loadstart should fire sync");
   1.100 +expectedTestCount++;
   1.101 +
   1.102 +var onloadHasRunArrayBuffer = false;
   1.103 +var onloadStartHasRunArrayBuffer = false;
   1.104 +r = new FileReader();
   1.105 +is(r.readyState, FileReader.EMPTY, "correct initial arrayBuffer readyState");
   1.106 +r.addEventListener("load", function() { onloadHasRunArrayBuffer = true }, false);
   1.107 +r.addEventListener("loadstart", function() { onloadStartHasRunArrayBuffer = true }, false);
   1.108 +r.readAsArrayBuffer(binaryFile);
   1.109 +r.onload = getLoadHandlerForArrayBuffer(testBinaryData, testBinaryData.length, "array buffer reading");
   1.110 +is(r.readyState, FileReader.LOADING, "correct loading arrayBuffer readyState");
   1.111 +is(onloadHasRunArrayBuffer, false, "arrayBuffer loading must be async");
   1.112 +is(onloadStartHasRunArrayBuffer, true, "arrayBuffer loadstart should fire sync");
   1.113 +expectedTestCount++;
   1.114 +
   1.115 +// Test a variety of encodings, and make sure they work properly
   1.116 +r = new FileReader();
   1.117 +r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "no encoding reading");
   1.118 +r.readAsText(asciiFile, "");
   1.119 +expectedTestCount++;
   1.120 +
   1.121 +r = new FileReader();
   1.122 +r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "iso8859 reading");
   1.123 +r.readAsText(asciiFile, "iso-8859-1");
   1.124 +expectedTestCount++;
   1.125 +
   1.126 +r = new FileReader();
   1.127 +r.onload = getLoadHandler(testTextData,
   1.128 +                          convertToUTF8(testTextData).length,
   1.129 +                          "utf8 reading");
   1.130 +r.readAsText(createFileWithData(convertToUTF8(testTextData)), "utf8");
   1.131 +expectedTestCount++;
   1.132 +
   1.133 +r = new FileReader();
   1.134 +r.readAsText(createFileWithData(convertToUTF16(testTextData)), "utf-16");
   1.135 +r.onload = getLoadHandler(testTextData,
   1.136 +                          convertToUTF16(testTextData).length,
   1.137 +                          "utf16 reading");
   1.138 +expectedTestCount++;
   1.139 +
   1.140 +// Test get result without reading
   1.141 +r = new FileReader();
   1.142 +is(r.readyState, FileReader.EMPTY,
   1.143 +  "readyState in test reader get result without reading");
   1.144 +is(r.error, null,
   1.145 +  "no error in test reader get result without reading");
   1.146 +is(r.result, null,
   1.147 +  "result in test reader get result without reading");
   1.148 +
   1.149 +// Test loading an empty file works (and doesn't crash!)
   1.150 +var emptyFile = createFileWithData("");
   1.151 +dump("hello nurse");
   1.152 +r = new FileReader();
   1.153 +r.onload = getLoadHandler("", 0, "empty no encoding reading");
   1.154 +r.readAsText(emptyFile, "");
   1.155 +expectedTestCount++;
   1.156 +
   1.157 +r = new FileReader();
   1.158 +r.onload = getLoadHandler("", 0, "empty utf8 reading");
   1.159 +r.readAsText(emptyFile, "utf8");
   1.160 +expectedTestCount++;
   1.161 +
   1.162 +r = new FileReader();
   1.163 +r.onload = getLoadHandler("", 0, "empty utf16 reading");
   1.164 +r.readAsText(emptyFile, "utf-16");
   1.165 +expectedTestCount++;
   1.166 +
   1.167 +r = new FileReader();
   1.168 +r.onload = getLoadHandler("", 0, "empty binary string reading");
   1.169 +r.readAsBinaryString(emptyFile);
   1.170 +expectedTestCount++;
   1.171 +
   1.172 +r = new FileReader();
   1.173 +r.onload = getLoadHandlerForArrayBuffer("", 0, "empty array buffer reading");
   1.174 +r.readAsArrayBuffer(emptyFile);
   1.175 +expectedTestCount++;
   1.176 +
   1.177 +r = new FileReader();
   1.178 +r.onload = getLoadHandler(convertToDataURL(""), 0, "empt binary string reading");
   1.179 +r.readAsDataURL(emptyFile);
   1.180 +expectedTestCount++;
   1.181 +
   1.182 +// Test reusing a FileReader to read multiple times
   1.183 +r = new FileReader();
   1.184 +r.onload = getLoadHandler(testASCIIData,
   1.185 +                          testASCIIData.length,
   1.186 +                          "to-be-reused reading text")
   1.187 +var makeAnotherReadListener = function(event) {
   1.188 +  r = event.target;
   1.189 +  r.removeEventListener("load", makeAnotherReadListener, false);
   1.190 +  r.onload = getLoadHandler(testASCIIData,
   1.191 +                            testASCIIData.length,
   1.192 +                            "reused reading text");
   1.193 +  r.readAsText(asciiFile);
   1.194 +};
   1.195 +r.addEventListener("load", makeAnotherReadListener, false);
   1.196 +r.readAsText(asciiFile);
   1.197 +expectedTestCount += 2;
   1.198 +
   1.199 +r = new FileReader();
   1.200 +r.onload = getLoadHandler(testBinaryData,
   1.201 +                          testBinaryData.length,
   1.202 +                          "to-be-reused reading binary")
   1.203 +var makeAnotherReadListener2 = function(event) {
   1.204 +  r = event.target;
   1.205 +  r.removeEventListener("load", makeAnotherReadListener2, false);
   1.206 +  r.onload = getLoadHandler(testBinaryData,
   1.207 +                            testBinaryData.length,
   1.208 +                            "reused reading binary");
   1.209 +  r.readAsBinaryString(binaryFile);
   1.210 +};
   1.211 +r.addEventListener("load", makeAnotherReadListener2, false);
   1.212 +r.readAsBinaryString(binaryFile);
   1.213 +expectedTestCount += 2;
   1.214 +
   1.215 +r = new FileReader();
   1.216 +r.onload = getLoadHandler(convertToDataURL(testBinaryData),
   1.217 +                          testBinaryData.length,
   1.218 +                          "to-be-reused reading data url")
   1.219 +var makeAnotherReadListener3 = function(event) {
   1.220 +  r = event.target;
   1.221 +  r.removeEventListener("load", makeAnotherReadListener3, false);
   1.222 +  r.onload = getLoadHandler(convertToDataURL(testBinaryData),
   1.223 +                            testBinaryData.length,
   1.224 +                            "reused reading data url");
   1.225 +  r.readAsDataURL(binaryFile);
   1.226 +};
   1.227 +r.addEventListener("load", makeAnotherReadListener3, false);
   1.228 +r.readAsDataURL(binaryFile);
   1.229 +expectedTestCount += 2;
   1.230 +
   1.231 +r = new FileReader();
   1.232 +r.onload = getLoadHandlerForArrayBuffer(testBinaryData,
   1.233 +                          testBinaryData.length,
   1.234 +                          "to-be-reused reading arrayBuffer")
   1.235 +var makeAnotherReadListener4 = function(event) {
   1.236 +  r = event.target;
   1.237 +  r.removeEventListener("load", makeAnotherReadListener4, false);
   1.238 +  r.onload = getLoadHandlerForArrayBuffer(testBinaryData,
   1.239 +                            testBinaryData.length,
   1.240 +                            "reused reading arrayBuffer");
   1.241 +  r.readAsArrayBuffer(binaryFile);
   1.242 +};
   1.243 +r.addEventListener("load", makeAnotherReadListener4, false);
   1.244 +r.readAsArrayBuffer(binaryFile);
   1.245 +expectedTestCount += 2;
   1.246 +
   1.247 +// Test first reading as ArrayBuffer then read as something else
   1.248 +// (BinaryString) and doesn't crash
   1.249 +r = new FileReader();
   1.250 +r.onload = getLoadHandlerForArrayBuffer(testBinaryData,
   1.251 +                          testBinaryData.length,
   1.252 +                          "to-be-reused reading arrayBuffer")
   1.253 +var makeAnotherReadListener5 = function(event) {
   1.254 +  r = event.target;
   1.255 +  r.removeEventListener("load", makeAnotherReadListener5, false);
   1.256 +  r.onload = getLoadHandler(testBinaryData,
   1.257 +                            testBinaryData.length,
   1.258 +                            "reused reading binary string");
   1.259 +  r.readAsBinaryString(binaryFile);
   1.260 +};
   1.261 +r.addEventListener("load", makeAnotherReadListener5, false);
   1.262 +r.readAsArrayBuffer(binaryFile);
   1.263 +expectedTestCount += 2;
   1.264 +
   1.265 +//Test data-URI encoding on differing file sizes
   1.266 +dataurldata = testBinaryData.substr(0, testBinaryData.length -
   1.267 +                                       testBinaryData.length % 3);
   1.268 +is(dataurldata.length % 3, 0, "Want to test data with length % 3 == 0");
   1.269 +r = new FileReader();
   1.270 +r.onload = getLoadHandler(convertToDataURL(dataurldata),
   1.271 +                          dataurldata.length,
   1.272 +                          "dataurl reading, %3 = 0");
   1.273 +r.readAsDataURL(createFileWithData(dataurldata));
   1.274 +expectedTestCount++;
   1.275 +
   1.276 +dataurldata = testBinaryData.substr(0, testBinaryData.length - 2 -
   1.277 +                                       testBinaryData.length % 3);
   1.278 +is(dataurldata.length % 3, 1, "Want to test data with length % 3 == 1");
   1.279 +r = new FileReader();
   1.280 +r.onload = getLoadHandler(convertToDataURL(dataurldata),
   1.281 +                          dataurldata.length,
   1.282 +                          "dataurl reading, %3 = 1");
   1.283 +r.readAsDataURL(createFileWithData(dataurldata));
   1.284 +expectedTestCount++;
   1.285 +
   1.286 +dataurldata = testBinaryData.substr(0, testBinaryData.length - 1 -
   1.287 +                                       testBinaryData.length % 3);
   1.288 +is(dataurldata.length % 3, 2, "Want to test data with length % 3 == 2");
   1.289 +r = new FileReader();
   1.290 +r.onload = getLoadHandler(convertToDataURL(dataurldata),
   1.291 +                          dataurldata.length,
   1.292 +                          "dataurl reading, %3 = 2");
   1.293 +r.readAsDataURL(createFileWithData(dataurldata));
   1.294 +expectedTestCount++;
   1.295 +
   1.296 +
   1.297 +// Test abort()
   1.298 +var abortHasRun = false;
   1.299 +var loadEndHasRun = false;
   1.300 +r = new FileReader();
   1.301 +r.onabort = function (event) {
   1.302 +  is(abortHasRun, false, "abort should only fire once");
   1.303 +  is(loadEndHasRun, false, "loadend shouldn't have fired yet");
   1.304 +  abortHasRun = true;
   1.305 +  is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort");
   1.306 +  is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads");
   1.307 +  is(event.target.result, null, "file data should be null on aborted reads");
   1.308 +}
   1.309 +r.onloadend = function (event) {
   1.310 +  is(abortHasRun, true, "abort should fire before loadend");
   1.311 +  is(loadEndHasRun, false, "loadend should only fire once");
   1.312 +  loadEndHasRun = true;
   1.313 +  is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort");
   1.314 +  is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads");
   1.315 +  is(event.target.result, null, "file data should be null on aborted reads");
   1.316 +}
   1.317 +r.onload = function() { ok(false, "load should not fire for aborted reads") };
   1.318 +r.onerror = function() { ok(false, "error should not fire for aborted reads") };
   1.319 +r.onprogress = function() { ok(false, "progress should not fire for aborted reads") };
   1.320 +var abortThrew = false;
   1.321 +try {
   1.322 +  r.abort();
   1.323 +} catch(e) {
   1.324 +  abortThrew = true;
   1.325 +}
   1.326 +is(abortThrew, true, "abort() must throw if not loading");
   1.327 +is(abortHasRun, false, "abort() is a no-op unless loading");
   1.328 +r.readAsText(asciiFile);
   1.329 +r.abort();
   1.330 +is(abortHasRun, true, "abort should fire sync");
   1.331 +is(loadEndHasRun, true, "loadend should fire sync");
   1.332 +
   1.333 +// Test calling readAsX to cause abort()
   1.334 +var reuseAbortHasRun = false;
   1.335 +r = new FileReader();
   1.336 +r.onabort = function (event) {
   1.337 +  is(reuseAbortHasRun, false, "abort should only fire once");
   1.338 +  reuseAbortHasRun = true;
   1.339 +  is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort");
   1.340 +  is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads");
   1.341 +  is(event.target.result, null, "file data should be null on aborted reads");
   1.342 +}
   1.343 +r.onload = function() { ok(false, "load should not fire for aborted reads") };
   1.344 +var abortThrew = false;
   1.345 +try {
   1.346 +  r.abort();
   1.347 +} catch(e) {
   1.348 +  abortThrew = true;
   1.349 +}
   1.350 +is(abortThrew, true, "abort() must throw if not loading");
   1.351 +is(reuseAbortHasRun, false, "abort() is a no-op unless loading");
   1.352 +r.readAsText(asciiFile);
   1.353 +r.readAsText(asciiFile);
   1.354 +is(reuseAbortHasRun, true, "abort should fire sync");
   1.355 +r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "reuse-as-abort reading");
   1.356 +expectedTestCount++;
   1.357 +
   1.358 +
   1.359 +// Test reading from nonexistent files
   1.360 +r = new FileReader();
   1.361 +var didThrow = false;
   1.362 +try {
   1.363 +  r.readAsDataURL(nonExistingFile);
   1.364 +} catch(ex) {
   1.365 +  didThrow = true;
   1.366 +}
   1.367 +// Once this test passes, we should test that onerror gets called and
   1.368 +// that the FileReader object is in the right state during that call.
   1.369 +todo(!didThrow, "shouldn't throw when opening nonexistent file, should fire error instead");
   1.370 +
   1.371 +
   1.372 +function getLoadHandler(expectedResult, expectedLength, testName) {
   1.373 +  return function (event) {
   1.374 +    is(event.target.readyState, FileReader.DONE,
   1.375 +       "readyState in test " + testName);
   1.376 +    is(event.target.error, null,
   1.377 +       "no error in test " + testName);
   1.378 +    is(event.target.result, expectedResult,
   1.379 +       "result in test " + testName);
   1.380 +    is(event.lengthComputable, true,
   1.381 +       "lengthComputable in test " + testName);
   1.382 +    is(event.loaded, expectedLength,
   1.383 +       "loaded in test " + testName);
   1.384 +    is(event.total, expectedLength,
   1.385 +       "total in test " + testName);
   1.386 +    testHasRun();
   1.387 +  }
   1.388 +}
   1.389 +
   1.390 +function getLoadHandlerForArrayBuffer(expectedResult, expectedLength, testName) {
   1.391 +  return function (event) {
   1.392 +    is(event.target.readyState, FileReader.DONE,
   1.393 +       "readyState in test " + testName);
   1.394 +    is(event.target.error, null,
   1.395 +       "no error in test " +  testName);
   1.396 +    is(event.lengthComputable, true,
   1.397 +       "lengthComputable in test " + testName);
   1.398 +    is(event.loaded, expectedLength,
   1.399 +       "loaded in test " + testName);
   1.400 +    is(event.total, expectedLength,
   1.401 +       "total in test " + testName);
   1.402 +    is(event.target.result.byteLength, expectedLength,
   1.403 +       "array buffer size in test " + testName);
   1.404 +    var u8v = new Uint8Array(event.target.result);
   1.405 +    is(String.fromCharCode.apply(String, u8v), expectedResult,
   1.406 +       "array buffer contents in test " + testName);
   1.407 +    u8v = null;
   1.408 +    SpecialPowers.gc();
   1.409 +    is(event.target.result.byteLength, expectedLength,
   1.410 +       "array buffer size after gc in test " + testName);
   1.411 +    u8v = new Uint8Array(event.target.result);
   1.412 +    is(String.fromCharCode.apply(String, u8v), expectedResult,
   1.413 +       "array buffer contents after gc in test " + testName);
   1.414 +    testHasRun();
   1.415 +  }
   1.416 +}
   1.417 +
   1.418 +function testHasRun() {
   1.419 + //alert(testRanCounter);
   1.420 + ++testRanCounter;
   1.421 + if (testRanCounter == expectedTestCount) {
   1.422 +    is(onloadHasRunText, true, "onload text should have fired by now"); 
   1.423 +    is(onloadHasRunBinary, true, "onload binary should have fired by now"); 
   1.424 +    SimpleTest.finish();
   1.425 +  }
   1.426 +}
   1.427 +
   1.428 +function createFileWithData(fileData) {
   1.429 +  var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"].getService(SpecialPowers.Ci.nsIProperties);
   1.430 +  var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
   1.431 +  testFile.append("fileAPItestfile" + fileNum);
   1.432 +  fileNum++;
   1.433 +  var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].createInstance(SpecialPowers.Ci.nsIFileOutputStream);
   1.434 +  outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
   1.435 +                 0666, 0);
   1.436 +  outStream.write(fileData, fileData.length);
   1.437 +  outStream.close();
   1.438 +
   1.439 +  var fileList = document.getElementById('fileList');
   1.440 +  SpecialPowers.wrap(fileList).value = testFile.path;
   1.441 +
   1.442 +  return fileList.files[0];
   1.443 +}
   1.444 +
   1.445 +function convertToUTF16(s) {
   1.446 +  res = "";
   1.447 +  for (var i = 0; i < s.length; ++i) {
   1.448 +    c = s.charCodeAt(i);
   1.449 +    res += String.fromCharCode(c & 255, c >>> 8);
   1.450 +  }
   1.451 +  return res;
   1.452 +}
   1.453 +
   1.454 +function convertToUTF8(s) {
   1.455 +  return unescape(encodeURIComponent(s));
   1.456 +}
   1.457 +
   1.458 +function convertToDataURL(s) {
   1.459 +  return "data:application/octet-stream;base64," + btoa(s);
   1.460 +}
   1.461 +
   1.462 +</script>
   1.463 +</pre>
   1.464 +</body> </html>

mercurial