sequence-conversion.html (4006B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>Sequence conversion</title> 4 <link rel="help" href="https://webidl.spec.whatwg.org/#es-sequence"> 5 <link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me"> 6 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 10 <canvas></canvas> 11 12 <script> 13 "use strict"; 14 15 const canvas = document.querySelector("canvas"); 16 const ctx = canvas.getContext("2d"); 17 18 test(() => { 19 ctx.setLineDash([1, 2]); 20 assert_array_equals(ctx.getLineDash(), [1, 2]); 21 }, "An array"); 22 23 test(() => { 24 function* generatorFunc() { 25 yield 4; 26 yield 5; 27 } 28 const generator = generatorFunc(); 29 30 ctx.setLineDash(generator); 31 assert_array_equals(ctx.getLineDash(), [4, 5]); 32 }, "A generator"); 33 34 test(() => { 35 function* generatorFunc() { 36 yield 6; 37 yield 7; 38 } 39 40 let callCount = 0; 41 const array = [1, 2]; 42 Object.defineProperty(array, Symbol.iterator, { 43 get() { 44 ++callCount; 45 return generatorFunc; 46 } 47 }); 48 49 ctx.setLineDash(array); 50 assert_array_equals(ctx.getLineDash(), [6, 7]); 51 assert_equals(callCount, 1, "@@iterator must only have been gotten once"); 52 }, "An array with an overridden Symbol.iterator"); 53 54 test(t => { 55 function* generatorFunc() { 56 yield ["foo", "bar"]; 57 yield ["baz", "quux"]; 58 } 59 60 let callCount = 0; 61 const obj = {}; 62 Object.defineProperty(obj, Symbol.iterator, { 63 get() { 64 ++callCount; 65 return generatorFunc; 66 } 67 }); 68 69 const searchParams = new URLSearchParams(obj); 70 assert_equals(searchParams.get("foo"), "bar"); 71 assert_equals(searchParams.get("baz"), "quux"); 72 assert_equals(callCount, 1, "@@iterator must only have been gotten once"); 73 }, "An object with an overriden Symbol.iterator"); 74 75 test(t => { 76 const originalIterator = Object.getOwnPropertyDescriptor(Array.prototype, Symbol.iterator); 77 t.add_cleanup(() => { 78 Object.defineProperty(Array.prototype, Symbol.iterator, originalIterator); 79 }); 80 81 function* generatorFunc() { 82 yield 11; 83 yield 12; 84 } 85 86 let callCount = 0; 87 const array = [1, 2]; 88 Object.defineProperty(Array.prototype, Symbol.iterator, { 89 get() { 90 ++callCount; 91 return generatorFunc; 92 } 93 }); 94 95 ctx.setLineDash(array); 96 assert_array_equals(ctx.getLineDash(), [11, 12]); 97 assert_equals(callCount, 1, "@@iterator must only have been gotten once"); 98 }, "An array with an overridden Symbol.iterator on the prototype"); 99 100 test(t => { 101 const arrayIteratorPrototype = Object.getPrototypeOf(Array.prototype[Symbol.iterator]()); 102 const nextBefore = arrayIteratorPrototype.next; 103 t.add_cleanup(() => { 104 arrayIteratorPrototype.next = nextBefore; 105 }); 106 107 let callCount = 0; 108 arrayIteratorPrototype.next = () => { 109 switch (callCount) { 110 case 0: { 111 ++callCount; 112 return { done: false, value: 8 }; 113 } 114 case 1: { 115 ++callCount; 116 return { done: false, value: 9 }; 117 } 118 case 2: { 119 ++callCount; 120 return { done: true, value: 10 }; // value should be ignored this time 121 } 122 default: { 123 assert_unreached("next() should be called three times exactly"); 124 } 125 } 126 }; 127 128 const array = [1, 2]; 129 ctx.setLineDash(array); 130 assert_array_equals(ctx.getLineDash(), [8, 9]); 131 assert_equals(callCount, 3, "next() must have been called thrice"); 132 }, "An array with an overridden %ArrayIterator%.prototype.next"); 133 134 test(t => { 135 t.add_cleanup(() => { 136 delete Array.prototype[1]; 137 }); 138 139 Object.defineProperty(Array.prototype, "1", { 140 configurable: true, 141 enumerable: true, 142 get() { 143 return 14; 144 } 145 }); 146 147 const array = [13, , 15, 16]; 148 ctx.setLineDash(array); 149 assert_array_equals(ctx.getLineDash(), [13, 14, 15, 16]); 150 }, "A holey array with fallback to an accessor on the prototype"); 151 152 test(t => { 153 // Should fail rather than falling back to record 154 assert_throws_js(TypeError, function() { new URLSearchParams(["key", "value"]); }); 155 }, "A string array in sequence<sequence> or record"); 156 157 </script>