From 389fb3a592832092835da0c2cc1608a57ba5f629 Mon Sep 17 00:00:00 2001 From: LalleSX Date: Sat, 24 Oct 2026 14:18:00 +0200 Subject: Add tests for math rendering and interactive scenes; update navigation and viewport handling - Updated `lab.spec.ts` to navigate directly to the field lesson. - Created `math.spec.ts` with tests for math rendering, error checking, and responsive design. - Added `test4.spec.ts` for interactive scenes, ensuring all questions are functional and accessible. - Modified `vite.config.ts` to keep original question/answer links navigable in production. --- src/physics/test4.test.ts | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/physics/test4.test.ts (limited to 'src/physics/test4.test.ts') diff --git a/src/physics/test4.test.ts b/src/physics/test4.test.ts new file mode 100644 index 0000000..08dd868 --- /dev/null +++ b/src/physics/test4.test.ts @@ -0,0 +1,42 @@ +import { describe, expect, it } from 'vitest'; +import { assembledEnergy, centralWork, dipoleState, energyTransfer, uniformWork } from './test4'; + +describe('Test 4 physical answers', () => { + it('uses only displacement along the uniform field and preserves the charge sign', () => { + expect(uniformWork(2e-9, 100, 3, Math.PI / 3)).toBeCloseTo(3e-7, 14); + expect(uniformWork(-2e-9, 100, 3, 0)).toBeCloseTo(-6e-7, 14); + expect(uniformWork(2e-9, 100, 3, Math.PI / 2)).toBeCloseTo(0, 14); + }); + it('computes point-charge work including the analytic infinity reference', () => { + expect(centralWork(3e-9, 2e-9, 2, 4)).toBeCloseTo(1.348132768845e-8, 16); + expect(centralWork(3e-9, -2e-9, 2, Infinity)).toBeCloseTo(-2.69626553769e-8, 16); + expect(() => centralWork(1, 1, 0, 2)).toThrow(RangeError); + }); + it('converts the potential drop to kinetic energy without changing total energy', () => { + const state = energyTransfer(3e-8, 1e-8, 5e-9, 1e-6); + expect(state.kinetic).toBeCloseTo(2.5e-8, 16); + expect(state.total).toBeCloseTo(3.5e-8, 16); + expect(state.speed).toBeCloseTo(0.22360679775, 10); + expect(() => energyTransfer(0, 1, 0, 1)).toThrow(RangeError); + }); + it('counts each pair once when building a charge configuration', () => { + const charges = [ + { x: 0, y: 0, z: 0, coulombs: 1e-9 }, + { x: 1, y: 0, z: 0, coulombs: 1e-9 }, + { x: 0, y: 0, z: 0.75, coulombs: -1e-9 }, + ]; + expect(assembledEnergy(charges.slice(0, 1))).toBe(0); + expect(assembledEnergy(charges)).toBeCloseTo(-1.0185892031273e-8, 16); + expect(() => assembledEnergy([charges[0], charges[0]])).toThrow(RangeError); + }); + it('distinguishes signed restoring torque, rotation work and zero at 90 degrees', () => { + const state = dipoleState(2e-9, 100, Math.PI / 2, 0); + expect(state.energy).toBeCloseTo(0, 14); + expect(state.torqueZ).toBeCloseTo(-2e-7, 14); + expect(state.work).toBeCloseTo(-2e-7, 14); + const aligned = dipoleState(2e-9, 100, 0, Math.PI / 2); + expect(aligned.energy).toBeCloseTo(-2e-7, 14); + expect(aligned.work).toBeCloseTo(2e-7, 14); + expect(dipoleState(2e-9, 100, Math.PI, 0).energy).toBeCloseTo(2e-7, 14); + }); +}); -- cgit v1.2.3