Skip to content

Commit

Permalink
Add advanced options section to Batch Calculator
Browse files Browse the repository at this point in the history
  • Loading branch information
ashermorgan committed Jul 9, 2024
1 parent ef6f238 commit fb26504
Show file tree
Hide file tree
Showing 4 changed files with 311 additions and 30 deletions.
61 changes: 53 additions & 8 deletions src/views/BatchCalculator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,25 @@
</div>
</div>

<details>
<summary>
<h2>Advanced Options</h2>
</summary>
<div>
Default units:
<select v-model="defaultUnitSystem" aria-label="Default units">
<option value="imperial">Miles</option>
<option value="metric">Kilometers</option>
</select>
</div>
<div>
Target Set:
<target-set-selector v-model:selectedTargetSet="selectedTargetSet"
v-model:targetSets="targetSets" :default-unit-system="defaultUnitSystem"/>
</div>
<race-options v-if="options.calculator !== 'pace'" v-model="advancedOptions"/>
</details>

<h2>Batch Results</h2>
<double-output-table class="output" :input-times="inputTimes" :input-distance="inputDistance"
:calculate-result="calculateResult"
Expand All @@ -40,6 +59,8 @@ import { detectDefaultUnitSystem } from '@/utils/units';
import DoubleOutputTable from '@/components/DoubleOutputTable.vue';
import IntegerInput from '@/components/IntegerInput.vue';
import PaceInput from '@/components/PaceInput.vue';
import RaceOptions from '@/components/RaceOptions.vue';
import TargetSetSelector from '@/components/TargetSetSelector.vue';
import TimeInput from '@/components/TimeInput.vue';
import useStorage from '@/composables/useStorage';
Expand Down Expand Up @@ -121,14 +142,25 @@ const inputTimes = computed(() => {
/**
* The selected target set for the current calculator
*/
const selectedTargetSet = computed(() => {
if (options.value.calculator === 'pace') {
return selectedPaceTargetSet.value;
} else if (options.value.calculator === 'race') {
return selectedRaceTargetSet.value;
} else {
return selectedWorkoutTargetSet.value;
}
const selectedTargetSet = computed({
get: () => {
if (options.value.calculator === 'pace') {
return selectedPaceTargetSet.value;
} else if (options.value.calculator === 'race') {
return selectedRaceTargetSet.value;
} else {
return selectedWorkoutTargetSet.value;
}
},
set: (newValue) => {
if (options.value.calculator === 'pace') {
selectedPaceTargetSet.value = newValue;
} else if (options.value.calculator === 'race') {
selectedRaceTargetSet.value = newValue;
} else {
selectedWorkoutTargetSet.value = newValue;
}
},
});
/**
Expand All @@ -144,6 +176,19 @@ const targetSets = computed(() => {
}
});
/**
* The advanced options for the current calculator
*/
const advancedOptions = computed(() => {
if (options.value.calculator === 'pace') {
return {};
} else if (options.value.calculator === 'race') {
return raceOptions.value;
} else {
return workoutOptions.value;
}
});
/**
* The appropriate calculate_results function for the current calculator
*/
Expand Down
102 changes: 99 additions & 3 deletions tests/e2e/batch-calculator.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ test('Basic usage', async ({ page }) => {
await expect(page.getByRole('row').nth(15).getByRole('cell')).toHaveCount(5);
await expect(page.getByRole('row')).toHaveCount(16);

// Change prediction model
await page.getByText('Advanced Options').click();
await page.getByLabel('Prediction model').selectOption('Riegel\'s Model');

// Assert workout results are correct
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(0)).toHaveText('2 mi');
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(2)).toHaveText('800 m @ 5 km');
await expect(page.getByRole('row').nth(0).getByRole('cell')).toHaveCount(5);
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(0)).toHaveText('10:30');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(2)).toHaveText('2:40.78');
await expect(page.getByRole('row').nth(1).getByRole('cell')).toHaveCount(5);
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(0)).toHaveText('12:50');
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(2)).toHaveText('3:16.51');
await expect(page.getByRole('row').nth(15).getByRole('cell')).toHaveCount(5);
await expect(page.getByRole('row')).toHaveCount(16);

// Change calculator
await expect(page.getByLabel('Calculator')).toHaveValue('workout');
await page.getByLabel('Calculator').selectOption('Pace Calculator');
Expand All @@ -50,6 +66,27 @@ test('Basic usage', async ({ page }) => {
await expect(page.getByRole('row').nth(15).getByRole('cell')).toHaveCount(31);
await expect(page.getByRole('row')).toHaveCount(16);

// Assert prediction options are hidden
await expect(page.getByLabel('Prediction model')).toHaveCount(0);

// Change default units
await page.getByLabel('Default units').selectOption('Kilometers');

// Assert pace results are correct
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(0)).toHaveText('2 mi');
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(6)).toHaveText('800 m');
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(28)).toHaveText('10:00');
await expect(page.getByRole('row').nth(0).getByRole('cell')).toHaveCount(31);
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(0)).toHaveText('10:30');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(6)).toHaveText('2:36.58');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(28)).toHaveText('3.07 km');
await expect(page.getByRole('row').nth(1).getByRole('cell')).toHaveCount(31);
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(0)).toHaveText('12:50');
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(6)).toHaveText('3:11.38');
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(28)).toHaveText('2.51 km');
await expect(page.getByRole('row').nth(15).getByRole('cell')).toHaveCount(31);
await expect(page.getByRole('row')).toHaveCount(16);

// Change calculator
await page.getByLabel('Calculator').selectOption('Race Calculator');

Expand All @@ -64,6 +101,22 @@ test('Basic usage', async ({ page }) => {
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(2)).toHaveText('2:43.61');
await expect(page.getByRole('row').nth(15).getByRole('cell')).toHaveCount(17);
await expect(page.getByRole('row')).toHaveCount(16);

// Change Riegel exponent
await expect(page.getByLabel('Prediction model')).toHaveValue('AverageModel');
await page.getByLabel('Riegel Exponent').fill('1.12');

// Assert race results are correct
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(0)).toHaveText('2 mi');
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(2)).toHaveText('800 m');
await expect(page.getByRole('row').nth(0).getByRole('cell')).toHaveCount(17);
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(0)).toHaveText('10:30');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(2)).toHaveText('2:11.72');
await expect(page.getByRole('row').nth(1).getByRole('cell')).toHaveCount(17);
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(0)).toHaveText('12:50');
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(2)).toHaveText('2:40.09');
await expect(page.getByRole('row').nth(15).getByRole('cell')).toHaveCount(17);
await expect(page.getByRole('row')).toHaveCount(16);
});

test('Save settings across page reloads', async ({ page }) => {
Expand All @@ -83,24 +136,67 @@ test('Save settings across page reloads', async ({ page }) => {
await page.getByLabel('Duration increment seconds').fill('10');
await page.getByLabel('Number of rows').fill('15');

// Change workout prediction model
await page.getByText('Advanced Options').click();
await page.getByLabel('Prediction model').selectOption('Riegel\'s Model');

// Change calculator
await page.getByLabel('Calculator').selectOption('Pace Calculator');

// Change default units
await page.getByLabel('Default units').selectOption('Kilometers');

// Change calculator
await page.getByLabel('Calculator').selectOption('Race Calculator');

// Change Riegel exponent
await page.getByLabel('Riegel Exponent').fill('1.12');

// Reload page
await page.reload();

// Assert pace results are correct (inputs and options not reset)
// Assert race results are correct (inputs and options not reset)
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(0)).toHaveText('2 mi');
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(2)).toHaveText('800 m');
await expect(page.getByRole('row').nth(0).getByRole('cell')).toHaveCount(17);
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(0)).toHaveText('10:30');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(2)).toHaveText('2:11.72');
await expect(page.getByRole('row').nth(1).getByRole('cell')).toHaveCount(17);
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(0)).toHaveText('12:50');
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(2)).toHaveText('2:40.09');
await expect(page.getByRole('row').nth(15).getByRole('cell')).toHaveCount(17);
await expect(page.getByRole('row')).toHaveCount(16);

// Change calculator
await page.getByLabel('Calculator').selectOption('Workout Calculator');

// Assert workout results are correct
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(0)).toHaveText('2 mi');
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(2)).toHaveText('800 m @ 5 km');
await expect(page.getByRole('row').nth(0).getByRole('cell')).toHaveCount(5);
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(0)).toHaveText('10:30');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(2)).toHaveText('2:40.78');
await expect(page.getByRole('row').nth(1).getByRole('cell')).toHaveCount(5);
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(0)).toHaveText('12:50');
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(2)).toHaveText('3:16.51');
await expect(page.getByRole('row').nth(15).getByRole('cell')).toHaveCount(5);
await expect(page.getByRole('row')).toHaveCount(16);

// Change calculator
await page.getByLabel('Calculator').selectOption('Pace Calculator');

// Assert pace results are correct
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(0)).toHaveText('2 mi');
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(6)).toHaveText('800 m');
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(28)).toHaveText('10:00');
await expect(page.getByRole('row').nth(0).getByRole('cell')).toHaveCount(31);
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(0)).toHaveText('10:30');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(6)).toHaveText('2:36.58');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(28)).toHaveText('1.90 mi');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(28)).toHaveText('3.07 km');
await expect(page.getByRole('row').nth(1).getByRole('cell')).toHaveCount(31);
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(0)).toHaveText('12:50');
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(6)).toHaveText('3:11.38');
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(28)).toHaveText('1.56 mi');
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(28)).toHaveText('2.51 km');
await expect(page.getByRole('row').nth(15).getByRole('cell')).toHaveCount(31);
await expect(page.getByRole('row')).toHaveCount(16);
});
38 changes: 19 additions & 19 deletions tests/e2e/cross-calculator.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ test('Save and update state when navigating between calculators', async ({ page
await page.getByLabel('Number of rows').fill('15');

// Change calculator
await page.getByLabel('Calculator').selectOption('Pace Calculator');
await page.getByLabel('Calculator').selectOption('Race Calculator');

// Change prediction model
await page.getByText('Advanced Options').click();
await page.getByLabel('Prediction model').selectOption('Riegel\'s Model');

// Go to pace calculator
await page.goto('/');
Expand Down Expand Up @@ -61,10 +65,6 @@ test('Save and update state when navigating between calculators', async ({ page
await page.getByLabel('Input race duration minutes').fill('10');
await page.getByLabel('Input race duration seconds').fill('30');

// Change prediction model
await page.getByText('Advanced Options').click();
await page.getByLabel('Prediction model').selectOption('Riegel\'s Model');

// Go to split calculator
await page.getByRole('link', { name: 'Back' }).click();
await page.getByRole('button', { name: 'Split Calculator' }).click();
Expand Down Expand Up @@ -118,29 +118,29 @@ test('Save and update state when navigating between calculators', async ({ page
await page.getByRole('link', { name: 'Back' }).click();
await page.getByRole('button', { name: 'Batch Calculator' }).click();

// Assert pace results are correct (inputs and options not reset, new pace targets loaded)
// Assert pace results are correct (inputs and options not reset)
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(0)).toHaveText('2 mi');
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(2)).toHaveText('800 m');
await expect(page.getByRole('row').nth(0).getByRole('cell')).toHaveCount(4);
await expect(page.getByRole('row').nth(0).getByRole('cell')).toHaveCount(17);
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(0)).toHaveText('10:30');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(2)).toHaveText('2:36.58');
await expect(page.getByRole('row').nth(1).getByRole('cell')).toHaveCount(4);
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(2)).toHaveText('2:24.04');
await expect(page.getByRole('row').nth(1).getByRole('cell')).toHaveCount(17);
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(0)).toHaveText('12:50');
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(2)).toHaveText('3:11.38');
await expect(page.getByRole('row').nth(15).getByRole('cell')).toHaveCount(4);
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(2)).toHaveText('2:56.05');
await expect(page.getByRole('row').nth(15).getByRole('cell')).toHaveCount(17);
await expect(page.getByRole('row')).toHaveCount(16);

// Assert race results are correct (new race options loaded)
await page.getByLabel('Calculator').selectOption('Race Calculator');
// Assert pace results are correct (inputs and options not reset, new pace targets loaded)
await page.getByLabel('Calculator').selectOption('Pace Calculator');
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(0)).toHaveText('2 mi');
await expect(page.getByRole('row').nth(0).getByRole('cell').nth(2)).toHaveText('800 m');
await expect(page.getByRole('row').nth(0).getByRole('cell')).toHaveCount(17);
await expect(page.getByRole('row').nth(0).getByRole('cell')).toHaveCount(4);
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(0)).toHaveText('10:30');
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(2)).toHaveText('2:24.04');
await expect(page.getByRole('row').nth(1).getByRole('cell')).toHaveCount(17);
await expect(page.getByRole('row').nth(1).getByRole('cell').nth(2)).toHaveText('2:36.58');
await expect(page.getByRole('row').nth(1).getByRole('cell')).toHaveCount(4);
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(0)).toHaveText('12:50');
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(2)).toHaveText('2:56.05');
await expect(page.getByRole('row').nth(15).getByRole('cell')).toHaveCount(17);
await expect(page.getByRole('row').nth(15).getByRole('cell').nth(2)).toHaveText('3:11.38');
await expect(page.getByRole('row').nth(15).getByRole('cell')).toHaveCount(4);
await expect(page.getByRole('row')).toHaveCount(16);

// Assert workout results are correct (new workout options loaded)
Expand Down Expand Up @@ -170,7 +170,7 @@ test('Save and update state when navigating between calculators', async ({ page
await page.getByRole('link', { name: 'Back' }).click();
await page.getByRole('button', { name: 'Race Calculator' }).click();

// Assert race predictions are correct (input race and prediction model not reset)
// Assert race predictions are correct (input race not resset and new prediction model loaded)
await expect(page.getByRole('row').nth(5)).toHaveText('1 mi' + '5:02.17' + '3:08 / km');
await expect(page.getByRole('row').nth(10)).toHaveText('5 km' + '16:44.86' + '3:21 / km');
await expect(page.getByRole('row')).toHaveCount(17);
Expand Down
Loading

0 comments on commit fb26504

Please sign in to comment.