/dom/workers/test/worker_fileReader.js

https://github.com/rillian/firefox · JavaScript · 419 lines · 358 code · 44 blank · 17 comment · 3 complexity · e51fa701b1858f55171b42474c056b98 MD5 · raw file

  1. var testRanCounter = 0;
  2. var expectedTestCount = 0;
  3. var testSetupFinished = false;
  4. function ok(a, msg) {
  5. postMessage({type: 'check', status: !!a, msg: msg });
  6. }
  7. function is(a, b, msg) {
  8. ok(a === b, msg);
  9. }
  10. function finish() {
  11. postMessage({type: 'finish'});
  12. }
  13. function convertToUTF16(s) {
  14. res = "";
  15. for (var i = 0; i < s.length; ++i) {
  16. c = s.charCodeAt(i);
  17. res += String.fromCharCode(c & 255, c >>> 8);
  18. }
  19. return res;
  20. }
  21. function convertToUTF8(s) {
  22. return unescape(encodeURIComponent(s));
  23. }
  24. function convertToDataURL(s) {
  25. return "data:application/octet-stream;base64," + btoa(s);
  26. }
  27. onmessage = function(message) {
  28. is(FileReader.EMPTY, 0, "correct EMPTY value");
  29. is(FileReader.LOADING, 1, "correct LOADING value");
  30. is(FileReader.DONE, 2, "correct DONE value");
  31. // List of blobs.
  32. var asciiFile = message.data.blobs.shift();
  33. var binaryFile = message.data.blobs.shift();
  34. var nonExistingFile = message.data.blobs.shift();
  35. var utf8TextFile = message.data.blobs.shift();
  36. var utf16TextFile = message.data.blobs.shift();
  37. var emptyFile = message.data.blobs.shift();
  38. var dataUrlFile0 = message.data.blobs.shift();
  39. var dataUrlFile1 = message.data.blobs.shift();
  40. var dataUrlFile2 = message.data.blobs.shift();
  41. // List of buffers for testing.
  42. var testTextData = message.data.testTextData;
  43. var testASCIIData = message.data.testASCIIData;
  44. var testBinaryData = message.data.testBinaryData;
  45. var dataurldata0 = message.data.dataurldata0;
  46. var dataurldata1 = message.data.dataurldata1;
  47. var dataurldata2 = message.data.dataurldata2;
  48. // Test that plain reading works and fires events as expected, both
  49. // for text and binary reading
  50. var onloadHasRunText = false;
  51. var onloadStartHasRunText = false;
  52. r = new FileReader();
  53. is(r.readyState, FileReader.EMPTY, "correct initial text readyState");
  54. r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "plain reading");
  55. r.addEventListener("load", function() { onloadHasRunText = true }, false);
  56. r.addEventListener("loadstart", function() { onloadStartHasRunText = true }, false);
  57. r.readAsText(asciiFile);
  58. is(r.readyState, FileReader.LOADING, "correct loading text readyState");
  59. is(onloadHasRunText, false, "text loading must be async");
  60. is(onloadStartHasRunText, true, "text loadstart should fire sync");
  61. expectedTestCount++;
  62. var onloadHasRunBinary = false;
  63. var onloadStartHasRunBinary = false;
  64. r = new FileReader();
  65. is(r.readyState, FileReader.EMPTY, "correct initial binary readyState");
  66. r.addEventListener("load", function() { onloadHasRunBinary = true }, false);
  67. r.addEventListener("loadstart", function() { onloadStartHasRunBinary = true }, false);
  68. r.readAsBinaryString(binaryFile);
  69. r.onload = getLoadHandler(testBinaryData, testBinaryData.length, "binary reading");
  70. is(r.readyState, FileReader.LOADING, "correct loading binary readyState");
  71. is(onloadHasRunBinary, false, "binary loading must be async");
  72. is(onloadStartHasRunBinary, true, "binary loadstart should fire sync");
  73. expectedTestCount++;
  74. var onloadHasRunArrayBuffer = false;
  75. var onloadStartHasRunArrayBuffer = false;
  76. r = new FileReader();
  77. is(r.readyState, FileReader.EMPTY, "correct initial arrayBuffer readyState");
  78. r.addEventListener("load", function() { onloadHasRunArrayBuffer = true }, false);
  79. r.addEventListener("loadstart", function() { onloadStartHasRunArrayBuffer = true }, false);
  80. r.readAsArrayBuffer(binaryFile);
  81. r.onload = getLoadHandlerForArrayBuffer(testBinaryData, testBinaryData.length, "array buffer reading");
  82. is(r.readyState, FileReader.LOADING, "correct loading arrayBuffer readyState");
  83. is(onloadHasRunArrayBuffer, false, "arrayBuffer loading must be async");
  84. is(onloadStartHasRunArrayBuffer, true, "arrayBuffer loadstart should fire sync");
  85. expectedTestCount++;
  86. // Test a variety of encodings, and make sure they work properly
  87. r = new FileReader();
  88. r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "no encoding reading");
  89. r.readAsText(asciiFile, "");
  90. expectedTestCount++;
  91. r = new FileReader();
  92. r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "iso8859 reading");
  93. r.readAsText(asciiFile, "iso-8859-1");
  94. expectedTestCount++;
  95. r = new FileReader();
  96. r.onload = getLoadHandler(testTextData,
  97. convertToUTF8(testTextData).length,
  98. "utf8 reading");
  99. r.readAsText(utf8TextFile, "utf8");
  100. expectedTestCount++;
  101. r = new FileReader();
  102. r.readAsText(utf16TextFile, "utf-16");
  103. r.onload = getLoadHandler(testTextData,
  104. convertToUTF16(testTextData).length,
  105. "utf16 reading");
  106. expectedTestCount++;
  107. // Test get result without reading
  108. r = new FileReader();
  109. is(r.readyState, FileReader.EMPTY,
  110. "readyState in test reader get result without reading");
  111. is(r.error, null,
  112. "no error in test reader get result without reading");
  113. is(r.result, null,
  114. "result in test reader get result without reading");
  115. // Test loading an empty file works (and doesn't crash!)
  116. r = new FileReader();
  117. r.onload = getLoadHandler("", 0, "empty no encoding reading");
  118. r.readAsText(emptyFile, "");
  119. expectedTestCount++;
  120. r = new FileReader();
  121. r.onload = getLoadHandler("", 0, "empty utf8 reading");
  122. r.readAsText(emptyFile, "utf8");
  123. expectedTestCount++;
  124. r = new FileReader();
  125. r.onload = getLoadHandler("", 0, "empty utf16 reading");
  126. r.readAsText(emptyFile, "utf-16");
  127. expectedTestCount++;
  128. r = new FileReader();
  129. r.onload = getLoadHandler("", 0, "empty binary string reading");
  130. r.readAsBinaryString(emptyFile);
  131. expectedTestCount++;
  132. r = new FileReader();
  133. r.onload = getLoadHandlerForArrayBuffer("", 0, "empty array buffer reading");
  134. r.readAsArrayBuffer(emptyFile);
  135. expectedTestCount++;
  136. r = new FileReader();
  137. r.onload = getLoadHandler(convertToDataURL(""), 0, "empt binary string reading");
  138. r.readAsDataURL(emptyFile);
  139. expectedTestCount++;
  140. // Test reusing a FileReader to read multiple times
  141. r = new FileReader();
  142. r.onload = getLoadHandler(testASCIIData,
  143. testASCIIData.length,
  144. "to-be-reused reading text")
  145. var makeAnotherReadListener = function(event) {
  146. r = event.target;
  147. r.removeEventListener("load", makeAnotherReadListener, false);
  148. r.onload = getLoadHandler(testASCIIData,
  149. testASCIIData.length,
  150. "reused reading text");
  151. r.readAsText(asciiFile);
  152. };
  153. r.addEventListener("load", makeAnotherReadListener, false);
  154. r.readAsText(asciiFile);
  155. expectedTestCount += 2;
  156. r = new FileReader();
  157. r.onload = getLoadHandler(testBinaryData,
  158. testBinaryData.length,
  159. "to-be-reused reading binary")
  160. var makeAnotherReadListener2 = function(event) {
  161. r = event.target;
  162. r.removeEventListener("load", makeAnotherReadListener2, false);
  163. r.onload = getLoadHandler(testBinaryData,
  164. testBinaryData.length,
  165. "reused reading binary");
  166. r.readAsBinaryString(binaryFile);
  167. };
  168. r.addEventListener("load", makeAnotherReadListener2, false);
  169. r.readAsBinaryString(binaryFile);
  170. expectedTestCount += 2;
  171. r = new FileReader();
  172. r.onload = getLoadHandler(convertToDataURL(testBinaryData),
  173. testBinaryData.length,
  174. "to-be-reused reading data url")
  175. var makeAnotherReadListener3 = function(event) {
  176. r = event.target;
  177. r.removeEventListener("load", makeAnotherReadListener3, false);
  178. r.onload = getLoadHandler(convertToDataURL(testBinaryData),
  179. testBinaryData.length,
  180. "reused reading data url");
  181. r.readAsDataURL(binaryFile);
  182. };
  183. r.addEventListener("load", makeAnotherReadListener3, false);
  184. r.readAsDataURL(binaryFile);
  185. expectedTestCount += 2;
  186. r = new FileReader();
  187. r.onload = getLoadHandlerForArrayBuffer(testBinaryData,
  188. testBinaryData.length,
  189. "to-be-reused reading arrayBuffer")
  190. var makeAnotherReadListener4 = function(event) {
  191. r = event.target;
  192. r.removeEventListener("load", makeAnotherReadListener4, false);
  193. r.onload = getLoadHandlerForArrayBuffer(testBinaryData,
  194. testBinaryData.length,
  195. "reused reading arrayBuffer");
  196. r.readAsArrayBuffer(binaryFile);
  197. };
  198. r.addEventListener("load", makeAnotherReadListener4, false);
  199. r.readAsArrayBuffer(binaryFile);
  200. expectedTestCount += 2;
  201. // Test first reading as ArrayBuffer then read as something else
  202. // (BinaryString) and doesn't crash
  203. r = new FileReader();
  204. r.onload = getLoadHandlerForArrayBuffer(testBinaryData,
  205. testBinaryData.length,
  206. "to-be-reused reading arrayBuffer")
  207. var makeAnotherReadListener5 = function(event) {
  208. r = event.target;
  209. r.removeEventListener("load", makeAnotherReadListener5, false);
  210. r.onload = getLoadHandler(testBinaryData,
  211. testBinaryData.length,
  212. "reused reading binary string");
  213. r.readAsBinaryString(binaryFile);
  214. };
  215. r.addEventListener("load", makeAnotherReadListener5, false);
  216. r.readAsArrayBuffer(binaryFile);
  217. expectedTestCount += 2;
  218. //Test data-URI encoding on differing file sizes
  219. is(dataurldata0.length % 3, 0, "Want to test data with length % 3 == 0");
  220. r = new FileReader();
  221. r.onload = getLoadHandler(convertToDataURL(dataurldata0),
  222. dataurldata0.length,
  223. "dataurl reading, %3 = 0");
  224. r.readAsDataURL(dataUrlFile0);
  225. expectedTestCount++;
  226. is(dataurldata1.length % 3, 1, "Want to test data with length % 3 == 1");
  227. r = new FileReader();
  228. r.onload = getLoadHandler(convertToDataURL(dataurldata1),
  229. dataurldata1.length,
  230. "dataurl reading, %3 = 1");
  231. r.readAsDataURL(dataUrlFile1);
  232. expectedTestCount++;
  233. is(dataurldata2.length % 3, 2, "Want to test data with length % 3 == 2");
  234. r = new FileReader();
  235. r.onload = getLoadHandler(convertToDataURL(dataurldata2),
  236. dataurldata2.length,
  237. "dataurl reading, %3 = 2");
  238. r.readAsDataURL(dataUrlFile2),
  239. expectedTestCount++;
  240. // Test abort()
  241. var abortHasRun = false;
  242. var loadEndHasRun = false;
  243. r = new FileReader();
  244. r.onabort = function (event) {
  245. is(abortHasRun, false, "abort should only fire once");
  246. is(loadEndHasRun, false, "loadend shouldn't have fired yet");
  247. abortHasRun = true;
  248. is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort");
  249. is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads");
  250. is(event.target.result, null, "file data should be null on aborted reads");
  251. }
  252. r.onloadend = function (event) {
  253. is(abortHasRun, true, "abort should fire before loadend");
  254. is(loadEndHasRun, false, "loadend should only fire once");
  255. loadEndHasRun = true;
  256. is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort");
  257. is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads");
  258. is(event.target.result, null, "file data should be null on aborted reads");
  259. }
  260. r.onload = function() { ok(false, "load should not fire for aborted reads") };
  261. r.onerror = function() { ok(false, "error should not fire for aborted reads") };
  262. r.onprogress = function() { ok(false, "progress should not fire for aborted reads") };
  263. var abortThrew = false;
  264. try {
  265. r.abort();
  266. } catch(e) {
  267. abortThrew = true;
  268. }
  269. is(abortThrew, false, "abort() never throws");
  270. is(abortHasRun, false, "abort() is a no-op unless loading");
  271. r.readAsText(asciiFile);
  272. r.abort();
  273. is(abortHasRun, true, "1 abort should fire sync");
  274. is(loadEndHasRun, true, "loadend should fire sync");
  275. // Test calling readAsX to cause abort()
  276. var reuseAbortHasRun = false;
  277. r = new FileReader();
  278. r.onabort = function (event) { reuseAbortHasRun = true; }
  279. r.onload = function() { ok(true, "load should fire for aborted reads") };
  280. var abortThrew = false;
  281. try {
  282. r.abort();
  283. } catch(e) {
  284. abortThrew = true;
  285. }
  286. is(abortThrew, false, "abort() never throws");
  287. is(reuseAbortHasRun, false, "abort() is a no-op unless loading");
  288. r.readAsText(asciiFile);
  289. var readThrew = false;
  290. try {
  291. r.readAsText(asciiFile);
  292. } catch(e) {
  293. readThrew = true;
  294. }
  295. is(readThrew, true, "readAsText() must throw if loading");
  296. is(reuseAbortHasRun, false, "2 abort should fire sync");
  297. r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "reuse-as-abort reading");
  298. expectedTestCount++;
  299. // Test reading from nonexistent files
  300. r = new FileReader();
  301. var didThrow = false;
  302. r.onerror = function (event) {
  303. is(event.target.readyState, FileReader.DONE, "should be DONE while firing onerror");
  304. is(event.target.error.name, "NotFoundError", "error set to NotFoundError for nonexistent files");
  305. is(event.target.result, null, "file data should be null on aborted reads");
  306. testHasRun();
  307. };
  308. r.onload = function (event) {
  309. is(false, "nonexistent file shouldn't load! (FIXME: bug 1122788)");
  310. testHasRun();
  311. };
  312. try {
  313. r.readAsDataURL(nonExistingFile);
  314. expectedTestCount++;
  315. } catch(ex) {
  316. didThrow = true;
  317. }
  318. // Once this test passes, we should test that onerror gets called and
  319. // that the FileReader object is in the right state during that call.
  320. is(didThrow, false, "shouldn't throw when opening nonexistent file, should fire error instead");
  321. function getLoadHandler(expectedResult, expectedLength, testName) {
  322. return function (event) {
  323. is(event.target.readyState, FileReader.DONE,
  324. "readyState in test " + testName);
  325. is(event.target.error, null,
  326. "no error in test " + testName);
  327. is(event.target.result, expectedResult,
  328. "result in test " + testName);
  329. is(event.lengthComputable, true,
  330. "lengthComputable in test " + testName);
  331. is(event.loaded, expectedLength,
  332. "loaded in test " + testName);
  333. is(event.total, expectedLength,
  334. "total in test " + testName);
  335. testHasRun();
  336. }
  337. }
  338. function getLoadHandlerForArrayBuffer(expectedResult, expectedLength, testName) {
  339. return function (event) {
  340. is(event.target.readyState, FileReader.DONE,
  341. "readyState in test " + testName);
  342. is(event.target.error, null,
  343. "no error in test " + testName);
  344. is(event.lengthComputable, true,
  345. "lengthComputable in test " + testName);
  346. is(event.loaded, expectedLength,
  347. "loaded in test " + testName);
  348. is(event.total, expectedLength,
  349. "total in test " + testName);
  350. is(event.target.result.byteLength, expectedLength,
  351. "array buffer size in test " + testName);
  352. var u8v = new Uint8Array(event.target.result);
  353. is(String.fromCharCode.apply(String, u8v), expectedResult,
  354. "array buffer contents in test " + testName);
  355. u8v = null;
  356. is(event.target.result.byteLength, expectedLength,
  357. "array buffer size after gc in test " + testName);
  358. u8v = new Uint8Array(event.target.result);
  359. is(String.fromCharCode.apply(String, u8v), expectedResult,
  360. "array buffer contents after gc in test " + testName);
  361. testHasRun();
  362. }
  363. }
  364. function testHasRun() {
  365. //alert(testRanCounter);
  366. ++testRanCounter;
  367. if (testRanCounter == expectedTestCount) {
  368. is(testSetupFinished, true, "test setup should have finished; check for exceptions");
  369. is(onloadHasRunText, true, "onload text should have fired by now");
  370. is(onloadHasRunBinary, true, "onload binary should have fired by now");
  371. finish();
  372. }
  373. }
  374. testSetupFinished = true;
  375. }