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