Skip to content

Commit

Permalink
feat: add RandomMocker class to mock Math.random
Browse files Browse the repository at this point in the history
  • Loading branch information
ojeytonwilliams committed Sep 23, 2024
1 parent 05a85d7 commit e4a8846
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
45 changes: 45 additions & 0 deletions lib/__tests__/curriculum-helper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,51 @@ const {
jsCodeWithCommentedCall,
} = jsTestValues;

describe("RandomMocker", () => {
let random: () => number;

beforeEach(() => {
random = Math.random;
});

afterEach(() => {
Math.random = random;
});

describe("mock", () => {
it('should replace "Math.random" with a mock function', () => {
const mocker = new helper.RandomMocker();
mocker.mock();
expect(Math.random).not.toBe(random);
});

it('should mock "Math.random" with a pseudorandom function', () => {
const mocker = new helper.RandomMocker();
mocker.mock();
// Predictable random values:
expect(Math.random()).toBe(0.2523451747838408);
expect(Math.random()).toBe(0.08812504541128874);
});

it("should reset the pseudorandom function when called multiple times", () => {
const mocker = new helper.RandomMocker();
mocker.mock();
expect(Math.random()).toBe(0.2523451747838408);
mocker.mock();
expect(Math.random()).toBe(0.2523451747838408);
});
});

describe("restore", () => {
it('should restore "Math.random" to its original function', () => {
const mocker = new helper.RandomMocker();
mocker.mock();
mocker.restore();
expect(Math.random).toBe(random);
});
});
});

describe("removeWhiteSpace", () => {
const { removeWhiteSpace } = helper;
it("returns a string", () => {
Expand Down
31 changes: 31 additions & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,37 @@
import { strip } from "./strip";
import astHelpers from "../python/py_helpers.py";

/**
* The `RandomMocker` class provides functionality to mock and restore the global `Math.random` function.
* It replaces the default random number generator with a deterministic pseudo-random number generator.
*/
export class RandomMocker {
private random: () => number;

constructor() {
this.random = Math.random;
}

private createRandom() {
let seed = 42;
const a = 1664525;
const c = 1013904223;
const mod = 2 ** 32;
return () => {
seed = (a * seed + c) % mod;
return seed / mod;
};
}

mock(): void {
globalThis.Math.random = this.createRandom();
}

restore(): void {
globalThis.Math.random = this.random;
}
}

/**
* Removes every HTML-comment from the string that is provided
* @param {String} str a HTML-string where the comments need to be removed of
Expand Down

0 comments on commit e4a8846

Please sign in to comment.