4be489d6d3
Cardio exercises now log a breathing "Gear" (1-5, per Brian MacKenzie) instead of RPE (6-10) as their effort field; strength keeps RPE. An exercise counts as cardio when its equipment type is "cardio" or it carries the "cardio" muscle group (isCardioExercise in lib/exerciseOptions), so the Assault Bike (type "assault bike") qualifies. New nullable SetLog.gear column added by the boot-time guarded ALTER in docker_entrypoint.sh (additive, idempotent); plumbed through all 5 set-write paths, the summary/edit views, and CSV/JSON import-export. Existing rpe data is untouched and still displays. Program/AI target-RPE is unaffected.
29 lines
1.1 KiB
TypeScript
29 lines
1.1 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { isCardioExercise } from '@/lib/exerciseOptions';
|
|
|
|
describe('isCardioExercise', () => {
|
|
it('treats type "cardio" as cardio', () => {
|
|
expect(isCardioExercise({ type: 'cardio', muscleGroups: '["cardio"]' })).toBe(true);
|
|
});
|
|
|
|
it('treats the cardio muscle group as cardio even when type differs (Assault Bike)', () => {
|
|
expect(
|
|
isCardioExercise({ type: 'assault bike', muscleGroups: '["cardio","legs","back","shoulders"]' })
|
|
).toBe(true);
|
|
});
|
|
|
|
it('is case/whitespace-insensitive on the muscle group', () => {
|
|
expect(isCardioExercise({ type: 'other', muscleGroups: '[" Cardio "]' })).toBe(true);
|
|
});
|
|
|
|
it('treats strength work (no cardio signal) as non-cardio', () => {
|
|
expect(isCardioExercise({ type: 'barbell', muscleGroups: '["back","biceps"]' })).toBe(false);
|
|
});
|
|
|
|
it('handles missing/empty fields without throwing', () => {
|
|
expect(isCardioExercise({})).toBe(false);
|
|
expect(isCardioExercise({ type: null, muscleGroups: null })).toBe(false);
|
|
expect(isCardioExercise({ type: '', muscleGroups: 'not json' })).toBe(false);
|
|
});
|
|
});
|