Thu, 15 Jan 2015 21:03:48 +0100
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>