|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <!-- |
|
4 https://bugzilla.mozilla.org/show_bug.cgi?id=721569 |
|
5 --> |
|
6 <head> |
|
7 <title>Test for Blob constructor (Bug 721569)</title> |
|
8 <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> |
|
9 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
10 <script type="text/javascript" src="fileutils.js"></script> |
|
11 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> |
|
12 </head> |
|
13 <body> |
|
14 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=721569">Mozilla Bug 721569</a> |
|
15 <p id="display"></p> |
|
16 <div id="content" style="display: none"> |
|
17 |
|
18 </div> |
|
19 <pre id="test"> |
|
20 <script class="testbody" type="text/javascript;version=1.7"> |
|
21 "use strict"; |
|
22 /** Test for Bug 721569 **/ |
|
23 var blob = Blob(); |
|
24 ok(blob, "Blob should exist"); |
|
25 |
|
26 ok(blob.size !== undefined, "Blob should have a size property"); |
|
27 ok(blob.type !== undefined, "Blob should have a type property"); |
|
28 ok(blob.slice, "Blob should have a slice method"); |
|
29 |
|
30 blob = Blob([], {type: null}); |
|
31 ok(blob, "Blob should exist"); |
|
32 is(blob.type, "null", "Blob type should be stringified"); |
|
33 |
|
34 blob = Blob([], {type: undefined}); |
|
35 ok(blob, "Blob should exist"); |
|
36 is(blob.type, "", "Blob type should be treated as missing"); |
|
37 |
|
38 try { |
|
39 blob = Blob([]); |
|
40 ok(true, "an empty blobParts argument should not throw"); |
|
41 } catch(e) { |
|
42 ok(false, "NOT REACHED"); |
|
43 } |
|
44 |
|
45 try { |
|
46 blob = Blob(null); |
|
47 ok(false, "NOT REACHED"); |
|
48 } catch(e) { |
|
49 ok(true, "a null blobParts member should throw"); |
|
50 } |
|
51 |
|
52 try { |
|
53 blob = Blob([], null); |
|
54 ok(true, "a null options member should not throw"); |
|
55 } catch(e) { |
|
56 ok(false, "NOT REACHED"); |
|
57 } |
|
58 |
|
59 try { |
|
60 blob = Blob([], undefined); |
|
61 ok(true, "an undefined options member should not throw"); |
|
62 } catch(e) { |
|
63 ok(false, "NOT REACHED"); |
|
64 } |
|
65 |
|
66 try { |
|
67 blob = Blob([], false); |
|
68 ok(false, "NOT REACHED"); |
|
69 } catch(e) { |
|
70 ok(true, "a boolean options member should throw"); |
|
71 } |
|
72 |
|
73 try { |
|
74 blob = Blob([], 0); |
|
75 ok(false, "NOT REACHED"); |
|
76 } catch(e) { |
|
77 ok(true, "a numeric options member should throw"); |
|
78 } |
|
79 |
|
80 try { |
|
81 blob = Blob([], ""); |
|
82 ok(false, "NOT REACHED"); |
|
83 } catch(e) { |
|
84 ok(true, "a string options member should throw"); |
|
85 } |
|
86 |
|
87 /** Test for dictionary initialization order **/ |
|
88 (function() { |
|
89 var o = {}; |
|
90 var p = {type: "text/plain", endings: "transparent"}; |
|
91 var called = []; |
|
92 function add_to_called(n) { |
|
93 called.push(n); |
|
94 return p[n]; |
|
95 } |
|
96 ["type", "endings"].forEach(function(n) { |
|
97 Object.defineProperty(o, n, { get: add_to_called.bind(null, n) }); |
|
98 }); |
|
99 var b = new Blob([], o); |
|
100 is(JSON.stringify(called), JSON.stringify(["endings", "type"]), "dictionary members should be get in lexicographical order"); |
|
101 })(); |
|
102 |
|
103 let blob1 = Blob(["squiggle"]); |
|
104 ok(blob1 instanceof Blob, "Blob constructor should produce Blobs"); |
|
105 ok(!(blob1 instanceof File), "Blob constructor should not produce Files"); |
|
106 is(blob1.type, "", "Blob constructor with no options should return Blob with empty type"); |
|
107 is(blob1.size, 8, "Blob constructor should return Blob with correct size"); |
|
108 |
|
109 let blob2 = Blob(["steak"], {type: "content/type"}); |
|
110 ok(blob2 instanceof Blob, "Blob constructor should produce Blobs"); |
|
111 ok(!(blob2 instanceof File), "Blob constructor should not produce Files"); |
|
112 is(blob2.type, "content/type", "Blob constructor with a type option should return Blob with the type"); |
|
113 is(blob2.size, 5, "Blob constructor should return Blob with correct size"); |
|
114 |
|
115 |
|
116 let aB = new ArrayBuffer(16); |
|
117 var int8View = new Int8Array(aB); |
|
118 for (var i = 0; i < 16; i++) { |
|
119 int8View[i] = i+65; |
|
120 } |
|
121 |
|
122 let testData = |
|
123 [ |
|
124 // Test 3 strings |
|
125 [["foo", "bar", "baz"], {}, |
|
126 [{start: 0, length: 9, contents: "foobarbaz"}, |
|
127 {start: 0, length: 3, contents: "foo"}, |
|
128 {start: 3, length:6, contents: "barbaz"}, |
|
129 {start: 6, length: 3, contents: "baz"}, |
|
130 {start: 6, length: 6, contents: "baz"}, |
|
131 {start: 0, length: 9, contents: "foobarbaz"}, |
|
132 {start: 0, length: 11, contents: "foobarbaz"}, |
|
133 {start: 10, length: 5, contents: ""}]], |
|
134 // Test string, Blob, string |
|
135 [["foo", blob1, "baz"], {}, |
|
136 [{start: 0, length: 3, contents: "foo"}, |
|
137 {start: 3, length: 8, contents: "squiggle"}, |
|
138 {start: 2, length: 2, contents: "os"}, |
|
139 {start: 10, length: 2, contents: "eb"}]], |
|
140 // Test blob, string, blob |
|
141 [[blob1, "foo", blob1], {}, |
|
142 [{start: 0, length: 8, contents: "squiggle"}, |
|
143 {start: 7, length: 2, contents: "ef"}, |
|
144 {start: 10, length: 2, contents: "os"}, |
|
145 {start: 1, length: 3, contents: "qui"}, |
|
146 {start: 12, length: 3, contents: "qui"}, |
|
147 {start: 40, length: 20, contents: ""}]], |
|
148 // Test blobs all the way down |
|
149 [[blob2, blob1, blob2], {}, |
|
150 [{start: 0, length: 5, contents: "steak"}, |
|
151 {start: 5, length: 8, contents: "squiggle"}, |
|
152 {start: 13, length: 5, contents: "steak"}, |
|
153 {start: 1, length: 2, contents: "te"}, |
|
154 {start: 6, length: 4, contents: "quig"}]], |
|
155 // Test an array buffer |
|
156 [[aB, blob1, "foo"], {}, |
|
157 [{start: 0, length: 8, contents: "ABCDEFGH"}, |
|
158 {start: 8, length:10, contents: "IJKLMNOPsq"}, |
|
159 {start: 17, length: 3, contents: "qui"}, |
|
160 {start: 4, length: 8, contents: "EFGHIJKL"}]], |
|
161 // Test an ArrayBufferView |
|
162 [[int8View, blob1, "foo"], {}, |
|
163 [{start: 0, length: 8, contents: "ABCDEFGH"}, |
|
164 {start: 8, length:10, contents: "IJKLMNOPsq"}, |
|
165 {start: 17, length: 3, contents: "qui"}, |
|
166 {start: 4, length: 8, contents: "EFGHIJKL"}]], |
|
167 // Test a partial ArrayBufferView |
|
168 [[new Uint8Array(aB, 3, 5), blob1, "foo"], {}, |
|
169 [{start: 0, length: 8, contents: "DEFGHsqu"}, |
|
170 {start: 8, length:10, contents: "igglefoo"}, |
|
171 {start: 4, length: 8, contents: "Hsquiggl"}]], |
|
172 // Test transparent line endings |
|
173 [["foo\r\n", "bar\r", "baz\n"], { endings: "transparent" }, |
|
174 [{start: 0, length: 5, contents: "foo\r\n"}, |
|
175 {start: 5, length: 4, contents: "bar\r"}, |
|
176 {start: 9, length: 4, contents: "baz\n"}]], |
|
177 // Test transparent line endings when the second argument is omitted |
|
178 [["foo\r\n", "bar\r", "baz\n"], undefined, |
|
179 [{start: 0, length: 5, contents: "foo\r\n"}, |
|
180 {start: 5, length: 4, contents: "bar\r"}, |
|
181 {start: 9, length: 4, contents: "baz\n"}]], |
|
182 // Test native line endings |
|
183 [["foo\r\n", "bar\r", "baz\n"], { endings: "native" }, |
|
184 navigator.platform.indexOf("Win") != -1 ? |
|
185 [{start: 0, length: 5, contents: "foo\r\n"}, |
|
186 {start: 5, length: 5, contents: "bar\r\n"}, |
|
187 {start: 10, length: 5, contents: "baz\r\n"}] : |
|
188 [{start: 0, length: 4, contents: "foo\n"}, |
|
189 {start: 4, length: 4, contents: "bar\n"}, |
|
190 {start: 8, length: 4, contents: "baz\n"}]], |
|
191 // Test type coercion of a number |
|
192 [[3, int8View, "foo"], {}, |
|
193 [{start: 0, length: 8, contents: "3ABCDEFG"}, |
|
194 {start: 8, length:10, contents: "HIJKLMNOPf"}, |
|
195 {start: 17, length: 4, contents: "foo"}, |
|
196 {start: 4, length: 8, contents: "DEFGHIJK"}]] |
|
197 ]; |
|
198 |
|
199 let testCounter = 0; |
|
200 |
|
201 function doTest(data) { |
|
202 testCounter++; |
|
203 |
|
204 var [blobs, options, tests] = data; |
|
205 |
|
206 function runTest(test) { |
|
207 |
|
208 let blob; |
|
209 if (options !== undefined) { |
|
210 blob = new Blob(blobs, options); |
|
211 } else { |
|
212 blob = new Blob(blobs); |
|
213 } |
|
214 ok(blob, "Test " + testCounter + " got blob"); |
|
215 ok(blob instanceof Blob, "Test " + testCounter + " blob is a Blob"); |
|
216 ok(!(blob instanceof File), "Test " + testCounter + " blob is not a File"); |
|
217 |
|
218 let slice = blob.slice(test.start, test.start + test.length); |
|
219 ok(slice, "Test " + testCounter + " got slice"); |
|
220 ok(slice instanceof Blob, "Test " + testCounter + " slice is a Blob"); |
|
221 ok(!(slice instanceof File), "Test " + testCounter + " slice is not a File"); |
|
222 is(slice.size, test.contents.length, |
|
223 "Test " + testCounter + " slice is correct size"); |
|
224 |
|
225 testFile(slice, test.contents, "Test " + testCounter); |
|
226 } |
|
227 if (Array.isArray(tests)) { |
|
228 tests.forEach(runTest); |
|
229 } else { |
|
230 try { |
|
231 let blob = new Blob(blobs, options); |
|
232 ok(false, "NOT REACHED"); |
|
233 } catch (e) { |
|
234 is(e.name, tests, "Blob constructor should throw " + tests); |
|
235 } |
|
236 } |
|
237 SpecialPowers.gc(); |
|
238 } |
|
239 |
|
240 SimpleTest.waitForExplicitFinish(); |
|
241 testData.forEach(doTest); |
|
242 |
|
243 </script> |
|
244 </pre> |
|
245 </body> |
|
246 </html> |