@aidc-toolkit/utility 0.9.3 → 0.9.5

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.
@@ -0,0 +1,252 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { IteratorProxy } from "../src/index.js";
3
+
4
+ const source: readonly string[] = [
5
+ "1", "2", "3", "4", "5"
6
+ ];
7
+
8
+ function iterableSource(): Iterable<string> {
9
+ return [...source];
10
+ }
11
+
12
+ function arraySource(): string[] {
13
+ return [...source];
14
+ }
15
+
16
+ function iteratorSource(): Iterator<string> {
17
+ return [...source][Symbol.iterator]();
18
+ }
19
+
20
+ function * generatorSource(): Generator<string> {
21
+ for (const s of source) {
22
+ yield s;
23
+ }
24
+ }
25
+
26
+ function callbackSource(): string[] {
27
+ return [...source];
28
+ }
29
+
30
+ describe("Basic", () => {
31
+ function validateIterable(iterationSource: Iterator<string> | Iterable<string>): void {
32
+ const iteratorProxy = IteratorProxy.from(iterationSource);
33
+
34
+ expect(IteratorProxy.from(iteratorProxy)).toBe(iteratorProxy);
35
+
36
+ // @ts-expect-error -- Property exists.
37
+ expect(iteratorProxy["_initialIterable"]).toBe(iterationSource);
38
+
39
+ expect(Array.from(iteratorProxy)).toStrictEqual(source);
40
+ }
41
+
42
+ test("Iterator proxy", () => {
43
+ expect(IteratorProxy).not.toBe(Iterator);
44
+ });
45
+
46
+ test("Iterable", () => {
47
+ validateIterable(iterableSource());
48
+ });
49
+
50
+ test("Array", () => {
51
+ validateIterable(arraySource());
52
+ });
53
+
54
+ test("Iterator", () => {
55
+ validateIterable(iteratorSource());
56
+ });
57
+
58
+ test("Generator", () => {
59
+ validateIterable(generatorSource());
60
+ });
61
+
62
+ test("Callback", () => {
63
+ validateIterable(callbackSource());
64
+ });
65
+ });
66
+
67
+ describe("Helpers", () => {
68
+ test("Map", () => {
69
+ let count = 0;
70
+
71
+ const mapIteratorProxy = IteratorProxy.from(source).map((element, index) => {
72
+ expect(Number(element)).toBe(index + 1);
73
+ expect(index).toBe(count++);
74
+
75
+ return -count;
76
+ });
77
+
78
+ expect(count).toBe(0);
79
+
80
+ let negativeCount = 0;
81
+
82
+ for (const element of mapIteratorProxy) {
83
+ expect(element).toBe(--negativeCount);
84
+ }
85
+
86
+ expect(count).toBe(source.length);
87
+ });
88
+
89
+ test("Flat map", () => {
90
+ let count = 0;
91
+
92
+ const flatMapIteratorProxy = IteratorProxy.from(source).flatMap((element, index) => {
93
+ expect(Number(element)).toBe(index + 1);
94
+ expect(index).toBe(count++);
95
+
96
+ return [count, -count];
97
+ });
98
+
99
+ expect(count).toBe(0);
100
+
101
+ let index = 0;
102
+
103
+ for (const element of flatMapIteratorProxy) {
104
+ const absoluteElement = Math.floor(index / 2) + 1;
105
+
106
+ expect(element).toBe(index % 2 === 0 ? absoluteElement : -absoluteElement);
107
+ index++;
108
+ }
109
+
110
+ expect(count).toBe(source.length);
111
+ });
112
+
113
+ test("Filter", () => {
114
+ let count = 0;
115
+
116
+ const filteredIterable = IteratorProxy.from(source).filter((element, index) => {
117
+ expect(Number(element)).toBe(index + 1);
118
+ expect(index).toBe(count++);
119
+
120
+ return Number(element) % 2 === 0;
121
+ });
122
+
123
+ expect(count).toBe(0);
124
+
125
+ let evenCount = 0;
126
+
127
+ for (const element of filteredIterable) {
128
+ const n = Number(element);
129
+
130
+ expect(n % 2).toBe(0);
131
+ expect(Math.floor((n - 1) / 2)).toBe(evenCount++);
132
+ }
133
+
134
+ expect(count).toBe(source.length);
135
+ expect(evenCount).toBe(Math.floor(source.length / 2));
136
+ });
137
+
138
+ test("Take", () => {
139
+ let count = 0;
140
+
141
+ for (const element of IteratorProxy.from(source).take(3)) {
142
+ expect(element).toBe(String(++count));
143
+ }
144
+
145
+ expect(count).toBe(3);
146
+
147
+ count = 0;
148
+
149
+ for (const element of IteratorProxy.from(source).take(source.length + 1)) {
150
+ expect(element).toBe(String(++count));
151
+ }
152
+
153
+ expect(count).toBe(source.length);
154
+
155
+ count = 0;
156
+
157
+ for (const element of IteratorProxy.from(source).take(0)) {
158
+ expect(element).toBe(String(++count));
159
+ }
160
+
161
+ expect(count).toBe(0);
162
+ });
163
+
164
+ test("Drop", () => {
165
+ let count = 0;
166
+
167
+ for (const element of IteratorProxy.from(source).drop(3)) {
168
+ expect(element).toBe(String(++count + 3));
169
+ }
170
+
171
+ expect(count).toBe(source.length - 3);
172
+
173
+ count = 0;
174
+
175
+ for (const element of IteratorProxy.from(source).drop(0)) {
176
+ expect(element).toBe(String(++count));
177
+ }
178
+
179
+ expect(count).toBe(source.length);
180
+
181
+ count = 0;
182
+
183
+ for (const element of IteratorProxy.from(source).drop(source.length)) {
184
+ expect(element).toBe(String(++count));
185
+ }
186
+
187
+ expect(count).toBe(0);
188
+ });
189
+
190
+ test("To array", () => {
191
+ const sourceToArray = IteratorProxy.from(source).toArray();
192
+
193
+ expect(sourceToArray).not.toBe(source);
194
+ expect(sourceToArray).toStrictEqual(source);
195
+ });
196
+
197
+ test("For each", () => {
198
+ let count = 0;
199
+
200
+ IteratorProxy.from(source).forEach((value, index) => {
201
+ expect(Number(value)).toBe(index + 1);
202
+ expect(index).toBe(count++);
203
+ });
204
+
205
+ expect(count).toBe(source.length);
206
+ });
207
+
208
+ test("Reduce no initial value", () => {
209
+ let count = 0;
210
+
211
+ expect(IteratorProxy.from(source).reduce((previousValue, currentValue, currentIndex) => {
212
+ expect(Number(currentValue)).toBe(currentIndex + 1);
213
+ expect(currentIndex - 1).toBe(count++);
214
+
215
+ return previousValue + currentValue;
216
+ })).toBe("".concat(...source));
217
+
218
+ expect(count).toBe(source.length - 1);
219
+
220
+ expect(() => IteratorProxy.from<string>([]).reduce(() => "")).toThrow("reduce() of empty iterator with no initial value");
221
+ });
222
+
223
+ test("Reduce initial value", () => {
224
+ let count = 0;
225
+
226
+ expect(IteratorProxy.from(source).reduce((previousValue, currentValue, currentIndex) => {
227
+ expect(Number(currentValue)).toBe(currentIndex + 1);
228
+ expect(currentIndex).toBe(count++);
229
+
230
+ return previousValue + currentValue;
231
+ }, "0")).toBe("0".concat(...source));
232
+
233
+ expect(count).toBe(source.length);
234
+
235
+ expect(IteratorProxy.from<string>([]).reduce(() => "", "0")).toBe("0");
236
+ });
237
+
238
+ test("Some", () => {
239
+ expect(IteratorProxy.from(source).some(value => value === "3")).toBe(true);
240
+ expect(IteratorProxy.from(source).some(value => value === "6")).toBe(false);
241
+ });
242
+
243
+ test("Every", () => {
244
+ expect(IteratorProxy.from(source).every(value => Number(value) > 0)).toBe(true);
245
+ expect(IteratorProxy.from(source).every(value => Number(value) < Number(source[source.length - 1]))).toBe(false);
246
+ });
247
+
248
+ test("Find", () => {
249
+ expect(IteratorProxy.from(source).find(value => Number(value) % 3 === 0)).toBe("3");
250
+ expect(IteratorProxy.from(source).find(value => Number(value) % 7 === 0)).toBeUndefined();
251
+ });
252
+ });
@@ -2,7 +2,7 @@ import { I18NEnvironment, i18nInit } from "@aidc-toolkit/core";
2
2
  import { describe, expect, test } from "vitest";
3
3
  import { RecordValidator } from "../src/index.js";
4
4
 
5
- await i18nInit(I18NEnvironment.CLI, true);
5
+ await i18nInit(I18NEnvironment.CLI);
6
6
 
7
7
  describe("Record validator", () => {
8
8
  enum StringEnum {
@@ -2,7 +2,7 @@ import { I18NEnvironment, i18nInit } from "@aidc-toolkit/core";
2
2
  import { describe, expect, test } from "vitest";
3
3
  import { RegExpValidator } from "../src/index.js";
4
4
 
5
- await i18nInit(I18NEnvironment.CLI, true);
5
+ await i18nInit(I18NEnvironment.CLI);
6
6
 
7
7
  describe("Regular expression validator", () => {
8
8
  test("Validation", () => {
@@ -1,8 +1,8 @@
1
1
  import { I18NEnvironment, i18nInit } from "@aidc-toolkit/core";
2
2
  import { describe, expect, test } from "vitest";
3
- import { Sequencer } from "../src/index.js";
3
+ import { IteratorProxy, Sequencer } from "../src/index.js";
4
4
 
5
- await i18nInit(I18NEnvironment.CLI, true);
5
+ await i18nInit(I18NEnvironment.CLI);
6
6
 
7
7
  describe("Sequence", () => {
8
8
  const sequencer1 = new Sequencer(10, 20);
@@ -29,7 +29,7 @@ describe("Sequence", () => {
29
29
  expectedValue = 10n;
30
30
  count = 0;
31
31
 
32
- for (const value of Iterator.from(sequencer1)) {
32
+ for (const value of IteratorProxy.from(sequencer1)) {
33
33
  expect(value).toBe(expectedValue);
34
34
 
35
35
  expectedValue++;
@@ -41,7 +41,7 @@ describe("Sequence", () => {
41
41
  expectedValue = 29n;
42
42
  count = 0;
43
43
 
44
- for (const value of Iterator.from(sequencer2)) {
44
+ for (const value of IteratorProxy.from(sequencer2)) {
45
45
  expect(value).toBe(expectedValue);
46
46
 
47
47
  expectedValue--;
@@ -60,7 +60,7 @@ describe("Sequence", () => {
60
60
 
61
61
  sequencer1.reset();
62
62
 
63
- for (const value of Iterator.from(sequencer1)) {
63
+ for (const value of IteratorProxy.from(sequencer1)) {
64
64
  expect(value).toBe(expectedValue);
65
65
 
66
66
  expectedValue++;
@@ -1,8 +1,8 @@
1
1
  import { I18NEnvironment, i18nInit } from "@aidc-toolkit/core";
2
2
  import { describe, expect, test } from "vitest";
3
- import { EncryptionTransformer, IdentityTransformer, Sequencer, Transformer } from "../src/index.js";
3
+ import { EncryptionTransformer, IdentityTransformer, IteratorProxy, Sequencer, Transformer } from "../src/index.js";
4
4
 
5
- await i18nInit(I18NEnvironment.CLI, true);
5
+ await i18nInit(I18NEnvironment.CLI);
6
6
 
7
7
  function testTransformer(domain: number, tweak?: number, callback?: (value: bigint, forwardValue: bigint) => void): void {
8
8
  const transformer = Transformer.get(domain, tweak);
@@ -11,7 +11,7 @@ function testTransformer(domain: number, tweak?: number, callback?: (value: bigi
11
11
 
12
12
  const transformedValuesSet = new Set<bigint>();
13
13
 
14
- Iterator.from(transformer.forward(new Sequencer(0n, domain))).forEach((transformedValue, index) => {
14
+ IteratorProxy.from(transformer.forward(new Sequencer(0n, domain))).forEach((transformedValue, index) => {
15
15
  const indexN = BigInt(index);
16
16
 
17
17
  if (sequential && transformedValue !== indexN) {
@@ -1,38 +0,0 @@
1
- # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
- # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3
-
4
- name: Node.js Package
5
-
6
- on:
7
- release:
8
- types: [created]
9
-
10
- jobs:
11
- build:
12
- runs-on: ubuntu-latest
13
- steps:
14
- - uses: actions/checkout@v4
15
- - uses: actions/setup-node@v4
16
- with:
17
- node-version: 22
18
- - run: npm ci
19
- # This is necessary to work around platform-specific optional dependencies bug (https://github.com/npm/cli/issues/4828).
20
- # - run: npm i @rollup/rollup-linux-x64-gnu
21
- # "vitest run" fails with:
22
- # Error: failed to resolve "extends":"@aidc-toolkit/dev/tsconfig.json" in /home/runner/work/utility/utility/tsconfig.json
23
- # Caused by: Error: Cannot find module '@aidc-toolkit/dev/tsconfig.json/tsconfig.json'
24
- # - run: npm test
25
-
26
- publish-npm:
27
- needs: build
28
- runs-on: ubuntu-latest
29
- steps:
30
- - uses: actions/checkout@v4
31
- - uses: actions/setup-node@v4
32
- with:
33
- node-version: 22
34
- registry-url: https://registry.npmjs.org/
35
- - run: npm ci
36
- - run: npm publish --access public
37
- env:
38
- NODE_AUTH_TOKEN: ${{secrets.npm_token}}
@@ -1,12 +0,0 @@
1
- <component name="ProjectRunConfigurationManager">
2
- <configuration default="false" name="build-dev" type="js.build_tools.npm" nameIsGenerated="true">
3
- <package-json value="$PROJECT_DIR$/package.json" />
4
- <command value="run" />
5
- <scripts>
6
- <script value="build-dev" />
7
- </scripts>
8
- <node-interpreter value="project" />
9
- <envs />
10
- <method v="2" />
11
- </configuration>
12
- </component>