fix: use crypto.getRandomValues in randId and stub it in tests for determinism

This commit is contained in:
copilot-swe-agent[bot]
2026-07-14 01:42:23 +00:00
committed by GitHub
parent a7721b66f7
commit cf41969ede
2 changed files with 32 additions and 21 deletions

View File

@@ -1,44 +1,53 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, describe, expect, it, vi } from "vitest";
import { randId } from "./randId.ts";
describe("randId", () => {
beforeEach(() => {
afterEach(() => {
vi.restoreAllMocks();
});
it("returns a number", () => {
const result = randId();
expect(typeof result).toBe("number");
});
it("returns an integer", () => {
const result = randId();
expect(typeof result).toBe("number");
expect(Number.isInteger(result)).toBe(true);
});
it("uses Math.random to generate the number", () => {
const mockRandom = vi.spyOn(Math, "random").mockReturnValue(0.5);
it("uses crypto.getRandomValues to generate the number", () => {
const mockGetRandomValues = vi
.spyOn(crypto, "getRandomValues")
.mockImplementation((array) => {
if (array instanceof Uint32Array) {
array[0] = 42;
}
return array;
});
const result = randId();
expect(mockRandom).toHaveBeenCalled();
expect(result).toBe(Math.floor(0.5 * 1e9));
expect(mockGetRandomValues).toHaveBeenCalled();
expect(result).toBe(42);
});
it("returns a value between 0 and 1e9 (exclusive)", () => {
it("returns a value within the uint32 range", () => {
const result = randId();
expect(result).toBeGreaterThanOrEqual(0);
expect(result).toBeLessThan(1e9);
expect(result).toBeLessThanOrEqual(0xffffffff);
});
it("returns different values on subsequent calls", () => {
vi.spyOn(Math, "random").mockRestore();
it("returns unique values across many calls", () => {
let counter = 0;
vi.spyOn(crypto, "getRandomValues").mockImplementation((array) => {
if (array instanceof Uint32Array) {
array[0] = counter++;
}
return array;
});
const results = new Set();
for (let i = 0; i < 100; i++) {
const results = new Set<number>();
for (let i = 0; i < 1000; i++) {
results.add(randId());
}
expect(results.size).toBeGreaterThan(95);
expect(results.size).toBe(1000);
});
});

View File

@@ -1,3 +1,5 @@
export const randId = () => {
return Math.floor(Math.random() * 1e9);
export const randId = (): number => {
const buf = new Uint32Array(1);
crypto.getRandomValues(buf);
return buf[0];
};