Add tests for resizable array buffer views

Covers spec compliance issues in at least one of JSC, V8, or SM.
This commit is contained in:
André Bargull 2024-02-07 13:31:10 +01:00 committed by Philip Chimento
parent 634933a489
commit 71f95c29bd
20 changed files with 883 additions and 0 deletions

View File

@ -0,0 +1,44 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-dataview-buffer-byteoffset-bytelength
description: >
The byteOffset argument is validated against the initial buffer length.
info: |
DataView ( buffer [ , byteOffset [ , byteLength ] ] )
...
3. Let offset be ? ToIndex(byteOffset).
...
5. Let bufferByteLength be ArrayBufferByteLength(buffer, seq-cst).
6. If offset > bufferByteLength, throw a RangeError exception.
...
10. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%DataView.prototype%",
« [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] »).
...
OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )
...
2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto).
...
features: [Reflect.construct]
---*/
let newTarget = Object.defineProperty(function(){}.bind(), "prototype", {
get() {
throw new Test262Error("GetPrototypeFromConstructor not executed");
}
});
// Zero length buffer.
let ab = new ArrayBuffer(0);
// Byte offset is larger than the buffer length, which is zero.
let byteOffset = 10;
assert.throws(RangeError, () => {
Reflect.construct(DataView, [ab, byteOffset], newTarget);
});

View File

@ -0,0 +1,37 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.from
description: >
Mapper function detaches result typed array.
info: |
%TypedArray%.from ( source [ , mapfn [ , thisArg ] ] )
...
12. Repeat, while k < len,
...
c. If mapping is true, then
i. Let mappedValue be ? Call(mapfn, thisArg, « kValue, 𝔽(k) »).
...
e. Perform ? Set(targetObj, Pk, mappedValue, true).
...
includes: [detachArrayBuffer.js]
features: [TypedArray]
---*/
let ab = new ArrayBuffer(3);
let target = new Int8Array(ab);
let values = [0, 1, 2];
let result = Int32Array.from.call(function() {
return target;
}, values, v => {
if (v === 1) {
$DETACHBUFFER(ab);
}
return v + 10;
});
assert.sameValue(result, target);
assert.sameValue(result.length, 0);

View File

@ -0,0 +1,37 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.from
description: >
Mapper function makes result typed array out-of-bounds.
info: |
%TypedArray%.from ( source [ , mapfn [ , thisArg ] ] )
...
12. Repeat, while k < len,
...
c. If mapping is true, then
i. Let mappedValue be ? Call(mapfn, thisArg, « kValue, 𝔽(k) »).
...
e. Perform ? Set(targetObj, Pk, mappedValue, true).
...
features: [TypedArray, resizable-arraybuffer]
---*/
let rab = new ArrayBuffer(3, {maxByteLength: 5});
let target = new Int8Array(rab);
let values = [0, 1, 2];
let result = Int32Array.from.call(function() {
return target;
}, values, v => {
if (v === 1) {
rab.resize(1);
}
return v + 10;
});
assert.sameValue(result, target);
assert.sameValue(result.length, 1);
assert.sameValue(result[0], 10);

View File

@ -0,0 +1,37 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.from
description: >
Mapper function detaches result typed array.
info: |
%TypedArray%.from ( source [ , mapfn [ , thisArg ] ] )
...
12. Repeat, while k < len,
...
c. If mapping is true, then
i. Let mappedValue be ? Call(mapfn, thisArg, « kValue, 𝔽(k) »).
...
e. Perform ? Set(targetObj, Pk, mappedValue, true).
...
includes: [detachArrayBuffer.js]
features: [TypedArray]
---*/
let ab = new ArrayBuffer(3);
let target = new Int8Array(ab);
target.set([0, 1, 2]);
let result = Int32Array.from.call(function() {
return target;
}, target, v => {
if (v === 1) {
$DETACHBUFFER(ab);
}
return v + 10;
});
assert.sameValue(result, target);
assert.sameValue(result.length, 0);

View File

