| <!DOCTYPE html> |
| <script src="../resources/testharness.js"></script> |
| <script src="../resources/testharnessreport.js"></script> |
| <script> |
| function createIterable(iterations) { |
| return { |
| [Symbol.iterator]() { |
| var i = 0; |
| return {next: () => iterations[i++]}; |
| }, |
| }; |
| } |
| |
| test(() => { |
| let sequenceTest = internals.sequenceTest(); |
| |
| assert_throws(new TypeError, () => { sequenceTest.identityLongSequence(null) }, |
| "Converting null to sequence must throw a type error"); |
| assert_throws(new TypeError, () => { sequenceTest.identityLongSequence(undefined) }, |
| "Converting undefined to sequence must throw a type error"); |
| assert_equals(sequenceTest.identityOctetSequenceOrNull(null), null, |
| "Converting null to a nullable sequence works"); |
| assert_equals(sequenceTest.identityOctetSequenceOrNull(undefined), null, |
| "Converting undefined to a nullable sequence works"); |
| }, "null and undefined conversions"); |
| |
| test(() => { |
| let sequenceTest = internals.sequenceTest(); |
| |
| let emptyArray = []; |
| let emptyObject = createIterable([{done: true}]); |
| |
| let convertedArray = sequenceTest.identityLongSequence(emptyArray); |
| assert_array_equals(convertedArray, [], "Empty array produces an empty vector"); |
| let convertedObject = sequenceTest.identityLongSequence(emptyObject); |
| assert_array_equals(convertedObject, [], "Empty object produces an empty vector"); |
| }, "Empty sequences"); |
| |
| test(() => { |
| let sequenceTest = internals.sequenceTest(); |
| |
| let obj = createIterable([ |
| { done: false, value: 34 }, |
| { done: false, value: 42 }, |
| { done: true } |
| ]); |
| let convertedObj = sequenceTest.identityLongSequence(obj); |
| assert_array_equals(convertedObj, [34, 42], |
| "'done: true' does not need a value property"); |
| |
| obj = createIterable([ |
| { done: false, value: 34 }, |
| { done: false, value: 42 }, |
| { done: true, value: 88 } |
| ]); |
| convertedObj = sequenceTest.identityLongSequence(obj); |
| assert_array_equals(convertedObj, [34, 42], |
| "'value' is ignored when 'done' is true"); |
| |
| obj = createIterable([ |
| { done: 0, value: 42 }, |
| { done: 1, value: 34 } |
| ]); |
| convertedObj = sequenceTest.identityDoubleSequence(obj); |
| assert_array_equals(convertedObj, [42], |
| "'done' is always converted to a boolean"); |
| }, "Iterator stop values"); |
| |
| test(() => { |
| let sequenceTest = internals.sequenceTest(); |
| |
| let array = [1, 2]; |
| let convertedArray = sequenceTest.identityDoubleSequence(array); |
| assert_not_equals(array, convertedArray); |
| convertedArray.push(42); |
| let convertedArray2 = sequenceTest.identityDoubleSequence(array); |
| assert_equals(array.length, 2); |
| assert_not_equals(convertedArray, convertedArray2); |
| assert_array_equals(convertedArray2, [1, 2]); |
| }, "Sequences are passed by value"); |
| |
| test(() => { |
| let sequenceTest = internals.sequenceTest(); |
| |
| let longArray = ['not', 'a', 'long']; |
| longArray[5] = 42; |
| let convertedLongArray = sequenceTest.identityLongSequence(longArray); |
| assert_array_equals(convertedLongArray, [0, 0, 0, 0, 0, 42], |
| "Long array with gaps correctly produces a vector"); |
| |
| let doubleArray = [34, 42.5]; |
| doubleArray[9] = 2; // The elements inbetween are all undefined. |
| assert_throws(new TypeError, () => { sequenceTest.identityDoubleSequence(doubleArray) }, |
| "Converting an undefined value to double throws a TypeError and " + |
| "causes the sequence -> C++ conversion to fail"); |
| |
| let byteStringSequenceSequence = [ |
| ["foo"], |
| ["bar"] |
| ]; |
| byteStringSequenceSequence[7] = ["baz"]; |
| assert_throws(new TypeError, () => { |
| sequenceTest.identityByteStringSequenceSequence(byteStringSequenceSequence); |
| }, "Converting an undefined to a sequence<> throws a TypeError and causes the " + |
| "entire conversion to fail"); |
| }, "Arrays with gaps in the elements"); |
| |
| test(() => { |
| let sequenceTest = internals.sequenceTest(); |
| |
| assert_throws(new TypeError, () => { sequenceTest.identityLongSequence({}) }, |
| "Objects without Symbol.iterator cannot be converted"); |
| |
| let obj = { |
| [Symbol.iterator]: 42 |
| }; |
| assert_throws(new TypeError, () => { sequenceTest.identityLongSequence(obj) }, |
| "Symbol.iterator must be callable"); |
| |
| obj = { |
| [Symbol.iterator]() { |
| return 42; |
| } |
| } |
| assert_throws(new TypeError, () => { sequenceTest.identityLongSequence(obj) }, |
| "Symbol.iterator must return an object"); |
| |
| obj = { |
| [Symbol.iterator]() { |
| return {} |
| } |
| } |
| assert_throws(new TypeError, () => { sequenceTest.identityLongSequence(obj) }, |
| "Symbol.iterator must return an object with a 'next' callable"); |
| |
| obj = { |
| [Symbol.iterator]() { |
| return {'next': 42} |
| } |
| } |
| assert_throws(new TypeError, () => { sequenceTest.identityLongSequence(obj) }, |
| "Symbol.iterator must return an object with a 'next' callable"); |
| |
| obj = { |
| [Symbol.iterator]() { |
| return {'next': () => { return 42 }} |
| } |
| } |
| assert_throws(new TypeError, () => { sequenceTest.identityLongSequence(obj) }, |
| "'next' must return an object"); |
| }, "Invalid iterable protocols"); |
| |
| test(() => { |
| let sequenceTest = internals.sequenceTest(); |
| |
| assert_false(sequenceTest.unionReceivedSequence(42), |
| "Passing a double should convert the union to double"); |
| assert_false(sequenceTest.unionReceivedSequence(true), |
| "Passing a boolean should convert the union to double"); |
| assert_true(sequenceTest.unionReceivedSequence([]), |
| "Passing an empty array should convert the union to a sequence"); |
| assert_true(sequenceTest.unionReceivedSequence([34, 42]), |
| "Passing an array should convert the union to a sequence"); |
| let obj = createIterable([{done: false, value: 99}, |
| {done: false, value: -3.14}, |
| {done: true}]); |
| assert_true(sequenceTest.unionReceivedSequence(obj), |
| "Passing an iterable object should convert the union to a sequence"); |
| }, "Sequences in unions"); |
| |
| test(() => { |
| let sequenceTest = internals.sequenceTest(); |
| |
| let foods = ["Sushi", "Beer"]; |
| assert_throws(new TypeError, () => { sequenceTest.identityFoodEnumSequence(foods) }, |
| "Invalid enum type must throw a type error"); |
| |
| foods = createIterable([{done: false, value: "Spaghetti"}, |
| {done: false, value: "Bread"}, |
| {done: true}]); |
| assert_array_equals(sequenceTest.identityFoodEnumSequence(foods), |
| ["Spaghetti", "Bread"]); |
| }, "Enum sequences"); |
| |
| test(() => { |
| let sequenceTest = internals.sequenceTest(); |
| |
| let sequenceCreationFunctions = [ |
| (elem) => { return [elem] }, |
| (elem) => { return createIterable([{done: false, value: elem}, |
| {done: true}]) } |
| ]; |
| for (sequenceCreationFunction of sequenceCreationFunctions) { |
| let elem = document.createElement('p'); |
| sequenceTest.setElementSequence(sequenceCreationFunction(elem)); |
| assert_array_equals(sequenceTest.getElementSequence(), [elem], |
| "The same DOM object was stored in the sequence"); |
| assert_not_equals(sequenceTest.getElementSequence()[0], |
| document.createElement('br'), |
| "The same DOM object was stored in the sequence"); |
| |
| elem = document.createElement('br'); |
| assert_not_equals(sequenceTest.getElementSequence()[0], elem, |
| "Changing the original object does not change the sequence value"); |
| } |
| }, "Converting DOM object sequences"); |
| </script> |