OLD | NEW |
| (Empty) |
1 <!-- | |
2 Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
3 Copyright (C) 2011 Apple Computer, Inc. All rights reserved. | |
4 | |
5 Redistribution and use in source and binary forms, with or without | |
6 modification, are permitted provided that the following conditions are | |
7 met: | |
8 | |
9 * Redistributions of source code must retain the above copyright | |
10 notice, this list of conditions and the following disclaimer. | |
11 * Redistributions in binary form must reproduce the above | |
12 copyright notice, this list of conditions and the following disclaimer | |
13 in the documentation and/or other materials provided with the | |
14 distribution. | |
15 * Neither the name of Google Inc. nor the names of its | |
16 contributors may be used to endorse or promote products derived from | |
17 this software without specific prior written permission. | |
18 | |
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
20 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
23 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
24 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
25 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
30 --> | |
31 <!DOCTYPE html> | |
32 <html> | |
33 <head> | |
34 <meta charset="utf-8"> | |
35 <link rel="stylesheet" href="../resources/js-test-style.css"/> | |
36 <script src="../resources/js-test-pre.js"></script> | |
37 <script src="resources/webgl-test.js"></script> | |
38 </head> | |
39 <body> | |
40 <div id="description"></div> | |
41 <div id="console"></div> | |
42 | |
43 <script> | |
44 | |
45 description("Verifies the functionality of the new array-like objects in the Typ
edArray spec"); | |
46 | |
47 var currentlyRunning = ''; | |
48 var allPassed = true; | |
49 function running(str) { | |
50 currentlyRunning = str; | |
51 } | |
52 | |
53 function output(str) { | |
54 debug(str); | |
55 } | |
56 | |
57 function pass() { | |
58 testPassed(currentlyRunning); | |
59 } | |
60 | |
61 function fail(str) { | |
62 allPassed = false; | |
63 var exc; | |
64 if (str) | |
65 exc = currentlyRunning + ': ' + str; | |
66 else | |
67 exc = currentlyRunning; | |
68 testFailed(exc); | |
69 } | |
70 | |
71 function assertEq(prefix, expected, val) { | |
72 if (expected != val) { | |
73 var str = prefix + ': expected ' + expected + ', got ' + val; | |
74 throw str; | |
75 } | |
76 } | |
77 | |
78 function assert(prefix, expected) { | |
79 if (!expected) { | |
80 var str = prefix + ': expected value / true'; | |
81 throw str; | |
82 } | |
83 } | |
84 | |
85 function printSummary() { | |
86 if (allPassed) { | |
87 debug("Test passed."); | |
88 } else { | |
89 debug("TEST FAILED"); | |
90 } | |
91 } | |
92 | |
93 // | |
94 // Tests for unsigned array variants | |
95 // | |
96 | |
97 function testSetAndGet10To1(type, name) { | |
98 running('test ' + name + ' SetAndGet10To1'); | |
99 try { | |
100 var array = new type(10); | |
101 for (var i = 0; i < 10; i++) { | |
102 array[i] = 10 - i; | |
103 } | |
104 for (var i = 0; i < 10; i++) { | |
105 assertEq('Element ' + i, 10 - i, array[i]); | |
106 } | |
107 pass(); | |
108 } catch (e) { | |
109 fail(e); | |
110 } | |
111 } | |
112 | |
113 function testConstructWithArrayOfUnsignedValues(type, name) { | |
114 running('test ' + name + ' ConstructWithArrayOfUnsignedValues'); | |
115 try { | |
116 var array = new type([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]); | |
117 assertEq('Array length', 10, array.length); | |
118 for (var i = 0; i < 10; i++) { | |
119 assertEq('Element ' + i, 10 - i, array[i]); | |
120 } | |
121 pass(); | |
122 } catch (e) { | |
123 fail(e); | |
124 } | |
125 } | |
126 | |
127 function testConstructWithTypedArrayOfUnsignedValues(type, name) { | |
128 running('test ' + name + ' ConstructWithTypedArrayOfUnsignedValues'); | |
129 try { | |
130 var tmp = new type([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]); | |
131 var array = new type(tmp); | |
132 assertEq('Array length', 10, array.length); | |
133 for (var i = 0; i < 10; i++) { | |
134 assertEq('Element ' + i, 10 - i, array[i]); | |
135 } | |
136 pass(); | |
137 } catch (e) { | |
138 fail(e); | |
139 } | |
140 } | |
141 | |
142 // | |
143 // Tests for signed array variants | |
144 // | |
145 | |
146 function testSetAndGetPos10ToNeg10(type, name) { | |
147 running('test ' + name + ' SetAndGetPos10ToNeg10'); | |
148 try { | |
149 var array = new type(21); | |
150 for (var i = 0; i < 21; i++) { | |
151 array[i] = 10 - i; | |
152 } | |
153 for (var i = 0; i < 21; i++) { | |
154 assertEq('Element ' + i, 10 - i, array[i]); | |
155 } | |
156 pass(); | |
157 } catch (e) { | |
158 fail(e); | |
159 } | |
160 } | |
161 | |
162 function testConstructWithArrayOfSignedValues(type, name) { | |
163 running('test ' + name + ' ConstructWithArrayOfSignedValues'); | |
164 try { | |
165 var array = new type([10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5,
-6, -7, -8, -9, -10]); | |
166 assertEq('Array length', 21, array.length); | |
167 for (var i = 0; i < 21; i++) { | |
168 assertEq('Element ' + i, 10 - i, array[i]); | |
169 } | |
170 pass(); | |
171 } catch (e) { | |
172 fail(e); | |
173 } | |
174 } | |
175 | |
176 function testConstructWithTypedArrayOfSignedValues(type, name) { | |
177 running('test ' + name + ' ConstructWithTypedArrayOfSignedValues'); | |
178 try { | |
179 var tmp = new type([10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6
, -7, -8, -9, -10]); | |
180 var array = new type(tmp); | |
181 assertEq('Array length', 21, array.length); | |
182 for (var i = 0; i < 21; i++) { | |
183 assertEq('Element ' + i, 10 - i, array[i]); | |
184 } | |
185 pass(); | |
186 } catch (e) { | |
187 fail(e); | |
188 } | |
189 } | |
190 | |
191 // | |
192 // Test cases for integral types. | |
193 // Some JavaScript engines need separate copies of this code in order | |
194 // to exercise all of their optimized code paths. | |
195 // | |
196 | |
197 function testIntegralArrayTruncationBehavior(type, name, unsigned) { | |
198 running('test integral array truncation behavior for ' + name); | |
199 | |
200 var sourceData; | |
201 var expectedResults; | |
202 | |
203 if (unsigned) { | |
204 sourceData = [0.6, 10.6]; | |
205 expectedResults = [0, 10]; | |
206 } else { | |
207 sourceData = [0.6, 10.6, -0.6, -10.6]; | |
208 expectedResults = [0, 10, 0, -10]; | |
209 } | |
210 | |
211 var numIterations = 10; | |
212 var array = new type(numIterations); | |
213 | |
214 // The code block in each of the case statements below is identical, but some | |
215 // JavaScript engines need separate copies in order to exercise all of | |
216 // their optimized code paths. | |
217 | |
218 try { | |
219 switch (type) { | |
220 case Int8Array: | |
221 for (var ii = 0; ii < sourceData.length; ++ii) { | |
222 for (var jj = 0; jj < numIterations; ++jj) { | |
223 array[jj] = sourceData[ii]; | |
224 assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]); | |
225 } | |
226 } | |
227 break; | |
228 case Int16Array: | |
229 for (var ii = 0; ii < sourceData.length; ++ii) { | |
230 for (var jj = 0; jj < numIterations; ++jj) { | |
231 array[jj] = sourceData[ii]; | |
232 assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]); | |
233 } | |
234 } | |
235 break; | |
236 case Int32Array: | |
237 for (var ii = 0; ii < sourceData.length; ++ii) { | |
238 for (var jj = 0; jj < numIterations; ++jj) { | |
239 array[jj] = sourceData[ii]; | |
240 assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]); | |
241 } | |
242 } | |
243 break; | |
244 case Uint8Array: | |
245 for (var ii = 0; ii < sourceData.length; ++ii) { | |
246 for (var jj = 0; jj < numIterations; ++jj) { | |
247 array[jj] = sourceData[ii]; | |
248 assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]); | |
249 } | |
250 } | |
251 break; | |
252 case Uint16Array: | |
253 for (var ii = 0; ii < sourceData.length; ++ii) { | |
254 for (var jj = 0; jj < numIterations; ++jj) { | |
255 array[jj] = sourceData[ii]; | |
256 assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]); | |
257 } | |
258 } | |
259 break; | |
260 case Uint32Array: | |
261 for (var ii = 0; ii < sourceData.length; ++ii) { | |
262 for (var jj = 0; jj < numIterations; ++jj) { | |
263 array[jj] = sourceData[ii]; | |
264 assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]); | |
265 } | |
266 } | |
267 break; | |
268 default: | |
269 fail("Unhandled type"); | |
270 break; | |
271 } | |
272 | |
273 pass(); | |
274 } catch (e) { | |
275 fail(e); | |
276 } | |
277 } | |
278 | |
279 | |
280 // | |
281 // Test cases for both signed and unsigned types | |
282 // | |
283 | |
284 function testGetWithOutOfRangeIndices(type, name) { | |
285 debug('Testing ' + name + ' GetWithOutOfRangeIndices'); | |
286 // See below for declaration of this global variable | |
287 array = new type([2, 3]); | |
288 shouldBeUndefined("array[2]"); | |
289 shouldBeUndefined("array[-1]"); | |
290 shouldBeUndefined("array[0x20000000]"); | |
291 } | |
292 | |
293 function testOffsetsAndSizes(type, name, elementSizeInBytes) { | |
294 running('test ' + name + ' OffsetsAndSizes'); | |
295 try { | |
296 var len = 10; | |
297 assertEq('type.BYTES_PER_ELEMENT', elementSizeInBytes, type.BYTES_PER_ELEMEN
T); | |
298 var array = new type(len); | |
299 assert('array.buffer', array.buffer); | |
300 assertEq('array.byteOffset', 0, array.byteOffset); | |
301 assertEq('array.length', len, array.length); | |
302 assertEq('array.byteLength', len * elementSizeInBytes, array.byteLength); | |
303 array = new type(array.buffer, elementSizeInBytes, len - 1); | |
304 assert('array.buffer', array.buffer); | |
305 assertEq('array.byteOffset', elementSizeInBytes, array.byteOffset); | |
306 assertEq('array.length', len - 1, array.length); | |
307 assertEq('array.byteLength', (len - 1) * elementSizeInBytes, array.byteLengt
h); | |
308 pass(); | |
309 } catch (e) { | |
310 fail(e); | |
311 } | |
312 } | |
313 | |
314 function testSetFromTypedArray(type, name) { | |
315 running('test ' + name + ' SetFromTypedArray'); | |
316 try { | |
317 var array = new type(10); | |
318 var array2 = new type(5); | |
319 for (var i = 0; i < 10; i++) { | |
320 assertEq('Element ' + i, 0, array[i]); | |
321 } | |
322 for (var i = 0; i < array2.length; i++) { | |
323 array2[i] = i; | |
324 } | |
325 array.set(array2); | |
326 for (var i = 0; i < array2.length; i++) { | |
327 assertEq('Element ' + i, i, array[i]); | |
328 } | |
329 array.set(array2, 5); | |
330 for (var i = 0; i < array2.length; i++) { | |
331 assertEq('Element ' + i, i, array[5 + i]); | |
332 } | |
333 pass(); | |
334 } catch (e) { | |
335 fail(e); | |
336 } | |
337 } | |
338 | |
339 function negativeTestSetFromTypedArray(type, name) { | |
340 running('negativeTest ' + name + ' SetFromTypedArray'); | |
341 try { | |
342 var array = new type(5); | |
343 var array2 = new type(6); | |
344 for (var i = 0; i < 5; i++) { | |
345 assertEq('Element ' + i, 0, array[i]); | |
346 } | |
347 for (var i = 0; i < array2.length; i++) { | |
348 array2[i] = i; | |
349 } | |
350 try { | |
351 array.set(array2); | |
352 fail('Expected exception from array.set(array2)'); | |
353 return; | |
354 } catch (e) { | |
355 } | |
356 try { | |
357 array2.set(array, 2); | |
358 fail('Expected exception from array2.set(array, 2)'); | |
359 return; | |
360 } catch (e) { | |
361 } | |
362 pass(); | |
363 } catch (e) { | |
364 fail(e); | |
365 } | |
366 } | |
367 | |
368 function testSetFromArray(type, name) { | |
369 running('test ' + name + ' SetFromArray'); | |
370 try { | |
371 var array = new type(10); | |
372 var array2 = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]; | |
373 for (var i = 0; i < 10; i++) { | |
374 assertEq('Element ' + i, 0, array[i]); | |
375 } | |
376 array.set(array2, 0); | |
377 for (var i = 0; i < array2.length; i++) { | |
378 assertEq('Element ' + i, 10 - i, array[i]); | |
379 } | |
380 pass(); | |
381 } catch (e) { | |
382 fail(e); | |
383 } | |
384 } | |
385 | |
386 function negativeTestSetFromArray(type, name) { | |
387 running('negativeTest ' + name + ' SetFromArray'); | |
388 try { | |
389 var array = new type([2, 3]); | |
390 try { | |
391 array.set([4, 5], 1); | |
392 fail(); | |
393 return; | |
394 } catch (e) { | |
395 } | |
396 try { | |
397 array.set([4, 5, 6]); | |
398 fail(); | |
399 return; | |
400 } catch (e) { | |
401 } | |
402 pass(); | |
403 } catch (e) { | |
404 fail(e); | |
405 } | |
406 } | |
407 | |
408 function testSubarray(type, name) { | |
409 running('test ' + name + ' Subarray'); | |
410 try { | |
411 var array = new type([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); | |
412 var subarray = array.subarray(0, 5); | |
413 assertEq('subarray.length', 5, subarray.length); | |
414 for (var i = 0; i < 5; i++) { | |
415 assertEq('Element ' + i, i, subarray[i]); | |
416 } | |
417 subarray = array.subarray(4, 10); | |
418 assertEq('subarray.length', 6, subarray.length); | |
419 for (var i = 0; i < 6; i++) { | |
420 assertEq('Element ' + i, 4 + i, subarray[i]); | |
421 } | |
422 pass(); | |
423 } catch (e) { | |
424 fail(e); | |
425 } | |
426 } | |
427 | |
428 function negativeTestSubarray(type, name) { | |
429 running('negativeTest ' + name + ' Subarray'); | |
430 try { | |
431 var array = new type([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); | |
432 subarray = array.subarray(5, 11); | |
433 if (subarray.length != 5) { | |
434 fail(); | |
435 return; | |
436 } | |
437 subarray = array.subarray(10, 10); | |
438 if (subarray.length != 0) { | |
439 fail(); | |
440 return; | |
441 } | |
442 pass(); | |
443 } catch (e) { | |
444 fail(e); | |
445 } | |
446 } | |
447 | |
448 function testSetBoundaryConditions(type, name, testValues, expectedValues) { | |
449 running('test ' + name + ' SetBoundaryConditions'); | |
450 try { | |
451 var array = new type(1); | |
452 assertEq('Array length', 1, array.length); | |
453 for (var ii = 0; ii < testValues.length; ++ii) { | |
454 for (var jj = 0; jj < 10; ++jj) { | |
455 array[0] = testValues[ii]; | |
456 assertEq('Element 0', expectedValues[ii], array[0]); | |
457 } | |
458 } | |
459 pass(); | |
460 } catch (e) { | |
461 fail(e); | |
462 } | |
463 } | |
464 | |
465 function testConstructionBoundaryConditions(type, name, testValues, expectedValu
es) { | |
466 running('test ' + name + ' ConstructionBoundaryConditions'); | |
467 try { | |
468 var array = new type(testValues); | |
469 assertEq('Array length', testValues.length, array.length); | |
470 for (var ii = 0; ii < testValues.length; ++ii) { | |
471 assertEq('Element ' + ii, expectedValues[ii], array[ii]); | |
472 } | |
473 pass(); | |
474 } catch (e) { | |
475 fail(e); | |
476 } | |
477 } | |
478 | |
479 function testConstructionWithNullBuffer(type, name) { | |
480 var array; | |
481 try { | |
482 array = new type(null); | |
483 testFailed("Construction of " + name + " with null buffer should throw e
xception"); | |
484 } catch (e) { | |
485 testPassed("Construction of " + name + " with null buffer threw exceptio
n"); | |
486 } | |
487 try { | |
488 array = new type(null, 0, 0); | |
489 testFailed("Construction of " + name + " with (null buffer, 0) should th
row exception"); | |
490 } catch (e) { | |
491 testPassed("Construction of " + name + " with (null buffer, 0) threw exc
eption"); | |
492 } | |
493 try { | |
494 array = new type(null, 0, 0); | |
495 testFailed("Construction of " + name + " with (null buffer, 0, 0) should
throw exception"); | |
496 } catch (e) { | |
497 testPassed("Construction of " + name + " with (null buffer, 0, 0) threw
exception"); | |
498 } | |
499 } | |
500 | |
501 function shouldThrowIndexSizeErr(func, text) { | |
502 var errorText = text + " should throw an exception"; | |
503 try { | |
504 func(); | |
505 testFailed(errorText); | |
506 } catch (e) { | |
507 testPassed(text + " threw an exception"); | |
508 } | |
509 } | |
510 | |
511 function testConstructionWithOutOfRangeValues(type, name) { | |
512 shouldThrowIndexSizeErr(function() { | |
513 var buffer = new ArrayBuffer(4); | |
514 var array = new type(buffer, 4, 0x3FFFFFFF); | |
515 }, "Construction of " + name + " with out-of-range values"); | |
516 } | |
517 | |
518 function testConstructionWithNegativeOutOfRangeValues(type, name) { | |
519 try { | |
520 var buffer = new ArrayBuffer(-1); | |
521 testFailed("Construction of ArrayBuffer with negative size should throw
exception"); | |
522 } catch (e) { | |
523 testPassed("Construction of ArrayBuffer with negative size threw excepti
on"); | |
524 } | |
525 try { | |
526 var array = new type(-1); | |
527 testFailed("Construction of " + name + " with negative size should throw
exception"); | |
528 } catch (e) { | |
529 testPassed("Construction of " + name + " with negative size threw except
ion"); | |
530 } | |
531 shouldThrowIndexSizeErr(function() { | |
532 var buffer = new ArrayBuffer(4); | |
533 var array = new type(buffer, 4, -2147483648); | |
534 }, "Construction of " + name + " with negative out-of-range values"); | |
535 } | |
536 | |
537 function testConstructionWithUnalignedOffset(type, name, elementSizeInBytes) { | |
538 if (elementSizeInBytes > 1) { | |
539 shouldThrowIndexSizeErr(function() { | |
540 var buffer = new ArrayBuffer(32); | |
541 var array = new type(buffer, 1, elementSizeInBytes); | |
542 }, "Construction of " + name + " with unaligned offset"); | |
543 } | |
544 } | |
545 | |
546 function testConstructionWithUnalignedLength(type, name, elementSizeInBytes) { | |
547 if (elementSizeInBytes > 1) { | |
548 shouldThrowIndexSizeErr(function() { | |
549 var buffer = new ArrayBuffer(elementSizeInBytes + 1); | |
550 var array = new type(buffer, 0); | |
551 }, "Construction of " + name + " with unaligned length"); | |
552 } | |
553 } | |
554 | |
555 function testConstructionOfHugeArray(type, name, sz) { | |
556 if (sz == 1) | |
557 return; | |
558 try { | |
559 // Construction of huge arrays must fail because byteLength is | |
560 // an unsigned long | |
561 array = new type(3000000000); | |
562 testFailed("Construction of huge " + name + " should throw exception"); | |
563 } catch (e) { | |
564 testPassed("Construction of huge " + name + " threw exception"); | |
565 } | |
566 } | |
567 | |
568 function testConstructionWithBothArrayBufferAndLength(type, name, elementSizeInB
ytes) { | |
569 var bufByteLength = 1000 * elementSizeInBytes; | |
570 var buf = new ArrayBuffer(bufByteLength); | |
571 var array1 = new type(buf); | |
572 var array2 = new type(bufByteLength / elementSizeInBytes); | |
573 if (array1.length == array2.length) { | |
574 testPassed("Array lengths matched with explicit and implicit creation of
ArrayBuffer"); | |
575 } else { | |
576 testFailed("Array lengths DID NOT MATCH with explicit and implicit creat
ion of ArrayBuffer"); | |
577 } | |
578 } | |
579 | |
580 // These need to be global for shouldBe to see them | |
581 var array; | |
582 var typeSize; | |
583 | |
584 function testSubarrayWithOutOfRangeValues(type, name, sz) { | |
585 debug("Testing subarray of " + name); | |
586 try { | |
587 var buffer = new ArrayBuffer(32); | |
588 array = new type(buffer); | |
589 typeSize = sz; | |
590 shouldBe("array.length", "32 / typeSize"); | |
591 try { | |
592 shouldBe("array.subarray(4, 0x3FFFFFFF).length", "(32 / typeSize) -
4"); | |
593 shouldBe("array.subarray(4, -2147483648).length", "0"); | |
594 // Test subarray() against overflows. | |
595 array = array.subarray(2); | |
596 if (sz > 1) { | |
597 // Full byte offset is +1 larger than the maximum unsigned long
int. | |
598 // Make sure subarray() still handles it correctly. Otherwise o
verflow would happen and | |
599 // offset would be 0, and array.length array.length would incorr
ectly be 1. | |
600 var start = 4294967296 / sz - 2; | |
601 array = array.subarray(start, start + 1); | |
602 shouldBe("array.length", "0"); | |
603 } | |
604 } catch (e) { | |
605 testFailed("Subarray of " + name + " threw exception"); | |
606 } | |
607 } catch (e) { | |
608 testFailed("Exception: " + e); | |
609 } | |
610 } | |
611 | |
612 function testSubarrayWithDefaultValues(type, name, sz) { | |
613 debug("Testing subarray with default inputs of " + name); | |
614 try { | |
615 var buffer = new ArrayBuffer(32); | |
616 array = new type(buffer); | |
617 typeSize = sz; | |
618 shouldBe("array.length", "32 / typeSize"); | |
619 try { | |
620 shouldBe("array.subarray(0).length", "(32 / typeSize)"); | |
621 shouldBe("array.subarray(2).length", "(32 / typeSize) - 2"); | |
622 shouldBe("array.subarray(-2).length", "2"); | |
623 shouldBe("array.subarray(-2147483648).length", "(32 / typeSize)"); | |
624 } catch (e) { | |
625 testFailed("Subarray of " + name + " threw exception"); | |
626 } | |
627 } catch (e) { | |
628 testFailed("Exception: " + e); | |
629 } | |
630 } | |
631 | |
632 function testSettingFromArrayWithOutOfRangeOffset(type, name) { | |
633 var webglArray = new type(32); | |
634 var array = []; | |
635 for (var i = 0; i < 16; i++) { | |
636 array.push(i); | |
637 } | |
638 try { | |
639 webglArray.set(array, 0x7FFFFFF8); | |
640 testFailed("Setting " + name + " from array with out-of-range offset was
not caught"); | |
641 } catch (e) { | |
642 testPassed("Setting " + name + " from array with out-of-range offset was
caught"); | |
643 } | |
644 } | |
645 | |
646 function testSettingFromFakeArrayWithOutOfRangeLength(type, name) { | |
647 var webglArray = new type(32); | |
648 var array = {}; | |
649 array.length = 0x80000000; | |
650 try { | |
651 webglArray.set(array, 8); | |
652 testFailed("Setting " + name + " from fake array with invalid length was
not caught"); | |
653 } catch (e) { | |
654 testPassed("Setting " + name + " from fake array with invalid length was
caught"); | |
655 } | |
656 } | |
657 | |
658 function testSettingFromTypedArrayWithOutOfRangeOffset(type, name) { | |
659 var webglArray = new type(32); | |
660 var srcArray = new type(16); | |
661 for (var i = 0; i < 16; i++) { | |
662 srcArray[i] = i; | |
663 } | |
664 try { | |
665 webglArray.set(srcArray, 0x7FFFFFF8); | |
666 testFailed("Setting " + name + " from " + name + " with out-of-range off
set was not caught"); | |
667 } catch (e) { | |
668 testPassed("Setting " + name + " from " + name + " with out-of-range off
set was caught"); | |
669 } | |
670 } | |
671 | |
672 function negativeTestGetAndSetMethods(type, name) { | |
673 array = new type([2, 3]); | |
674 shouldBeUndefined("array.get"); | |
675 var exceptionThrown = false; | |
676 // We deliberately check for an exception here rather than using | |
677 // shouldThrow here because the precise contents of the syntax | |
678 // error are not specified. | |
679 try { | |
680 webGLArray.set(0, 1); | |
681 } catch (e) { | |
682 exceptionThrown = true; | |
683 } | |
684 var output = "array.set(0, 1) "; | |
685 if (exceptionThrown) { | |
686 testPassed(output + "threw exception."); | |
687 } else { | |
688 testFailed(output + "did not throw exception."); | |
689 } | |
690 } | |
691 | |
692 function testNaNConversion(type, name) { | |
693 running('test storing NaN in ' + name); | |
694 | |
695 var array = new type([1, 1]); | |
696 var results = []; | |
697 | |
698 // The code block in each of the case statements below is identical, but some | |
699 // JavaScript engines need separate copies in order to exercise all of | |
700 // their optimized code paths. | |
701 try { | |
702 switch (type) { | |
703 case Float32Array: | |
704 for (var i = 0; i < array.length; ++i) { | |
705 array[i] = NaN; | |
706 results[i] = array[i]; | |
707 } | |
708 break; | |
709 case Float64Array: | |
710 for (var i = 0; i < array.length; ++i) { | |
711 array[i] = NaN; | |
712 results[i] = array[i]; | |
713 } | |
714 break; | |
715 case Int8Array: | |
716 for (var i = 0; i < array.length; ++i) { | |
717 array[i] = NaN; | |
718 results[i] = array[i]; | |
719 } | |
720 break; | |
721 case Int16Array: | |
722 for (var i = 0; i < array.length; ++i) { | |
723 array[i] = NaN; | |
724 results[i] = array[i]; | |
725 } | |
726 break; | |
727 case Int32Array: | |
728 for (var i = 0; i < array.length; ++i) { | |
729 array[i] = NaN; | |
730 results[i] = array[i]; | |
731 } | |
732 break; | |
733 case Uint8Array: | |
734 for (var i = 0; i < array.length; ++i) { | |
735 array[i] = NaN; | |
736 results[i] = array[i]; | |
737 } | |
738 break; | |
739 case Uint16Array: | |
740 for (var i = 0; i < array.length; ++i) { | |
741 array[i] = NaN; | |
742 results[i] = array[i]; | |
743 } | |
744 break; | |
745 case Uint32Array: | |
746 for (var i = 0; i < array.length; ++i) { | |
747 array[i] = NaN; | |
748 results[i] = array[i]; | |
749 } | |
750 break; | |
751 default: | |
752 fail("Unhandled type"); | |
753 break; | |
754 } | |
755 | |
756 // Some types preserve NaN values; all other types convert NaN to zero. | |
757 if (type === Float32Array || type === Float64Array) { | |
758 assert('initial NaN preserved', isNaN(new type([NaN])[0])); | |
759 for (var i = 0; i < array.length; ++i) | |
760 assert('NaN preserved via setter', isNaN(results[i])); | |
761 } else { | |
762 assertEq('initial NaN converted to zero', 0, new type([NaN])[0]); | |
763 for (var i = 0; i < array.length; ++i) | |
764 assertEq('NaN converted to zero by setter', 0, results[i]); | |
765 } | |
766 | |
767 pass(); | |
768 } catch (e) { | |
769 fail(e); | |
770 } | |
771 } | |
772 | |
773 // | |
774 // Test driver | |
775 // | |
776 | |
777 function runTests() { | |
778 allPassed = true; | |
779 | |
780 // The "name" attribute is a concession to browsers which don't | |
781 // implement the "name" property on function objects | |
782 var testCases = | |
783 [ {name: "Float32Array", | |
784 unsigned: false, | |
785 integral: false, | |
786 elementSizeInBytes: 4, | |
787 testValues: [ -500.5, 500.5 ], | |
788 expectedValues: [ -500.5, 500.5 ] | |
789 }, | |
790 {name: "Float64Array", | |
791 unsigned: false, | |
792 integral: false, | |
793 elementSizeInBytes: 8, | |
794 testValues: [ -500.5, 500.5 ], | |
795 expectedValues: [ -500.5, 500.5 ] | |
796 }, | |
797 {name: "Int8Array", | |
798 unsigned: false, | |
799 integral: true, | |
800 elementSizeInBytes: 1, | |
801 testValues: [ -128, 127, -129, 128 ], | |
802 expectedValues: [ -128, 127, 127, -128 ] | |
803 }, | |
804 {name: "Int16Array", | |
805 unsigned: false, | |
806 integral: true, | |
807 elementSizeInBytes: 2, | |
808 testValues: [ -32768, 32767, -32769, 32768 ], | |
809 expectedValues: [ -32768, 32767, 32767, -32768 ] | |
810 }, | |
811 {name: "Int32Array", | |
812 unsigned: false, | |
813 integral: true, | |
814 elementSizeInBytes: 4, | |
815 testValues: [ -2147483648, 2147483647, -2147483649, 2147483648 ], | |
816 expectedValues: [ -2147483648, 2147483647, 2147483647, -2147483648 ] | |
817 }, | |
818 {name: "Uint8Array", | |
819 unsigned: true, | |
820 integral: true, | |
821 elementSizeInBytes: 1, | |
822 testValues: [ 0, 255, -1, 256 ], | |
823 expectedValues: [ 0, 255, 255, 0 ] | |
824 }, | |
825 {name: "Uint16Array", | |
826 unsigned: true, | |
827 integral: true, | |
828 elementSizeInBytes: 2, | |
829 testValues: [ 0, 65535, -1, 65536 ], | |
830 expectedValues: [ 0, 65535, 65535, 0 ] | |
831 }, | |
832 {name: "Uint32Array", | |
833 unsigned: true, | |
834 integral: true, | |
835 elementSizeInBytes: 4, | |
836 testValues: [ 0, 4294967295, -1, 4294967296 ], | |
837 expectedValues: [ 0, 4294967295, 4294967295, 0 ] | |
838 } | |
839 ]; | |
840 for (var i = 0; i < testCases.length; i++) { | |
841 var testCase = testCases[i]; | |
842 running(testCase.name); | |
843 if (!(testCase.name in window)) { | |
844 fail("does not exist"); | |
845 continue; | |
846 } | |
847 var type = window[testCase.name]; | |
848 var name = testCase.name; | |
849 if (testCase.unsigned) { | |
850 testSetAndGet10To1(type, name); | |
851 testConstructWithArrayOfUnsignedValues(type, name); | |
852 testConstructWithTypedArrayOfUnsignedValues(type, name); | |
853 } else { | |
854 testSetAndGetPos10ToNeg10(type, name); | |
855 testConstructWithArrayOfSignedValues(type, name); | |
856 testConstructWithTypedArrayOfSignedValues(type, name); | |
857 } | |
858 if (testCase.integral) { | |
859 testIntegralArrayTruncationBehavior(type, name, testCase.unsigned); | |
860 } | |
861 testGetWithOutOfRangeIndices(type, name); | |
862 testOffsetsAndSizes(type, name, testCase.elementSizeInBytes); | |
863 testSetFromTypedArray(type, name); | |
864 negativeTestSetFromTypedArray(type, name); | |
865 testSetFromArray(type, name); | |
866 negativeTestSetFromArray(type, name); | |
867 testSubarray(type, name); | |
868 negativeTestSubarray(type, name); | |
869 testSetBoundaryConditions(type, | |
870 name, | |
871 testCase.testValues, | |
872 testCase.expectedValues); | |
873 testConstructionBoundaryConditions(type, | |
874 name, | |
875 testCase.testValues, | |
876 testCase.expectedValues); | |
877 testConstructionWithNullBuffer(type, name); | |
878 testConstructionWithOutOfRangeValues(type, name); | |
879 testConstructionWithNegativeOutOfRangeValues(type, name); | |
880 testConstructionWithUnalignedOffset(type, name, testCase.elementSizeInBytes)
; | |
881 testConstructionWithUnalignedLength(type, name, testCase.elementSizeInBytes)
; | |
882 testConstructionOfHugeArray(type, name, testCase.elementSizeInBytes); | |
883 testConstructionWithBothArrayBufferAndLength(type, name, testCase.elementSiz
eInBytes); | |
884 testSubarrayWithOutOfRangeValues(type, name, testCase.elementSizeInBytes); | |
885 testSubarrayWithDefaultValues(type, name, testCase.elementSizeInBytes); | |
886 testSettingFromArrayWithOutOfRangeOffset(type, name); | |
887 testSettingFromFakeArrayWithOutOfRangeLength(type, name); | |
888 testSettingFromTypedArrayWithOutOfRangeOffset(type, name); | |
889 negativeTestGetAndSetMethods(type, name); | |
890 testNaNConversion(type, name); | |
891 } | |
892 | |
893 printSummary(); | |
894 } | |
895 | |
896 runTests(); | |
897 successfullyParsed = true; | |
898 | |
899 </script> | |
900 <script src="../resources/js-test-post.js"></script> | |
901 | |
902 </body> | |
903 </html> | |
OLD | NEW |