@ -0,0 +1,37 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.from
description: >
Mapper function makes result typed array out-of-bounds.
info: |
%TypedArray%.from ( source [ , mapfn [ , thisArg ] ] )
...
12. Repeat, while k < len,
...
c. If mapping is true, then
i. Let mappedValue be ? Call(mapfn, thisArg, « kValue, 𝔽(k) »).
...
e. Perform ? Set(targetObj, Pk, mappedValue, true).
...
features: [TypedArray, resizable-arraybuffer]
---*/
let rab = new ArrayBuffer(3, {maxByteLength: 5});
let target = new Int8Array(rab);
target.set([0, 1, 2]);
let result = Int32Array.from.call(function() {
return target;
}, target, v => {
if (v === 1) {
rab.resize(1);
}
return v + 10;
});
assert.sameValue(result, target);
assert.sameValue(result.length, 1);
assert.sameValue(result[0], 10);

View File

@ -0,0 +1,37 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.from
description: >
Mapper function detaches result typed array.
info: |
%TypedArray%.from ( source [ , mapfn [ , thisArg ] ] )
...
12. Repeat, while k < len,
...
c. If mapping is true, then
i. Let mappedValue be ? Call(mapfn, thisArg, « kValue, 𝔽(k) »).
...
e. Perform ? Set(targetObj, Pk, mappedValue, true).
...
includes: [detachArrayBuffer.js]
features: [TypedArray]
---*/
let ab = new ArrayBuffer(3);
let target = new Int8Array(ab);
let values = new Int8Array([0, 1, 2]);
let result = Int32Array.from.call(function() {
return target;
}, values, v => {
if (v === 1) {
$DETACHBUFFER(ab);
}
return v + 10;
});
assert.sameValue(result, target);
assert.sameValue(result.length, 0);

View File

@ -0,0 +1,37 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.from
description: >
Mapper function makes result typed array out-of-bounds.
info: |
%TypedArray%.from ( source [ , mapfn [ , thisArg ] ] )
...
12. Repeat, while k < len,
...
c. If mapping is true, then
i. Let mappedValue be ? Call(mapfn, thisArg, « kValue, 𝔽(k) »).
...
e. Perform ? Set(targetObj, Pk, mappedValue, true).
...
features: [TypedArray, resizable-arraybuffer]
---*/
let rab = new ArrayBuffer(3, {maxByteLength: 5});
let target = new Int8Array(rab);
let values = new Int8Array([0, 1, 2]);
let result = Int32Array.from.call(function() {
return target;
}, values, v => {
if (v === 1) {
rab.resize(1);
}
return v + 10;
});
assert.sameValue(result, target);
assert.sameValue(result.length, 1);
assert.sameValue(result[0], 10);

View File

@ -0,0 +1,37 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.from
description: >
Modifications to input array after iteration are handled correctly.
info: |
%TypedArray%.from ( source [ , mapfn [ , thisArg ] ] )
...
6. If usingIterator is not undefined, then
a. Let values be ? IteratorToList(? GetIteratorFromMethod(source, usingIterator)).
b. Let len be the number of elements in values.
...
e. Repeat, while k < len,
...
vi. Perform ? Set(targetObj, Pk, mappedValue, true).
...
features: [TypedArray]
---*/
let values = [0, {
valueOf() {
// Removes all array elements. Caller must have saved all elements.
values.length = 0;
return 100;
}
}, 2];
// `from` called with array which uses the built-in array iterator.
let ta = Int32Array.from(values);
assert.sameValue(ta.length, 3);
assert.sameValue(ta[0], 0);
assert.sameValue(ta[1], 100);
assert.sameValue(ta[2], 2);

View File

@ -0,0 +1,57 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.of
description: >
Performs Set operation which ignores out-of-bounds indices.
info: |
%TypedArray%.of ( ...items )
...
6. Repeat, while k < len,
...
c. Perform ? Set(newObj, Pk, kValue, true).
...
features: [TypedArray, resizable-arraybuffer]
---*/
let rab = new ArrayBuffer(3, {maxByteLength: 4});
let ta = new Int8Array(rab);
let one = {
valueOf() {
// Shrink buffer. Assignment to `ta[0]` should be ignored.
rab.resize(0);
return 1;
}
};
let two = {
valueOf() {
// Grow buffer. All following assignment should succeed.
rab.resize(4);
return 2;
}
};
// Typed array is correctly zero initialised.
assert.sameValue(ta.length, 3);
assert.sameValue(ta[0], 0);
assert.sameValue(ta[1], 0);
assert.sameValue(ta[2], 0);
let result = Int8Array.of.call(function() {
return ta;
}, one, two, 3);
// Correct result value.
assert.sameValue(result, ta);
// Values are correctly set.
assert.sameValue(ta.length, 4);
assert.sameValue(ta[0], 0);
assert.sameValue(ta[1], 2);
assert.sameValue(ta[2], 3);
assert.sameValue(ta[3], 0);

