@aidc-toolkit/utility 0.9.0 → 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.
@@ -1,5 +1,5 @@
1
- import { IterationHelper, type IterationSource } from "./iteration.js";
2
1
  import i18next, { utilityNS } from "./locale/i18n.js";
2
+ import { Sequencer } from "./sequencer.js";
3
3
 
4
4
  /**
5
5
  * Transformation callback, used to convert transformed value to its final value.
@@ -52,15 +52,15 @@ export abstract class Transformer {
52
52
  * @param domain
53
53
  * Domain.
54
54
  */
55
- constructor(domain: bigint) {
56
- if (domain <= 0n) {
55
+ constructor(domain: number | bigint) {
56
+ this._domain = BigInt(domain);
57
+
58
+ if (this._domain <= 0n) {
57
59
  throw new RangeError(i18next.t("Transformer.domainMustBeGreaterThanZero", {
58
60
  ns: utilityNS,
59
61
  domain
60
62
  }));
61
63
  }
62
-
63
- this._domain = BigInt(domain);
64
64
  }
65
65
 
66
66
  /**
@@ -108,30 +108,23 @@ export abstract class Transformer {
108
108
  }
109
109
 
110
110
  /**
111
- * Validate that a start value and count are within the domain.
111
+ * Validate that a value is within the domain.
112
112
  *
113
- * @param startValue
114
- * Start value of range to validate.
115
- *
116
- * @param count
117
- * Number of entries in the range to validate or 1 if undefined.
118
- *
119
- * @throws RangeError
113
+ * @param value
114
+ * Value.
120
115
  */
121
- private validate(startValue: bigint, count?: number): void {
122
- if (startValue < 0n) {
123
- throw new RangeError(i18next.t(count === undefined ? "Transformer.valueMustBeGreaterThanOrEqualToZero" : "Transformer.startValueMustBeGreaterThanOrEqualToZero", {
116
+ private validate(value: bigint): void {
117
+ if (value < 0n) {
118
+ throw new RangeError(i18next.t("Transformer.valueMustBeGreaterThanOrEqualToZero", {
124
119
  ns: utilityNS,
125
- startValue
120
+ value
126
121
  }));
127
122
  }
128
123
 
129
- const endValue = count === undefined ? startValue : startValue + BigInt(count - 1);
130
-
131
- if (endValue >= this.domain) {
132
- throw new RangeError(i18next.t(count === undefined ? "Transformer.valueMustBeLessThan" : "Transformer.endValueMustBeLessThan", {
124
+ if (value >= this.domain) {
125
+ throw new RangeError(i18next.t("Transformer.valueMustBeLessThan", {
133
126
  ns: utilityNS,
134
- endValue,
127
+ value,
135
128
  domain: this.domain
136
129
  }));
137
130
  }
@@ -157,13 +150,13 @@ export abstract class Transformer {
157
150
  * @returns
158
151
  * Transformed value.
159
152
  */
160
- forward(value: bigint): bigint;
153
+ forward(value: number | bigint): bigint;
161
154
 
162
155
  /**
163
156
  * Transform a value forward.
164
157
  *
165
158
  * @template T
166
- * Type returned by transformation callback or bigint if none.
159
+ * Type returned by transformation callback.
167
160
  *
168
161
  * @param value
169
162
  * Value.
@@ -174,118 +167,126 @@ export abstract class Transformer {
174
167
  * @returns
175
168
  * Value transformed into object.
176
169
  */
177
- forward<T>(value: bigint, transformationCallback: TransformationCallback<T>): T;
178
-
179
- forward<T>(value: bigint, transformationCallback?: TransformationCallback<T>): bigint | T {
180
- this.validate(value);
170
+ forward<T>(value: number | bigint, transformationCallback: TransformationCallback<T>): T;
181
171
 
182
- const transformedValue = this.doForward(value);
183
-
184
- return transformationCallback === undefined ? transformedValue : transformationCallback(transformedValue, 0);
185
- }
172
+ /**
173
+ * Transform values forward.
174
+ *
175
+ * @param values
176
+ * Values. If this is an instance of {@link Sequencer}, the minimum and maximum values are validated prior to
177
+ * transformation. Otherwise, the individual values are validated at the time of transformation.
178
+ *
179
+ * @returns
180
+ * Transformed values.
181
+ */
182
+ forward(values: Iterable<number | bigint>): IterableIterator<bigint>;
186
183
 
187
184
  /**
188
- * Do the work for the forward sequence method. Parameters are as defined in the public methods.
185
+ * Transform values forward.
189
186
  *
190
187
  * @template T
191
- * See public methods.
188
+ * Type returned by transformation callback.
192
189
  *
193
- * @param startValue
194
- * See public methods.
195
- *
196
- * @param count
197
- * See public methods.
190
+ * @param values
191
+ * Values. If this is an instance of {@link Sequencer}, the minimum and maximum values are validated prior to
192
+ * transformation. Otherwise, the individual values are validated at the time of transformation.
198
193
  *
199
194
  * @param transformationCallback
200
- * See public methods.
195
+ * Called after each value is transformed to convert it to its final value.
201
196
  *
202
- * @yields
203
- * Transformed value optionally defined by transformation callback.
197
+ * @returns
198
+ * Values transformed into objects.
204
199
  */
205
- private * doForwardSequence<T>(startValue: bigint, count: number, transformationCallback?: TransformationCallback<T>): Generator<bigint | T> {
206
- for (let index = 0, value = startValue; index < count; index++, value++) {
207
- const transformedValue = this.doForward(value);
208
-
209
- yield transformationCallback !== undefined ? transformationCallback(transformedValue, index) : transformedValue;
210
- }
211
- }
200
+ forward<T>(values: Iterable<number | bigint>, transformationCallback: TransformationCallback<T>): IterableIterator<T>;
212
201
 
213
202
  /**
214
- * Transform a sequence of values forward.
203
+ * Transform a value or values forward. This signature exists to allow similar overloaded methods in other classes
204
+ * to call this method correctly.
215
205
  *
216
- * @param startValue
217
- * Numerical value of the first object. Objects are created from `startValue` to `startValue + count - 1`.
206
+ * @param valueOrValues
218
207
  *
219
- * @param count
220
- * Number of objects to create.
221
- *
222
- * @yields
223
- * Transformed value.
208
+ * @returns
224
209
  */
225
- forwardSequence(startValue: bigint, count: number): IterableIterator<bigint>;
210
+ forward(valueOrValues: number | bigint | Iterable<number | bigint>): bigint | IterableIterator<bigint>;
226
211
 
227
212
  /**
228
- * Transform a sequence of values forward.
213
+ * Transform a value or values forward. This signature exists to allow similar overloaded methods in other classes
214
+ * to call this method correctly.
229
215
  *
230
216
  * @template T
231
- * Type returned by transformation callback or bigint if none.
232
- *
233
- * @param startValue
234
- * Numerical value of the first object. Objects are created from `startValue` to `startValue + count - 1`.
235
217
  *
236
- * @param count
237
- * Number of objects to create.
218
+ * @param valueOrValues
238
219
  *
239
220
  * @param transformationCallback
240
- * Transformation callback called after the value is transformed to convert it to its final value.
241
221
  *
242
222
  * @returns
243
- * Iterable iterator over transformed values as defined by transformation callback.
244
223
  */
245
- forwardSequence<T>(startValue: bigint, count: number, transformationCallback: TransformationCallback<T>): IterableIterator<T>;
246
-
247
- forwardSequence<T>(startValue: bigint, count: number, transformationCallback?: TransformationCallback<T>): IterableIterator<bigint | T> {
248
- this.validate(startValue, count);
249
-
250
- return this.doForwardSequence(startValue, count, transformationCallback);
251
- }
224
+ forward<T>(valueOrValues: number | bigint | Iterable<number | bigint>, transformationCallback: TransformationCallback<T>): T | IterableIterator<T>;
252
225
 
253
226
  /**
254
- * Transform multiple values forward.
255
- *
256
- * @param valuesSource
257
- * Source of values.
258
- *
259
- * @returns
260
- * Iterable iterator over transformed values.
261
- */
262
- forwardMultiple(valuesSource: IterationSource<bigint>): IterableIterator<bigint>;
263
-
264
- /**
265
- * Transform multiple values forward.
227
+ * Transform a value or values forward.
266
228
  *
267
229
  * @template T
268
- * Type returned by transformation callback or bigint if none.
230
+ * Type returned by transformation callback.
269
231
  *
270
- * @param valuesSource
271
- * Source of values.
232
+ * @param valueOrValues
233
+ * Value(s).
272
234
  *
273
235
  * @param transformationCallback
274
- * Transformation callback called after the value is transformed to convert it to its final value.
236
+ * Called after value(s) is/are transformed to convert it/them to its/their final value(s).
275
237
  *
276
238
  * @returns
277
- * Iterable iterator over transformed values as defined by transformation callback.
239
+ * Value(s) transformed into object(s).
278
240
  */
279
- forwardMultiple<T>(valuesSource: IterationSource<bigint>, transformationCallback: TransformationCallback<T>): IterableIterator<T>;
241
+ forward<T>(valueOrValues: number | bigint | Iterable<number | bigint>, transformationCallback?: TransformationCallback<T>): bigint | T | IterableIterator<bigint> | IterableIterator<T> {
242
+ let result: bigint | T | IterableIterator<bigint> | IterableIterator<T>;
280
243
 
281
- forwardMultiple<T>(valuesSource: IterationSource<bigint>, transformationCallback?: TransformationCallback<T>): IterableIterator<bigint | T> {
282
- return IterationHelper.from(valuesSource).map((value, index) => {
283
- this.validate(value);
244
+ if (typeof valueOrValues !== "object") {
245
+ const valueN = BigInt(valueOrValues);
284
246
 
285
- const transformedValue = this.doForward(value);
247
+ this.validate(valueN);
286
248
 
287
- return transformationCallback !== undefined ? transformationCallback(transformedValue, index) : transformedValue;
288
- });
249
+ const transformedValue = this.doForward(valueN);
250
+
251
+ result = transformationCallback === undefined ? transformedValue : transformationCallback(transformedValue, 0);
252
+ } else if (valueOrValues instanceof Sequencer) {
253
+ if (valueOrValues.minValue < 0n) {
254
+ throw new RangeError(i18next.t("Transformer.minValueMustBeGreaterThanOrEqualToZero", {
255
+ ns: utilityNS,
256
+ minValue: valueOrValues.minValue
257
+ }));
258
+ }
259
+
260
+ if (valueOrValues.maxValue >= this.domain) {
261
+ throw new RangeError(i18next.t("Transformer.maxValueMustBeLessThan", {
262
+ ns: utilityNS,
263
+ maxValue: valueOrValues.maxValue,
264
+ domain: this.domain
265
+ }));
266
+ }
267
+
268
+ result = transformationCallback === undefined ?
269
+ Iterator.from(valueOrValues).map(value => this.doForward(value)) :
270
+ Iterator.from(valueOrValues).map((value, index) => transformationCallback(this.doForward(value), index));
271
+ } else {
272
+ result = transformationCallback === undefined ?
273
+ Iterator.from(valueOrValues).map((value) => {
274
+ const valueN = BigInt(value);
275
+
276
+ this.validate(valueN);
277
+
278
+ return this.doForward(valueN);
279
+ }) :
280
+ Iterator.from(valueOrValues).map((value, index) => {
281
+ const valueN = BigInt(value);
282
+
283
+ this.validate(valueN);
284
+
285
+ return transformationCallback(this.doForward(valueN), index);
286
+ });
287
+ }
288
+
289
+ return result;
289
290
  }
290
291
 
291
292
  /**
@@ -308,10 +309,12 @@ export abstract class Transformer {
308
309
  * @returns
309
310
  * Value.
310
311
  */
311
- reverse(transformedValue: bigint): bigint {
312
- this.validate(transformedValue);
312
+ reverse(transformedValue: number | bigint): bigint {
313
+ const transformedValueN = BigInt(transformedValue);
314
+
315
+ this.validate(transformedValueN);
313
316
 
314
- return this.doReverse(transformedValue);
317
+ return this.doReverse(transformedValueN);
315
318
  }
316
319
  }
317
320
 
@@ -319,10 +322,16 @@ export abstract class Transformer {
319
322
  * Identity transformer. Values are transformed to themselves.
320
323
  */
321
324
  export class IdentityTransformer extends Transformer {
325
+ /**
326
+ * @inheritDoc
327
+ */
322
328
  protected doForward(value: bigint): bigint {
323
329
  return value;
324
330
  }
325
331
 
332
+ /**
333
+ * @inheritDoc
334
+ */
326
335
  protected doReverse(transformedValue: bigint): bigint {
327
336
  return transformedValue;
328
337
  }
@@ -402,7 +411,7 @@ export class EncryptionTransformer extends Transformer {
402
411
  * @param tweak
403
412
  * Tweak.
404
413
  */
405
- constructor(domain: bigint, tweak: bigint) {
414
+ constructor(domain: number | bigint, tweak: number | bigint) {
406
415
  super(domain);
407
416
 
408
417
  if (tweak < 0n) {
@@ -415,19 +424,19 @@ export class EncryptionTransformer extends Transformer {
415
424
  let domainBytes = 0;
416
425
 
417
426
  // The number of bytes in the domain determines the size of the shuffle and xor operations.
418
- for (let reducedDomainMinusOne = domain - 1n; reducedDomainMinusOne !== 0n; reducedDomainMinusOne = reducedDomainMinusOne >> 8n) {
427
+ for (let reducedDomainMinusOne = this.domain - 1n; reducedDomainMinusOne !== 0n; reducedDomainMinusOne = reducedDomainMinusOne >> 8n) {
419
428
  domainBytes++;
420
429
  }
421
430
 
422
431
  this._domainBytes = domainBytes;
423
- this._tweak = tweak;
432
+ this._tweak = BigInt(tweak);
424
433
 
425
434
  const xorBytes = new Array<number>();
426
435
  const bits = new Array<number>();
427
436
  const inverseBits = new Array<number>();
428
437
 
429
438
  // Key is the product of domain, tweak, and an 8-digit prime to force at least four rounds.
430
- for (let reducedKey = domain * tweak * 603868999n; reducedKey !== 0n; reducedKey = reducedKey >> 8n) {
439
+ for (let reducedKey = this.domain * this.tweak * 603868999n; reducedKey !== 0n; reducedKey = reducedKey >> 8n) {
431
440
  // Extract least-significant byte.
432
441
  const keyByte = Number(reducedKey & 0xFFn);
433
442
 
@@ -618,6 +627,9 @@ export class EncryptionTransformer extends Transformer {
618
627
  });
619
628
  }
620
629
 
630
+ /**
631
+ * @inheritDoc
632
+ */
621
633
  protected doForward(value: bigint): bigint {
622
634
  let bytes = this.valueToBytes(value);
623
635
  let transformedValue: bigint;
@@ -635,6 +647,9 @@ export class EncryptionTransformer extends Transformer {
635
647
  return transformedValue;
636
648
  }
637
649
 
650
+ /**
651
+ * @inheritDoc
652
+ */
638
653
  protected doReverse(transformedValue: bigint): bigint {
639
654
  let bytes = this.valueToBytes(transformedValue);
640
655
  let value: bigint;
@@ -2,11 +2,10 @@ import { I18NEnvironment, i18nInit } from "@aidc-toolkit/core";
2
2
  import { describe, expect, test } from "vitest";
3
3
  import {
4
4
  ALPHABETIC_CREATOR,
5
- ALPHANUMERIC_CREATOR,
5
+ ALPHANUMERIC_CREATOR, Sequencer,
6
6
  CharacterSetCreator,
7
7
  Exclusion,
8
8
  HEXADECIMAL_CREATOR,
9
- IterationHelper,
10
9
  NUMERIC_CREATOR
11
10
  } from "../src/index.js";
12
11
 
@@ -66,7 +65,7 @@ function testCharacterSetCreator(name: string, characterSetCreator: CharacterSet
66
65
  break;
67
66
  }
68
67
 
69
- const sequence = IterationHelper.from(characterSetCreator.createSequence(length, 0n, domain, exclusion));
68
+ const sequence = Iterator.from(characterSetCreator.create(length, new Sequencer(0n, domain), exclusion));
70
69
 
71
70
  let previousS = "";
72
71
 
@@ -78,26 +77,26 @@ function testCharacterSetCreator(name: string, characterSetCreator: CharacterSet
78
77
 
79
78
  expect(s.length).toBe(length);
80
79
 
81
- expect(characterSetCreator.value(s, exclusion)).toBe(BigInt(index));
80
+ expect(characterSetCreator.valueFor(s, exclusion)).toBe(BigInt(index));
82
81
 
83
82
  sequenceCount++;
84
83
  });
85
84
 
86
85
  expect(sequenceCount).toBe(domain);
87
86
 
88
- expect(() => characterSetCreator.create(length, domain, exclusion)).toThrow(RangeError);
87
+ expect(() => characterSetCreator.create(length, domain, exclusion)).toThrow(`Value ${domain} must be less than ${domain}`);
89
88
 
90
- const sparseSequence = IterationHelper.from(characterSetCreator.createSequence(length, 0n, domain, exclusion, 123456n));
89
+ const sparseSequence = Iterator.from(characterSetCreator.create(length, new Sequencer(domain - 1, -domain), exclusion, 123456n));
91
90
 
92
91
  let sequential = true;
93
- previousS = "";
92
+ previousS = "~";
94
93
 
95
94
  const sequenceSet = new Set<string>();
96
95
 
97
96
  sequenceCount = 0;
98
97
 
99
98
  sparseSequence.forEach((s, index) => {
100
- sequential = sequential && s > previousS;
99
+ sequential = sequential && s < previousS;
101
100
  previousS = s;
102
101
 
103
102
  expect(s.length).toBe(length);
@@ -105,7 +104,7 @@ function testCharacterSetCreator(name: string, characterSetCreator: CharacterSet
105
104
  expect(sequenceSet.has(s)).toBe(false);
106
105
  sequenceSet.add(s);
107
106
 
108
- expect(characterSetCreator.value(s, exclusion, 123456n)).toBe(BigInt(index));
107
+ expect(characterSetCreator.valueFor(s, exclusion, 123456n)).toBe(BigInt(domain - index - 1));
109
108
 
110
109
  sequenceCount++;
111
110
  });
@@ -125,12 +124,19 @@ function testCharacterSetCreator(name: string, characterSetCreator: CharacterSet
125
124
  sparseRandomValues.push(characterSetCreator.create(length, randomValue, exclusion, 123456n));
126
125
  }
127
126
 
128
- expect(Array.from(characterSetCreator.createMultiple(length, randomValues, exclusion))).toStrictEqual(straightRandomValues);
129
- expect(Array.from(characterSetCreator.createMultiple(length, randomValues, exclusion, 123456n))).toStrictEqual(sparseRandomValues);
127
+ expect(Array.from(characterSetCreator.create(length, randomValues, exclusion))).toStrictEqual(straightRandomValues);
128
+ expect(Array.from(characterSetCreator.create(length, randomValues, exclusion, 123456n))).toStrictEqual(sparseRandomValues);
130
129
 
131
- expect(() => characterSetCreator.create(length, exclusion, domain, 123456n)).toThrow(RangeError);
130
+ expect(() => characterSetCreator.create(length, domain, exclusion, 123456n)).toThrow(`Value ${domain} must be less than ${domain}`);
132
131
  }
133
132
 
133
+ test("Length", () => {
134
+ expect(() => characterSetCreator.create(0, 0)).not.toThrow(RangeError);
135
+ expect(() => characterSetCreator.create(-1, 0)).toThrow("Length -1 must be greater than or equal to 0");
136
+ expect(() => characterSetCreator.create(40, 0)).not.toThrow(RangeError);
137
+ expect(() => characterSetCreator.create(41, 0)).toThrow("Length 41 must be less than or equal to 40");
138
+ });
139
+
134
140
  test("Create sequence", () => {
135
141
  testCreate(Exclusion.None);
136
142
  });
@@ -139,8 +145,8 @@ function testCharacterSetCreator(name: string, characterSetCreator: CharacterSet
139
145
  test("Create sequence, exclude first zero", () => {
140
146
  testCreate(Exclusion.FirstZero);
141
147
 
142
- expect(() => characterSetCreator.value("0000", Exclusion.FirstZero)).toThrow(RangeError);
143
- expect(() => characterSetCreator.value("1000", Exclusion.FirstZero)).not.toThrow(RangeError);
148
+ expect(() => characterSetCreator.valueFor("0000", Exclusion.FirstZero)).toThrow("Invalid character '0' at position 1");
149
+ expect(() => characterSetCreator.valueFor("1000", Exclusion.FirstZero)).not.toThrow(RangeError);
144
150
  });
145
151
  }
146
152
 
@@ -148,12 +154,12 @@ function testCharacterSetCreator(name: string, characterSetCreator: CharacterSet
148
154
  test("Create sequence, exclude all numeric", () => {
149
155
  testCreate(Exclusion.AllNumeric);
150
156
 
151
- expect(() => characterSetCreator.value("0000", Exclusion.AllNumeric)).toThrow(RangeError);
157
+ expect(() => characterSetCreator.valueFor("0000", Exclusion.AllNumeric)).toThrow("String must not be all numeric");
152
158
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
153
- expect(() => characterSetCreator.value("000" + characterSetCreator.character(characterSetCreator.characterIndex("9")! + 1), Exclusion.AllNumeric)).not.toThrow(RangeError);
154
- expect(() => characterSetCreator.value("9999", Exclusion.AllNumeric)).toThrow(RangeError);
159
+ expect(() => characterSetCreator.valueFor("000" + characterSetCreator.character(characterSetCreator.characterIndex("9")! + 1), Exclusion.AllNumeric)).not.toThrow(RangeError);
160
+ expect(() => characterSetCreator.valueFor("9999", Exclusion.AllNumeric)).toThrow("String must not be all numeric");
155
161
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
156
- expect(() => characterSetCreator.value("999" + characterSetCreator.character(characterSetCreator.characterIndex("9")! + 1), Exclusion.AllNumeric)).not.toThrow(RangeError);
162
+ expect(() => characterSetCreator.valueFor("999" + characterSetCreator.character(characterSetCreator.characterIndex("9")! + 1), Exclusion.AllNumeric)).not.toThrow(RangeError);
157
163
  });
158
164
  }
159
165
  });
@@ -1,10 +1,11 @@
1
- import {I18NEnvironment, i18nInit} from "@aidc-toolkit/core";
2
- import {describe, expect, test} from "vitest";
3
- import {RecordValidator} from "../src/index.js";
1
+ import { I18NEnvironment, i18nInit } from "@aidc-toolkit/core";
2
+ import { describe, expect, test } from "vitest";
3
+ import { RecordValidator } from "../src/index.js";
4
4
 
5
5
  await i18nInit(I18NEnvironment.CLI, true);
6
6
 
7
7
  describe("Record validator", () => {
8
+ // eslint-disable-next-line jsdoc/require-jsdoc
8
9
  enum StringEnum {
9
10
  ValueA = "A",
10
11
  ValueB = "B",
@@ -1,6 +1,6 @@
1
- import {I18NEnvironment, i18nInit} from "@aidc-toolkit/core";
2
- import {describe, expect, test} from "vitest";
3
- import {RegExpValidator} from "../src/index.js";
1
+ import { I18NEnvironment, i18nInit } from "@aidc-toolkit/core";
2
+ import { describe, expect, test } from "vitest";
3
+ import { RegExpValidator } from "../src/index.js";
4
4
 
5
5
  await i18nInit(I18NEnvironment.CLI, true);
6
6
 
@@ -34,6 +34,7 @@ describe("Regular expression validator", () => {
34
34
  test("Error message", () => {
35
35
  expect(() => {
36
36
  new class extends RegExpValidator {
37
+ // eslint-disable-next-line jsdoc/require-jsdoc
37
38
  protected override createErrorMessage(s: string): string {
38
39
  return `Failed to validate "${s}"`;
39
40
  }
@@ -0,0 +1,72 @@
1
+ import { I18NEnvironment, i18nInit } from "@aidc-toolkit/core";
2
+ import { describe, expect, test } from "vitest";
3
+ import { Sequencer } from "../src/index.js";
4
+
5
+ await i18nInit(I18NEnvironment.CLI, true);
6
+
7
+ describe("Sequence", () => {
8
+ const sequencer1 = new Sequencer(10, 20);
9
+ const sequencer2 = new Sequencer(29, -20);
10
+
11
+ test("Structure", () => {
12
+ expect(sequencer1.startValue).toBe(10n);
13
+ expect(sequencer1.endValue).toBe(30n);
14
+ expect(sequencer1.count).toBe(20);
15
+ expect(sequencer1.minValue).toBe(10n);
16
+ expect(sequencer1.maxValue).toBe(29n);
17
+
18
+ expect(sequencer2.startValue).toBe(29n);
19
+ expect(sequencer2.endValue).toBe(9n);
20
+ expect(sequencer2.count).toBe(-20);
21
+ expect(sequencer2.minValue).toBe(10n);
22
+ expect(sequencer2.maxValue).toBe(29n);
23
+ });
24
+
25
+ test("Iteration", () => {
26
+ let expectedValue: bigint;
27
+ let count: number;
28
+
29
+ expectedValue = 10n;
30
+ count = 0;
31
+
32
+ for (const value of Iterator.from(sequencer1)) {
33
+ expect(value).toBe(expectedValue);
34
+
35
+ expectedValue++;
36
+ count++;
37
+ }
38
+
39
+ expect(count).toBe(20);
40
+
41
+ expectedValue = 29n;
42
+ count = 0;
43
+
44
+ for (const value of Iterator.from(sequencer2)) {
45
+ expect(value).toBe(expectedValue);
46
+
47
+ expectedValue--;
48
+ count++;
49
+ }
50
+
51
+ expect(count).toBe(20);
52
+ });
53
+
54
+ test("Reset", () => {
55
+ let expectedValue: bigint;
56
+ let count: number;
57
+
58
+ expectedValue = 10n;
59
+ count = 0;
60
+
61
+ sequencer1.reset();
62
+
63
+ for (const value of Iterator.from(sequencer1)) {
64
+ expect(value).toBe(expectedValue);
65
+
66
+ expectedValue++;
67
+ count++;
68
+ }
69
+
70
+ expect(count).toBe(20);
71
+ });
72
+ });
@@ -1,9 +1,10 @@
1
- import {I18NEnvironment, i18nInit} from "@aidc-toolkit/core";
2
- import {describe, expect, test} from "vitest";
3
- import { EncryptionTransformer, IdentityTransformer, IterationHelper, Transformer } from "../src/index.js";
1
+ import { I18NEnvironment, i18nInit } from "@aidc-toolkit/core";
2
+ import { describe, expect, test } from "vitest";
3
+ import { Sequencer, EncryptionTransformer, IdentityTransformer, Transformer } from "../src/index.js";
4
4
 
5
5
  await i18nInit(I18NEnvironment.CLI, true);
6
6
 
7
+ // eslint-disable-next-line jsdoc/require-jsdoc
7
8
  function testTransformer(domain: number, tweak?: number, callback?: (value: bigint, forwardValue: bigint) => void): void {
8
9
  const transformer = Transformer.get(domain, tweak);
9
10
 
@@ -11,7 +12,7 @@ function testTransformer(domain: number, tweak?: number, callback?: (value: bigi
11
12
 
12
13
  const transformedValuesSet = new Set<bigint>();
13
14
 
14
- IterationHelper.from(transformer.forwardSequence(0n, domain)).forEach((transformedValue, index) => {
15
+ Iterator.from(transformer.forward(new Sequencer(0n, domain))).forEach((transformedValue, index) => {
15
16
  const indexN = BigInt(index);
16
17
 
17
18
  if (sequential && transformedValue !== indexN) {
@@ -40,12 +41,14 @@ function testTransformer(domain: number, tweak?: number, callback?: (value: bigi
40
41
  transformedRandomValues.push(transformer.forward(randomValue));
41
42
  }
42
43
 
43
- expect(Array.from(transformer.forwardMultiple(randomValues))).toStrictEqual(transformedRandomValues);
44
+ expect(Array.from(transformer.forward(randomValues))).toStrictEqual(transformedRandomValues);
44
45
 
45
- expect(() => transformer.forward(BigInt(domain))).toThrow(`Value ${domain} must be less than ${domain}`);
46
- expect(() => transformer.forwardSequence(BigInt(domain), 0)).not.toThrow(RangeError);
47
- expect(() => transformer.forwardSequence(BigInt(domain) - 1n, 1)).not.toThrow(RangeError);
48
- expect(() => transformer.forwardSequence(BigInt(domain), 1)).toThrow(`End value (start value + count - 1) ${domain} must be less than ${domain}`);
46
+ expect(() => transformer.forward(domain)).toThrow(`Value ${domain} must be less than ${domain}`);
47
+ expect(() => transformer.forward(new Sequencer(domain, 0))).not.toThrow(RangeError);
48
+ expect(() => transformer.forward(new Sequencer(domain - 1, 1))).not.toThrow(RangeError);
49
+ expect(() => transformer.forward(new Sequencer(domain, 1))).toThrow(`Maximum value ${domain} must be less than ${domain}`);
50
+ expect(() => transformer.forward(new Sequencer(0, -1))).not.toThrow(RangeError);
51
+ expect(() => transformer.forward(new Sequencer(-1, -1))).toThrow("Minimum value -1 must be greater than or equal to 0");
49
52
  }
50
53
 
51
54
  describe("Identity", () => {
@@ -131,7 +134,7 @@ describe("Encryption", () => {
131
134
  });
132
135
 
133
136
  test("Tweak variation", () => {
134
- expect(Array.from(Transformer.get(1000, 1235).forwardSequence(0n, 1000))).not.toStrictEqual(Array.from(Transformer.get(1000, 1234).forwardSequence(0n, 1000)));
137
+ expect(Array.from(Transformer.get(1000, 1235).forward(new Sequencer(0n, 1000)))).not.toStrictEqual(Array.from(Transformer.get(1000, 1234).forward(new Sequencer(0n, 1000))));
135
138
  });
136
139
 
137
140
  test("Consistency", () => {
package/typedoc.json CHANGED
@@ -6,5 +6,6 @@
6
6
  "name": "Utility",
7
7
  "entryPoints": [
8
8
  "src/index.ts"
9
- ]
9
+ ],
10
+ "gitRevision": "main"
10
11
  }
@@ -1,12 +0,0 @@
1
- <component name="ProjectRunConfigurationManager">
2
- <configuration default="false" name="Test iteration" type="JavaScriptTestRunnerVitest">
3
- <node-interpreter value="project" />
4
- <vitest-package value="$PROJECT_DIR$/node_modules/vitest" />
5
- <working-dir value="$PROJECT_DIR$" />
6
- <vitest-options value="--run" />
7
- <envs />
8
- <scope-kind value="TEST_FILE" />
9
- <test-file value="$PROJECT_DIR$/test/iteration.test.ts" />
10
- <method v="2" />
11
- </configuration>
12
- </component>