running-tools

A collection of tools for runners and their coaches
git clone https://git.ashermorgan.net/running-tools/
Log | Files | Refs | README

racePrediction.spec.js (7951B)


      1 import { describe, test, expect } from 'vitest';
      2 import * as racePrediction from '@/core/racePrediction';
      3 
      4 describe('predictTime method', () => {
      5   describe('PredictTime method', () => {
      6     test('Average Model', () => {
      7       const riegel = racePrediction.predictTime(5000, 1200, 10000, {
      8         model: 'RiegelModel',
      9         riegelExponent: 1.06,
     10       });
     11       const cameron = racePrediction.predictTime(5000, 1200, 10000, {
     12         model: 'CameronModel',
     13         riegelExponent: 1.06,
     14       });
     15       const purdyPoints = racePrediction.predictTime(5000, 1200, 10000, {
     16         model: 'PurdyPointsModel',
     17         riegelExponent: 1.06,
     18       });
     19       const vo2Max = racePrediction.predictTime(5000, 1200, 10000, {
     20         model: 'VO2MaxModel',
     21         riegelExponent: 1.06,
     22       });
     23       const expected = (riegel + cameron + purdyPoints + vo2Max) / 4;
     24 
     25       const result = racePrediction.predictTime(5000, 1200, 10000, {
     26         model: 'AverageModel',
     27         riegelExponent: 1.06,
     28       });
     29       expect(result).to.equal(expected);
     30     });
     31 
     32     test('Should predict identical times for itentical distances', () => {
     33       const result = racePrediction.predictTime(5000, 1200, 5000, {
     34         model: 'AverageModel',
     35         riegelExponent: 1.06,
     36       });
     37       expect(result).to.be.closeTo(1200, 0.001);
     38     });
     39   });
     40 
     41   describe('Purdy Points Model', () => {
     42     test('Predictions should be approximately correct', () => {
     43       const result = racePrediction.predictTime(5000, 1200, 10000, {
     44         model: 'PurdyPointsModel',
     45         riegelExponent: 1.06,
     46       });
     47       expect(result).to.be.closeTo(2490, 1);
     48     });
     49 
     50     test('Should predict identical times for itentical distances', () => {
     51       const result = racePrediction.predictTime(5000, 1200, 5000, {
     52         model: 'PurdyPointsModel',
     53         riegelExponent: 1.06,
     54       });
     55       expect(result).to.be.closeTo(1200, 0.001);
     56     });
     57   });
     58 
     59   describe('VO2 Max Model', () => {
     60     test('Predictions should be approximately correct', () => {
     61       const result = racePrediction.predictTime(5000, 1200, 10000, {
     62         model: 'VO2MaxModel',
     63         riegelExponent: 1.06,
     64       });
     65       expect(result).to.be.closeTo(2488, 1);
     66     });
     67 
     68     test('Should predict identical times for itentical distances', () => {
     69       const result = racePrediction.predictTime(5000, 1200, 5000, {
     70         model: 'VO2MaxModel',
     71         riegelExponent: 1.06,
     72       });
     73       expect(result).to.be.closeTo(1200, 0.001);
     74     });
     75   });
     76 
     77   describe('Cameron Model', () => {
     78     test('Predictions should be approximately correct', () => {
     79       const result = racePrediction.predictTime(5000, 1200, 10000, {
     80         model: 'CameronModel',
     81         riegelExponent: 1.06,
     82       });
     83       expect(result).to.be.closeTo(2500, 1);
     84     });
     85 
     86     test('Should predict identical times for itentical distances', () => {
     87       const result = racePrediction.predictTime(5000, 1200, 5000, {
     88         model: 'CameronModel',
     89         riegelExponent: 1.06,
     90       });
     91       expect(result).to.be.closeTo(1200, 0.001);
     92     });
     93   });
     94 
     95   describe('Riegel Model', () => {
     96     test('Predictions should be approximately correct', () => {
     97       const result = racePrediction.predictTime(5000, 1200, 10000, {
     98         model: 'RiegelModel',
     99         RiegelModel: 1.06,
    100       });
    101       expect(result).to.be.closeTo(2502, 1);
    102     });
    103 
    104     test('Should predict identical times for itentical distances', () => {
    105       const result = racePrediction.predictTime(5000, 1200, 5000, {
    106         model: 'RiegelModel',
    107         RiegelModel: 1.06,
    108       });
    109       expect(result).to.be.closeTo(1200, 0.001);
    110     });
    111   });
    112 });
    113 
    114 describe('predictDistance method', () => {
    115   describe('Average Model', () => {
    116     test('Predictions should be correct', () => {
    117       const riegel = racePrediction.predictTime(5000, 1200, 10000, {
    118         model: 'RiegelModel',
    119         riegel: 1.06,
    120       });
    121       const cameron = racePrediction.predictTime(5000, 1200, 10000, {
    122         model: 'CameronModel',
    123         riegel: 1.06,
    124       });
    125       const purdyPoints = racePrediction.predictTime(5000, 1200, 10000, {
    126         model: 'PurdyPointsModel',
    127         riegel: 1.06,
    128       });
    129       const vo2Max = racePrediction.predictTime(5000, 1200, 10000, {
    130         model: 'VO2MaxModel',
    131         riegel: 1.06,
    132       });
    133       const expected = (riegel + cameron + purdyPoints + vo2Max) / 4;
    134 
    135       const result = racePrediction.predictDistance(1200, 5000, expected, {
    136         model: 'AverageModel',
    137         riegelExponent: 1.06,
    138       });
    139       expect(result).to.be.closeTo(10000, 10);
    140     });
    141 
    142     test('Should predict identical times for itentical distances', () => {
    143       const result = racePrediction.predictDistance(1200, 5000, 1200, {
    144         model: 'AverageModel',
    145         riegel: 1.06,
    146       });
    147       expect(result).to.be.closeTo(5000, 0.001);
    148     });
    149   });
    150 
    151   describe('Purdy Points Model', () => {
    152     test('Predictions should be approximately correct', () => {
    153       const result = racePrediction.predictDistance(1200, 5000, 2490, {
    154         model: 'PurdyPointsModel',
    155         riegel: 1.06,
    156       });
    157       expect(result).to.be.closeTo(10000, 10);
    158     });
    159 
    160     test('Should predict identical times for itentical distances', () => {
    161       const result = racePrediction.predictDistance(1200, 5000, 1200, {
    162         model: 'PurdyPointsModel',
    163         riegel: 1.06,
    164       });
    165       expect(result).to.be.closeTo(5000, 0.001);
    166     });
    167   });
    168 
    169   describe('VO2 Max Model', () => {
    170     test('Predictions should be approximately correct', () => {
    171       const result = racePrediction.predictDistance(1200, 5000, 2488, {
    172         model: 'VO2MaxModel',
    173         riegel: 1.06,
    174       });
    175       expect(result).to.be.closeTo(10000, 10);
    176     });
    177 
    178     test('Should predict identical times for itentical distances', () => {
    179       const result = racePrediction.predictDistance(1200, 5000, 1200, {
    180         model: 'VO2MaxModel',
    181         riegel: 1.06,
    182       });
    183       expect(result).to.be.closeTo(5000, 0.001);
    184     });
    185   });
    186 
    187   describe('Cameron Model', () => {
    188     test('Predictions should be approximately correct', () => {
    189       const result = racePrediction.predictDistance(1200, 5000, 2500, {
    190         model: 'CameronModel',
    191         riegel: 1.06,
    192       });
    193       expect(result).to.be.closeTo(10000, 10);
    194     });
    195 
    196     test('Should predict identical times for itentical distances', () => {
    197       const result = racePrediction.predictDistance(1200, 5000, 1200, {
    198         model: 'CameronModel',
    199         riegel: 1.06,
    200       });
    201       expect(result).to.be.closeTo(5000, 0.001);
    202     });
    203   });
    204 
    205   describe('Riegel Model', () => {
    206     test('Predictions should be approximately correct', () => {
    207       const result = racePrediction.predictDistance(1200, 5000, 2502, {
    208         model: 'RiegelModel',
    209         RiegelModel: 1.06,
    210       });
    211       expect(result).to.be.closeTo(10000, 10);
    212     });
    213 
    214     test('Should predict identical times for itentical distances', () => {
    215       const result = racePrediction.predictDistance(1200, 5000, 1200, {
    216         model: 'RiegelModel',
    217         RiegelModel: 1.06,
    218       });
    219       expect(result).to.be.closeTo(5000, 0.001);
    220     });
    221   });
    222 });
    223 
    224 describe('getVO2 method', () => {
    225   test('Result should be approximately correct', () => {
    226     const result = racePrediction.getVO2(5000, 1200);
    227     expect(result).to.be.closeTo(47.4, 0.1);
    228   });
    229 });
    230 
    231 describe('getVO2Percentage method', () => {
    232   test('Result should be approximately correct', () => {
    233     const result = racePrediction.getVO2Percentage(660);
    234     expect(result).to.be.closeTo(1, 0.001);
    235   });
    236 });
    237 
    238 describe('getVO2Max method', () => {
    239   test('Result should be approximately correct', () => {
    240     const result = racePrediction.getVO2Max(5000, 1200);
    241     expect(result).to.be.closeTo(49.8, 0.1);
    242   });
    243 });
    244 
    245 describe('getPurdyPoints method', () => {
    246   test('Result should be approximately correct', () => {
    247     const result = racePrediction.getPurdyPoints(5000, 1200);
    248     expect(result).to.be.closeTo(454, 1);
    249   });
    250 });