Index: conformance/typedarrays/array-unit-tests.html |
=================================================================== |
--- conformance/typedarrays/array-unit-tests.html (revision 0) |
+++ conformance/typedarrays/array-unit-tests.html (revision 0) |
@@ -0,0 +1,923 @@ |
+<!-- |
+Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+Copyright (C) 2011 Apple Computer, Inc. All rights reserved. |
+ |
+Redistribution and use in source and binary forms, with or without |
+modification, are permitted provided that the following conditions are |
+met: |
+ |
+ * Redistributions of source code must retain the above copyright |
+notice, this list of conditions and the following disclaimer. |
+ * Redistributions in binary form must reproduce the above |
+copyright notice, this list of conditions and the following disclaimer |
+in the documentation and/or other materials provided with the |
+distribution. |
+ * Neither the name of Google Inc. nor the names of its |
+contributors may be used to endorse or promote products derived from |
+this software without specific prior written permission. |
+ |
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+--> |
+<!DOCTYPE html> |
+<html> |
+<head> |
+<meta charset="utf-8"> |
+<link rel="stylesheet" href="../../resources/js-test-style.css"/> |
+<script src="../../resources/js-test-pre.js"></script> |
+<script src="../resources/webgl-test.js"></script> |
+</head> |
+<body> |
+<div id="description"></div> |
+<div id="console"></div> |
+ |
+<script> |
+ |
+description("Verifies the functionality of the new array-like objects in the TypedArray spec"); |
+ |
+var currentlyRunning = ''; |
+var allPassed = true; |
+function running(str) { |
+ currentlyRunning = str; |
+} |
+ |
+function output(str) { |
+ debug(str); |
+} |
+ |
+function pass() { |
+ testPassed(currentlyRunning); |
+} |
+ |
+function fail(str) { |
+ allPassed = false; |
+ var exc; |
+ if (str) |
+ exc = currentlyRunning + ': ' + str; |
+ else |
+ exc = currentlyRunning; |
+ testFailed(exc); |
+} |
+ |
+function assertEq(prefix, expected, val) { |
+ if (expected != val) { |
+ var str = prefix + ': expected ' + expected + ', got ' + val; |
+ throw str; |
+ } |
+} |
+ |
+function assert(prefix, expected) { |
+ if (!expected) { |
+ var str = prefix + ': expected value / true'; |
+ throw str; |
+ } |
+} |
+ |
+function printSummary() { |
+ if (allPassed) { |
+ debug("Test passed."); |
+ } else { |
+ debug("TEST FAILED"); |
+ } |
+} |
+ |
+// |
+// Tests for unsigned array variants |
+// |
+ |
+function testSetAndGet10To1(type, name) { |
+ running('test ' + name + ' SetAndGet10To1'); |
+ try { |
+ var array = new type(10); |
+ for (var i = 0; i < 10; i++) { |
+ array[i] = 10 - i; |
+ } |
+ for (var i = 0; i < 10; i++) { |
+ assertEq('Element ' + i, 10 - i, array[i]); |
+ } |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+function testConstructWithArrayOfUnsignedValues(type, name) { |
+ running('test ' + name + ' ConstructWithArrayOfUnsignedValues'); |
+ try { |
+ var array = new type([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]); |
+ assertEq('Array length', 10, array.length); |
+ for (var i = 0; i < 10; i++) { |
+ assertEq('Element ' + i, 10 - i, array[i]); |
+ } |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+function testConstructWithTypedArrayOfUnsignedValues(type, name) { |
+ running('test ' + name + ' ConstructWithTypedArrayOfUnsignedValues'); |
+ try { |
+ var tmp = new type([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]); |
+ var array = new type(tmp); |
+ assertEq('Array length', 10, array.length); |
+ for (var i = 0; i < 10; i++) { |
+ assertEq('Element ' + i, 10 - i, array[i]); |
+ } |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+// |
+// Tests for signed array variants |
+// |
+ |
+function testSetAndGetPos10ToNeg10(type, name) { |
+ running('test ' + name + ' SetAndGetPos10ToNeg10'); |
+ try { |
+ var array = new type(21); |
+ for (var i = 0; i < 21; i++) { |
+ array[i] = 10 - i; |
+ } |
+ for (var i = 0; i < 21; i++) { |
+ assertEq('Element ' + i, 10 - i, array[i]); |
+ } |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+function testConstructWithArrayOfSignedValues(type, name) { |
+ running('test ' + name + ' ConstructWithArrayOfSignedValues'); |
+ try { |
+ 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]); |
+ assertEq('Array length', 21, array.length); |
+ for (var i = 0; i < 21; i++) { |
+ assertEq('Element ' + i, 10 - i, array[i]); |
+ } |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+function testConstructWithTypedArrayOfSignedValues(type, name) { |
+ running('test ' + name + ' ConstructWithTypedArrayOfSignedValues'); |
+ try { |
+ 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]); |
+ var array = new type(tmp); |
+ assertEq('Array length', 21, array.length); |
+ for (var i = 0; i < 21; i++) { |
+ assertEq('Element ' + i, 10 - i, array[i]); |
+ } |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+// |
+// Test cases for integral types. |
+// Some JavaScript engines need separate copies of this code in order |
+// to exercise all of their optimized code paths. |
+// |
+ |
+function testIntegralArrayTruncationBehavior(type, name, unsigned) { |
+ running('test integral array truncation behavior for ' + name); |
+ |
+ var sourceData; |
+ var expectedResults; |
+ |
+ if (unsigned) { |
+ sourceData = [0.6, 10.6]; |
+ expectedResults = [0, 10]; |
+ } else { |
+ sourceData = [0.6, 10.6, -0.6, -10.6]; |
+ expectedResults = [0, 10, 0, -10]; |
+ } |
+ |
+ var numIterations = 10; |
+ var array = new type(numIterations); |
+ |
+ // The code block in each of the case statements below is identical, but some |
+ // JavaScript engines need separate copies in order to exercise all of |
+ // their optimized code paths. |
+ |
+ try { |
+ switch (type) { |
+ case Int8Array: |
+ for (var ii = 0; ii < sourceData.length; ++ii) { |
+ for (var jj = 0; jj < numIterations; ++jj) { |
+ array[jj] = sourceData[ii]; |
+ assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]); |
+ } |
+ } |
+ break; |
+ case Int16Array: |
+ for (var ii = 0; ii < sourceData.length; ++ii) { |
+ for (var jj = 0; jj < numIterations; ++jj) { |
+ array[jj] = sourceData[ii]; |
+ assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]); |
+ } |
+ } |
+ break; |
+ case Int32Array: |
+ for (var ii = 0; ii < sourceData.length; ++ii) { |
+ for (var jj = 0; jj < numIterations; ++jj) { |
+ array[jj] = sourceData[ii]; |
+ assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]); |
+ } |
+ } |
+ break; |
+ case Uint8Array: |
+ for (var ii = 0; ii < sourceData.length; ++ii) { |
+ for (var jj = 0; jj < numIterations; ++jj) { |
+ array[jj] = sourceData[ii]; |
+ assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]); |
+ } |
+ } |
+ break; |
+ case Uint16Array: |
+ for (var ii = 0; ii < sourceData.length; ++ii) { |
+ for (var jj = 0; jj < numIterations; ++jj) { |
+ array[jj] = sourceData[ii]; |
+ assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]); |
+ } |
+ } |
+ break; |
+ case Uint32Array: |
+ for (var ii = 0; ii < sourceData.length; ++ii) { |
+ for (var jj = 0; jj < numIterations; ++jj) { |
+ array[jj] = sourceData[ii]; |
+ assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]); |
+ } |
+ } |
+ break; |
+ default: |
+ fail("Unhandled type"); |
+ break; |
+ } |
+ |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+ |
+// |
+// Test cases for both signed and unsigned types |
+// |
+ |
+function testGetWithOutOfRangeIndices(type, name) { |
+ debug('Testing ' + name + ' GetWithOutOfRangeIndices'); |
+ // See below for declaration of this global variable |
+ array = new type([2, 3]); |
+ shouldBeUndefined("array[2]"); |
+ shouldBeUndefined("array[-1]"); |
+ shouldBeUndefined("array[0x20000000]"); |
+} |
+ |
+function testOffsetsAndSizes(type, name, elementSizeInBytes) { |
+ running('test ' + name + ' OffsetsAndSizes'); |
+ try { |
+ var len = 10; |
+ assertEq('type.BYTES_PER_ELEMENT', elementSizeInBytes, type.BYTES_PER_ELEMENT); |
+ var array = new type(len); |
+ assert('array.buffer', array.buffer); |
+ assertEq('array.byteOffset', 0, array.byteOffset); |
+ assertEq('array.length', len, array.length); |
+ assertEq('array.byteLength', len * elementSizeInBytes, array.byteLength); |
+ array = new type(array.buffer, elementSizeInBytes, len - 1); |
+ assert('array.buffer', array.buffer); |
+ assertEq('array.byteOffset', elementSizeInBytes, array.byteOffset); |
+ assertEq('array.length', len - 1, array.length); |
+ assertEq('array.byteLength', (len - 1) * elementSizeInBytes, array.byteLength); |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+function testSetFromTypedArray(type, name) { |
+ running('test ' + name + ' SetFromTypedArray'); |
+ try { |
+ var array = new type(10); |
+ var array2 = new type(5); |
+ for (var i = 0; i < 10; i++) { |
+ assertEq('Element ' + i, 0, array[i]); |
+ } |
+ for (var i = 0; i < array2.length; i++) { |
+ array2[i] = i; |
+ } |
+ array.set(array2); |
+ for (var i = 0; i < array2.length; i++) { |
+ assertEq('Element ' + i, i, array[i]); |
+ } |
+ array.set(array2, 5); |
+ for (var i = 0; i < array2.length; i++) { |
+ assertEq('Element ' + i, i, array[5 + i]); |
+ } |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+function negativeTestSetFromTypedArray(type, name) { |
+ running('negativeTest ' + name + ' SetFromTypedArray'); |
+ try { |
+ var array = new type(5); |
+ var array2 = new type(6); |
+ for (var i = 0; i < 5; i++) { |
+ assertEq('Element ' + i, 0, array[i]); |
+ } |
+ for (var i = 0; i < array2.length; i++) { |
+ array2[i] = i; |
+ } |
+ try { |
+ array.set(array2); |
+ fail('Expected exception from array.set(array2)'); |
+ return; |
+ } catch (e) { |
+ } |
+ try { |
+ array2.set(array, 2); |
+ fail('Expected exception from array2.set(array, 2)'); |
+ return; |
+ } catch (e) { |
+ } |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+function testSetFromArray(type, name) { |
+ running('test ' + name + ' SetFromArray'); |
+ try { |
+ var array = new type(10); |
+ var array2 = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]; |
+ for (var i = 0; i < 10; i++) { |
+ assertEq('Element ' + i, 0, array[i]); |
+ } |
+ array.set(array2, 0); |
+ for (var i = 0; i < array2.length; i++) { |
+ assertEq('Element ' + i, 10 - i, array[i]); |
+ } |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+function negativeTestSetFromArray(type, name) { |
+ running('negativeTest ' + name + ' SetFromArray'); |
+ try { |
+ var array = new type([2, 3]); |
+ try { |
+ array.set([4, 5], 1); |
+ fail(); |
+ return; |
+ } catch (e) { |
+ } |
+ try { |
+ array.set([4, 5, 6]); |
+ fail(); |
+ return; |
+ } catch (e) { |
+ } |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+function testSubarray(type, name) { |
+ running('test ' + name + ' Subarray'); |
+ try { |
+ var array = new type([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); |
+ var subarray = array.subarray(0, 5); |
+ assertEq('subarray.length', 5, subarray.length); |
+ for (var i = 0; i < 5; i++) { |
+ assertEq('Element ' + i, i, subarray[i]); |
+ } |
+ subarray = array.subarray(4, 10); |
+ assertEq('subarray.length', 6, subarray.length); |
+ for (var i = 0; i < 6; i++) { |
+ assertEq('Element ' + i, 4 + i, subarray[i]); |
+ } |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+function negativeTestSubarray(type, name) { |
+ running('negativeTest ' + name + ' Subarray'); |
+ try { |
+ var array = new type([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); |
+ subarray = array.subarray(5, 11); |
+ if (subarray.length != 5) { |
+ fail(); |
+ return; |
+ } |
+ subarray = array.subarray(10, 10); |
+ if (subarray.length != 0) { |
+ fail(); |
+ return; |
+ } |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+function testSetBoundaryConditions(type, name, testValues, expectedValues) { |
+ running('test ' + name + ' SetBoundaryConditions'); |
+ try { |
+ var array = new type(1); |
+ assertEq('Array length', 1, array.length); |
+ for (var ii = 0; ii < testValues.length; ++ii) { |
+ for (var jj = 0; jj < 10; ++jj) { |
+ array[0] = testValues[ii]; |
+ assertEq('Element 0', expectedValues[ii], array[0]); |
+ } |
+ } |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+function testConstructionBoundaryConditions(type, name, testValues, expectedValues) { |
+ running('test ' + name + ' ConstructionBoundaryConditions'); |
+ try { |
+ var array = new type(testValues); |
+ assertEq('Array length', testValues.length, array.length); |
+ for (var ii = 0; ii < testValues.length; ++ii) { |
+ assertEq('Element ' + ii, expectedValues[ii], array[ii]); |
+ } |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+function testConstructionWithNullBuffer(type, name) { |
+ var array; |
+ try { |
+ array = new type(null); |
+ testFailed("Construction of " + name + " with null buffer should throw exception"); |
+ } catch (e) { |
+ testPassed("Construction of " + name + " with null buffer threw exception"); |
+ } |
+ try { |
+ array = new type(null, 0, 0); |
+ testFailed("Construction of " + name + " with (null buffer, 0) should throw exception"); |
+ } catch (e) { |
+ testPassed("Construction of " + name + " with (null buffer, 0) threw exception"); |
+ } |
+ try { |
+ array = new type(null, 0, 0); |
+ testFailed("Construction of " + name + " with (null buffer, 0, 0) should throw exception"); |
+ } catch (e) { |
+ testPassed("Construction of " + name + " with (null buffer, 0, 0) threw exception"); |
+ } |
+} |
+ |
+function shouldThrowIndexSizeErr(func, text) { |
+ var errorText = text + " should throw an exception"; |
+ try { |
+ func(); |
+ testFailed(errorText); |
+ } catch (e) { |
+ testPassed(text + " threw an exception"); |
+ } |
+} |
+ |
+function testConstructionWithOutOfRangeValues(type, name) { |
+ shouldThrowIndexSizeErr(function() { |
+ var buffer = new ArrayBuffer(4); |
+ var array = new type(buffer, 4, 0x3FFFFFFF); |
+ }, "Construction of " + name + " with out-of-range number of elements"); |
+ shouldThrowIndexSizeErr(function() { |
+ var buffer = new ArrayBuffer(4); |
+ var array = new type(buffer, 8); |
+ }, "Construction of " + name + " with out-of-range offset"); |
+} |
+ |
+function testConstructionWithNegativeOutOfRangeValues(type, name) { |
+ try { |
+ var buffer = new ArrayBuffer(-1); |
+ testFailed("Construction of ArrayBuffer with negative size should throw exception"); |
+ } catch (e) { |
+ testPassed("Construction of ArrayBuffer with negative size threw exception"); |
+ } |
+ try { |
+ var array = new type(-1); |
+ testFailed("Construction of " + name + " with negative size should throw exception"); |
+ } catch (e) { |
+ testPassed("Construction of " + name + " with negative size threw exception"); |
+ } |
+ shouldThrowIndexSizeErr(function() { |
+ var buffer = new ArrayBuffer(4); |
+ var array = new type(buffer, 4, -2147483648); |
+ }, "Construction of " + name + " with negative out-of-range values"); |
+} |
+ |
+function testConstructionWithUnalignedOffset(type, name, elementSizeInBytes) { |
+ if (elementSizeInBytes > 1) { |
+ shouldThrowIndexSizeErr(function() { |
+ var buffer = new ArrayBuffer(32); |
+ var array = new type(buffer, 1, elementSizeInBytes); |
+ }, "Construction of " + name + " with unaligned offset"); |
+ } |
+} |
+ |
+function testConstructionWithUnalignedLength(type, name, elementSizeInBytes) { |
+ if (elementSizeInBytes > 1) { |
+ shouldThrowIndexSizeErr(function() { |
+ var buffer = new ArrayBuffer(elementSizeInBytes + 1); |
+ var array = new type(buffer, 0); |
+ }, "Construction of " + name + " with unaligned length"); |
+ } |
+} |
+ |
+function testConstructionOfHugeArray(type, name, sz) { |
+ if (sz == 1) |
+ return; |
+ try { |
+ // Construction of huge arrays must fail because byteLength is |
+ // an unsigned long |
+ array = new type(3000000000); |
+ testFailed("Construction of huge " + name + " should throw exception"); |
+ } catch (e) { |
+ testPassed("Construction of huge " + name + " threw exception"); |
+ } |
+} |
+ |
+function testConstructionWithBothArrayBufferAndLength(type, name, elementSizeInBytes) { |
+ var bufByteLength = 1000 * elementSizeInBytes; |
+ var buf = new ArrayBuffer(bufByteLength); |
+ var array1 = new type(buf); |
+ var array2 = new type(bufByteLength / elementSizeInBytes); |
+ if (array1.length == array2.length) { |
+ testPassed("Array lengths matched with explicit and implicit creation of ArrayBuffer"); |
+ } else { |
+ testFailed("Array lengths DID NOT MATCH with explicit and implicit creation of ArrayBuffer"); |
+ } |
+} |
+ |
+function testConstructionWithSubPortionOfArrayBuffer(type, name, elementSizeInBytes) { |
+ if (elementSizeInBytes > 1) { |
+ // Test construction with a valid sub-portion of an array buffer |
+ // (whose size is not an integral multiple of the element size). |
+ var size = 4 * elementSizeInBytes + (elementSizeInBytes / 2); |
+ var buf = new ArrayBuffer(size); |
+ try { |
+ var array = new type(buf, 0, 2); |
+ testPassed("new " + name + "(new ArrayBuffer(" + size + "), 0, 2) succeeded"); |
+ } catch (e) { |
+ testFailed("new " + name + "(new ArrayBuffer(" + size + "), 0, 2) failed: " + e); |
+ } |
+ } |
+} |
+ |
+// These need to be global for shouldBe to see them |
+var array; |
+var typeSize; |
+ |
+function testSubarrayWithOutOfRangeValues(type, name, sz) { |
+ debug("Testing subarray of " + name); |
+ try { |
+ var buffer = new ArrayBuffer(32); |
+ array = new type(buffer); |
+ typeSize = sz; |
+ shouldBe("array.length", "32 / typeSize"); |
+ try { |
+ shouldBe("array.subarray(4, 0x3FFFFFFF).length", "(32 / typeSize) - 4"); |
+ shouldBe("array.subarray(4, -2147483648).length", "0"); |
+ // Test subarray() against overflows. |
+ array = array.subarray(2); |
+ if (sz > 1) { |
+ // Full byte offset is +1 larger than the maximum unsigned long int. |
+ // Make sure subarray() still handles it correctly. Otherwise overflow would happen and |
+ // offset would be 0, and array.length array.length would incorrectly be 1. |
+ var start = 4294967296 / sz - 2; |
+ array = array.subarray(start, start + 1); |
+ shouldBe("array.length", "0"); |
+ } |
+ } catch (e) { |
+ testFailed("Subarray of " + name + " threw exception"); |
+ } |
+ } catch (e) { |
+ testFailed("Exception: " + e); |
+ } |
+} |
+ |
+function testSubarrayWithDefaultValues(type, name, sz) { |
+ debug("Testing subarray with default inputs of " + name); |
+ try { |
+ var buffer = new ArrayBuffer(32); |
+ array = new type(buffer); |
+ typeSize = sz; |
+ shouldBe("array.length", "32 / typeSize"); |
+ try { |
+ shouldBe("array.subarray(0).length", "(32 / typeSize)"); |
+ shouldBe("array.subarray(2).length", "(32 / typeSize) - 2"); |
+ shouldBe("array.subarray(-2).length", "2"); |
+ shouldBe("array.subarray(-2147483648).length", "(32 / typeSize)"); |
+ } catch (e) { |
+ testFailed("Subarray of " + name + " threw exception"); |
+ } |
+ } catch (e) { |
+ testFailed("Exception: " + e); |
+ } |
+} |
+ |
+function testSettingFromArrayWithOutOfRangeOffset(type, name) { |
+ var webglArray = new type(32); |
+ var array = []; |
+ for (var i = 0; i < 16; i++) { |
+ array.push(i); |
+ } |
+ try { |
+ webglArray.set(array, 0x7FFFFFF8); |
+ testFailed("Setting " + name + " from array with out-of-range offset was not caught"); |
+ } catch (e) { |
+ testPassed("Setting " + name + " from array with out-of-range offset was caught"); |
+ } |
+} |
+ |
+function testSettingFromFakeArrayWithOutOfRangeLength(type, name) { |
+ var webglArray = new type(32); |
+ var array = {}; |
+ array.length = 0x80000000; |
+ try { |
+ webglArray.set(array, 8); |
+ testFailed("Setting " + name + " from fake array with invalid length was not caught"); |
+ } catch (e) { |
+ testPassed("Setting " + name + " from fake array with invalid length was caught"); |
+ } |
+} |
+ |
+function testSettingFromTypedArrayWithOutOfRangeOffset(type, name) { |
+ var webglArray = new type(32); |
+ var srcArray = new type(16); |
+ for (var i = 0; i < 16; i++) { |
+ srcArray[i] = i; |
+ } |
+ try { |
+ webglArray.set(srcArray, 0x7FFFFFF8); |
+ testFailed("Setting " + name + " from " + name + " with out-of-range offset was not caught"); |
+ } catch (e) { |
+ testPassed("Setting " + name + " from " + name + " with out-of-range offset was caught"); |
+ } |
+} |
+ |
+function negativeTestGetAndSetMethods(type, name) { |
+ array = new type([2, 3]); |
+ shouldBeUndefined("array.get"); |
+ var exceptionThrown = false; |
+ // We deliberately check for an exception here rather than using |
+ // shouldThrow here because the precise contents of the syntax |
+ // error are not specified. |
+ try { |
+ webGLArray.set(0, 1); |
+ } catch (e) { |
+ exceptionThrown = true; |
+ } |
+ var output = "array.set(0, 1) "; |
+ if (exceptionThrown) { |
+ testPassed(output + "threw exception."); |
+ } else { |
+ testFailed(output + "did not throw exception."); |
+ } |
+} |
+ |
+function testNaNConversion(type, name) { |
+ running('test storing NaN in ' + name); |
+ |
+ var array = new type([1, 1]); |
+ var results = []; |
+ |
+ // The code block in each of the case statements below is identical, but some |
+ // JavaScript engines need separate copies in order to exercise all of |
+ // their optimized code paths. |
+ try { |
+ switch (type) { |
+ case Float32Array: |
+ for (var i = 0; i < array.length; ++i) { |
+ array[i] = NaN; |
+ results[i] = array[i]; |
+ } |
+ break; |
+ case Float64Array: |
+ for (var i = 0; i < array.length; ++i) { |
+ array[i] = NaN; |
+ results[i] = array[i]; |
+ } |
+ break; |
+ case Int8Array: |
+ for (var i = 0; i < array.length; ++i) { |
+ array[i] = NaN; |
+ results[i] = array[i]; |
+ } |
+ break; |
+ case Int16Array: |
+ for (var i = 0; i < array.length; ++i) { |
+ array[i] = NaN; |
+ results[i] = array[i]; |
+ } |
+ break; |
+ case Int32Array: |
+ for (var i = 0; i < array.length; ++i) { |
+ array[i] = NaN; |
+ results[i] = array[i]; |
+ } |
+ break; |
+ case Uint8Array: |
+ for (var i = 0; i < array.length; ++i) { |
+ array[i] = NaN; |
+ results[i] = array[i]; |
+ } |
+ break; |
+ case Uint16Array: |
+ for (var i = 0; i < array.length; ++i) { |
+ array[i] = NaN; |
+ results[i] = array[i]; |
+ } |
+ break; |
+ case Uint32Array: |
+ for (var i = 0; i < array.length; ++i) { |
+ array[i] = NaN; |
+ results[i] = array[i]; |
+ } |
+ break; |
+ default: |
+ fail("Unhandled type"); |
+ break; |
+ } |
+ |
+ // Some types preserve NaN values; all other types convert NaN to zero. |
+ if (type === Float32Array || type === Float64Array) { |
+ assert('initial NaN preserved', isNaN(new type([NaN])[0])); |
+ for (var i = 0; i < array.length; ++i) |
+ assert('NaN preserved via setter', isNaN(results[i])); |
+ } else { |
+ assertEq('initial NaN converted to zero', 0, new type([NaN])[0]); |
+ for (var i = 0; i < array.length; ++i) |
+ assertEq('NaN converted to zero by setter', 0, results[i]); |
+ } |
+ |
+ pass(); |
+ } catch (e) { |
+ fail(e); |
+ } |
+} |
+ |
+// |
+// Test driver |
+// |
+ |
+function runTests() { |
+ allPassed = true; |
+ |
+ // The "name" attribute is a concession to browsers which don't |
+ // implement the "name" property on function objects |
+ var testCases = |
+ [ {name: "Float32Array", |
+ unsigned: false, |
+ integral: false, |
+ elementSizeInBytes: 4, |
+ testValues: [ -500.5, 500.5 ], |
+ expectedValues: [ -500.5, 500.5 ] |
+ }, |
+ {name: "Float64Array", |
+ unsigned: false, |
+ integral: false, |
+ elementSizeInBytes: 8, |
+ testValues: [ -500.5, 500.5 ], |
+ expectedValues: [ -500.5, 500.5 ] |
+ }, |
+ {name: "Int8Array", |
+ unsigned: false, |
+ integral: true, |
+ elementSizeInBytes: 1, |
+ testValues: [ -128, 127, -129, 128 ], |
+ expectedValues: [ -128, 127, 127, -128 ] |
+ }, |
+ {name: "Int16Array", |
+ unsigned: false, |
+ integral: true, |
+ elementSizeInBytes: 2, |
+ testValues: [ -32768, 32767, -32769, 32768 ], |
+ expectedValues: [ -32768, 32767, 32767, -32768 ] |
+ }, |
+ {name: "Int32Array", |
+ unsigned: false, |
+ integral: true, |
+ elementSizeInBytes: 4, |
+ testValues: [ -2147483648, 2147483647, -2147483649, 2147483648 ], |
+ expectedValues: [ -2147483648, 2147483647, 2147483647, -2147483648 ] |
+ }, |
+ {name: "Uint8Array", |
+ unsigned: true, |
+ integral: true, |
+ elementSizeInBytes: 1, |
+ testValues: [ 0, 255, -1, 256 ], |
+ expectedValues: [ 0, 255, 255, 0 ] |
+ }, |
+ {name: "Uint16Array", |
+ unsigned: true, |
+ integral: true, |
+ elementSizeInBytes: 2, |
+ testValues: [ 0, 65535, -1, 65536 ], |
+ expectedValues: [ 0, 65535, 65535, 0 ] |
+ }, |
+ {name: "Uint32Array", |
+ unsigned: true, |
+ integral: true, |
+ elementSizeInBytes: 4, |
+ testValues: [ 0, 4294967295, -1, 4294967296 ], |
+ expectedValues: [ 0, 4294967295, 4294967295, 0 ] |
+ } |
+ ]; |
+ for (var i = 0; i < testCases.length; i++) { |
+ var testCase = testCases[i]; |
+ running(testCase.name); |
+ if (!(testCase.name in window)) { |
+ fail("does not exist"); |
+ continue; |
+ } |
+ var type = window[testCase.name]; |
+ var name = testCase.name; |
+ if (testCase.unsigned) { |
+ testSetAndGet10To1(type, name); |
+ testConstructWithArrayOfUnsignedValues(type, name); |
+ testConstructWithTypedArrayOfUnsignedValues(type, name); |
+ } else { |
+ testSetAndGetPos10ToNeg10(type, name); |
+ testConstructWithArrayOfSignedValues(type, name); |
+ testConstructWithTypedArrayOfSignedValues(type, name); |
+ } |
+ if (testCase.integral) { |
+ testIntegralArrayTruncationBehavior(type, name, testCase.unsigned); |
+ } |
+ testGetWithOutOfRangeIndices(type, name); |
+ testOffsetsAndSizes(type, name, testCase.elementSizeInBytes); |
+ testSetFromTypedArray(type, name); |
+ negativeTestSetFromTypedArray(type, name); |
+ testSetFromArray(type, name); |
+ negativeTestSetFromArray(type, name); |
+ testSubarray(type, name); |
+ negativeTestSubarray(type, name); |
+ testSetBoundaryConditions(type, |
+ name, |
+ testCase.testValues, |
+ testCase.expectedValues); |
+ testConstructionBoundaryConditions(type, |
+ name, |
+ testCase.testValues, |
+ testCase.expectedValues); |
+ testConstructionWithNullBuffer(type, name); |
+ testConstructionWithOutOfRangeValues(type, name); |
+ testConstructionWithNegativeOutOfRangeValues(type, name); |
+ testConstructionWithUnalignedOffset(type, name, testCase.elementSizeInBytes); |
+ testConstructionWithUnalignedLength(type, name, testCase.elementSizeInBytes); |
+ testConstructionOfHugeArray(type, name, testCase.elementSizeInBytes); |
+ testConstructionWithBothArrayBufferAndLength(type, name, testCase.elementSizeInBytes); |
+ testConstructionWithSubPortionOfArrayBuffer(type, name, testCase.elementSizeInBytes); |
+ testSubarrayWithOutOfRangeValues(type, name, testCase.elementSizeInBytes); |
+ testSubarrayWithDefaultValues(type, name, testCase.elementSizeInBytes); |
+ testSettingFromArrayWithOutOfRangeOffset(type, name); |
+ testSettingFromFakeArrayWithOutOfRangeLength(type, name); |
+ testSettingFromTypedArrayWithOutOfRangeOffset(type, name); |
+ negativeTestGetAndSetMethods(type, name); |
+ testNaNConversion(type, name); |
+ } |
+ |
+ printSummary(); |
+} |
+ |
+runTests(); |
+successfullyParsed = true; |
+ |
+</script> |
+<script src="../../resources/js-test-post.js"></script> |
+ |
+</body> |
+</html> |
Property changes on: conformance/typedarrays/array-unit-tests.html |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |