Skip to content

Commit c97b0d2

Browse files
committed
test: no need to filter MersenneModule anymore
refactor!: simplify mersenne functions chore: add @internal tag chore: cant use `@internal` types chore: need to import type via relative chore: revert changes to do them in separate PR
1 parent 66a6afd commit c97b0d2

File tree

5 files changed

+70
-69
lines changed

5 files changed

+70
-69
lines changed

src/faker.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { LocaleDefinition } from './definitions';
22
import { FakerError } from './errors/faker-error';
3-
import type { Mersenne } from './internal/mersenne/mersenne';
4-
import mersenne from './internal/mersenne/mersenne';
3+
import { MersenneModule } from './internal/mersenne/mersenne';
54
import type { KnownLocale } from './locales';
65
import { AddressModule } from './modules/address';
76
import { AnimalModule } from './modules/animal';
@@ -76,7 +75,7 @@ export class Faker {
7675
readonly definitions: LocaleDefinition = this.initDefinitions();
7776

7877
/** @internal */
79-
private readonly _mersenne: Mersenne = mersenne();
78+
private readonly _mersenne: MersenneModule = new MersenneModule();
8079

8180
readonly random: RandomModule = new RandomModule(this);
8281

@@ -241,7 +240,7 @@ export class Faker {
241240
seed: number | number[] = Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER)
242241
): number | number[] {
243242
if (Array.isArray(seed) && seed.length) {
244-
this._mersenne.seedArray(seed);
243+
this._mersenne.seed_array(seed);
245244
} else if (!Array.isArray(seed) && !isNaN(seed)) {
246245
this._mersenne.seed(seed);
247246
}

src/internal/mersenne/mersenne.ts

Lines changed: 51 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,47 @@
11
import { FakerError } from '../../errors/faker-error';
2-
import Twister from './twister';
2+
import Gen from './twister';
3+
4+
/**
5+
* Module to generate seed based random numbers.
6+
*
7+
* @internal
8+
*/
9+
export class MersenneModule {
10+
private gen = new Gen();
11+
12+
constructor() {
13+
this.gen.initGenrand(Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER));
14+
15+
// Bind `this` so namespaced is working correctly
16+
for (const name of Object.getOwnPropertyNames(MersenneModule.prototype)) {
17+
if (name === 'constructor' || typeof this[name] !== 'function') {
18+
continue;
19+
}
20+
this[name] = this[name].bind(this);
21+
}
22+
}
323

4-
export interface Mersenne {
524
/**
625
* Generates a random number between `[min, max)`.
726
*
827
* @param max The maximum number. Defaults to `32768`.
928
* @param min The minimum number. Defaults to `0`.
1029
*
30+
* @example
31+
* faker.mersenne.rand() // 15515
32+
* faker.mersenne.rand(1000, 500) // 578
33+
*
1134
* @since 5.5.0
1235
*/
13-
rand(max?: number, min?: number): number;
36+
rand(max = 32768, min = 0): number {
37+
if (min > max) {
38+
const temp = min;
39+
min = max;
40+
max = temp;
41+
}
42+
43+
return Math.floor(this.gen.genrandReal2() * (max - min) + min);
44+
}
1445

1546
/**
1647
* Sets the seed to use.
@@ -20,7 +51,15 @@ export interface Mersenne {
2051
*
2152
* @since 5.5.0
2253
*/
23-
seed(S: number): void;
54+
seed(S: number): void {
55+
if (typeof S !== 'number') {
56+
throw new FakerError(
57+
`seed(S) must take numeric argument; is ${typeof S}`
58+
);
59+
}
60+
61+
this.gen.initGenrand(S);
62+
}
2463

2564
/**
2665
* Sets the seed to use.
@@ -30,48 +69,13 @@ export interface Mersenne {
3069
*
3170
* @since 5.5.0
3271
*/
33-
seedArray(A: number[]): void;
34-
}
35-
36-
/**
37-
* Generate seed based random numbers.
38-
*
39-
* @internal
40-
*/
41-
export default function mersenne(): Mersenne {
42-
const twister = new Twister();
43-
44-
twister.initGenrand(Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER));
45-
46-
return {
47-
rand(max = 32768, min = 0): number {
48-
if (min > max) {
49-
const temp = min;
50-
min = max;
51-
max = temp;
52-
}
53-
54-
return Math.floor(twister.genrandReal2() * (max - min) + min);
55-
},
56-
57-
seed(S: number): void {
58-
if (typeof S !== 'number') {
59-
throw new FakerError(
60-
`seed(S) must take numeric argument; is ${typeof S}`
61-
);
62-
}
63-
64-
twister.initGenrand(S);
65-
},
66-
67-
seedArray(A: number[]): void {
68-
if (typeof A !== 'object') {
69-
throw new FakerError(
70-
`seedArray(A) must take array of numbers; is ${typeof A}`
71-
);
72-
}
72+
seed_array(A: number[]): void {
73+
if (typeof A !== 'object') {
74+
throw new FakerError(
75+
`seed_array(A) must take array of numbers; is ${typeof A}`
76+
);
77+
}
7378

74-
twister.initByArray(A, A.length);
75-
},
76-
};
79+
this.gen.initByArray(A, A.length);
80+
}
7781
}

