Skip to content

Commit dd3689a

Browse files
committed
Revert "chore: revert changes to do them in separate PR"
This reverts commit 56c7a95.
1 parent 931de69 commit dd3689a

File tree

5 files changed

+89
-115
lines changed

5 files changed

+89
-115
lines changed

src/faker.ts

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

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

8081
readonly random: RandomModule = new RandomModule(this);
8182

@@ -239,11 +240,7 @@ export class Faker {
239240
seed(
240241
seed: number | number[] = Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER)
241242
): number | number[] {
242-
if (Array.isArray(seed) && seed.length) {
243-
this._mersenne.seed_array(seed);
244-
} else if (!Array.isArray(seed) && !isNaN(seed)) {
245-
this._mersenne.seed(seed);
246-
}
243+
this._mersenne.seed(seed);
247244

248245
return seed;
249246
}

src/internal/mersenne/mersenne.ts

Lines changed: 42 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,64 @@
11
import { FakerError } from '../../errors/faker-error';
2-
import Gen from './twister';
2+
import Twister from './twister';
33

44
/**
5-
* Module to generate seed based random numbers.
5+
* Generate seed based random numbers.
66
*
77
* @internal
88
*/
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-
}
23-
9+
export interface Mersenne {
2410
/**
2511
* Generates a random number between `[min, max)`.
2612
*
2713
* @param max The maximum number. Defaults to `32768`.
2814
* @param min The minimum number. Defaults to `0`.
29-
*
30-
* @example
31-
* faker.mersenne.rand() // 15515
32-
* faker.mersenne.rand(1000, 500) // 578
33-
*
34-
* @since 5.5.0
3515
*/
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-
}
16+
next(max?: number, min?: number): number;
4517

4618
/**
4719
* Sets the seed to use.
4820
*
49-
* @param S The seed to use.
50-
* @throws If the seed is not a `number`.
51-
*
52-
* @since 5.5.0
21+
* @param seed The seed to use.
22+
* @throws If the seed is not a `number` or `number[]`.
5323
*/
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-
}
24+
seed(seed: number | number[]): void;
25+
}
6026

61-
this.gen.initGenrand(S);
62-
}
27+
/**
28+
* Generate seed based random numbers.
29+
*
30+
* @internal
31+
*/
32+
export default function mersenne(): Mersenne {
33+
const twister = new Twister();
34+
35+
twister.initGenrand(Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER));
36+
37+
return {
38+
next(max = 32768, min = 0): number {
39+
if (min > max) {
40+
const temp = min;
41+
min = max;
42+
max = temp;
43+
}
44+
45+
return Math.floor(twister.genrandReal2() * (max - min) + min);
46+
},
47+
48+
seed(seed: number | number[]): void {
49+
if (typeof seed === 'number') {
50+
twister.initGenrand(seed);
51+
return;
52+
}
53+
54+
if (Array.isArray(seed)) {
55+
twister.initByArray(seed, seed.length);
56+
return;
57+
}
6358

64-
/**
65-
* Sets the seed to use.
66-
*
67-
* @param A The seed to use.
68-
* @throws If the seed is not a `number[]`.
69-
*
70-
* @since 5.5.0
71-
*/
72-
seed_array(A: number[]): void {
73-
if (typeof A !== 'object') {
7459
throw new FakerError(
75-
`seed_array(A) must take array of numbers; is ${typeof A}`
60+
`seed must take numeric argument(s); is ${typeof seed}`
7661
);
77-
}
78-
79-
this.gen.initByArray(A, A.length);
80-
}
62+
},
63+
};
8164
}

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 { Mersenne } from '../../internal/mersenne/mersenne';
34

