Skip to content

Commit ed1853f

Browse files
committed
Updates RandomUtil Tests
Updates the tests for the changes made to the RandomUtil class.
1 parent f2b8efe commit ed1853f

File tree

1 file changed

+65
-82
lines changed

1 file changed

+65
-82
lines changed

project/tests/utils/RandomUtil.test.ts

+65-82
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,13 @@ describe("RandomUtil", () => {
88
let mockLogger: any;
99

1010
beforeEach(() => {
11-
// Mock dependencies
1211
mockCloner = {
1312
clone: vi.fn((obj) => JSON.parse(JSON.stringify(obj))),
1413
};
15-
1614
mockLogger = {
1715
warning: vi.fn(),
1816
info: vi.fn(),
1917
};
20-
21-
// Instantiate RandomUtil with mocked dependencies
2218
randomUtil = new RandomUtil(mockCloner, mockLogger);
2319
});
2420

@@ -74,18 +70,6 @@ describe("RandomUtil", () => {
7470
expect(result).toBeLessThanOrEqual(Math.floor(max));
7571
expect(Number.isInteger(result)).toBe(true);
7672
});
77-
78-
it("should return predictable result when Math.random is mocked", () => {
79-
// Mock Math.random to always return 0.5
80-
vi.spyOn(Math, "random").mockReturnValue(0.5);
81-
82-
const min = 1;
83-
const max = 5;
84-
const expected = Math.floor(0.5 * (Math.floor(max) - Math.ceil(min) + 1) + Math.ceil(min));
85-
const result = randomUtil.getInt(min, max);
86-
87-
expect(result).toBe(expected);
88-
});
8973
});
9074

9175
describe("getIntEx", () => {
@@ -112,28 +96,6 @@ describe("RandomUtil", () => {
11296

11397
expect(result).toBe(1);
11498
});
115-
116-
it("should return predictable result when Math.random is mocked", () => {
117-
// Mock Math.random to always return 0.5
118-
vi.spyOn(Math, "random").mockReturnValue(0.5);
119-
120-
const max = 10;
121-
// Expected calculation: Math.floor(0.5 * (10 - 2) + 1) = Math.floor(0.5 * 8 + 1) = Math.floor(5) = 5
122-
const expected = 5;
123-
const result = randomUtil.getIntEx(max);
124-
125-
expect(result).toBe(expected);
126-
});
127-
128-
it("should return 1 when max is 2 (edge case with Math.random mocked)", () => {
129-
// Mock Math.random to always return 0.99
130-
vi.spyOn(Math, "random").mockReturnValue(0.99);
131-
132-
const max = 2;
133-
const result = randomUtil.getIntEx(max);
134-
135-
expect(result).toBe(1);
136-
});
13799
});
138100

139101
describe("getFloat", () => {
@@ -162,17 +124,6 @@ describe("RandomUtil", () => {
162124

163125
expect(result).toBe(min);
164126
});
165-
166-
it("should return a predictable value when Math.random is mocked", () => {
167-
vi.spyOn(Math, "random").mockReturnValue(0.5);
168-
169-
const min = 2.0;
170-
const max = 4.0;
171-
const expected = 3.0;
172-
const result = randomUtil.getFloat(min, max);
173-
174-
expect(result).toBe(expected);
175-
});
176127
});
177128

