Skip to content

Commit f3b9a3f

Browse files
authored
Merge pull request #21 from kos984/1.0.0-rc.3
1.0.0 rc.3
2 parents 0f5bed2 + ee83db2 commit f3b9a3f

26 files changed

Lines changed: 1735 additions & 76 deletions

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ku-progress-bar",
3-
"version": "1.0.0-rc.2",
3+
"version": "1.0.0-rc.3",
44
"description": "cli progress bar",
55
"main": "dist/index.js",
66
"homepage": "https://github.com/kos984/ku-cli-progress",
@@ -90,6 +90,12 @@
9090
"functions": 100,
9191
"lines": 100,
9292
"statements": -10
93+
},
94+
"src/examples": {
95+
"branches": 80,
96+
"functions": 80,
97+
"lines": 80,
98+
"statements": 80
9399
}
94100
}
95101
},

sonar-project.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ sonar.projectKey=kos984_ku-cli-progress
22
sonar.organization=kos984
33
sonar.javascript.lcov.reportPaths=./coverage/lcov.info
44
sonar.eslint.reportPaths=./reports/eslint-report.json
5-
sonar.coverage.exclusions=**/__tests__/*,**/examples/**
5+
sonar.coverage.exclusions=**/__tests__/*,**/examples/**,**/__mocks__/*
66
# Scope of duplication detection
7-
sonar.cpd.exclusions=**/__tests__/*
7+
sonar.cpd.exclusions=**/__tests__/*,**/examples/**,**/__mocks__/*
88

99
# This is the name and version displayed in the SonarCloud UI.
1010
#sonar.projectName=ku-cli-progress

src/examples/composite-progress/composite-progress.example.spec.ts

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ jest.mock('../../lib/terminals/terminal-tty');
22
jest.mock('../helpers/loop-progresses');
33
jest.mock('../../lib/formatters/bars-formatter');
44
jest.mock('../../lib/time/time');
5+
jest.mock('chalk', () => {
6+
return {
7+
green: (str: string) => `<green>${str}</green>`,
8+
yellowBright: (str: string) => `<yellowBright>${str}</yellowBright>`,
9+
};
10+
});
511

612
import { TerminalTty } from '../../lib/terminals/terminal-tty';
713
import { bar } from './composite-progress.example';
@@ -25,16 +31,16 @@ describe('CompositeProgressComponent', () => {
2531
exampleBarTestHelper.iterate(progress => progress.getTotal() / MAX_STEPS);
2632
const calls = terminalMock.write.mock.calls.map(call => call[0]);
2733
expect(calls).toMatchObject([
28-
'[00001111░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░] \x1B[32mread: 200/1000 ( 20% eta: ∞)\x1B[39m \x1B[93mwrite: 100/1000 ( 10% eta: ∞)\x1B[39m\n',
29-
'[000000001111░░░░░░░░░░░░░░░░░░░░░░░░░░░░] \x1B[32mread: 300/1000 ( 30% eta: 4s)\x1B[39m \x1B[93mwrite: 200/1000 ( 20% eta: 4s)\x1B[39m\n',
30-
'[0000000000001111░░░░░░░░░░░░░░░░░░░░░░░░] \x1B[32mread: 400/1000 ( 40% eta: 4s)\x1B[39m \x1B[93mwrite: 300/1000 ( 30% eta: 5s)\x1B[39m\n',
31-
'[00000000000000001111░░░░░░░░░░░░░░░░░░░░] \x1B[32mread: 500/1000 ( 50% eta: 4s)\x1B[39m \x1B[93mwrite: 400/1000 ( 40% eta: 5s)\x1B[39m\n',
32-
'[000000000000000000001111░░░░░░░░░░░░░░░░] \x1B[32mread: 600/1000 ( 60% eta: 3s)\x1B[39m \x1B[93mwrite: 500/1000 ( 50% eta: 4s)\x1B[39m\n',
33-
'[0000000000000000000000001111░░░░░░░░░░░░] \x1B[32mread: 700/1000 ( 70% eta: 3s)\x1B[39m \x1B[93mwrite: 600/1000 ( 60% eta: 4s)\x1B[39m\n',
34-
'[00000000000000000000000000001111░░░░░░░░] \x1B[32mread: 800/1000 ( 80% eta: 2s)\x1B[39m \x1B[93mwrite: 700/1000 ( 70% eta: 3s)\x1B[39m\n',
35-
'[000000000000000000000000000000001111░░░░] \x1B[32mread: 900/1000 ( 90% eta: 1s)\x1B[39m \x1B[93mwrite: 800/1000 ( 80% eta: 2s)\x1B[39m\n',
36-
'[0000000000000000000000000000000000001111] \x1B[32mread: 1000/1000 ( 100% eta: 0s)\x1B[39m \x1B[93mwrite: 900/1000 ( 90% eta: 1s)\x1B[39m\n',
37-
'[0000000000000000000000000000000000000000] \x1B[32mread: 1000/1000 ( 100% eta: 0s)\x1B[39m \x1B[93mwrite: 1000/1000 ( 100% eta: 0s)\x1B[39m\n',
34+
'[00001111░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░] <green>read: 200/1000 ( 20% eta: ∞)</green> <yellowBright>write: 100/1000 ( 10% eta: ∞)</yellowBright>\n',
35+
'[000000001111░░░░░░░░░░░░░░░░░░░░░░░░░░░░] <green>read: 300/1000 ( 30% eta: 4s)</green> <yellowBright>write: 200/1000 ( 20% eta: 4s)</yellowBright>\n',
36+
'[0000000000001111░░░░░░░░░░░░░░░░░░░░░░░░] <green>read: 400/1000 ( 40% eta: 4s)</green> <yellowBright>write: 300/1000 ( 30% eta: 5s)</yellowBright>\n',
37+
'[00000000000000001111░░░░░░░░░░░░░░░░░░░░] <green>read: 500/1000 ( 50% eta: 4s)</green> <yellowBright>write: 400/1000 ( 40% eta: 5s)</yellowBright>\n',
38+
'[000000000000000000001111░░░░░░░░░░░░░░░░] <green>read: 600/1000 ( 60% eta: 3s)</green> <yellowBright>write: 500/1000 ( 50% eta: 4s)</yellowBright>\n',
39+
'[0000000000000000000000001111░░░░░░░░░░░░] <green>read: 700/1000 ( 70% eta: 3s)</green> <yellowBright>write: 600/1000 ( 60% eta: 4s)</yellowBright>\n',
40+
'[00000000000000000000000000001111░░░░░░░░] <green>read: 800/1000 ( 80% eta: 2s)</green> <yellowBright>write: 700/1000 ( 70% eta: 3s)</yellowBright>\n',
41+
'[000000000000000000000000000000001111░░░░] <green>read: 900/1000 ( 90% eta: 1s)</green> <yellowBright>write: 800/1000 ( 80% eta: 2s)</yellowBright>\n',
42+
'[0000000000000000000000000000000000001111] <green>read: 1000/1000 ( 100% eta: 0s)</green> <yellowBright>write: 900/1000 ( 90% eta: 1s)</yellowBright>\n',
43+
'[0000000000000000000000000000000000000000] <green>read: 1000/1000 ( 100% eta: 0s)</green> <yellowBright>write: 1000/1000 ( 100% eta: 0s)</yellowBright>\n',
3844
]);
3945
});
4046

@@ -44,15 +50,15 @@ describe('CompositeProgressComponent', () => {
4450
);
4551
const calls = terminalMock.write.mock.calls.map(call => call[0]);
4652
expect(calls).toMatchObject([
47-
'[00000000░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░] \x1B[32mread: 200/1000 ( 20% eta: ∞)\x1B[39m \x1B[93mwrite: 200/1000 ( 20% eta: ∞)\x1B[39m\n',
48-
'[0000000000001111░░░░░░░░░░░░░░░░░░░░░░░░] \x1B[32mread: 300/1000 ( 30% eta: 4s)\x1B[39m \x1B[93mwrite: 400/1000 ( 40% eta: 2s)\x1B[39m\n',
49-
'[000000000000000011111111░░░░░░░░░░░░░░░░] \x1B[32mread: 400/1000 ( 40% eta: 4s)\x1B[39m \x1B[93mwrite: 600/1000 ( 60% eta: 1s)\x1B[39m\n',
50-
'[00000000000000000000111111111111░░░░░░░░] \x1B[32mread: 500/1000 ( 50% eta: 4s)\x1B[39m \x1B[93mwrite: 800/1000 ( 80% eta: 1s)\x1B[39m\n',
51-
'[0000000000000000000000001111111111111111] \x1B[32mread: 600/1000 ( 60% eta: 3s)\x1B[39m \x1B[93mwrite: 1000/1000 ( 100% eta: 0s)\x1B[39m\n',
52-
'[0000000000000000000000000000111111111111] \x1B[32mread: 700/1000 ( 70% eta: 3s)\x1B[39m \x1B[93mwrite: 1000/1000 ( 100% eta: 0s)\x1B[39m\n',
53-
'[0000000000000000000000000000000011111111] \x1B[32mread: 800/1000 ( 80% eta: 2s)\x1B[39m \x1B[93mwrite: 1000/1000 ( 100% eta: 0s)\x1B[39m\n',
54-
'[0000000000000000000000000000000000001111] \x1B[32mread: 900/1000 ( 90% eta: 1s)\x1B[39m \x1B[93mwrite: 1000/1000 ( 100% eta: 0s)\x1B[39m\n',
55-
'[0000000000000000000000000000000000000000] \x1B[32mread: 1000/1000 ( 100% eta: 0s)\x1B[39m \x1B[93mwrite: 1000/1000 ( 100% eta: 0s)\x1B[39m\n',
53+
'[00000000░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░] <green>read: 200/1000 ( 20% eta: ∞)</green> <yellowBright>write: 200/1000 ( 20% eta: ∞)</yellowBright>\n',
54+
'[0000000000001111░░░░░░░░░░░░░░░░░░░░░░░░] <green>read: 300/1000 ( 30% eta: 4s)</green> <yellowBright>write: 400/1000 ( 40% eta: 2s)</yellowBright>\n',
55+
'[000000000000000011111111░░░░░░░░░░░░░░░░] <green>read: 400/1000 ( 40% eta: 4s)</green> <yellowBright>write: 600/1000 ( 60% eta: 1s)</yellowBright>\n',
56+
'[00000000000000000000111111111111░░░░░░░░] <green>read: 500/1000 ( 50% eta: 4s)</green> <yellowBright>write: 800/1000 ( 80% eta: 1s)</yellowBright>\n',
57+
'[0000000000000000000000001111111111111111] <green>read: 600/1000 ( 60% eta: 3s)</green> <yellowBright>write: 1000/1000 ( 100% eta: 0s)</yellowBright>\n',
58+
'[0000000000000000000000000000111111111111] <green>read: 700/1000 ( 70% eta: 3s)</green> <yellowBright>write: 1000/1000 ( 100% eta: 0s)</yellowBright>\n',
59+
'[0000000000000000000000000000000011111111] <green>read: 800/1000 ( 80% eta: 2s)</green> <yellowBright>write: 1000/1000 ( 100% eta: 0s)</yellowBright>\n',
60+
'[0000000000000000000000000000000000001111] <green>read: 900/1000 ( 90% eta: 1s)</green> <yellowBright>write: 1000/1000 ( 100% eta: 0s)</yellowBright>\n',
61+
'[0000000000000000000000000000000000000000] <green>read: 1000/1000 ( 100% eta: 0s)</green> <yellowBright>write: 1000/1000 ( 100% eta: 0s)</yellowBright>\n',
5662
]);
5763
});
5864

@@ -65,16 +71,16 @@ describe('CompositeProgressComponent', () => {
6571
);
6672
const calls = terminalMock.write.mock.calls.map(call => call[0]);
6773
expect(calls).toMatchObject([
68-
'[000011111111░░░░░░░░░░░░░░░░░░░░░░░░░░░░] \x1B[32mread: 300/1000 ( 30% eta: ∞)\x1B[39m \x1B[93mwrite: 100/1000 ( 10% eta: ∞)\x1B[39m\n',
69-
'[00000000111111111111░░░░░░░░░░░░░░░░░░░░] \x1B[32mread: 500/1000 ( 50% eta: 1s)\x1B[39m \x1B[93mwrite: 200/1000 ( 20% eta: 4s)\x1B[39m\n',
70-
'[0000000000001111111111111111░░░░░░░░░░░░] \x1B[32mread: 700/1000 ( 70% eta: 1s)\x1B[39m \x1B[93mwrite: 300/1000 ( 30% eta: 5s)\x1B[39m\n',
71-
'[000000000000000011111111111111111111░░░░] \x1B[32mread: 900/1000 ( 90% eta: 0s)\x1B[39m \x1B[93mwrite: 400/1000 ( 40% eta: 5s)\x1B[39m\n',
72-
'[0000000000000000000011111111111111111111] \x1B[32mread: 1000/1000 ( 100% eta: 0s)\x1B[39m \x1B[93mwrite: 500/1000 ( 50% eta: 4s)\x1B[39m\n',
73-
'[0000000000000000000000001111111111111111] \x1B[32mread: 1000/1000 ( 100% eta: 0s)\x1B[39m \x1B[93mwrite: 600/1000 ( 60% eta: 4s)\x1B[39m\n',
74-
'[0000000000000000000000000000111111111111] \x1B[32mread: 1000/1000 ( 100% eta: 0s)\x1B[39m \x1B[93mwrite: 700/1000 ( 70% eta: 3s)\x1B[39m\n',
75-
'[0000000000000000000000000000000011111111] \x1B[32mread: 1000/1000 ( 100% eta: 0s)\x1B[39m \x1B[93mwrite: 800/1000 ( 80% eta: 2s)\x1B[39m\n',
76-
'[0000000000000000000000000000000000001111] \x1B[32mread: 1000/1000 ( 100% eta: 0s)\x1B[39m \x1B[93mwrite: 900/1000 ( 90% eta: 1s)\x1B[39m\n',
77-
'[0000000000000000000000000000000000000000] \x1B[32mread: 1000/1000 ( 100% eta: 0s)\x1B[39m \x1B[93mwrite: 1000/1000 ( 100% eta: 0s)\x1B[39m\n',
74+
'[000011111111░░░░░░░░░░░░░░░░░░░░░░░░░░░░] <green>read: 300/1000 ( 30% eta: ∞)</green> <yellowBright>write: 100/1000 ( 10% eta: ∞)</yellowBright>\n',
75+
'[00000000111111111111░░░░░░░░░░░░░░░░░░░░] <green>read: 500/1000 ( 50% eta: 1s)</green> <yellowBright>write: 200/1000 ( 20% eta: 4s)</yellowBright>\n',
76+
'[0000000000001111111111111111░░░░░░░░░░░░] <green>read: 700/1000 ( 70% eta: 1s)</green> <yellowBright>write: 300/1000 ( 30% eta: 5s)</yellowBright>\n',
77+
'[000000000000000011111111111111111111░░░░] <green>read: 900/1000 ( 90% eta: 0s)</green> <yellowBright>write: 400/1000 ( 40% eta: 5s)</yellowBright>\n',
78+
'[0000000000000000000011111111111111111111] <green>read: 1000/1000 ( 100% eta: 0s)</green> <yellowBright>write: 500/1000 ( 50% eta: 4s)</yellowBright>\n',
79+
'[0000000000000000000000001111111111111111] <green>read: 1000/1000 ( 100% eta: 0s)</green> <yellowBright>write: 600/1000 ( 60% eta: 4s)</yellowBright>\n',
80+
'[0000000000000000000000000000111111111111] <green>read: 1000/1000 ( 100% eta: 0s)</green> <yellowBright>write: 700/1000 ( 70% eta: 3s)</yellowBright>\n',
81+
'[0000000000000000000000000000000011111111] <green>read: 1000/1000 ( 100% eta: 0s)</green> <yellowBright>write: 800/1000 ( 80% eta: 2s)</yellowBright>\n',
82+
'[0000000000000000000000000000000000001111] <green>read: 1000/1000 ( 100% eta: 0s)</green> <yellowBright>write: 900/1000 ( 90% eta: 1s)</yellowBright>\n',
83+
'[0000000000000000000000000000000000000000] <green>read: 1000/1000 ( 100% eta: 0s)</green> <yellowBright>write: 1000/1000 ( 100% eta: 0s)</yellowBright>\n',
7884
]);
7985
});
8086
});
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { loopProgresses, start } from '../loop-progresses';
2+
import { IProgress } from '../../../lib/interfaces/progress.interface';
3+
4+
// Mock console.error to avoid noise in tests
5+
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
6+
7+
describe('loop-progresses', () => {
8+
beforeEach(() => {
9+
jest.clearAllMocks();
10+
jest.useFakeTimers();
11+
});
12+
13+
afterEach(() => {
14+
jest.useRealTimers();
15+
});
16+
17+
describe('loopProgresses', () => {
18+
it('should loop progresses with default delay', () => {
19+
const mockProgress1 = {
20+
increment: jest.fn(),
21+
getProgress: jest.fn().mockReturnValue(0),
22+
} as unknown as IProgress;
23+
24+
const mockProgress2 = {
25+
increment: jest.fn(),
26+
getProgress: jest.fn().mockReturnValue(0),
27+
} as unknown as IProgress;
28+
29+
const progresses = [mockProgress1, mockProgress2];
30+
const intervals = loopProgresses(progresses);
31+
32+
expect(intervals).toHaveLength(2);
33+
expect(intervals[0]).toBeDefined();
34+
expect(intervals[1]).toBeDefined();
35+
36+
// Fast-forward time to trigger intervals
37+
jest.advanceTimersByTime(100);
38+
39+
expect(mockProgress1.increment).toHaveBeenCalled();
40+
expect(mockProgress2.increment).toHaveBeenCalled();
41+
});
42+
43+
it('should loop progresses with custom delay function', () => {
44+
const mockProgress = {
45+
increment: jest.fn(),
46+
getProgress: jest.fn().mockReturnValue(0),
47+
} as unknown as IProgress;
48+
49+
const customDelay = jest.fn().mockReturnValue(200);
50+
const progresses = [mockProgress];
51+
const intervals = loopProgresses(progresses, { getDelay: customDelay });
52+
53+
expect(intervals).toHaveLength(1);
54+
expect(customDelay).toHaveBeenCalled();
55+
56+
// Fast-forward time to trigger interval
57+
jest.advanceTimersByTime(200);
58+
59+
expect(mockProgress.increment).toHaveBeenCalled();
60+
});
61+
62+
it('should stop interval when progress reaches 1', () => {
63+
const mockProgress = {
64+
increment: jest.fn(),
65+
getProgress: jest.fn().mockReturnValue(1), // Always return 1 (complete)
66+
} as unknown as IProgress;
67+
68+
const progresses = [mockProgress];
69+
const intervals = loopProgresses(progresses);
70+
71+
expect(intervals).toHaveLength(1);
72+
73+
// Fast-forward time to trigger interval
74+
jest.advanceTimersByTime(100);
75+
76+
// Should increment once, then check and stop
77+
expect(mockProgress.increment).toHaveBeenCalledTimes(1);
78+
});
79+
80+
it('should handle empty progresses array', () => {
81+
const intervals = loopProgresses([]);
82+
expect(intervals).toHaveLength(0);
83+
});
84+
});
85+
86+
describe('start', () => {
87+
it('should execute function and catch errors', () => {
88+
const mockFunction = jest.fn().mockRejectedValue(new Error('Test error'));
89+
90+
start(mockFunction);
91+
92+
// The function should be called immediately
93+
expect(mockFunction).toHaveBeenCalled();
94+
});
95+
96+
it('should execute function successfully', () => {
97+
const mockFunction = jest.fn().mockResolvedValue(undefined);
98+
99+
start(mockFunction);
100+
101+
// The function should be called immediately
102+
expect(mockFunction).toHaveBeenCalled();
103+
});
104+
});
105+
});
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import { SeededRandom } from '../seed-random';
2+
3+
describe('SeededRandom', () => {
4+
describe('constructor', () => {
5+
it('should initialize with positive seed', () => {
6+
const rnd = new SeededRandom(12345);
7+
expect(rnd.seed).toBe(12345);
8+
});
9+
10+
it('should handle negative seed by adding 2147483646', () => {
11+
const rnd = new SeededRandom(-5);
12+
expect(rnd.seed).toBe(2147483641); // -5 + 2147483646
13+
});
14+
15+
it('should handle zero seed by adding 2147483646', () => {
16+
const rnd = new SeededRandom(0);
17+
expect(rnd.seed).toBe(2147483646);
18+
});
19+
20+
it('should handle large seed by modulo operation', () => {
21+
const rnd = new SeededRandom(3000000000);
22+
expect(rnd.seed).toBe(852516353); // 3000000000 % 2147483647
23+
});
24+
25+
it('should handle large negative seed', () => {
26+
const rnd = new SeededRandom(-3000000000);
27+
expect(rnd.seed).toBe(1294967293); // (-3000000000 % 2147483647) + 2147483646
28+
});
29+
});
30+
31+
describe('next', () => {
32+
it('should generate consistent values with same seed', () => {
33+
const rnd1 = new SeededRandom(12345);
34+
const rnd2 = new SeededRandom(12345);
35+
36+
const values1 = [rnd1.next(), rnd1.next(), rnd1.next()];
37+
const values2 = [rnd2.next(), rnd2.next(), rnd2.next()];
38+
39+
expect(values1).toEqual(values2);
40+
});
41+
42+
it('should generate different values with different seeds', () => {
43+
const rnd1 = new SeededRandom(12345);
44+
const rnd2 = new SeededRandom(54321);
45+
46+
const value1 = rnd1.next();
47+
const value2 = rnd2.next();
48+
49+
expect(value1).not.toBe(value2);
50+
});
51+
52+
it('should generate values between 0 and 1', () => {
53+
const rnd = new SeededRandom(12345);
54+
55+
for (let i = 0; i < 100; i++) {
56+
const value = rnd.next();
57+
expect(value).toBeGreaterThanOrEqual(0);
58+
expect(value).toBeLessThan(1);
59+
}
60+
});
61+
62+
it('should update internal seed', () => {
63+
const rnd = new SeededRandom(12345);
64+
const initialSeed = rnd.seed;
65+
66+
rnd.next();
67+
const newSeed = rnd.seed;
68+
69+
expect(newSeed).not.toBe(initialSeed);
70+
});
71+
});
72+
73+
describe('nextInRange', () => {
74+
it('should generate values within specified range', () => {
75+
const rnd = new SeededRandom(12345);
76+
77+
for (let i = 0; i < 100; i++) {
78+
const value = rnd.nextInRange(5, 10);
79+
expect(value).toBeGreaterThanOrEqual(5);
80+
expect(value).toBeLessThanOrEqual(10);
81+
}
82+
});
83+
84+
it('should handle single value range', () => {
85+
const rnd = new SeededRandom(12345);
86+
87+
for (let i = 0; i < 10; i++) {
88+
const value = rnd.nextInRange(7, 7);
89+
expect(value).toBe(7);
90+
}
91+
});
92+
93+
it('should handle negative range', () => {
94+
const rnd = new SeededRandom(12345);
95+
96+
for (let i = 0; i < 100; i++) {
97+
const value = rnd.nextInRange(-10, -5);
98+
expect(value).toBeGreaterThanOrEqual(-10);
99+
expect(value).toBeLessThanOrEqual(-5);
100+
}
101+
});
102+
103+
it('should generate consistent values with same seed', () => {
104+
const rnd1 = new SeededRandom(12345);
105+
const rnd2 = new SeededRandom(12345);
106+
107+
const values1 = [
108+
rnd1.nextInRange(1, 10),
109+
rnd1.nextInRange(1, 10),
110+
rnd1.nextInRange(1, 10),
111+
];
112+
const values2 = [
113+
rnd2.nextInRange(1, 10),
114+
rnd2.nextInRange(1, 10),
115+
rnd2.nextInRange(1, 10),
116+
];
117+
118+
expect(values1).toEqual(values2);
119+
});
120+
121+
it('should handle large range', () => {
122+
const rnd = new SeededRandom(12345);
123+
124+
for (let i = 0; i < 100; i++) {
125+
const value = rnd.nextInRange(1, 1000);
126+
expect(value).toBeGreaterThanOrEqual(1);
127+
expect(value).toBeLessThanOrEqual(1000);
128+
}
129+
});
130+
});
131+
});
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
export class SeededRandom {
2-
protected seed: number;
2+
public seed: number;
33

44
public constructor(seed) {
55
this.seed = seed % 2147483647;
66
if (this.seed <= 0) this.seed += 2147483646;
77
}
88

9-
public next() {
9+
public next(): number {
1010
this.seed = (this.seed * 16807) % 2147483647;
1111
return (this.seed - 1) / 2147483646;
1212
}
1313

14-
nextInRange(min, max) {
14+
nextInRange(min, max): number {
1515
return Math.floor(this.next() * (max - min + 1)) + min;
1616
}
1717
}

0 commit comments

Comments
 (0)