calculators.spec.js (7746B)
1 import { describe, test, expect } from 'vitest'; 2 import * as calculators from '@/core/calculators'; 3 4 describe('calculatePaceResults method', () => { 5 test('should correctly calculate pace times', () => { 6 const input = { 7 distanceValue: 1, 8 distanceUnit: 'kilometers', 9 time: 100, 10 }; 11 const target = { 12 distanceValue: 20, 13 distanceUnit: 'meters', 14 type: 'distance', 15 }; 16 17 const result = calculators.calculatePaceResults(input, target, 'metric', true); 18 19 expect(result).to.deep.equal({ 20 key: '20 m', 21 value: '0:02.00', 22 pace: '1:40 / km', 23 result: 'value', 24 sort: 2, 25 }); 26 }); 27 28 test('should correctly calculate pace distances according to default units setting', () => { 29 const input = { 30 distanceValue: 2, 31 distanceUnit: 'miles', 32 time: 1200, 33 }; 34 const target = { 35 time: 600, 36 type: 'time', 37 }; 38 39 const result1 = calculators.calculatePaceResults(input, target, 'metric', true); 40 const result2 = calculators.calculatePaceResults(input, target, 'imperial', true); 41 42 expect(result1.key).to.equal('1.61 km'); 43 expect(result1.value).to.equal('10:00'); 44 expect(result1.pace).to.equal('6:13 / km'); 45 expect(result1.result).to.equal('key'); 46 expect(result1.sort).to.be.closeTo(600, 0.01); 47 48 expect(result2.key).to.equal('1.00 mi'); 49 expect(result2.value).to.equal('10:00'); 50 expect(result2.pace).to.equal('10:00 / mi'); 51 expect(result2.result).to.equal('key'); 52 expect(result2.sort).to.be.closeTo(600, 0.01); 53 }); 54 }); 55 56 describe('calculateRaceResults method', () => { 57 test('should correctly predict race times', () => { 58 const input = { 59 distanceValue: 5, 60 distanceUnit: 'kilometers', 61 time: 1200, 62 }; 63 const target = { 64 distanceValue: 10, 65 distanceUnit: 'kilometers', 66 type: 'distance', 67 }; 68 const racePredictionOptions = { 69 model: 'AverageModel', 70 riegelExponent: 1.06, 71 } 72 73 const result = calculators.calculateRaceResults(input, target, racePredictionOptions, 74 'imperial', true); 75 76 expect(result.key).to.equal('10 km'); 77 expect(result.value).to.equal('41:34.80'); 78 expect(result.pace).to.equal('6:41 / mi'); 79 expect(result.result).to.equal('value'); 80 expect(result.sort).to.be.closeTo(2494.80, 0.01); 81 }); 82 83 test('should correctly calculate race distances according to default units setting', () => { 84 const input = { 85 distanceValue: 5, 86 distanceUnit: 'kilometers', 87 time: 1200, 88 }; 89 const target = { 90 time: 2495, 91 type: 'time', 92 }; 93 const racePredictionOptions = { 94 model: 'AverageModel', 95 riegelExponent: 1.06, 96 }; 97 98 const result1 = calculators.calculateRaceResults(input, target, racePredictionOptions, 99 'metric', true); 100 const result2 = calculators.calculateRaceResults(input, target, racePredictionOptions, 101 'imperial', true); 102 103 expect(result1.key).to.equal('10.00 km'); 104 expect(result1.value).to.equal('41:35'); 105 expect(result1.pace).to.equal('4:09 / km'); 106 expect(result1.result).to.equal('key'); 107 expect(result1.sort).to.equal(2495); 108 109 expect(result2.key).to.equal('6.21 mi'); 110 expect(result2.value).to.equal('41:35'); 111 expect(result2.pace).to.equal('6:41 / mi'); 112 expect(result2.result).to.equal('key'); 113 expect(result2.sort).to.equal(2495); 114 }); 115 116 test('should correctly predict race times according to race options', () => { 117 const input = { 118 distanceValue: 2, 119 distanceUnit: 'miles', 120 time: 630, 121 }; 122 const target = { 123 distanceValue: 5, 124 distanceUnit: 'kilometers', 125 type: 'distance', 126 }; 127 const racePredictionOptions = { 128 model: 'RiegelModel', 129 riegelExponent: 1.12, 130 } 131 132 const result = calculators.calculateRaceResults(input, target, racePredictionOptions, 133 'imperial', true); 134 135 expect(result.key).to.equal('5 km'); 136 expect(result.value).to.equal('17:11.78'); 137 expect(result.pace).to.equal('5:32 / mi'); 138 expect(result.result).to.equal('value'); 139 expect(result.sort).to.be.closeTo(1031.77, 0.01); 140 }); 141 }); 142 143 describe('calculateRaceStats method', () => { 144 test('should correctly calculate race statistics', () => { 145 const input = { 146 distanceValue: 5, 147 distanceUnit: 'kilometers', 148 time: 1200, 149 }; 150 151 const results = calculators.calculateRaceStats(input); 152 153 expect(results.purdyPoints).to.be.closeTo(454.5, 0.1); 154 expect(results.vo2).to.be.closeTo(47.4, 0.1); 155 expect(results.vo2MaxPercentage).to.be.closeTo(95.3, 0.1); 156 expect(results.vo2Max).to.be.closeTo(49.8, 0.1); 157 }); 158 }); 159 160 describe('calculateWorkoutResults method', () => { 161 test('should correctly calculate distance-based workouts according to race options', () => { 162 const input = { 163 distanceValue: 2, 164 distanceUnit: 'miles', 165 time: 630, 166 }; 167 const target = { 168 distanceValue: 5, 169 distanceUnit: 'kilometers', // 5k split is ~17:11.77 170 splitValue: 1000, 171 splitUnit: 'meters', 172 type: 'distance', 173 }; 174 const racePredictionOptions = { 175 model: 'RiegelModel', 176 riegelExponent: 1.12, 177 } 178 179 const result = calculators.calculateWorkoutResults(input, target, racePredictionOptions, 180 false, true); 181 182 expect(result.key).to.equal('1000 m @ 5 km'); 183 expect(result.value).to.equal('3:26.36'); 184 expect(result.pace).to.equal(''); 185 expect(result.result).to.equal('value'); 186 expect(result.sort).to.be.closeTo(206.35, 0.01); 187 }); 188 189 test('should correctly calculate distance-based workouts according to custom names', () => { 190 const input = { 191 distanceValue: 2, 192 distanceUnit: 'miles', 193 time: 630, 194 }; 195 const target_1 = { 196 distanceValue: 5, 197 distanceUnit: 'kilometers', // 5k split is ~17:11.77 198 splitValue: 1000, 199 splitUnit: 'meters', 200 type: 'distance', 201 // no custom name 202 }; 203 const target_2 = { 204 distanceValue: 5, 205 distanceUnit: 'kilometers', // 5k split is ~17:11.77 206 splitValue: 1000, 207 splitUnit: 'meters', 208 type: 'distance', 209 customName: 'my custom name', 210 }; 211 const racePredictionOptions = { 212 model: 'RiegelModel', 213 riegelExponent: 1.12, 214 }; 215 216 const result1a = calculators.calculateWorkoutResults(input, target_1, racePredictionOptions, 217 false, true); 218 const result1b = calculators.calculateWorkoutResults(input, target_1, racePredictionOptions, 219 true, true); 220 const result2a = calculators.calculateWorkoutResults(input, target_2, racePredictionOptions, 221 false, true); 222 const result2b = calculators.calculateWorkoutResults(input, target_2, racePredictionOptions, 223 true, true); 224 225 expect(result1a.key).to.equal('1000 m @ 5 km'); 226 expect(result1b.key).to.equal('1000 m @ 5 km'); 227 expect(result2a.key).to.equal('1000 m @ 5 km'); 228 expect(result2b.key).to.equal('my custom name'); 229 }); 230 231 test('should correctly calculate time-based workouts', () => { 232 const input = { 233 distanceValue: 5, 234 distanceUnit: 'kilometers', 235 time: 1200, 236 }; 237 const target = { 238 time: 2495, // ~10k split is 41:35 239 splitValue: 1, 240 splitUnit: 'miles', 241 type: 'time', 242 }; 243 const racePredictionOptions = { 244 model: 'AverageModel', 245 riegelExponent: 1.06, 246 } 247 248 const result = calculators.calculateWorkoutResults(input, target, racePredictionOptions, false, 249 true); 250 251 expect(result.key).to.equal('1 mi @ 41:35'); 252 expect(result.value).to.equal('6:41.50'); 253 expect(result.pace).to.equal(''); 254 expect(result.result).to.equal('value'); 255 expect(result.sort).to.be.closeTo(401.50, 0.01); 256 }); 257 });