source: frontend/node_modules/es-iterator-helpers/test/Iterator.zip.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 12.1 KB
RevLine 
[9af201e]1'use strict';
2
3var defineProperties = require('define-properties');
4var test = require('tape');
5var callBind = require('call-bind');
6var functionsHaveNames = require('functions-have-names')();
7var forEach = require('for-each');
8var debug = require('object-inspect');
9var v = require('es-value-fixtures');
10var hasSymbols = require('has-symbols/shams')();
11var mockProperty = require('mock-property');
12
13var index = require('../Iterator.zip');
14var impl = require('../Iterator.zip/implementation');
15var from = require('../Iterator.from/polyfill')();
16
17var isEnumerable = Object.prototype.propertyIsEnumerable;
18
19var testIterator = require('./helpers/testIterator');
20
21module.exports = {
22 tests: function (zip, name, t) {
23 t['throws'](
24 function () { return new zip(); }, // eslint-disable-line new-cap
25 TypeError,
26 '`' + name + '` itself is not a constructor'
27 );
28 t['throws'](
29 function () { return new zip({}); }, // eslint-disable-line new-cap
30 TypeError,
31 '`' + name + '` itself is not a constructor, with an argument'
32 );
33
34 forEach(v.primitives.concat(v.objects), function (nonIterator) {
35 t['throws'](
36 function () { zip(nonIterator, []); },
37 TypeError,
38 debug(nonIterator) + ' is not an iterable Object'
39 );
40 });
41
42 t.test('actual iteration', { skip: !hasSymbols }, function (st) {
43 forEach(v.nonFunctions, function (nonFunction) {
44 if (nonFunction != null) {
45 var badIterable = {};
46 badIterable[Symbol.iterator] = nonFunction;
47 st['throws'](
48 function () { zip([[], badIterable, []]).next(); },
49 TypeError,
50 debug(badIterable) + ' is not a function'
51 );
52 }
53 });
54
55 forEach(v.strings, function (string) {
56 st['throws'](
57 function () { zip([string]); },
58 TypeError,
59 'non-objects are not considered iterable'
60 );
61 });
62
63 var arrayIt = zip([[1, 2, 3]]);
64 st.equal(typeof arrayIt.next, 'function', 'has a `next` function');
65
66 st.test('real iterators', { skip: !hasSymbols }, function (s2t) {
67 var iter = [1, 2][Symbol.iterator]();
68 testIterator(zip([iter, [3, 4]]), [[1, 3], [2, 4]], s2t, 'array iterator + array yields combined results');
69
70 s2t.end();
71 });
72
73 st.test('observability in a replaced String iterator', function (s2t) {
74 var originalStringIterator = String.prototype[Symbol.iterator];
75 var observedType;
76 s2t.teardown(mockProperty(String.prototype, Symbol.iterator, {
77 get: function () {
78 'use strict'; // eslint-disable-line strict, lines-around-directive
79
80 observedType = typeof this;
81 return originalStringIterator;
82 }
83 }));
84
85 zip([from('')]);
86 s2t.equal(observedType, 'string', 'string primitive -> primitive receiver in Symbol.iterator getter');
87 zip([from(Object(''))]);
88 s2t.equal(observedType, 'object', 'boxed string -> boxed string in Symbol.iterator getter');
89
90 s2t.end();
91 });
92
93 st.test('262: mode option validation', function (s2t) {
94 // valid modes should not throw
95 s2t.doesNotThrow(function () { zip([[1], [2]]); }, 'undefined mode is valid');
96 s2t.doesNotThrow(function () { zip([[1], [2]], { mode: undefined }); }, 'explicit undefined mode is valid');
97 s2t.doesNotThrow(function () { zip([[1], [2]], { mode: 'shortest' }); }, '"shortest" mode is valid');
98 s2t.doesNotThrow(function () { zip([[1], [2]], { mode: 'longest' }); }, '"longest" mode is valid');
99 s2t.doesNotThrow(function () { zip([[1], [2]], { mode: 'strict' }); }, '"strict" mode is valid');
100
101 // invalid modes should throw TypeError
102 s2t['throws'](function () { zip([[1], [2]], { mode: null }); }, TypeError, 'null mode throws TypeError');
103 s2t['throws'](function () { zip([[1], [2]], { mode: false }); }, TypeError, 'false mode throws TypeError');
104 s2t['throws'](function () { zip([[1], [2]], { mode: '' }); }, TypeError, 'empty string mode throws TypeError');
105 s2t['throws'](function () { zip([[1], [2]], { mode: 'short' }); }, TypeError, '"short" mode throws TypeError');
106 s2t['throws'](function () { zip([[1], [2]], { mode: 'long' }); }, TypeError, '"long" mode throws TypeError');
107 s2t['throws'](function () { zip([[1], [2]], { mode: 'loose' }); }, TypeError, '"loose" mode throws TypeError');
108 s2t['throws'](function () { zip([[1], [2]], { mode: 0 }); }, TypeError, '0 mode throws TypeError');
109 s2t['throws'](function () { zip([[1], [2]], { mode: {} }); }, TypeError, 'object mode throws TypeError');
110
111 // String wrapper should not be coerced
112 s2t['throws'](function () { zip([[1], [2]], { mode: Object('shortest') }); }, TypeError, 'String wrapper mode throws TypeError');
113
114 // objects with toString/valueOf should not be coerced
115 s2t['throws'](function () { zip([[1], [2]], { mode: { toString: function () { return 'shortest'; } } }); }, TypeError, 'object with toString throws TypeError');
116 s2t['throws'](function () { zip([[1], [2]], { mode: { valueOf: function () { return 'shortest'; } } }); }, TypeError, 'object with valueOf throws TypeError');
117
118 s2t.end();
119 });
120
121 st.test('262: basic shortest mode', function (s2t) {
122 // shortest mode (default) stops at minimum length
123 testIterator(zip([[1, 2, 3], [4, 5]]), [[1, 4], [2, 5]], s2t, 'shortest mode stops at shorter iterator');
124 testIterator(zip([[1, 2], [3, 4, 5]]), [[1, 3], [2, 4]], s2t, 'shortest mode stops at shorter first iterator');
125 testIterator(zip([[1], [2], [3]]), [[1, 2, 3]], s2t, 'three iterators of length 1');
126 testIterator(zip([[], [1, 2, 3]]), [], s2t, 'empty first iterator yields nothing');
127 testIterator(zip([[1, 2, 3], []]), [], s2t, 'empty second iterator yields nothing');
128
129 // explicit shortest mode
130 testIterator(zip([[1, 2, 3], [4, 5]], { mode: 'shortest' }), [[1, 4], [2, 5]], s2t, 'explicit shortest mode');
131
132 s2t.end();
133 });
134
135 st.test('262: basic longest mode', function (s2t) {
136 // longest mode continues with undefined padding by default
137 testIterator(zip([[1, 2, 3], [4, 5]], { mode: 'longest' }), [[1, 4], [2, 5], [3, undefined]], s2t, 'longest mode pads with undefined');
138 testIterator(zip([[1, 2], [3, 4, 5]], { mode: 'longest' }), [[1, 3], [2, 4], [undefined, 5]], s2t, 'longest mode pads first iterator');
139 testIterator(zip([[1], [2, 3], [4, 5, 6]], { mode: 'longest' }), [[1, 2, 4], [undefined, 3, 5], [undefined, undefined, 6]], s2t, 'longest mode with three iterators');
140
141 s2t.end();
142 });
143
144 st.test('262: basic strict mode', function (s2t) {
145 // strict mode succeeds when lengths match
146 testIterator(zip([[1, 2], [3, 4]], { mode: 'strict' }), [[1, 3], [2, 4]], s2t, 'strict mode succeeds with equal lengths');
147 testIterator(zip([[1], [2], [3]], { mode: 'strict' }), [[1, 2, 3]], s2t, 'strict mode with three iterators of length 1');
148
149 // strict mode throws when lengths differ
150 var strictIter1 = zip([[1, 2, 3], [4, 5]], { mode: 'strict' });
151 strictIter1.next(); // [1, 4]
152 strictIter1.next(); // [2, 5]
153 s2t['throws'](function () { strictIter1.next(); }, TypeError, 'strict mode throws when first iterator has more');
154
155 var strictIter2 = zip([[1, 2], [3, 4, 5]], { mode: 'strict' });
156 strictIter2.next(); // [1, 3]
157 strictIter2.next(); // [2, 4]
158 s2t['throws'](function () { strictIter2.next(); }, TypeError, 'strict mode throws when second iterator has more');
159
160 s2t.end();
161 });
162
163 st.test('strict mode: errored iterator not double-closed', function (s2t) {
164 var closeCounts = { a: 0, b: 0 };
165 var iterA = {
166 next: function () { return { done: true, value: undefined }; },
167 'return': function () {
168 closeCounts.a += 1;
169 return { done: true };
170 }
171 };
172 iterA[Symbol.iterator] = function () { return iterA; };
173 var iterB = {
174 next: function () { throw new EvalError('iterB.next threw'); },
175 'return': function () {
176 closeCounts.b += 1;
177 return { done: true };
178 }
179 };
180 iterB[Symbol.iterator] = function () { return iterB; };
181
182 var strictZip = zip([iterA, iterB], { mode: 'strict' });
183 // iterA.next() returns done:true, then in strict mode we check iterB
184 // iterB.next() throws - iterB should be removed from openIters before closing
185 s2t['throws'](
186 function () { strictZip.next(); },
187 EvalError,
188 'strict mode propagates error from next()'
189 );
190 s2t.equal(closeCounts.b, 0, 'errored iterator is not closed again');
191
192 s2t.end();
193 });
194
195 st.test('262: padding option validation', function (s2t) {
196 // padding is only used in longest mode
197 s2t.doesNotThrow(function () { zip([[1], [2]], { mode: 'shortest', padding: null }); }, 'invalid padding ignored in shortest mode');
198 s2t.doesNotThrow(function () { zip([[1], [2]], { mode: 'strict', padding: null }); }, 'invalid padding ignored in strict mode');
199
200 // invalid padding in longest mode
201 s2t['throws'](function () { zip([[1], [2]], { mode: 'longest', padding: null }); }, TypeError, 'null padding throws in longest mode');
202 s2t['throws'](function () { zip([[1], [2]], { mode: 'longest', padding: 'abc' }); }, TypeError, 'string padding throws in longest mode');
203 s2t['throws'](function () { zip([[1], [2]], { mode: 'longest', padding: 123 }); }, TypeError, 'number padding throws in longest mode');
204 s2t['throws'](function () { zip([[1], [2]], { mode: 'longest', padding: true }); }, TypeError, 'boolean padding throws in longest mode');
205
206 s2t.end();
207 });
208
209 st.test('262: result is iterator', function (s2t) {
210 var zipIter = zip([[1, 2], [3, 4]]);
211 s2t.equal(typeof zipIter.next, 'function', 'has next method');
212 s2t.equal(typeof zipIter[Symbol.iterator], 'function', 'has Symbol.iterator method');
213 s2t.equal(zipIter[Symbol.iterator](), zipIter, 'Symbol.iterator returns itself');
214
215 s2t.end();
216 });
217
218 st.test('262: return closes all underlying iterators', function (s2t) {
219 var return1Calls = 0;
220 var return2Calls = 0;
221
222 var iter1 = {
223 next: function () { return { done: false, value: 1 }; },
224 'return': function () {
225 return1Calls += 1;
226 return { done: true, value: undefined };
227 }
228 };
229 iter1[Symbol.iterator] = function () { return iter1; };
230
231 var iter2 = {
232 next: function () { return { done: false, value: 2 }; },
233 'return': function () {
234 return2Calls += 1;
235 return { done: true, value: undefined };
236 }
237 };
238 iter2[Symbol.iterator] = function () { return iter2; };
239
240 var zipIter = zip([iter1, iter2]);
241 zipIter.next();
242 s2t.equal(return1Calls, 0, 'return not called before calling return()');
243 s2t.equal(return2Calls, 0, 'return not called before calling return()');
244
245 zipIter['return']();
246 s2t.equal(return1Calls, 1, 'iter1.return called once');
247 s2t.equal(return2Calls, 1, 'iter2.return called once');
248
249 s2t.end();
250 });
251
252 st.test('262: next method throws closes other iterators', function (s2t) {
253 var return2Calls = 0;
254
255 var iter1 = {
256 next: function () { throw new EvalError('iter1 next threw'); }
257 };
258 iter1[Symbol.iterator] = function () { return iter1; };
259
260 var iter2 = {
261 next: function () { return { done: false, value: 2 }; },
262 'return': function () {
263 return2Calls += 1;
264 return { done: true, value: undefined };
265 }
266 };
267 iter2[Symbol.iterator] = function () { return iter2; };
268
269 var zipIter = zip([iter1, iter2]);
270 s2t['throws'](function () { zipIter.next(); }, EvalError, 'throws error from iter1.next');
271 s2t.equal(return2Calls, 1, 'iter2.return called when iter1.next throws');
272
273 s2t.end();
274 });
275
276 st.end();
277 });
278 },
279 index: function () {
280 test('Iterator.zip: index', function (t) {
281 module.exports.tests(index, 'Iterator.zip', t);
282
283 t.end();
284 });
285 },
286 implementation: function () {
287 test('Iterator.zip: implementation', function (t) {
288 module.exports.tests(impl, 'Iterator.zip', t);
289
290 t.end();
291 });
292 },
293 shimmed: function () {
294 test('Iterator.zip: shimmed', function (t) {
295 t.test('Function name', { skip: !functionsHaveNames }, function (st) {
296 st.equal(Iterator.zip.name, 'zip', 'Iterator.zip has name "zip"');
297 st.end();
298 });
299
300 t.test('enumerability', { skip: !defineProperties.supportsDescriptors }, function (et) {
301 et.equal(false, isEnumerable.call(Iterator, 'zip'), 'Iterator.zip is not enumerable');
302 et.end();
303 });
304
305 module.exports.tests(callBind(Iterator.zip, Iterator), 'Iterator.zip', t);
306
307 t.end();
308 });
309 }
310};
Note: See TracBrowser for help on using the repository browser.