UNPKG

powerhouse-rp-toolkit

Version:

Renaissance Periodization Training Toolkit for PowerHouseATX

366 lines (313 loc) 10.5 kB
/** * LogSet Algorithm Tests * Tests for Phase-4 set logging functionality */ /** * LogSet Algorithm Tests * Tests for Phase-4 set logging functionality */ import { vi as jest } from "vitest"; import { makeTrainingState } from "../helpers/mockState.js"; const mockTrainingState = makeTrainingState(); // Mock the core module vi.mock("../js/core/trainingState.js", () => ({ default: mockTrainingState, saveState: vi.fn(), })); // Import the modules after mocking const { logSet } = await import("../js/algorithms/workout.js"); describe("LogSet Algorithm", () => { let mockSession; beforeEach(() => { // Reset mock state before each test mockTrainingState.currentWorkout = null; // Create a fresh mock session for each test mockSession = { id: "test-workout-123", startTime: "2024-01-15T10:00:00Z", status: "active", exercises: [], totalSets: 0, totalVolume: 0, sessionType: "standard", muscleGroups: [], notes: "", metadata: { week: 1, mesocycle: 1, programVersion: "1.0", }, }; }); describe("logSet validation", () => { test("should throw error when no session provided", () => { const setData = { exercise: "Bench Press", weight: 135, reps: 10, rir: 2, }; expect(() => logSet(null, setData)).toThrow( "No active workout session provided", ); }); test("should throw error when session is not active", () => { mockSession.status = "completed"; const setData = { exercise: "Bench Press", weight: 135, reps: 10, rir: 2, }; expect(() => logSet(mockSession, setData)).toThrow( "Cannot log set - workout session is not active", ); }); test("should throw error when setData is invalid", () => { expect(() => logSet(mockSession, null)).toThrow( "Invalid set data provided", ); expect(() => logSet(mockSession, undefined)).toThrow( "Invalid set data provided", ); expect(() => logSet(mockSession, "string")).toThrow( "Invalid set data provided", ); }); test("should throw error when exercise name is missing", () => { const setData = { weight: 135, reps: 10, rir: 2 }; expect(() => logSet(mockSession, setData)).toThrow( "Exercise name is required", ); const setDataEmptyExercise = { exercise: "", weight: 135, reps: 10, rir: 2, }; expect(() => logSet(mockSession, setDataEmptyExercise)).toThrow( "Exercise name is required", ); }); test("should throw error when weight is invalid", () => { const baseSetData = { exercise: "Bench Press", reps: 10, rir: 2 }; expect(() => logSet(mockSession, { ...baseSetData, weight: undefined }), ).toThrow("Valid weight is required"); expect(() => logSet(mockSession, { ...baseSetData, weight: null }), ).toThrow("Valid weight is required"); expect(() => logSet(mockSession, { ...baseSetData, weight: -5 })).toThrow( "Valid weight is required", ); }); test("should throw error when reps is invalid", () => { const baseSetData = { exercise: "Bench Press", weight: 135, rir: 2 }; expect(() => logSet(mockSession, { ...baseSetData, reps: undefined }), ).toThrow("Valid reps count is required"); expect(() => logSet(mockSession, { ...baseSetData, reps: null })).toThrow( "Valid reps count is required", ); expect(() => logSet(mockSession, { ...baseSetData, reps: -1 })).toThrow( "Valid reps count is required", ); }); test("should throw error when RIR is out of range", () => { const baseSetData = { exercise: "Bench Press", weight: 135, reps: 10 }; expect(() => logSet(mockSession, { ...baseSetData, rir: -1 })).toThrow( "RIR must be between 0 and 10", ); expect(() => logSet(mockSession, { ...baseSetData, rir: 11 })).toThrow( "RIR must be between 0 and 10", ); }); test("should allow valid RIR values", () => { const baseSetData = { exercise: "Bench Press", weight: 135, reps: 10 }; expect(() => logSet(mockSession, { ...baseSetData, rir: 0 }), ).not.toThrow(); expect(() => logSet(mockSession, { ...baseSetData, rir: 5 }), ).not.toThrow(); expect(() => logSet(mockSession, { ...baseSetData, rir: 10 }), ).not.toThrow(); }); test("should allow undefined RIR", () => { const setData = { exercise: "Bench Press", weight: 135, reps: 10 }; expect(() => logSet(mockSession, setData)).not.toThrow(); }); }); describe("logSet functionality", () => { test("should log first set for new exercise", () => { const setData = { exercise: "Bench Press", weight: 135, reps: 10, rir: 2, notes: "Good form", }; const updatedSession = logSet(mockSession, setData); expect(updatedSession.exercises).toHaveLength(1); expect(updatedSession.exercises[0]).toMatchObject({ name: "Bench Press", totalSets: 1, totalVolume: 1350, // 135 * 10 muscleGroups: ["chest", "triceps"], }); const loggedSet = updatedSession.exercises[0].sets[0]; expect(loggedSet).toMatchObject({ exercise: "Bench Press", weight: 135, reps: 10, rir: 2, notes: "Good form", setNumber: 1, }); expect(loggedSet.id).toMatch(/^set_\d+_[a-z0-9]{4}$/); expect(loggedSet.timestamp).toBeDefined(); }); test("should add second set to existing exercise", () => { // Log first set const firstSet = { exercise: "Bench Press", weight: 135, reps: 10, rir: 2, }; logSet(mockSession, firstSet); // Log second set const secondSet = { exercise: "Bench Press", weight: 140, reps: 8, rir: 1, }; const updatedSession = logSet(mockSession, secondSet); expect(updatedSession.exercises).toHaveLength(1); expect(updatedSession.exercises[0].sets).toHaveLength(2); expect(updatedSession.exercises[0].totalSets).toBe(2); expect(updatedSession.exercises[0].totalVolume).toBe(2470); // (135*10) + (140*8) const loggedSet = updatedSession.exercises[0].sets[1]; expect(loggedSet.setNumber).toBe(2); expect(loggedSet.weight).toBe(140); expect(loggedSet.reps).toBe(8); }); test("should handle multiple exercises", () => { // Log bench press set const benchSet = { exercise: "Bench Press", weight: 135, reps: 10, rir: 2, }; logSet(mockSession, benchSet); // Log squat set const squatSet = { exercise: "Squat", weight: 185, reps: 8, rir: 3, }; const updatedSession = logSet(mockSession, squatSet); expect(updatedSession.exercises).toHaveLength(2); expect(updatedSession.exercises[0].name).toBe("Bench Press"); expect(updatedSession.exercises[1].name).toBe("Squat"); expect(updatedSession.exercises[1].muscleGroups).toEqual([ "quadriceps", "glutes", ]); }); test("should update session totals correctly", () => { // Log multiple sets across exercises logSet(mockSession, { exercise: "Bench Press", weight: 135, reps: 10, rir: 2, }); logSet(mockSession, { exercise: "Bench Press", weight: 140, reps: 8, rir: 1, }); const updatedSession = logSet(mockSession, { exercise: "Squat", weight: 185, reps: 8, rir: 3, }); expect(updatedSession.totalSets).toBe(3); expect(updatedSession.totalVolume).toBe(3950); // (135*10) + (140*8) + (185*8) expect(updatedSession.muscleGroups).toEqual( expect.arrayContaining(["chest", "triceps", "quadriceps", "glutes"]), ); }); test("should update trainingState.currentWorkout", () => { const setData = { exercise: "Bench Press", weight: 135, reps: 10, rir: 2, }; const updatedSession = logSet(mockSession, setData); expect(mockTrainingState.currentWorkout).toBe(updatedSession); }); test("should handle zero weight and reps", () => { const setData = { exercise: "Bodyweight Exercise", weight: 0, reps: 0, rir: 5, }; const updatedSession = logSet(mockSession, setData); expect(updatedSession.exercises[0].totalVolume).toBe(0); expect(updatedSession.totalVolume).toBe(0); }); test("should convert numeric strings to numbers", () => { const setData = { exercise: "Bench Press", weight: "135", reps: "10", rir: "2", notes: 123, // Non-string notes should be converted }; const updatedSession = logSet(mockSession, setData); const loggedSet = updatedSession.exercises[0].sets[0]; expect(loggedSet.weight).toBe(135); expect(loggedSet.reps).toBe(10); expect(loggedSet.rir).toBe(2); expect(loggedSet.notes).toBe("123"); }); test("should handle null RIR", () => { const setData = { exercise: "Bench Press", weight: 135, reps: 10, rir: null, }; const updatedSession = logSet(mockSession, setData); const loggedSet = updatedSession.exercises[0].sets[0]; expect(loggedSet.rir).toBeNull(); }); test("should assign muscle groups based on exercise name", () => { const exercises = [ { name: "Pull-up", expected: ["back", "biceps"] }, { name: "Deadlift", expected: ["back", "glutes", "hamstrings"] }, { name: "Shoulder Press", expected: ["shoulders", "triceps"] }, { name: "Bicep Curl", expected: ["biceps"] }, { name: "Unknown Exercise", expected: ["other"] }, ]; exercises.forEach(({ name, expected }) => { const freshSession = { ...mockSession, exercises: [] }; const updatedSession = logSet(freshSession, { exercise: name, weight: 100, reps: 10, }); expect(updatedSession.exercises[0].muscleGroups).toEqual(expected); }); }); }); });