|
1 // Utility functions |
|
2 var testRanCounter = 0; |
|
3 var expectedTestCount = 0; |
|
4 |
|
5 function testHasRun() { |
|
6 //alert(testRanCounter); |
|
7 ++testRanCounter; |
|
8 if (testRanCounter == expectedTestCount) { |
|
9 SimpleTest.finish(); |
|
10 } |
|
11 } |
|
12 |
|
13 |
|
14 function testFile(file, contents, test) { |
|
15 SimpleTest.requestLongerTimeout(2); |
|
16 |
|
17 // Load file using FileReader |
|
18 var r = new FileReader(); |
|
19 r.onload = getFileReaderLoadHandler(contents, contents.length, "FileReader.readAsBinaryString of " + test); |
|
20 r.readAsBinaryString(file); |
|
21 expectedTestCount++; |
|
22 |
|
23 // Load file using URL.createObjectURL and XMLHttpRequest |
|
24 var xhr = new XMLHttpRequest; |
|
25 xhr.open("GET", URL.createObjectURL(file)); |
|
26 xhr.onload = getXHRLoadHandler(contents, contents.length, false, |
|
27 "XMLHttpRequest load of " + test); |
|
28 xhr.overrideMimeType('text/plain; charset=x-user-defined'); |
|
29 xhr.send(); |
|
30 expectedTestCount++; |
|
31 |
|
32 // Send file to server using FormData and XMLHttpRequest |
|
33 xhr = new XMLHttpRequest(); |
|
34 xhr.onload = function(event) { |
|
35 checkMPSubmission(JSON.parse(event.target.responseText), |
|
36 [{ name: "hello", value: "world"}, |
|
37 { name: "myfile", |
|
38 value: contents, |
|
39 fileName: file.name || "blob", |
|
40 contentType: file.type || "application/octet-stream" }]); |
|
41 testHasRun(); |
|
42 } |
|
43 xhr.open("POST", "../../html/content/test/form_submit_server.sjs"); |
|
44 var fd = new FormData; |
|
45 fd.append("hello", "world"); |
|
46 fd.append("myfile", file); |
|
47 xhr.send(fd); |
|
48 expectedTestCount++; |
|
49 |
|
50 // Send file to server using plain XMLHttpRequest |
|
51 var xhr = new XMLHttpRequest; |
|
52 xhr.open("POST", "file_XHRSendData.sjs"); |
|
53 xhr.onload = function (event) { |
|
54 is(event.target.getResponseHeader("Result-Content-Type"), |
|
55 file.type ? file.type : null, |
|
56 "request content-type in XMLHttpRequest send of " + test); |
|
57 is(event.target.getResponseHeader("Result-Content-Length"), |
|
58 file.size, |
|
59 "request content-length in XMLHttpRequest send of " + test); |
|
60 }; |
|
61 xhr.addEventListener("load", |
|
62 getXHRLoadHandler(contents, contents.length, true, |
|
63 "XMLHttpRequest send of " + test), |
|
64 false); |
|
65 xhr.overrideMimeType('text/plain; charset=x-user-defined'); |
|
66 xhr.send(file); |
|
67 expectedTestCount++; |
|
68 } |
|
69 |
|
70 function getFileReaderLoadHandler(expectedResult, expectedLength, testName) { |
|
71 return function (event) { |
|
72 is(event.target.readyState, FileReader.DONE, |
|
73 "[FileReader] readyState in test " + testName); |
|
74 is(event.target.error, null, |
|
75 "[FileReader] no error in test " + testName); |
|
76 // Do not use |is(event.target.result, expectedResult, "...");| that may output raw binary data. |
|
77 is(event.target.result.length, expectedResult.length, |
|
78 "[FileReader] Length of result in test " + testName); |
|
79 ok(event.target.result == expectedResult, |
|
80 "[FileReader] Content of result in test " + testName); |
|
81 is(event.lengthComputable, true, |
|
82 "[FileReader] lengthComputable in test " + testName); |
|
83 is(event.loaded, expectedLength, |
|
84 "[FileReader] Loaded length in test " + testName); |
|
85 is(event.total, expectedLength, |
|
86 "[FileReader] Total length in test " + testName); |
|
87 testHasRun(); |
|
88 } |
|
89 } |
|
90 |
|
91 function getXHRLoadHandler(expectedResult, expectedLength, statusWorking, testName) { |
|
92 return function (event) { |
|
93 is(event.target.readyState, 4, |
|
94 "[XHR] readyState in test " + testName); |
|
95 if (statusWorking) { |
|
96 is(event.target.status, 200, |
|
97 "[XHR] no error in test " + testName); |
|
98 } |
|
99 else { |
|
100 todo_is(event.target.status, 200, |
|
101 "[XHR] no error in test " + testName); |
|
102 } |
|
103 // Do not use |is(convertXHRBinary(event.target.responseText), expectedResult, "...");| that may output raw binary data. |
|
104 var convertedData = convertXHRBinary(event.target.responseText); |
|
105 is(convertedData.length, expectedResult.length, |
|
106 "[XHR] Length of result in test " + testName); |
|
107 ok(convertedData == expectedResult, |
|
108 "[XHR] Content of result in test " + testName); |
|
109 is(event.lengthComputable, true, |
|
110 "[XHR] lengthComputable in test " + testName); |
|
111 is(event.loaded, expectedLength, |
|
112 "[XHR] Loaded length in test " + testName); |
|
113 is(event.total, expectedLength, |
|
114 "[XHR] Total length in test " + testName); |
|
115 |
|
116 testHasRun(); |
|
117 } |
|
118 } |
|
119 |
|
120 function convertXHRBinary(s) { |
|
121 var res = ""; |
|
122 for (var i = 0; i < s.length; ++i) { |
|
123 res += String.fromCharCode(s.charCodeAt(i) & 255); |
|
124 } |
|
125 return res; |
|
126 } |
|
127 |
|
128 function testHasRun() { |
|
129 //alert(testRanCounter); |
|
130 ++testRanCounter; |
|
131 if (testRanCounter == expectedTestCount) { |
|
132 SimpleTest.finish(); |
|
133 } |
|
134 } |
|
135 |
|
136 function createFileWithData(fileData) { |
|
137 var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"].getService(SpecialPowers.Ci.nsIProperties); |
|
138 var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile); |
|
139 testFile.append("fileAPItestfile2-" + fileNum); |
|
140 fileNum++; |
|
141 var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].createInstance(SpecialPowers.Ci.nsIFileOutputStream); |
|
142 outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate |
|
143 0666, 0); |
|
144 outStream.write(fileData, fileData.length); |
|
145 outStream.close(); |
|
146 |
|
147 var fileList = document.getElementById('fileList'); |
|
148 SpecialPowers.wrap(fileList).value = testFile.path; |
|
149 |
|
150 return fileList.files[0]; |
|
151 } |
|
152 |
|
153 function gc() { |
|
154 window.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) |
|
155 .getInterface(SpecialPowers.Ci.nsIDOMWindowUtils) |
|
156 .garbageCollect(); |
|
157 } |
|
158 |
|
159 function checkMPSubmission(sub, expected) { |
|
160 function getPropCount(o) { |
|
161 var x, l = 0; |
|
162 for (x in o) ++l; |
|
163 return l; |
|
164 } |
|
165 |
|
166 is(sub.length, expected.length, |
|
167 "Correct number of items"); |
|
168 var i; |
|
169 for (i = 0; i < expected.length; ++i) { |
|
170 if (!("fileName" in expected[i])) { |
|
171 is(sub[i].headers["Content-Disposition"], |
|
172 "form-data; name=\"" + expected[i].name + "\"", |
|
173 "Correct name (A)"); |
|
174 is (getPropCount(sub[i].headers), 1, |
|
175 "Wrong number of headers (A)"); |
|
176 } |
|
177 else { |
|
178 is(sub[i].headers["Content-Disposition"], |
|
179 "form-data; name=\"" + expected[i].name + "\"; filename=\"" + |
|
180 expected[i].fileName + "\"", |
|
181 "Correct name (B)"); |
|
182 is(sub[i].headers["Content-Type"], |
|
183 expected[i].contentType, |
|
184 "Correct content type (B)"); |
|
185 is (getPropCount(sub[i].headers), 2, |
|
186 "Wrong number of headers (B)"); |
|
187 } |
|
188 // Do not use |is(sub[i].body, expected[i].value, "...");| that may output raw binary data. |
|
189 is(sub[i].body.length, expected[i].value.length, |
|
190 "Length of correct value"); |
|
191 ok(sub[i].body == expected[i].value, |
|
192 "Content of correct value"); |
|
193 } |
|
194 } |
|
195 |
|
196 function testSlice(file, size, type, contents, fileType) { |
|
197 is(file.type, type, fileType + " file is correct type"); |
|
198 is(file.size, size, fileType + " file is correct size"); |
|
199 ok(file instanceof File, fileType + " file is a File"); |
|
200 ok(file instanceof Blob, fileType + " file is also a Blob"); |
|
201 |
|
202 var slice = file.slice(0, size); |
|
203 ok(slice instanceof Blob, fileType + " fullsize slice is a Blob"); |
|
204 ok(!(slice instanceof File), fileType + " fullsize slice is not a File"); |
|
205 |
|
206 slice = file.slice(0, 1234); |
|
207 ok(slice instanceof Blob, fileType + " sized slice is a Blob"); |
|
208 ok(!(slice instanceof File), fileType + " sized slice is not a File"); |
|
209 |
|
210 slice = file.slice(0, size, "foo/bar"); |
|
211 is(slice.type, "foo/bar", fileType + " fullsize slice foo/bar type"); |
|
212 |
|
213 slice = file.slice(0, 5432, "foo/bar"); |
|
214 is(slice.type, "foo/bar", fileType + " sized slice foo/bar type"); |
|
215 |
|
216 is(slice.slice(0, 10).type, "", fileType + " slice-slice type"); |
|
217 is(slice.slice(0, 10).size, 10, fileType + " slice-slice size"); |
|
218 is(slice.slice(0, 10, "hello/world").type, "hello/world", fileType + " slice-slice hello/world type"); |
|
219 is(slice.slice(0, 10, "hello/world").size, 10, fileType + " slice-slice hello/world size"); |
|
220 |
|
221 // Start, end, expected size |
|
222 var indexes = [[0, size, size], |
|
223 [0, 1234, 1234], |
|
224 [size-500, size, 500], |
|
225 [size-500, size+500, 500], |
|
226 [size+500, size+1500, 0], |
|
227 [0, 0, 0], |
|
228 [1000, 1000, 0], |
|
229 [size, size, 0], |
|
230 [undefined, undefined, size], |
|
231 [0, undefined, size], |
|
232 [100, undefined, size-100], |
|
233 [-100, undefined, 100], |
|
234 [100, -100, size-200], |
|
235 [-size-100, undefined, size], |
|
236 [-2*size-100, 500, 500], |
|
237 [0, -size-100, 0], |
|
238 [100, -size-100, 0], |
|
239 [50, -size+100, 50], |
|
240 [0, 33000, 33000], |
|
241 [1000, 34000, 33000], |
|
242 ]; |
|
243 |
|
244 for (var i = 0; i < indexes.length; ++i) { |
|
245 var sliceContents; |
|
246 var testName; |
|
247 if (indexes[i][0] == undefined) { |
|
248 slice = file.slice(); |
|
249 sliceContents = contents.slice(); |
|
250 testName = fileType + " slice()"; |
|
251 } |
|
252 else if (indexes[i][1] == undefined) { |
|
253 slice = file.slice(indexes[i][0]); |
|
254 sliceContents = contents.slice(indexes[i][0]); |
|
255 testName = fileType + " slice(" + indexes[i][0] + ")"; |
|
256 } |
|
257 else { |
|
258 slice = file.slice(indexes[i][0], indexes[i][1]); |
|
259 sliceContents = contents.slice(indexes[i][0], indexes[i][1]); |
|
260 testName = fileType + " slice(" + indexes[i][0] + ", " + indexes[i][1] + ")"; |
|
261 } |
|
262 is(slice.type, "", testName + " type"); |
|
263 is(slice.size, indexes[i][2], testName + " size"); |
|
264 is(sliceContents.length, indexes[i][2], testName + " data size"); |
|
265 testFile(slice, sliceContents, testName); |
|
266 } |
|
267 |
|
268 // Slice of slice |
|
269 var slice = file.slice(0, 40000); |
|
270 testFile(slice.slice(5000, 42000), contents.slice(5000, 40000), "file slice slice"); |
|
271 |
|
272 // ...of slice of slice |
|
273 slice = slice.slice(5000, 42000).slice(400, 700); |
|
274 SpecialPowers.gc(); |
|
275 testFile(slice, contents.slice(5400, 5700), "file slice slice slice"); |
|
276 } |
|
277 |