View File

@ -0,0 +1,51 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.prototype.fill
description: >
Absent start and end parameters are computed from initial length.
info: |
%TypedArray%.prototype.fill ( value [ , start [ , end ] ] )
...
2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
3. Let len be TypedArrayLength(taRecord).
...
5. Otherwise, set value to ? ToNumber(value).
6. Let relativeStart be ? ToIntegerOrInfinity(start).
...
9. Else, let startIndex be min(relativeStart, len).
10. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
...
13. Else, let endIndex be min(relativeEnd, len).
...
features: [TypedArray, resizable-arraybuffer]
---*/
let rab = new ArrayBuffer(1, {maxByteLength: 4});
let ta = new Int8Array(rab);
let value = {
valueOf() {
// Set buffer to maximum byte length.
rab.resize(4);
// Return the fill value.
return 123;
}
};
// Ensure typed array is correctly initialised.
assert.sameValue(ta.length, 1);
assert.sameValue(ta[0], 0);
ta.fill(value);
// Ensure typed array has correct length and only the first element was filled.
assert.sameValue(ta.length, 4);
assert.sameValue(ta[0], 123);
assert.sameValue(ta[1], 0);
assert.sameValue(ta[2], 0);
assert.sameValue(ta[3], 0);

View File

@ -0,0 +1,51 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.prototype.includes
description: >
Index is compared against the initial length when typed array is made out-of-bounds.
info: |
%TypedArray%.prototype.includes ( searchElement [ , fromIndex ] )
...
2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
3. Let len be TypedArrayLength(taRecord).
...
5. Let n be ? ToIntegerOrInfinity(fromIndex).
...
9. If n 0, then
a. Let k be n.
...
11. Repeat, while k < len,
...
features: [TypedArray, resizable-arraybuffer]
---*/
let rab = new ArrayBuffer(4, {maxByteLength: 20});
// Uses byteOffset to make typed array out-of-bounds when shrinking size to zero.
let byteOffset = 1;
let ta = new Int8Array(rab, byteOffset);
let index = {
valueOf() {
// Shrink buffer to zero.
rab.resize(0);
// Index is larger than the initial length.
return 10;
}
};
// Typed array is in-bounds.
assert.sameValue(ta.length, 3);
let result = ta.includes(undefined, index);
// Typed array is out-of-bounds.
assert.sameValue(ta.length, 0);
assert.sameValue(result, false);

View File

@ -0,0 +1,47 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.prototype.includes
description: >
Index is compared against the initial length.
info: |
%TypedArray%.prototype.includes ( searchElement [ , fromIndex ] )
...
2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
3. Let len be TypedArrayLength(taRecord).
...
5. Let n be ? ToIntegerOrInfinity(fromIndex).
...
9. If n 0, then
a. Let k be n.
...
11. Repeat, while k < len,
...
features: [TypedArray, resizable-arraybuffer]
---*/
let rab = new ArrayBuffer(4, {maxByteLength: 20});
let ta = new Int8Array(rab);
let index = {
valueOf() {
// Shrink buffer to zero.
rab.resize(0);
// Index is larger than the initial length.
return 10;
}
};
// Auto-length is correctly tracked.
assert.sameValue(ta.length, 4);
let result = ta.includes(undefined, index);
// Auto-length is correctly set to zero.
assert.sameValue(ta.length, 0);
assert.sameValue(result, false);

View File

@ -0,0 +1,39 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.prototype.join
description: >
ToString is called once when the array is resized.
info: |
%TypedArray%.prototype.join ( separator )
...
2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
3. Let len be TypedArrayLength(taRecord).
...
5. Else, let sep be ? ToString(separator).
...
features: [TypedArray, resizable-arraybuffer]
---*/
let rab = new ArrayBuffer(3, {maxByteLength: 5});
let ta = new Int8Array(rab);
let callCount = 0;
let index = {
toString() {
callCount++;
rab.resize(0);
return "-";
}
};
assert.sameValue(callCount, 0);
let r = ta.join(index);
assert.sameValue(callCount, 1);
assert.sameValue(r, "--");

View File

