commit 783bec010a56da3ca441605b034b29225180849a
parent 281a018f690d1e8415c766c65ae3ffd1f933e439
Author: Asher Morgan <59518073+ashermorgan@users.noreply.github.com>
Date: Thu, 29 May 2025 19:33:16 -0700
Implement workoutTargetToString util function
Diffstat:
3 files changed, 67 insertions(+), 14 deletions(-)
diff --git a/src/utils/calculators.js b/src/utils/calculators.js
@@ -1,6 +1,7 @@
import { formatDuration, formatNumber } from '@/utils/format';
import * as paceUtils from '@/utils/paces';
import * as raceUtils from '@/utils/races';
+import { workoutTargetToString } from '@/utils/targets';
import { DISTANCE_UNITS, convertDistance, getDefaultDistanceUnit } from '@/utils/units';
/**
@@ -145,34 +146,30 @@ export function calculateRaceStats(input) {
* @returns {Object} The result
*/
export function calculateWorkoutResults(input, target, options, preciseDurations = true) {
+ // Initialize distance and time variables
const d1 = convertDistance(input.distanceValue, input.distanceUnit, 'meters');
const t1 = input.time;
const d3 = convertDistance(target.splitValue, target.splitUnit, 'meters');
let d2, t2, t3;
- // Calculate pace
- let key = formatNumber(target.splitValue, 0, 2, false) + ' ' +
- DISTANCE_UNITS[target.splitUnit].symbol;
+ // Calculate result
if (target.type === 'distance') {
// Convert target distance into meters
d2 = convertDistance(target.distanceValue, target.distanceUnit, 'meters');
+
+ // Get workout split prediction
t2 = raceUtils.predictTime(d1, input.time, d2, options.model, options.riegelExponent);
- if (target.distanceValue != target.splitValue || target.distanceUnit != target.splitUnit) {
- key += ' @ ' + formatNumber(target.distanceValue, 0, 2, false) + ' ' +
- DISTANCE_UNITS[target.distanceUnit].symbol;
- }
} else {
t2 = target.time;
- d2 = raceUtils.predictDistance(t1, d1, t2, options.model,
- options.riegelExponent);
- key += ' @ ' + formatDuration(target.time, 3, 2, false);
- }
+ // Get workout split prediction
+ d2 = raceUtils.predictDistance(t1, d1, t2, options.model, options.riegelExponent);
+ }
t3 = paceUtils.calculateTime(d2, t2, d3);
- // Calculate time
+ // Return result
return {
- key: key,
+ key: workoutTargetToString(target),
value: formatDuration(t3, 3, preciseDurations ? 2 : 0, true),
pace: '', // Pace not used in workout calculator
result: 'value',
diff --git a/src/utils/targets.js b/src/utils/targets.js
@@ -1,4 +1,5 @@
-import { convertDistance } from '@/utils/units';
+import { formatDuration, formatNumber } from '@/utils/format';
+import { DISTANCE_UNITS, convertDistance } from '@/utils/units';
/**
* Sort an array of targets
@@ -16,6 +17,23 @@ export function sort(targets) {
];
}
+/**
+ * Generate a string description of a workout target
+ * @param {Object} target The workout target
+ * @return {String} The string description
+ */
+export function workoutTargetToString(target) {
+ let result = formatNumber(target.splitValue, 0, 2, false) + ' ' +
+ DISTANCE_UNITS[target.splitUnit].symbol;
+ if (target.type === 'time') {
+ result += ' @ ' + formatDuration(target.time, 3, 2, false);
+ } else if (target.distanceValue != target.splitValue || target.distanceUnit != target.splitUnit) {
+ result += ' @ ' + formatNumber(target.distanceValue, 0, 2, false) + ' ' +
+ DISTANCE_UNITS[target.distanceUnit].symbol;
+ }
+ return result;
+}
+
export const defaultTargetSets = {
'_pace_targets': {
name: 'Common Pace Targets',
diff --git a/tests/unit/utils/targets.spec.js b/tests/unit/utils/targets.spec.js
@@ -19,3 +19,41 @@ describe('sort method', () => {
expect(targets.sort(input)).to.deep.equal(expected);
});
});
+
+describe('workoutTargetToString method', () => {
+ test('should correctly stringify time target', () => {
+ // Initialize original and stringified target
+ const input = {
+ splitValue: 1600, splitUnit: 'meters',
+ type: 'time', time: 3600,
+ };
+ const expected = '1600 m @ 1:00:00';
+
+ // Assert sort method sorts targets correctly
+ expect(targets.workoutTargetToString(input)).to.deep.equal(expected);
+ });
+
+ test('should correctly stringify distance target', () => {
+ // Initialize original and stringified target
+ const input = {
+ splitValue: 800, splitUnit: 'meters',
+ type: 'distance', distanceValue: 5, distanceUnit: 'kilometers',
+ };
+ const expected = '800 m @ 5 km';
+
+ // Assert sort method sorts targets correctly
+ expect(targets.workoutTargetToString(input)).to.deep.equal(expected);
+ });
+
+ test('should correctly stringify race target', () => {
+ // Initialize original and stringified target
+ const input = {
+ splitValue: 5, splitUnit: 'kilometers',
+ type: 'distance', distanceValue: 5, distanceUnit: 'kilometers',
+ };
+ const expected = '5 km';
+
+ // Assert sort method sorts targets correctly
+ expect(targets.workoutTargetToString(input)).to.deep.equal(expected);
+ });
+});