| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <title>Sequence conversion</title> | |
| <link rel="help" href="https://heycam.github.io/webidl/#es-sequence"> | |
| <link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me"> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <canvas></canvas> | |
| <script> | |
| "use strict"; | |
| const canvas = document.querySelector("canvas"); | |
| const ctx = canvas.getContext("2d"); | |
| test(() => { | |
| ctx.setLineDash([1, 2]); | |
| assert_array_equals(ctx.getLineDash(), [1, 2]); | |
| }, "An array"); | |
| test(() => { | |
| function* generatorFunc() { | |
| yield 4; | |
| yield 5; | |
| } | |
| const generator = generatorFunc(); | |
| ctx.setLineDash(generator); | |
| assert_array_equals(ctx.getLineDash(), [4, 5]); | |
| }, "A generator"); | |
| test(() => { | |
| function* generatorFunc() { | |
| yield 6; | |
| yield 7; | |
| } | |
| let callCount = 0; | |
| const array = [1, 2]; | |
| Object.defineProperty(array, Symbol.iterator, { | |
| get() { | |
| ++callCount; | |
| return generatorFunc; | |
| } | |
| }); | |
| ctx.setLineDash(array); | |
| assert_array_equals(ctx.getLineDash(), [6, 7]); | |
| assert_equals(callCount, 1, "@@iterator must only have been gotten once"); | |
| }, "An array with an overridden Symbol.iterator"); | |
| test(t => { | |
| const originalIterator = Object.getOwnPropertyDescriptor(Array.prototype, Symbol.iterator); | |
| t.add_cleanup(() => { | |
| Object.defineProperty(Array.prototype, Symbol.iterator, originalIterator); | |
| }); | |
| function* generatorFunc() { | |
| yield 11; | |
| yield 12; | |
| } | |
| let callCount = 0; | |
| const array = [1, 2]; | |
| Object.defineProperty(Array.prototype, Symbol.iterator, { | |
| get() { | |
| ++callCount; | |
| return generatorFunc; | |
| } | |
| }); | |
| ctx.setLineDash(array); | |
| assert_array_equals(ctx.getLineDash(), [11, 12]); | |
| assert_equals(callCount, 1, "@@iterator must only have been gotten once"); | |
| }, "An array with an overridden Symbol.iterator on the prototype"); | |
| test(t => { | |
| const arrayIteratorPrototype = Object.getPrototypeOf(Array.prototype[Symbol.iterator]()); | |
| const nextBefore = arrayIteratorPrototype.next; | |
| t.add_cleanup(() => { | |
| arrayIteratorPrototype.next = nextBefore; | |
| }); | |
| let callCount = 0; | |
| arrayIteratorPrototype.next = () => { | |
| switch (callCount) { | |
| case 0: { | |
| ++callCount; | |
| return { done: false, value: 8 }; | |
| } | |
| case 1: { | |
| ++callCount; | |
| return { done: false, value: 9 }; | |
| } | |
| case 2: { | |
| ++callCount; | |
| return { done: true, value: 10 }; // value should be ignored this time | |
| } | |
| default: { | |
| assert_unreached("next() should be called three times exactly"); | |
| } | |
| } | |
| }; | |
| const array = [1, 2]; | |
| ctx.setLineDash(array); | |
| assert_array_equals(ctx.getLineDash(), [8, 9]); | |
| assert_equals(callCount, 3, "next() must have been called thrice"); | |
| }, "An array with an overridden %ArrayIterator%.prototype.next"); | |
| test(t => { | |
| t.add_cleanup(() => { | |
| delete Array.prototype[1]; | |
| }); | |
| Object.defineProperty(Array.prototype, "1", { | |
| configurable: true, | |
| enumerable: true, | |
| get() { | |
| return 14; | |
| } | |
| }); | |
| const array = [13, , 15, 16]; | |
| ctx.setLineDash(array); | |
| assert_array_equals(ctx.getLineDash(), [13, 14, 15, 16]); | |
| }, "A holey array with fallback to an accessor on the prototype"); | |
| </script> |