@ -0,0 +1,49 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.prototype.subarray
description: >
Result has correct the byteOffset when input is initially out-of-bounds.
info: |
%TypedArray%.prototype.subarray ( start, end )
...
13. Let srcByteOffset be O.[[ByteOffset]].
14. Let beginByteOffset be srcByteOffset + (startIndex × elementSize).
15. If O.[[ArrayLength]] is auto and end is undefined, then
a. Let argumentsList be « buffer, 𝔽(beginByteOffset) ».
16.
...
e. Let newLength be max(endIndex - startIndex, 0).
f. Let argumentsList be « buffer, 𝔽(beginByteOffset), 𝔽(newLength) ».
17. Return ? TypedArraySpeciesCreate(O, argumentsList).
features: [TypedArray, resizable-arraybuffer]
---*/
let rab = new ArrayBuffer(10, {maxByteLength: 10});
let autoLength = new Int8Array(rab, 4);
let withLength = new Int8Array(rab, 4, 2);
let start = {
valueOf() {
// Make |autoLength| and |withLength| in-bounds again.
rab.resize(10);
return 1;
}
};
// Make |autoLength| out-of-bounds.
rab.resize(0);
let resultAutoLength = autoLength.subarray(start);
assert.sameValue(resultAutoLength.byteOffset, 4);
assert.sameValue(resultAutoLength.length, 6);
// Make |withLength| out-of-bounds.
rab.resize(0);
let resultWithLength = withLength.subarray(start);
assert.sameValue(resultWithLength.byteOffset, 4);
assert.sameValue(resultWithLength.length, 0);

View File

@ -0,0 +1,55 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.prototype.values
description: >
Iterator is still exhausted when typedarray is changed to in-bounds.
features: [TypedArray, resizable-arraybuffer]
---*/
let rab = new ArrayBuffer(3, {maxByteLength: 5});
let ta = new Int8Array(rab);
// Ensure the TypedArray is correctly initialised.
assert.sameValue(ta.length, 3);
assert.sameValue(ta.byteOffset, 0);
ta[0] = 11;
ta[1] = 22;
ta[2] = 33;
let it = ta.values();
let r;
// Fetch the first value.
r = it.next();
assert.sameValue(r.done, false);
assert.sameValue(r.value, 11);
// Resize buffer to zero.
rab.resize(0);
// TypedArray is now out-of-bounds.
assert.sameValue(ta.length, 0);
assert.sameValue(ta.byteOffset, 0);
// Resize buffer to zero.
rab.resize(0);
// Attempt to fetch the next value. This exhausts the iterator.
r = it.next();
assert.sameValue(r.done, true);
assert.sameValue(r.value, undefined);
// Resize buffer so the typed array is again in-bounds.
rab.resize(5);
// TypedArray is now in-bounds.
assert.sameValue(ta.length, 5);
assert.sameValue(ta.byteOffset, 0);
// Attempt to fetch another value from an already exhausted iterator.
r = it.next();
assert.sameValue(r.done, true);
assert.sameValue(r.value, undefined);

View File

@ -0,0 +1,49 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.prototype.values
description: >
Calling next on an out-of-bounds typedarray throws no error when iterator exhausted.
features: [TypedArray, resizable-arraybuffer]
---*/
let rab = new ArrayBuffer(3, {maxByteLength: 5});
let ta = new Int8Array(rab, 1);
// Ensure the TypedArray is correctly initialised.
assert.sameValue(ta.length, 2);
assert.sameValue(ta.byteOffset, 1);
ta[0] = 11;
ta[1] = 22;
let it = ta.values();
let r;
// Fetch the first value.
r = it.next();
assert.sameValue(r.done, false);
assert.sameValue(r.value, 11);
// Fetch the second value.
r = it.next();
assert.sameValue(r.done, false);
assert.sameValue(r.value, 22);
// Iterator is now exhausted.
r = it.next();
assert.sameValue(r.done, true);
assert.sameValue(r.value, undefined);
// Resize buffer to zero.
rab.resize(0);
// TypedArray is now out-of-bounds.
assert.sameValue(ta.length, 0);
assert.sameValue(ta.byteOffset, 0);
// Calling next doesn't throw an error.
r = it.next();
assert.sameValue(r.done, true);
assert.sameValue(r.value, undefined);

View File

