From 5f741fc90ae2cb4e3f3cd771bc590cbf8708bec0 Mon Sep 17 00:00:00 2001 From: Henry Burgess Date: Thu, 11 Sep 2025 11:01:52 -0500 Subject: [PATCH 1/2] INT-75 Use `randomUniform` from `d3-random` * Generate all statuses from one function call --- src/index.tsx | 3 +-- src/util.ts | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 892dcd7..02d727f 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -97,8 +97,7 @@ experiment.getState().set("experimentID", experimentID); initializeLocalStorage(experimentID); // Generate status values for participant and partner during actual trials -const { partnerStatus: partnerLowStatus, participantStatus: participantDefaultStatus } = generateStatuses(false); -const { partnerStatus: partnerHighStatus } = generateStatuses(true); +const { participantStatus: participantDefaultStatus, partnerLowStatus, partnerHighStatus } = generateStatuses(); // Store status values in the experiment state experiment.getState().set("participantDefaultStatus", participantDefaultStatus); diff --git a/src/util.ts b/src/util.ts index dfce26e..960e2cf 100644 --- a/src/util.ts +++ b/src/util.ts @@ -21,6 +21,9 @@ import FileSaver from "file-saver"; // Logging import consola from "consola"; +// Random number generation +import { randomUniform } from "d3-random"; + // Experiment configuration import { Configuration } from "./configuration"; @@ -250,26 +253,23 @@ export const generatePartnerID = (): string => { }; /** - * Generate the participant and partner statuses - * @param partnerHighStatus whether the partner is in high status - * @returns + * Generate the participant and partner statuses using uniform distributions + * @returns Object containing participant status (40-60%), partner low status (10-25%), and partner high status (75-90%) */ -export const generateStatuses = (partnerHighStatus: boolean): { participantStatus: number, partnerStatus: number } => { - // Access `experiment` instance to generate random numbers - const experiment = window.Experiment; - - // Generate the participant status - const participantVariance = experiment.random() * Configuration.statusDisplay.participantRange * experiment.random() > 0.5 ? 1 : -1; - const participantStatus = Configuration.statusDisplay.participantDefault + participantVariance; +export const generateStatuses = (): { participantStatus: number, partnerLowStatus: number, partnerHighStatus: number } => { + // Create uniform distribution generators + const participantRandom = randomUniform(40, 60); + const partnerLowRandom = randomUniform(10, 25); + const partnerHighRandom = randomUniform(75, 90); - // Generate the partner status - let partnerStatus = partnerHighStatus ? Configuration.statusDisplay.partnerHigh : Configuration.statusDisplay.partnerLow; - const partnerVariance = experiment.random() * Configuration.statusDisplay.partnerRange * experiment.random() > 0.5 ? 1 : -1; - partnerStatus += partnerVariance; + // Generate the statuses using uniform distributions + const participantStatus = Math.round(participantRandom() * 10) / 10; // Round to 1 decimal place + const partnerLowStatus = Math.round(partnerLowRandom() * 10) / 10; + const partnerHighStatus = Math.round(partnerHighRandom() * 10) / 10; // Log the statuses - consola.info(`Participant status: ${participantStatus}, Partner status (${partnerHighStatus ? "high" : "low"}): ${partnerStatus}`); + consola.info(`Generated statuses - Participant: ${participantStatus}%, Partner Low: ${partnerLowStatus}%, Partner High: ${partnerHighStatus}%`); - // Return the statuses - return { participantStatus, partnerStatus }; + // Return all three statuses + return { participantStatus, partnerLowStatus, partnerHighStatus }; }; From 2d7566d1999cf1e24eb46c51762d2662b8603c3b Mon Sep 17 00:00:00 2001 From: Henry Burgess Date: Thu, 11 Sep 2025 11:10:29 -0500 Subject: [PATCH 2/2] INT-75 Add test mock for `d3-random` * Increment version number --- jest.config.js | 3 ++- package.json | 2 +- test/__mocks__/d3-random.js | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 test/__mocks__/d3-random.js diff --git a/jest.config.js b/jest.config.js index 978ab82..65f2120 100644 --- a/jest.config.js +++ b/jest.config.js @@ -6,9 +6,10 @@ module.exports = { "^src(.*)$": "/src$1", "^test(.*)$": "/test$1", webr: require.resolve("webr"), + "^d3-random$": "/test/__mocks__/d3-random.js", }, transform: { - "^.+.tsx?$": ["ts-jest", {}], + "^.+\\.tsx?$": ["ts-jest", {}], }, testEnvironment: "./jest.environment.js", transformIgnorePatterns: ["/node_modules/(?!(webr))/"], diff --git a/package.json b/package.json index cf7a54b..fc4b45e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "task_intentions", - "version": "1.7.3", + "version": "1.7.9", "description": "Intentions Game", "private": true, "main": "dist/index.js", diff --git a/test/__mocks__/d3-random.js b/test/__mocks__/d3-random.js new file mode 100644 index 0000000..e30abf2 --- /dev/null +++ b/test/__mocks__/d3-random.js @@ -0,0 +1,20 @@ +/** + * Mock for d3-random library for Jest tests + * Provides deterministic random number generation for testing + */ + +// Mock randomUniform function that returns a generator function +const mockRandomUniform = (min, max) => { + // Return a function that generates deterministic values for testing + let callCount = 0; + return () => { + callCount++; + // Generate deterministic values based on call count for consistent testing + const seed = (callCount * 0.1) % 1; + return min + (max - min) * seed; + }; +}; + +module.exports = { + randomUniform: mockRandomUniform, +};