45
/**
56
* Module to generate various primitive values and data types.
@@ -59,7 +60,7 @@ export class DatatypeModule {
5960
this.faker._mersenne;
6061

6162
const randomNumber = Math.floor(
62-
mersenne.rand(max / precision + 1, min / precision)
63+
mersenne.next(max / precision + 1, min / precision)
6364
);
6465

6566
// Workaround problem in float point arithmetics for e.g. 6681493 / 0.01
Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,49 @@
11
// Vitest Snapshot v1
22

3-
exports[`mersenne twister > seed: [42,1,2] > rand() 1`] = `28056`;
3+
exports[`mersenne twister > seed: [42,1,2] > next() 1`] = `28056`;
44

5-
exports[`mersenne twister > seed: [42,1,2] > should return deterministic values for rand(100, 0) 1`] = `85`;
5+
exports[`mersenne twister > seed: [42,1,2] > should return deterministic values for next(100, 0) 1`] = `85`;
66

7-
exports[`mersenne twister > seed: [42,1,2] > should return deterministic values for rand(100, undefined) 1`] = `85`;
7+
exports[`mersenne twister > seed: [42,1,2] > should return deterministic values for next(100, undefined) 1`] = `85`;
88

9-
exports[`mersenne twister > seed: [42,1,2] > should return deterministic values for rand(undefined, 0) 1`] = `28056`;
9+
exports[`mersenne twister > seed: [42,1,2] > should return deterministic values for next(undefined, 0) 1`] = `28056`;
1010

11-
exports[`mersenne twister > seed: [1211,1,2] > rand() 1`] = `29217`;
11+
exports[`mersenne twister > seed: [1211,1,2] > next() 1`] = `29217`;
1212

13-
exports[`mersenne twister > seed: [1211,1,2] > should return deterministic values for rand(100, 0) 1`] = `89`;
13+
exports[`mersenne twister > seed: [1211,1,2] > should return deterministic values for next(100, 0) 1`] = `89`;
1414

15-
exports[`mersenne twister > seed: [1211,1,2] > should return deterministic values for rand(100, undefined) 1`] = `89`;
15+
exports[`mersenne twister > seed: [1211,1,2] > should return deterministic values for next(100, undefined) 1`] = `89`;
1616

17-
exports[`mersenne twister > seed: [1211,1,2] > should return deterministic values for rand(undefined, 0) 1`] = `29217`;
17+
exports[`mersenne twister > seed: [1211,1,2] > should return deterministic values for next(undefined, 0) 1`] = `29217`;
1818

19-
exports[`mersenne twister > seed: [1337,1,2] > rand() 1`] = `5895`;
19+
exports[`mersenne twister > seed: [1337,1,2] > next() 1`] = `5895`;
2020

21-
exports[`mersenne twister > seed: [1337,1,2] > should return deterministic values for rand(100, 0) 1`] = `17`;
21+
exports[`mersenne twister > seed: [1337,1,2] > should return deterministic values for next(100, 0) 1`] = `17`;
2222

23-
exports[`mersenne twister > seed: [1337,1,2] > should return deterministic values for rand(100, undefined) 1`] = `17`;
23+
exports[`mersenne twister > seed: [1337,1,2] > should return deterministic values for next(100, undefined) 1`] = `17`;
2424

25-
exports[`mersenne twister > seed: [1337,1,2] > should return deterministic values for rand(undefined, 0) 1`] = `5895`;
25+
exports[`mersenne twister > seed: [1337,1,2] > should return deterministic values for next(undefined, 0) 1`] = `5895`;
2626

27-
exports[`mersenne twister > seed: 42 > rand() 1`] = `12272`;
27+
exports[`mersenne twister > seed: 42 > next() 1`] = `12272`;
2828

29-
exports[`mersenne twister > seed: 42 > should return deterministic values for rand(100, 0) 1`] = `37`;
29+
exports[`mersenne twister > seed: 42 > should return deterministic values for next(100, 0) 1`] = `37`;
3030

31-
exports[`mersenne twister > seed: 42 > should return deterministic values for rand(100, undefined) 1`] = `37`;
31+
exports[`mersenne twister > seed: 42 > should return deterministic values for next(100, undefined) 1`] = `37`;
3232

33-
exports[`mersenne twister > seed: 42 > should return deterministic values for rand(undefined, 0) 1`] = `12272`;
33+
exports[`mersenne twister > seed: 42 > should return deterministic values for next(undefined, 0) 1`] = `12272`;
3434

35-
exports[`mersenne twister > seed: 1211 > rand() 1`] = `30425`;
35+
exports[`mersenne twister > seed: 1211 > next() 1`] = `30425`;
3636

37-
exports[`mersenne twister > seed: 1211 > should return deterministic values for rand(100, 0) 1`] = `92`;
37+
exports[`mersenne twister > seed: 1211 > should return deterministic values for next(100, 0) 1`] = `92`;
3838

39-
exports[`mersenne twister > seed: 1211 > should return deterministic values for rand(100, undefined) 1`] = `92`;
39+
exports[`mersenne twister > seed: 1211 > should return deterministic values for next(100, undefined) 1`] = `92`;
4040

41-
exports[`mersenne twister > seed: 1211 > should return deterministic values for rand(undefined, 0) 1`] = `30425`;
41+
exports[`mersenne twister > seed: 1211 > should return deterministic values for next(undefined, 0) 1`] = `30425`;
4242

43-
exports[`mersenne twister > seed: 1337 > rand() 1`] = `8586`;
43+
exports[`mersenne twister > seed: 1337 > next() 1`] = `8586`;
4444

45-
exports[`mersenne twister > seed: 1337 > should return deterministic values for rand(100, 0) 1`] = `26`;
45+
exports[`mersenne twister > seed: 1337 > should return deterministic values for next(100, 0) 1`] = `26`;
4646

47-
exports[`mersenne twister > seed: 1337 > should return deterministic values for rand(100, undefined) 1`] = `26`;
47+
exports[`mersenne twister > seed: 1337 > should return deterministic values for next(100, undefined) 1`] = `26`;
4848

49-
exports[`mersenne twister > seed: 1337 > should return deterministic values for rand(undefined, 0) 1`] = `8586`;
49+
exports[`mersenne twister > seed: 1337 > should return deterministic values for next(undefined, 0) 1`] = `8586`;

test/mersenne.spec.ts

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

67
const minMaxTestCases = [
@@ -9,25 +10,21 @@ const minMaxTestCases = [
910
{ max: 100, min: undefined },
1011
];
1112

12-
const functionNames = ['rand'];
13+
const functionNames = ['next'];
1314

1415
const NON_SEEDED_BASED_RUN = 25;
1516

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

1920
beforeEach(() => {
20-
mersenne = new MersenneModule();
21+
mersenne = mersenneFn();
2122
});
2223

2324
for (const seed of [...seededRuns, [42, 1, 2], [1337, 1, 2], [1211, 1, 2]]) {
2425
describe(`seed: ${JSON.stringify(seed)}`, () => {
2526
beforeEach(() => {
26-
if (Array.isArray(seed)) {
27-
mersenne.seed_array(seed);
28-
} else {
29-
mersenne.seed(seed);
30-
}
27+
mersenne.seed(seed);
3128
});
3229

3330
for (const functionName of functionNames) {
@@ -39,15 +36,15 @@ describe('mersenne twister', () => {
3936
}
4037

4138
for (const { min, max } of minMaxTestCases) {
42-
it(`should return deterministic values for rand(${max}, ${min})`, () => {
43-
const actual = mersenne.rand(max, min);
39+
it(`should return deterministic values for next(${max}, ${min})`, () => {
40+
const actual = mersenne.next(max, min);
4441

4542
expect(actual).toMatchSnapshot();
4643
});
4744
}
4845

49-
it.todo(`should return 0 for rand(1)`, () => {
50-
const actual = mersenne.rand(1);
46+
it.todo(`should return 0 for next(1)`, () => {
47+
const actual = mersenne.next(1);
5148

5249
expect(actual).toEqual(0);
5350
});
@@ -66,22 +63,18 @@ describe('mersenne twister', () => {
6663
for (const seed of seeds) {
6764
describe(`random seeded tests ${JSON.stringify(seed)}`, () => {
6865
beforeAll(() => {
69-
if (Array.isArray(seed)) {
70-
mersenne.seed_array(seed);
71-
} else {
72-
mersenne.seed(seed);
73-
}
66+
mersenne.seed(seed);
7467
});
7568

7669
for (let i = 1; i <= NON_SEEDED_BASED_RUN; i++) {
77-
describe('rand', () => {
70+
describe('next', () => {
7871
it('should return a random number without given min / max arguments', () => {
79-
const randomNumber = mersenne.rand();
72+
const randomNumber = mersenne.next();
8073
expect(randomNumber).toBeTypeOf('number');
8174
});
8275

8376
it('should return random number from interval [min, max)', () => {
84-
const actual = mersenne.rand(0, 2);
77+
const actual = mersenne.next(0, 2);
8578

8679
expect(actual).toBeGreaterThanOrEqual(0);
8780
expect(actual).toBeLessThan(2);
@@ -98,18 +91,18 @@ describe('mersenne twister', () => {
9891
'abc'
9992
)
10093
).toThrowError(
101-
new FakerError('seed(S) must take numeric argument; is string')
94+
new FakerError('seed must take numeric argument(s); is string')
10295
);
10396
});
10497

10598
it('should throw an error when attempting to seed() a non-integer', () => {
10699
expect(() =>
107-
mersenne.seed_array(
100+
mersenne.seed(
108101
// @ts-expect-error: non-integer error
109102
'abc'
110103
)
111104
).toThrowError(
112-
new FakerError('seed_array(A) must take array of numbers; is string')
105+
new FakerError('seed must take numeric argument(s); is string')
113106
);
114107
});
115108
});

0 commit comments

Comments
 (0)