@ -0,0 +1,53 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-%typedarray%.prototype.with
description: >
The index is validated against the current length.
info: |
%TypedArray%.prototype.with ( index, value )
...
8. Else, let numericValue be ? ToNumber(value).
9. If IsValidIntegerIndex(O, 𝔽(actualIndex)) is false, throw a RangeError exception.
...
features: [TypedArray, resizable-arraybuffer]
---*/
let rab = new ArrayBuffer(2, {maxByteLength: 5});
let ta = new Int8Array(rab);
ta[0] = 11;
ta[1] = 22;
// Ensure typed array is correctly initialised.
assert.sameValue(ta.length, 2);
assert.sameValue(ta[0], 11);
assert.sameValue(ta[1], 22);
// Index is initially out-of-bounds.
let index = 4;
let value = {
valueOf() {
rab.resize(5);
return 123;
}
};
let result = ta.with(index, value);
// Typed array has been resized.
assert.sameValue(ta.length, 5);
assert.sameValue(ta[0], 11);
assert.sameValue(ta[1], 22);
assert.sameValue(ta[2], 0);
assert.sameValue(ta[3], 0);
assert.sameValue(ta[4], 0);
// Result is correctly initialised.
assert.sameValue(result.length, 2);
assert.sameValue(result[0], 11);
assert.sameValue(result[1], 22);

View File

@ -0,0 +1,43 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-typedarray
description: >
Modifications to input array after iteration are handled correctly.
info: |
TypedArray ( ...args )
...
6. Else,
...
b. If firstArgument is an Object, then
...
iv. Else,
...
2. Let usingIterator be ? GetMethod(firstArgument, @@iterator).
3. If usingIterator is not undefined, then
a. Let values be ? IteratorToList(? GetIteratorFromMethod(firstArgument, usingIterator)).
b. Perform ? InitializeTypedArrayFromList(O, values).
...
includes: [testTypedArray.js]
features: [TypedArray]
---*/
testWithTypedArrayConstructors(function(TypedArray) {
let values = [0, {
valueOf() {
// Removes all array elements. Caller must have saved all elements.
values.length = 0;
return 100;
}
}, 2];
// Constructor called with array which uses the built-in array iterator.
var ta = new TypedArray(values);
assert.sameValue(ta.length, 3);
assert.sameValue(ta[0], 0);
assert.sameValue(ta[1], 100);
assert.sameValue(ta[2], 2);
});

View File

@ -0,0 +1,49 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-typedarray
description: >
Modifications to input array after iteration are handled correctly.
info: |
TypedArray ( ...args )
...
6. Else,
...
b. If firstArgument is an Object, then
...
iv. Else,
...
2. Let usingIterator be ? GetMethod(firstArgument, @@iterator).
3. If usingIterator is not undefined, then
a. Let values be ? IteratorToList(? GetIteratorFromMethod(firstArgument, usingIterator)).
b. Perform ? InitializeTypedArrayFromList(O, values).
...
includes: [testTypedArray.js]
features: [TypedArray]
---*/
let ArrayIteratorPrototype = Object.getPrototypeOf([].values());
let values;
// Modify the built-in ArrayIteratorPrototype `next` method.
ArrayIteratorPrototype.next = function() {
let done = values.length === 0;
let value = values.pop();
return {value, done};
};
testWithTypedArrayConstructors(function(TypedArray) {
// Reset `values` array.
values = [1, 2, 3, 4];
// Constructor called with array which uses the modified array iterator.
var ta = new TypedArray([0]);
assert.sameValue(ta.length, 4);
assert.sameValue(ta[0], 4);
assert.sameValue(ta[1], 3);
assert.sameValue(ta[2], 2);
assert.sameValue(ta[3], 1);
});

View File

@ -0,0 +1,37 @@
// Copyright (C) 2024 André Bargull. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-typedarraysetelement
description: >
Index is validated after converting the right-hand side operand.
info: |
TypedArraySetElement ( O, index, value )
...
2. Otherwise, let numValue be ? ToNumber(value).
3. If IsValidIntegerIndex(O, index) is true, then
...
features: [TypedArray, resizable-arraybuffer]
---*/
let rab = new ArrayBuffer(0, {maxByteLength: 1});
let ta = new Int8Array(rab);
// Index is initially out-of-bounds.
let index = 0;
let value = {
valueOf() {
// Make `index` an in-bounds access.
rab.resize(1);
return 100;
}
};
assert.sameValue(ta.length, 0);
ta[index] = value;
assert.sameValue(ta.length, 1);
assert.sameValue(ta[0], 100);