]>
Commit | Line | Data |
---|---|---|
ed1e77d3 A |
1 | function shouldBe(actual, expected) { |
2 | if (actual !== expected) | |
3 | throw new Error('bad value: ' + actual); | |
4 | } | |
5 | ||
6 | function shouldThrow(func, message) { | |
7 | var error = null; | |
8 | try { | |
9 | func(); | |
10 | } catch (e) { | |
11 | error = e; | |
12 | } | |
13 | if (!error) | |
14 | throw new Error("not thrown."); | |
15 | if (String(error) !== message) | |
16 | throw new Error("bad error: " + String(error)); | |
17 | } | |
18 | ||
19 | var originalArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; | |
20 | ||
21 | var array = Array.from(originalArray.values()); | |
22 | shouldBe(array.length, originalArray.length); | |
23 | for (var i = 0; i < array.length; ++i) { | |
24 | shouldBe(array[i], originalArray[i]); | |
25 | } | |
26 | ||
27 | function createIterator(callback) { | |
28 | var array = [0,1,2,3,4,5]; | |
29 | var iterator = array[Symbol.iterator](); | |
30 | iterator.return = function () { | |
31 | iterator.returned = true; | |
32 | if (callback) | |
33 | return callback(this); | |
34 | return { done: true, value: undefined }; | |
35 | }; | |
36 | iterator.returned = false; | |
37 | return iterator; | |
38 | } | |
39 | ||
40 | var iterator = createIterator(); | |
41 | var result = Array.from(iterator); | |
42 | shouldBe(result.length, 6); | |
43 | for (var i = 0; i < 6; ++i) { | |
44 | shouldBe(result[i], i); | |
45 | } | |
46 | shouldBe(iterator.returned, false); | |
47 | ||
48 | // mapFn raises an error. | |
49 | var iterator = createIterator(); | |
50 | shouldThrow(function () { | |
51 | var result = Array.from(iterator, function () { | |
52 | throw new Error('map func'); | |
53 | }); | |
54 | }, "Error: map func"); | |
55 | shouldBe(iterator.returned, true); | |
56 | ||
57 | // mapFn raises an error and iterator.return also raises an error. | |
58 | var iterator = createIterator(function () { | |
59 | throw new Error('iterator.return'); | |
60 | }); | |
61 | ||
62 | // An error raised in iterator.return is discarded. | |
63 | shouldThrow(function () { | |
64 | var result = Array.from(iterator, function () { | |
65 | throw new Error('map func'); | |
66 | }); | |
67 | }, "Error: map func"); | |
68 | shouldBe(iterator.returned, true); | |
69 | ||
70 | // iterable[Symbol.iterator] is not a function. | |
71 | shouldThrow(function () { | |
72 | var iterator = [].values(); | |
73 | iterator[Symbol.iterator] = {}; | |
74 | Array.from(iterator); | |
75 | }, "TypeError: Array.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function"); | |
76 | ||
77 | // iterable[Symbol.iterator] raises an error. | |
78 | shouldThrow(function () { | |
79 | var iterable = []; | |
80 | iterable[Symbol.iterator] = function () { | |
81 | throw new Error("iterator"); | |
82 | }; | |
83 | Array.from(iterable); | |
84 | }, "Error: iterator"); | |
85 | ||
86 | // iterable[Symbol.iterator] lookup is only once. | |
87 | (function () { | |
88 | var iterable = [0, 1, 2, 3, 4, 5]; | |
89 | var count = 0; | |
90 | var iteratorCallCount = 0; | |
91 | Object.defineProperty(iterable, Symbol.iterator, { | |
92 | get() { | |
93 | ++count; | |
94 | return function () { | |
95 | ++iteratorCallCount; | |
96 | return this.values(); | |
97 | }; | |
98 | } | |
99 | }); | |
100 | var generated = Array.from(iterable); | |
101 | shouldBe(generated.length, iterable.length); | |
102 | for (var i = 0; i < iterable.length; ++i) { | |
103 | shouldBe(generated[i], iterable[i]); | |
104 | } | |
105 | shouldBe(count, 1); | |
106 | shouldBe(iteratorCallCount, 1); | |
107 | }()); | |
108 | ||
109 | // The Symbol.iterator method of the iterator generated by iterable[Symbol.iterator] is not looked up. | |
110 | (function () { | |
111 | var iterable = [0, 1, 2, 3, 4, 5]; | |
112 | var count = 0; | |
113 | iterable[Symbol.iterator] = function () { | |
114 | ++count; | |
115 | var iterator = this.values(); | |
116 | Object.defineProperty(iterator, Symbol.iterator, { | |
117 | get() { | |
118 | throw new Error('iterator[@@iterator] is touched'); | |
119 | } | |
120 | }); | |
121 | return iterator; | |
122 | }; | |
123 | var generated = Array.from(iterable); | |
124 | shouldBe(generated.length, iterable.length); | |
125 | for (var i = 0; i < iterable.length; ++i) { | |
126 | shouldBe(generated[i], iterable[i]); | |
127 | } | |
128 | shouldBe(count, 1); | |
129 | }()); |