178129
describe("getBool", () => {
@@ -182,13 +133,13 @@ describe("RandomUtil", () => {
182133
});
183134

184135
it("should return true when Math.random is less than 0.5", () => {
185-
vi.spyOn(Math, "random").mockReturnValue(0.3);
136+
vi.spyOn(randomUtil as any, "getSecureRandomNumber").mockReturnValue(0.4);
186137
const result = randomUtil.getBool();
187138
expect(result).toBe(true);
188139
});
189140

190-
it("should return false when Math.random is greater than or equal to 0.5", () => {
191-
vi.spyOn(Math, "random").mockReturnValue(0.5);
141+
it("should return false when getSecureRandomNumber returns 0.5", () => {
142+
vi.spyOn(randomUtil as any, "getSecureRandomNumber").mockReturnValue(0.5);
192143
const result = randomUtil.getBool();
193144
expect(result).toBe(false);
194145
});
@@ -332,6 +283,20 @@ describe("RandomUtil", () => {
332283
expect(result).toBe("onlyKey");
333284
});
334285

286+
it("should handle empty objects", () => {
287+
const obj = {};
288+
const result = randomUtil.getKey(obj);
289+
290+
expect(result).toBeUndefined();
291+
});
292+
293+
it("should handle objects with integer keys", () => {
294+
const obj = { 1: "a", 2: "b", 3: "c" };
295+
const result = randomUtil.getKey(obj);
296+
297+
expect(Object.keys(obj)).toContain(result);
298+
});
299+
335300
it("should return predictable key when getArrayValue is mocked", () => {
336301
vi.spyOn(randomUtil, "getArrayValue").mockReturnValue("b");
337302

@@ -382,7 +347,7 @@ describe("RandomUtil", () => {
382347

383348
it("should handle high attempt counts", () => {
384349
let callCount = 0;
385-
vi.spyOn(Math, "random").mockImplementation(() => {
350+
vi.spyOn(randomUtil as any, "getSecureRandomNumber").mockImplementation(() => {
386351
callCount++;
387352
// Alternate between u and v
388353
if (callCount % 2 === 1) {
@@ -410,7 +375,7 @@ describe("RandomUtil", () => {
410375

411376
it("should return a fallback value after many attempts", () => {
412377
let callCount = 0;
413-
vi.spyOn(Math, "random").mockImplementation(() => {
378+
vi.spyOn(randomUtil as any, "getSecureRandomNumber").mockImplementation(() => {
414379
// Alternate between u and v
415380
const value = callCount % 2 === 0 ? 0.0000001 : 0.5;
416381
callCount++;
@@ -456,16 +421,6 @@ describe("RandomUtil", () => {
456421
expect(result).toBeGreaterThanOrEqual(low);
457422
expect(result).toBeLessThan(high);
458423
});
459-
460-
it("should return predictable result when Math.random is mocked", () => {
461-
vi.spyOn(Math, "random").mockReturnValue(0.5);
462-
463-
const low = 0;
464-
const high = 10;
465-
const result = randomUtil.randInt(low, high);
466-
467-
expect(result).toBe(5);
468-
});
469424
});
470425

471426
describe("drawRandomFromList", () => {
@@ -541,6 +496,26 @@ describe("RandomUtil", () => {
541496
expect(new Set(result).size).toBe(count);
542497
});
543498

499+
it("should handle single-key dictionaries", () => {
500+
const dict = { onlyKey: 1 };
501+
const count = 2;
502+
const result = randomUtil.drawRandomFromDict(dict, count, false);
503+
504+
expect(result.length).toBe(1);
505+
expect(result).toEqual(["onlyKey"]);
506+
});
507+
508+
it("should handle dictionaries with integer keys", () => {
509+
const dict = { 1: "a", 2: "b", 3: "c" };
510+
const count = 2;
511+
const result = randomUtil.drawRandomFromDict(dict, count, false);
512+
513+
expect(result.length).toBe(count);
514+
for (const key of result) {
515+
expect(Object.keys(dict)).toContain(key);
516+
}
517+
});
518+
544519
it("should handle count greater than number of keys without replacement", () => {
545520
const dict = { a: 1, b: 2 };
546521
const count = 3;
@@ -599,13 +574,24 @@ describe("RandomUtil", () => {
599574
expect(mockLogger.info).toHaveBeenCalledWith(`min -> ${min}; max -> ${max}; shift -> ${shift}`);
600575
});
601576

602-
it("should return predictable result when gaussianRandom is mocked", () => {
603-
vi.spyOn(Math, "random").mockReturnValue(0.5);
577+
it("should return predictable result when getSecureRandomNumber is mocked", () => {
578+
vi.spyOn(randomUtil as any, "getSecureRandomNumber").mockReturnValue(0.5);
604579

605580
const min = 1;
606581
const max = 10;
607582
const shift = 0;
608-
const n = 1;
583+
const n = 2; // n affects how many times getSecureRandomNumber is summed/averaged
584+
585+
// With getSecureRandomNumber always returning 0.5,
586+
// gaussianRandom(n) = 0.5 no matter what
587+
// boundedGaussian(start, end, n) = round(start + 0.5 * (end - start + 1))
588+
589+
// For shift = 0:
590+
// biasedMin = min = 1
591+
// biasedMax = max = 10
592+
// boundedGaussian(1, 10, 2) = round(1 + 0.5*(10 - 1 + 1)) = round(1 + 0.5*10) = round(1+5) = 6
593+
594+
// The loop ensures num is within [min, max], and since 6 is within [1,10], it returns 6 immediately.
609595
const result = randomUtil.getBiasedRandomNumber(min, max, shift, n);
610596

611597
expect(result).toBe(6);
@@ -635,44 +621,41 @@ describe("RandomUtil", () => {
635621

636622
expect(shuffled).toEqual([1]);
637623
});
638-
639-
it("should produce predictable shuffle when Math.random is mocked", () => {
640-
const array = [1, 2, 3, 4, 5];
641-
vi.spyOn(Math, "random").mockReturnValue(0.5);
642-
643-
const shuffled = randomUtil.shuffle([...array]);
644-
645-
expect(shuffled).toEqual([1, 4, 2, 5, 3]);
646-
});
647624
});
648625

649626
describe("rollForChanceProbability", () => {
650627
it("should return true when rolled chance is less than or equal to probabilityChance", () => {
651-
vi.spyOn(randomUtil, "getInt").mockReturnValue(4999);
628+
vi.spyOn(randomUtil as any, "getSecureRandomNumber").mockReturnValue(0.5);
652629

653-
const probabilityChance = 0.5;
630+
const probabilityChance = 0.6;
654631
const result = randomUtil.rollForChanceProbability(probabilityChance);
655632

656633
expect(result).toBe(true);
657634
});
658635

659636
it("should return false when rolled chance is greater than probabilityChance", () => {
660-
vi.spyOn(randomUtil, "getInt").mockReturnValue(5001);
637+
vi.spyOn(randomUtil as any, "getSecureRandomNumber").mockReturnValue(0.7);
661638

662-
const probabilityChance = 0.5;
639+
const probabilityChance = 0.6;
663640
const result = randomUtil.rollForChanceProbability(probabilityChance);
664641

665642
expect(result).toBe(false);
666643
});
667644

668645
it("should handle probabilityChance of 0", () => {
669-
const result = randomUtil.rollForChanceProbability(0);
646+
vi.spyOn(randomUtil as any, "getSecureRandomNumber").mockReturnValue(0.1);
647+
648+
const probabilityChance = 0;
649+
const result = randomUtil.rollForChanceProbability(probabilityChance);
670650

671651
expect(result).toBe(false);
672652
});
673653

674654
it("should handle probabilityChance of 1", () => {
675-
const result = randomUtil.rollForChanceProbability(1);
655+
vi.spyOn(randomUtil as any, "getSecureRandomNumber").mockReturnValue(0.99);
656+
657+
const probabilityChance = 1;
658+
const result = randomUtil.rollForChanceProbability(probabilityChance);
676659

677660
expect(result).toBe(true);
678661
});

0 commit comments

Comments
 (0)