@aidc-toolkit/utility 0.0.1 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/ISSUE_TEMPLATE/bug_report.md +32 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/.github/workflows/npm-publish.yml +6 -0
- package/.idea/runConfigurations/build_dev.xml +12 -0
- package/eslint.config.js +3 -0
- package/package.json +14 -13
- package/src/character_set.ts +78 -113
- package/src/index.ts +2 -2
- package/src/locale/en/locale_strings.ts +4 -4
- package/src/locale/i18next.d.ts +6 -0
- package/src/record.ts +0 -2
- package/src/reg_exp.ts +3 -0
- package/src/sequencer.ts +149 -0
- package/src/string.ts +2 -2
- package/src/transformer.ts +120 -105
- package/test/character_set.test.ts +24 -18
- package/test/record.test.ts +4 -3
- package/test/reg_exp.test.ts +4 -3
- package/test/sequencer.test.ts +72 -0
- package/test/transformer.test.ts +13 -10
- package/typedoc.json +2 -1
- package/.idea/runConfigurations/Test_iteration.xml +0 -12
- package/src/iteration.ts +0 -343
- package/test/iteration.test.ts +0 -282
package/src/iteration.ts
DELETED
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Iteration source type. The underlying source is an iterable or iterator or a callback to an iterable or iterator.
|
|
3
|
-
*/
|
|
4
|
-
export type IterationSource<T> = Iterable<T> | Iterator<T> | (() => (Iterable<T> | Iterator<T>));
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Iteration proxy class for applying a callback for mapping or filtering.
|
|
8
|
-
*/
|
|
9
|
-
class IterationProxy<T, U, V> implements IterableIterator<V> {
|
|
10
|
-
/**
|
|
11
|
-
* Proxied iterable iterator.
|
|
12
|
-
*/
|
|
13
|
-
private readonly _proxiedIterableIterator: IterableIterator<T>;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Callback for map or filter.
|
|
17
|
-
*/
|
|
18
|
-
private readonly _callback: (element: T, index: number) => U;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* If true, callback is a predicate for a filter.
|
|
22
|
-
*/
|
|
23
|
-
private readonly _isPredicate: boolean;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Index into proxied iterable iterator.
|
|
27
|
-
*/
|
|
28
|
-
private _index: number;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Constructor.
|
|
32
|
-
*
|
|
33
|
-
* @param proxiedIterableIterator
|
|
34
|
-
* Proxied iterable iterator.
|
|
35
|
-
*
|
|
36
|
-
* @param callback
|
|
37
|
-
* Callback for map or filter.
|
|
38
|
-
*
|
|
39
|
-
* @param isPredicate
|
|
40
|
-
* If true, callback is a predicate for a filter.
|
|
41
|
-
*/
|
|
42
|
-
constructor(proxiedIterableIterator: IterableIterator<T>, callback: (element: T, index: number) => U, isPredicate: boolean) {
|
|
43
|
-
this._proxiedIterableIterator = proxiedIterableIterator;
|
|
44
|
-
this._callback = callback;
|
|
45
|
-
this._isPredicate = isPredicate;
|
|
46
|
-
|
|
47
|
-
this._index = 0;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* {@link Iterable} interface implementation.
|
|
52
|
-
*
|
|
53
|
-
* @returns
|
|
54
|
-
* Iterable iterator.
|
|
55
|
-
*/
|
|
56
|
-
[Symbol.iterator](): IterableIterator<V> {
|
|
57
|
-
return this;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* {@link Iterator} interface implementation.
|
|
62
|
-
*
|
|
63
|
-
* @param args
|
|
64
|
-
* Arguments.
|
|
65
|
-
*
|
|
66
|
-
* @returns
|
|
67
|
-
* Next element or number or total number of elements if none.
|
|
68
|
-
*/
|
|
69
|
-
next(...args: [] | [undefined]): IteratorResult<V, number> {
|
|
70
|
-
let done = false;
|
|
71
|
-
let value: V | undefined;
|
|
72
|
-
|
|
73
|
-
let callbackDone: boolean;
|
|
74
|
-
|
|
75
|
-
do {
|
|
76
|
-
const proxiedNext = this._proxiedIterableIterator.next(...args);
|
|
77
|
-
|
|
78
|
-
if (!(proxiedNext.done ?? false)) {
|
|
79
|
-
const proxiedValue = proxiedNext.value;
|
|
80
|
-
const callbackValue = this._callback(proxiedValue, this._index++);
|
|
81
|
-
|
|
82
|
-
if (!this._isPredicate) {
|
|
83
|
-
// Types U and V are known to be identical.
|
|
84
|
-
value = callbackValue as unknown as V;
|
|
85
|
-
|
|
86
|
-
callbackDone = true;
|
|
87
|
-
} else {
|
|
88
|
-
callbackDone = callbackValue as boolean;
|
|
89
|
-
|
|
90
|
-
if (callbackDone) {
|
|
91
|
-
// Types T and V are known to be identical.
|
|
92
|
-
value = proxiedValue as unknown as V;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
} else {
|
|
96
|
-
done = true;
|
|
97
|
-
callbackDone = true;
|
|
98
|
-
}
|
|
99
|
-
} while (!callbackDone);
|
|
100
|
-
|
|
101
|
-
return done ?
|
|
102
|
-
{
|
|
103
|
-
done: true,
|
|
104
|
-
value: this._index
|
|
105
|
-
} :
|
|
106
|
-
{
|
|
107
|
-
done: false,
|
|
108
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
109
|
-
value: value!
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Iteration helper. Adds array-like functionality through {@link forEach}, {@link map}, {@link filter}, and
|
|
116
|
-
* {@link reduce} methods. Likely to be refactored as {@link
|
|
117
|
-
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator#iterator_helpers | iterator
|
|
118
|
-
* helpers} are more widely deployed.
|
|
119
|
-
*/
|
|
120
|
-
export class IterationHelper<T> implements IterableIterator<T> {
|
|
121
|
-
/**
|
|
122
|
-
* Iteration source.
|
|
123
|
-
*/
|
|
124
|
-
private readonly _iterationSource: IterationSource<T>;
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Iterable extracted from iteration source.
|
|
128
|
-
*/
|
|
129
|
-
private _iterable?: Iterable<T>;
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Iterator extracted from iteration source.
|
|
133
|
-
*/
|
|
134
|
-
private _iterator?: Iterator<T>;
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Constructor.
|
|
138
|
-
*
|
|
139
|
-
* @param iterationSource
|
|
140
|
-
* Iteration source.
|
|
141
|
-
*/
|
|
142
|
-
private constructor(iterationSource: IterationSource<T>) {
|
|
143
|
-
this._iterationSource = iterationSource;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Get an iteration helper from an iteration source. If the iteration source is itself an iteration helper, it is
|
|
148
|
-
* returned verbatim, otherwise a new iteration helper is constructed.
|
|
149
|
-
*
|
|
150
|
-
* @param iterationSource
|
|
151
|
-
* Iteration source.
|
|
152
|
-
*
|
|
153
|
-
* @returns
|
|
154
|
-
* Iteration helper.
|
|
155
|
-
*/
|
|
156
|
-
static from<T>(iterationSource: IterationSource<T>): IterationHelper<T> {
|
|
157
|
-
return iterationSource instanceof IterationHelper ? iterationSource as IterationHelper<T> : new IterationHelper(iterationSource);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Get the iteration source.
|
|
162
|
-
*/
|
|
163
|
-
get iterationSource(): IterationSource<T> {
|
|
164
|
-
return this._iterationSource;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Get the iteration source as an iterable.
|
|
169
|
-
*
|
|
170
|
-
* @returns
|
|
171
|
-
* Iterable.
|
|
172
|
-
*/
|
|
173
|
-
asIterable(): Iterable<T> {
|
|
174
|
-
if (this._iterable === undefined) {
|
|
175
|
-
const resolvedIterationSource = typeof this.iterationSource === "function" ? this.iterationSource() : this.iterationSource;
|
|
176
|
-
|
|
177
|
-
this._iterable = Symbol.iterator in resolvedIterationSource ?
|
|
178
|
-
resolvedIterationSource :
|
|
179
|
-
{
|
|
180
|
-
[Symbol.iterator](): Iterator<T> {
|
|
181
|
-
return resolvedIterationSource;
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return this._iterable;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Get the iteration source as an array.
|
|
191
|
-
*
|
|
192
|
-
* @returns
|
|
193
|
-
* Array.
|
|
194
|
-
*/
|
|
195
|
-
asArray(): readonly T[] {
|
|
196
|
-
const iterable = this.asIterable();
|
|
197
|
-
|
|
198
|
-
// Return iterable as array.
|
|
199
|
-
return Array.isArray(iterable) ? iterable as readonly T[] : Array.from(iterable);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Get the iteration source as an iterator.
|
|
204
|
-
*
|
|
205
|
-
* @returns
|
|
206
|
-
* Iterator.
|
|
207
|
-
*/
|
|
208
|
-
asIterator(): Iterator<T> {
|
|
209
|
-
if (this._iterator === undefined) {
|
|
210
|
-
this._iterator = this.asIterable()[Symbol.iterator]();
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
return this._iterator;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Get the iteration source as a callback.
|
|
218
|
-
*
|
|
219
|
-
* @returns
|
|
220
|
-
* Callback.
|
|
221
|
-
*/
|
|
222
|
-
asCallback(): () => IterationSource<T> {
|
|
223
|
-
return typeof this._iterationSource === "function" ? this._iterationSource : () => this._iterationSource;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* {@link Iterable} interface implementation.
|
|
228
|
-
*
|
|
229
|
-
* @returns
|
|
230
|
-
* Iterable iterator.
|
|
231
|
-
*/
|
|
232
|
-
[Symbol.iterator](): IterableIterator<T> {
|
|
233
|
-
return this;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* {@link Iterator} interface implementation.
|
|
238
|
-
*
|
|
239
|
-
* @param args
|
|
240
|
-
* Arguments.
|
|
241
|
-
*
|
|
242
|
-
* @returns
|
|
243
|
-
* Next element.
|
|
244
|
-
*/
|
|
245
|
-
next(...args: [] | [undefined]): IteratorResult<T, unknown> {
|
|
246
|
-
return this.asIterator().next(...args);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Perform an action for each element in the iteration helper.
|
|
251
|
-
*
|
|
252
|
-
* @param callback
|
|
253
|
-
* Callback that processes the element and its index in the iteration sequence.
|
|
254
|
-
*/
|
|
255
|
-
forEach(callback: (element: T, index: number) => void): void {
|
|
256
|
-
let index = 0;
|
|
257
|
-
|
|
258
|
-
for (const element of this) {
|
|
259
|
-
callback(element, index++);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Map the iteration helper to another iteration helper by performing an action for each element in the iteration
|
|
265
|
-
* helper along the way.
|
|
266
|
-
*
|
|
267
|
-
* @param callback
|
|
268
|
-
* Callback that processes the element and its index in the iteration sequence.
|
|
269
|
-
*
|
|
270
|
-
* @returns
|
|
271
|
-
* Iterable iterator over callback results.
|
|
272
|
-
*/
|
|
273
|
-
map<U>(callback: (element: T, index: number) => U): IterableIterator<U> {
|
|
274
|
-
return new IterationProxy(this, callback, false);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Filter the iteration helper based on the condition specified in a predicate. Each call to `.next()` will iterate
|
|
279
|
-
* as far as necessary until it reaches an element that satisfies the predicate. Care should be taken when working
|
|
280
|
-
* with large iterators and infrequently truthy predicates.
|
|
281
|
-
*
|
|
282
|
-
* @param predicate
|
|
283
|
-
* Predicate that processes the element and its index in the iteration sequence.
|
|
284
|
-
*
|
|
285
|
-
* @returns
|
|
286
|
-
* Iterator iterable over elements that satisfy the predicate.
|
|
287
|
-
*/
|
|
288
|
-
filter(predicate: (element: T, index: number) => boolean): IterableIterator<T> {
|
|
289
|
-
return new IterationProxy(this, predicate, true);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Reduce the iterator to a single value by applying a callback.
|
|
294
|
-
*
|
|
295
|
-
* @param callback
|
|
296
|
-
* Callback that processes the previous return value of the callback, the current value of the iterator, and the
|
|
297
|
-
* current index. The initial value is considered to be the first element in the iteration helper.
|
|
298
|
-
*
|
|
299
|
-
* @returns
|
|
300
|
-
* Reduced value.
|
|
301
|
-
*/
|
|
302
|
-
reduce(callback: (previousValue: T, currentValue: T, currentIndex: number) => T): T;
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Reduce the iterator to a single value by applying a callback.
|
|
306
|
-
*
|
|
307
|
-
* @param callback
|
|
308
|
-
* Callback that processes the previous return value of the callback, the current value of the iterator, and the
|
|
309
|
-
* current index.
|
|
310
|
-
*
|
|
311
|
-
* @param initialValue
|
|
312
|
-
* Initial value, passed as the first previous return value of the callback.
|
|
313
|
-
*
|
|
314
|
-
* @returns
|
|
315
|
-
* Reduced value.
|
|
316
|
-
*/
|
|
317
|
-
reduce(callback: (previousValue: T, currentValue: T, currentIndex: number) => T, initialValue: T): T;
|
|
318
|
-
|
|
319
|
-
reduce<U>(callback: (previousValue: U, currentValue: T, currentIndex: number) => U, initialValue?: U): U {
|
|
320
|
-
let index = 0;
|
|
321
|
-
let result = initialValue;
|
|
322
|
-
|
|
323
|
-
for (const value of this) {
|
|
324
|
-
if (index === 0 && initialValue === undefined) {
|
|
325
|
-
result = value as unknown as U;
|
|
326
|
-
} else {
|
|
327
|
-
// Iteration has occurred at least once so result is of the expected type.
|
|
328
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
329
|
-
result = callback(result!, value, index);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
index++;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
if (index === 0 && initialValue === undefined) {
|
|
336
|
-
throw new Error("reduce() of empty iterator with no initial value");
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// Iteration has occurred at least once so result is of the expected type.
|
|
340
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
341
|
-
return result!;
|
|
342
|
-
}
|
|
343
|
-
}
|
package/test/iteration.test.ts
DELETED
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "vitest";
|
|
2
|
-
import { IterationHelper, type IterationSource } from "../src/index.js";
|
|
3
|
-
|
|
4
|
-
const source: readonly string[] = [
|
|
5
|
-
"1", "2", "3", "4", "5"
|
|
6
|
-
];
|
|
7
|
-
|
|
8
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
9
|
-
function iterableSource(): Iterable<string> {
|
|
10
|
-
return [...source];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
14
|
-
function arraySource(): string[] {
|
|
15
|
-
return [...source];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
19
|
-
function iteratorSource(): Iterator<string> {
|
|
20
|
-
return [...source][Symbol.iterator]();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
24
|
-
function * generatorSource(): Generator<string> {
|
|
25
|
-
for (const s of source) {
|
|
26
|
-
yield s;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
31
|
-
function callbackSource(): string[] {
|
|
32
|
-
return [...source];
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
describe("Iterable", () => {
|
|
36
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
37
|
-
function validateIterable(iterationSource: IterationSource<string>, testEquality: boolean): void {
|
|
38
|
-
const iterationHelper = IterationHelper.from(iterationSource);
|
|
39
|
-
|
|
40
|
-
expect(IterationHelper.from(iterationHelper)).toBe(iterationHelper);
|
|
41
|
-
expect(iterationHelper.iterationSource).toBe(iterationSource);
|
|
42
|
-
|
|
43
|
-
expect(iterationHelper.asIterable() === iterationSource).toBe(testEquality);
|
|
44
|
-
expect(Array.from(iterationHelper)).toStrictEqual(source);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
test("Iterable", () => {
|
|
48
|
-
validateIterable(iterableSource, false);
|
|
49
|
-
validateIterable(iterableSource(), true);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
test("Array", () => {
|
|
53
|
-
validateIterable(arraySource, false);
|
|
54
|
-
validateIterable(arraySource(), true);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
test("Iterator", () => {
|
|
58
|
-
validateIterable(iteratorSource, false);
|
|
59
|
-
validateIterable(iteratorSource(), true);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
test("Generator", () => {
|
|
63
|
-
validateIterable(generatorSource, false);
|
|
64
|
-
validateIterable(generatorSource(), true);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
test("Callback", () => {
|
|
68
|
-
validateIterable(callbackSource, false);
|
|
69
|
-
validateIterable(callbackSource(), true);
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
describe("Array", () => {
|
|
74
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
75
|
-
function validateArray(iterationSource: IterationSource<string>, testEquality: boolean): void {
|
|
76
|
-
const iterationHelper = IterationHelper.from(iterationSource);
|
|
77
|
-
|
|
78
|
-
expect(IterationHelper.from(iterationHelper)).toBe(iterationHelper);
|
|
79
|
-
expect(iterationHelper.iterationSource).toBe(iterationSource);
|
|
80
|
-
|
|
81
|
-
const array = iterationHelper.asArray();
|
|
82
|
-
|
|
83
|
-
expect(array === iterationSource).toBe(testEquality);
|
|
84
|
-
expect(array).toStrictEqual(source);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
test("Iterable", () => {
|
|
88
|
-
validateArray(iterableSource, false);
|
|
89
|
-
validateArray(iterableSource(), true);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
test("Array", () => {
|
|
93
|
-
validateArray(arraySource, false);
|
|
94
|
-
validateArray(arraySource(), true);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
test("Iterator", () => {
|
|
98
|
-
validateArray(iteratorSource, false);
|
|
99
|
-
validateArray(iteratorSource(), false);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
test("Generator", () => {
|
|
103
|
-
validateArray(generatorSource, false);
|
|
104
|
-
validateArray(generatorSource(), false);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
test("Callback", () => {
|
|
108
|
-
validateArray(callbackSource, false);
|
|
109
|
-
validateArray(callbackSource(), true);
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
describe("Iterator", () => {
|
|
114
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
115
|
-
function validateIterator(iterationSource: IterationSource<string>, testEquality: boolean): void {
|
|
116
|
-
const iterationHelper = IterationHelper.from(iterationSource);
|
|
117
|
-
|
|
118
|
-
expect(IterationHelper.from(iterationHelper)).toBe(iterationHelper);
|
|
119
|
-
expect(iterationHelper.iterationSource).toBe(iterationSource);
|
|
120
|
-
|
|
121
|
-
const iterator = iterationHelper.asIterator();
|
|
122
|
-
|
|
123
|
-
expect(iterator === iterationSource).toBe(testEquality);
|
|
124
|
-
expect(Array.from({
|
|
125
|
-
[Symbol.iterator](): Iterator<string> {
|
|
126
|
-
return iterator;
|
|
127
|
-
}
|
|
128
|
-
})).toStrictEqual(source);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
test("Iterable", () => {
|
|
132
|
-
validateIterator(iterableSource, false);
|
|
133
|
-
validateIterator(iterableSource(), false);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
test("Array", () => {
|
|
137
|
-
validateIterator(arraySource, false);
|
|
138
|
-
validateIterator(arraySource(), false);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
test("Iterator", () => {
|
|
142
|
-
validateIterator(iteratorSource, false);
|
|
143
|
-
validateIterator(iteratorSource(), true);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
test("Generator", () => {
|
|
147
|
-
validateIterator(generatorSource, false);
|
|
148
|
-
validateIterator(generatorSource(), true);
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
test("Callback", () => {
|
|
152
|
-
validateIterator(callbackSource, false);
|
|
153
|
-
validateIterator(callbackSource(), false);
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
describe("Callback", () => {
|
|
158
|
-
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
159
|
-
function validateCallback(iterationSource: IterationSource<string>, testEquality: boolean): void {
|
|
160
|
-
const iterationHelper = IterationHelper.from(iterationSource);
|
|
161
|
-
|
|
162
|
-
expect(IterationHelper.from(iterationHelper)).toBe(iterationHelper);
|
|
163
|
-
expect(iterationHelper.iterationSource).toBe(iterationSource);
|
|
164
|
-
|
|
165
|
-
expect(iterationHelper.asCallback() === iterationSource).toBe(testEquality);
|
|
166
|
-
expect(iterationHelper.asArray()).toStrictEqual(source);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
test("Iterable", () => {
|
|
170
|
-
validateCallback(iterableSource, true);
|
|
171
|
-
validateCallback(iterableSource(), false);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
test("Array", () => {
|
|
175
|
-
validateCallback(arraySource, true);
|
|
176
|
-
validateCallback(arraySource(), false);
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
test("Iterator", () => {
|
|
180
|
-
validateCallback(iteratorSource, true);
|
|
181
|
-
validateCallback(iteratorSource(), false);
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
test("Generator", () => {
|
|
185
|
-
validateCallback(generatorSource, true);
|
|
186
|
-
validateCallback(generatorSource(), false);
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
test("Callback", () => {
|
|
190
|
-
validateCallback(callbackSource, true);
|
|
191
|
-
validateCallback(callbackSource(), false);
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
describe("Helpers", () => {
|
|
196
|
-
test("For each", () => {
|
|
197
|
-
let count = 0;
|
|
198
|
-
|
|
199
|
-
IterationHelper.from(source).forEach((value, index) => {
|
|
200
|
-
expect(Number(value)).toBe(index + 1);
|
|
201
|
-
expect(index).toBe(count++);
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
expect(count).toBe(source.length);
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
test("Map", () => {
|
|
208
|
-
let count = 0;
|
|
209
|
-
|
|
210
|
-
const mappedIterationHelper = IterationHelper.from(source).map((element, index) => {
|
|
211
|
-
expect(Number(element)).toBe(index + 1);
|
|
212
|
-
expect(index).toBe(count++);
|
|
213
|
-
|
|
214
|
-
return -count;
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
expect(count).toBe(0);
|
|
218
|
-
|
|
219
|
-
let negativeCount = 0;
|
|
220
|
-
|
|
221
|
-
for (const element of mappedIterationHelper) {
|
|
222
|
-
expect(element).toBe(--negativeCount);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
expect(count).toBe(source.length);
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
test("Filter", () => {
|
|
229
|
-
let count = 0;
|
|
230
|
-
|
|
231
|
-
const filteredIterable = IterationHelper.from(source).filter((element, index) => {
|
|
232
|
-
expect(Number(element)).toBe(index + 1);
|
|
233
|
-
expect(index).toBe(count++);
|
|
234
|
-
|
|
235
|
-
return Number(element) % 2 === 0;
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
expect(count).toBe(0);
|
|
239
|
-
|
|
240
|
-
let evenCount = 0;
|
|
241
|
-
|
|
242
|
-
for (const element of filteredIterable) {
|
|
243
|
-
const n = Number(element);
|
|
244
|
-
|
|
245
|
-
expect(n % 2).toBe(0);
|
|
246
|
-
expect(Math.floor((n - 1) / 2)).toBe(evenCount++);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
expect(count).toBe(source.length);
|
|
250
|
-
expect(evenCount).toBe(Math.floor(source.length / 2));
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
test("Reduce no initial value", () => {
|
|
254
|
-
let count = 0;
|
|
255
|
-
|
|
256
|
-
expect(IterationHelper.from(source).reduce((previousValue, currentValue, currentIndex) => {
|
|
257
|
-
expect(Number(currentValue)).toBe(currentIndex + 1);
|
|
258
|
-
expect(currentIndex - 1).toBe(count++);
|
|
259
|
-
|
|
260
|
-
return previousValue + currentValue;
|
|
261
|
-
})).toBe("".concat(...source));
|
|
262
|
-
|
|
263
|
-
expect(count).toBe(source.length - 1);
|
|
264
|
-
|
|
265
|
-
expect(() => IterationHelper.from<string>([]).reduce(() => "")).toThrow("reduce() of empty iterator with no initial value");
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
test("Reduce initial value", () => {
|
|
269
|
-
let count = 0;
|
|
270
|
-
|
|
271
|
-
expect(IterationHelper.from(source).reduce((previousValue, currentValue, currentIndex) => {
|
|
272
|
-
expect(Number(currentValue)).toBe(currentIndex + 1);
|
|
273
|
-
expect(currentIndex).toBe(count++);
|
|
274
|
-
|
|
275
|
-
return previousValue + currentValue;
|
|
276
|
-
}, "0")).toBe("0".concat(...source));
|
|
277
|
-
|
|
278
|
-
expect(count).toBe(source.length);
|
|
279
|
-
|
|
280
|
-
expect(IterationHelper.from<string>([]).reduce(() => "", "0")).toBe("0");
|
|
281
|
-
});
|
|
282
|
-
});
|