src/modules/datatype/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { Faker } from '../..';
22
import { FakerError } from '../../errors/faker-error';
3+
import type { MersenneModule } from '../../internal/mersenne/mersenne';
34

45
/**
56
* Module to generate various primitive values and data types.
@@ -54,7 +55,7 @@ export class DatatypeModule {
5455
throw new FakerError(`Max ${max} should be greater than min ${min}.`);
5556
}
5657

57-
const mersenne =
58+
const mersenne: MersenneModule =
5859
// @ts-expect-error: access private member field
5960
this.faker._mersenne;
6061

test/mersenne.spec.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { beforeAll, beforeEach, describe, expect, it } from 'vitest';
22
import { FakerError } from '../src/errors/faker-error';
3-
import type { Mersenne } from '../src/internal/mersenne/mersenne';
4-
import mersenneFn from '../src/internal/mersenne/mersenne';
3+
import { MersenneModule } from '../src/internal/mersenne/mersenne';
54
import { seededRuns } from './support/seededRuns';
65

76
const minMaxTestCases = [
@@ -15,17 +14,17 @@ const functionNames = ['rand'];
1514
const NON_SEEDED_BASED_RUN = 25;
1615

1716
describe('mersenne twister', () => {
18-
let mersenne: Mersenne;
17+
let mersenne: MersenneModule;
1918

2019
beforeEach(() => {
21-
mersenne = mersenneFn();
20+
mersenne = new MersenneModule();
2221
});
2322

2423
for (const seed of [...seededRuns, [42, 1, 2], [1337, 1, 2], [1211, 1, 2]]) {
2524
describe(`seed: ${JSON.stringify(seed)}`, () => {
2625
beforeEach(() => {
2726
if (Array.isArray(seed)) {
28-
mersenne.seedArray(seed);
27+
mersenne.seed_array(seed);
2928
} else {
3029
mersenne.seed(seed);
3130
}
@@ -68,7 +67,7 @@ describe('mersenne twister', () => {
6867
describe(`random seeded tests ${JSON.stringify(seed)}`, () => {
6968
beforeAll(() => {
7069
if (Array.isArray(seed)) {
71-
mersenne.seedArray(seed);
70+
mersenne.seed_array(seed);
7271
} else {
7372
mersenne.seed(seed);
7473
}
@@ -105,12 +104,12 @@ describe('mersenne twister', () => {
105104

106105
it('should throw an error when attempting to seed() a non-integer', () => {
107106
expect(() =>
108-
mersenne.seedArray(
107+
mersenne.seed_array(
109108
// @ts-expect-error: non-integer error
110109
'abc'
111110
)
112111
).toThrowError(
113-
new FakerError('seedArray(A) must take array of numbers; is string')
112+
new FakerError('seed_array(A) must take array of numbers; is string')
114113
);
115114
});
116115
});

test/scripts/apidoc/examplesAndDeprecations.spec.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,13 @@ describe('examples and deprecations', () => {
3232

3333
const modules: Record<string, DeclarationReflection[]> = selectApiModules(
3434
project
35-
)
36-
.filter((module) => module.name !== 'MersenneModule')
37-
.reduce(
38-
(a, v) => ({
39-
...a,
40-
[v.name]: v.getChildrenByKind(ReflectionKind.Method),
41-
}),
42-
{}
43-
);
35+
).reduce(
36+
(a, v) => ({
37+
...a,
38+
[v.name]: v.getChildrenByKind(ReflectionKind.Method),
39+
}),
40+
{}
41+
);
4442

4543
const consoleSpies: Array<SpyInstance> = Object.keys(console)
4644
.filter((key) => typeof console[key] === 'function')

0 commit comments

Comments
 (0)