running-tools

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

commit b490ff7f0e90684a1eb94726ed8396527797e16f
parent 7c6a17cfefa0e454a2e4880ba57bae0e1514ecfc
Author: Asher Morgan <59518073+ashermorgan@users.noreply.github.com>
Date:   Mon, 27 May 2024 10:20:15 -0700

Add targetSets v-model to TargetSetSelector

Eliminates the need for TargetSetSelector to access localStorage

Diffstat:
Msrc/components/TargetSetSelector.vue | 42+++++++++++-------------------------------
Msrc/views/PaceCalculator.vue | 13++++++++++---
Msrc/views/RaceCalculator.vue | 13++++++++++---
Msrc/views/SplitCalculator.vue | 6+++---
Mtests/unit/components/TargetSetSelector.spec.js | 116+++++++++++++++++++++++++++++--------------------------------------------------
Mtests/unit/views/PaceCalculator.spec.js | 21++++++++++++++-------
Mtests/unit/views/RaceCalculator.spec.js | 24++++++++++++++++--------
Mtests/unit/views/SplitCalculator.spec.js | 55++++++++++++++++++++++++++++++++++++-------------------
8 files changed, 142 insertions(+), 148 deletions(-)

diff --git a/src/components/TargetSetSelector.vue b/src/components/TargetSetSelector.vue @@ -8,7 +8,7 @@ </select> <button class="icon" title="Edit target set" - @click="reloadTargetSets(); sortTargetSet(); dialogElement.showModal()"> + @click="sortTargetSet(); dialogElement.showModal()"> <vue-feather type="edit" aria-hidden="true"/> </button> @@ -33,11 +33,19 @@ import TargetEditor from '@/components/TargetEditor.vue'; /** * The selected target set */ -const model = defineModel({ +const model = defineModel('selectedTargetSet', { type: String, default: '_new', }); +/** + * The target sets + */ +const targetSets = defineModel('targetSets', { + type: Object, + default: targetUtils.defaultTargetSets, +}); + defineProps({ /** * The unit system to use when creating distance targets @@ -48,20 +56,12 @@ defineProps({ }, }); -// Declare emitted events -const emit = defineEmits(['targets-updated']); - /** * The internal value */ const internalValue = ref(model.value); /** - * The target sets - */ -const targetSets = ref(storage.get('target-sets', targetUtils.defaultTargetSets)); - -/** * The dialog element */ const dialogElement = ref(null); @@ -76,11 +76,10 @@ watch(model, (newValue) => { }); /** - * Update the component vvalue when the internal value changes and create a new set if necessary + * Update the component value when the internal value changes and create a new set if necessary */ watch(internalValue, async (newValue) => { if (newValue == '_new') { - reloadTargetSets(); let key = Date.now().toString(); targetSets.value[key] = { name: 'New target set', @@ -94,14 +93,6 @@ watch(internalValue, async (newValue) => { }, { immediate: true }); /** - * Save target sets - */ -watch(targetSets, (newValue) => { - storage.set('target-sets', newValue); - emit('targets-updated'); -}, { deep: true }); - -/** * Revert or remove the current target set */ function revertTargetSet() { @@ -125,17 +116,6 @@ function sortTargetSet() { targetSets.value[internalValue.value].targets = targetUtils.sort(targetSets.value[internalValue.value].targets); } - -/** - * Reload the target sets - */ -function reloadTargetSets() { - targetSets.value = storage.get('target-sets', targetUtils.defaultTargetSets); -} - -onActivated(() => { - reloadTargetSets(); -}); </script> <style scoped> diff --git a/src/views/PaceCalculator.vue b/src/views/PaceCalculator.vue @@ -31,8 +31,8 @@ </div> <div> Target Set: - <target-set-selector v-model="selectedTargetSet" @targets-updated="reloadTargets" - :default-unit-system="defaultUnitSystem"/> + <target-set-selector v-model:selectedTargetSet="selectedTargetSet" + v-model:targetSets="targetSets" :default-unit-system="defaultUnitSystem"/> </div> </details> @@ -125,6 +125,13 @@ watch(selectedTargetSet, (newValue) => { }); /** + * Save target sets + */ +watch(targetSets, (newValue) => { + storage.set('target-sets', newValue); +}, { deep: true }); + +/** * The input pace (in seconds per meter) */ const pace = computed(() => { @@ -184,7 +191,7 @@ function calculatePace(target) { * (Re)load settings used in multiple calculators */ onActivated(() => { - targetSets.value = storage.get('target-sets', targetUtils.defaultTargetSets); + reloadTargets(); defaultUnitSystem.value = storage.get('default-unit-system', unitUtils.detectDefaultUnitSystem()); }); </script> diff --git a/src/views/RaceCalculator.vue b/src/views/RaceCalculator.vue @@ -46,8 +46,8 @@ </div> <div> Target Set: - <target-set-selector v-model="selectedTargetSet" @targets-updated="reloadTargets" - :default-unit-system="defaultUnitSystem"/> + <target-set-selector v-model:selectedTargetSet="selectedTargetSet" + v-model:targetSets="targetSets" :default-unit-system="defaultUnitSystem"/> </div> <div> Prediction Model: @@ -309,10 +309,17 @@ watch(selectedTargetSet, (newValue) => { }); /** + * Save target sets + */ +watch(targetSets, (newValue) => { + storage.set('target-sets', newValue); +}, { deep: true }); + +/** * (Re)load settings used in multiple calculators */ onActivated(() => { - targetSets.value = storage.get('target-sets', targetUtils.defaultTargetSets); + reloadTargets(); defaultUnitSystem.value = storage.get('default-unit-system', unitUtils.detectDefaultUnitSystem()); }); </script> diff --git a/src/views/SplitCalculator.vue b/src/views/SplitCalculator.vue @@ -10,8 +10,8 @@ <div class="target-set"> Target Set: - <target-set-selector v-model="selectedTargetSet" @targets-updated="reloadTargets" - :default-unit-system="defaultUnitSystem"/> + <target-set-selector v-model:selectedTargetSet="selectedTargetSet" + v-model:targetSets="targetSets" :default-unit-system="defaultUnitSystem"/> </div> <div class="output"> @@ -171,7 +171,7 @@ function reloadTargets() { * (Re)load settings used in multiple calculators */ onActivated(() => { - targetSets.value = storage.get('target-sets', targetUtils.defaultTargetSets); + reloadTargets(); defaultUnitSystem.value = storage.get('default-unit-system', unitUtils.detectDefaultUnitSystem()); }); </script> diff --git a/tests/unit/components/TargetSetSelector.spec.js b/tests/unit/components/TargetSetSelector.spec.js @@ -2,36 +2,29 @@ import { beforeEach, test, expect, vi } from 'vitest'; import { shallowMount } from '@vue/test-utils'; import TargetSetSelector from '@/components/TargetSetSelector.vue'; -beforeEach(() => { - localStorage.clear(); -}) - test('should correctly render target sets options', async () => { - // Initialize localStorage - const targetSets = { - 'A': { - name: '1st target set', - targets: [ - { result: 'time', distanceValue: 1, distanceUnit: 'miles' }, - { result: 'time', distanceValue: 2, distanceUnit: 'miles' }, - { result: 'time', distanceValue: 3, distanceUnit: 'miles' }, - ], - }, - 'B': { - name: '2nd target set', - targets: [ - { result: 'time', distanceValue: 1, distanceUnit: 'kilometers' }, - { result: 'time', distanceValue: 5, distanceUnit: 'kilometers' }, - { result: 'time', distanceValue: 10, distanceUnit: 'kilometers' }, - ], - }, - }; - localStorage.setItem('running-tools.target-sets', JSON.stringify(targetSets)); - // Initialize component const wrapper = shallowMount(TargetSetSelector, { propsData: { - modelValue: 'B', + selectedTargetSet: 'B', + targetSets: { + 'A': { + name: '1st target set', + targets: [ + { result: 'time', distanceValue: 1, distanceUnit: 'miles' }, + { result: 'time', distanceValue: 2, distanceUnit: 'miles' }, + { result: 'time', distanceValue: 3, distanceUnit: 'miles' }, + ], + }, + 'B': { + name: '2nd target set', + targets: [ + { result: 'time', distanceValue: 1, distanceUnit: 'kilometers' }, + { result: 'time', distanceValue: 5, distanceUnit: 'kilometers' }, + { result: 'time', distanceValue: 10, distanceUnit: 'kilometers' }, + ], + }, + }, } }); @@ -50,7 +43,7 @@ test('should correctly render target sets options', async () => { }); test('Create New Target Set option should correctly add target set', async () => { - // Initialize localStorage + // Initialize component let targetSets = { 'A': { name: '1st target set', @@ -69,12 +62,10 @@ test('Create New Target Set option should correctly add target set', async () => ], }, }; - localStorage.setItem('running-tools.target-sets', JSON.stringify(targetSets)); - - // Initialize component const wrapper = shallowMount(TargetSetSelector, { propsData: { - modelValue: 'A', + selectedTargetSet: 'A', + targetSets, } }); @@ -102,14 +93,11 @@ test('Create New Target Set option should correctly add target set', async () => name: 'New target set', targets: [], }; - expect(localStorage.getItem('running-tools.target-sets')).to.equal(JSON.stringify(targetSets)); - - // Assert targets-updated event was emitted - expect(wrapper.emitted()['targets-updated'].length).to.equal(1); + expect(wrapper.vm.targetSets).to.deep.equal(targetSets); }); test('Revert event should correctly reset a default target set', async () => { - // Initialize localStorage + // Initialize component let targetSets = { '_split_targets': { name: '1st target set', @@ -128,12 +116,10 @@ test('Revert event should correctly reset a default target set', async () => { ], }, }; - localStorage.setItem('running-tools.target-sets', JSON.stringify(targetSets)); - - // Initialize component const wrapper = shallowMount(TargetSetSelector, { propsData: { - modelValue: '_split_targets', + selectedTargetSet: '_split_targets', + targetSets, } }); @@ -157,14 +143,11 @@ test('Revert event should correctly reset a default target set', async () => { distanceValue: 5, distanceUnit: 'kilometers', }; - expect(localStorage.getItem('running-tools.target-sets')).to.equal(JSON.stringify(targetSets)); - - // Assert targets-updated event was emitted - expect(wrapper.emitted()['targets-updated'].length).to.equal(1); + expect(wrapper.vm.targetSets).to.deep.equal(targetSets); }); test('Revert event should correctly delete a custom target set', async () => { - // Initialize localStorage + // Initialize component let targetSets = { '_split_targets': { name: '1st target set', @@ -183,12 +166,10 @@ test('Revert event should correctly delete a custom target set', async () => { ], }, }; - localStorage.setItem('running-tools.target-sets', JSON.stringify(targetSets)); - - // Initialize component const wrapper = shallowMount(TargetSetSelector, { propsData: { - modelValue: '1234567890123', + selectedTargetSet: '1234567890123', + targetSets, } }); @@ -205,14 +186,11 @@ test('Revert event should correctly delete a custom target set', async () => { // Assert target sets were correctly updated delete targetSets['1234567890123']; - expect(localStorage.getItem('running-tools.target-sets')).to.equal(JSON.stringify(targetSets)); - - // Assert targets-updated event was emitted - expect(wrapper.emitted()['targets-updated'].length).to.equal(1); + expect(wrapper.vm.targetSets).to.deep.equal(targetSets); }); test('edit button should open target editor with the correct props for default set', async () => { - // Initialize localStorage + // Initialize component const targetSets = { '_split_targets': { name: '5K Mile Splits', @@ -223,12 +201,10 @@ test('edit button should open target editor with the correct props for default s ], }, }; - localStorage.setItem('running-tools.target-sets', JSON.stringify(targetSets)); - - // Initialize component const wrapper = shallowMount(TargetSetSelector, { propsData: { - modelValue: '_split_targets', + selectedTargetSet: '_split_targets', + targetSets, defaultUnitSystem: 'fake-unit-system', } }); @@ -247,7 +223,7 @@ test('edit button should open target editor with the correct props for default s }); test('edit button should open target editor with the correct props for custom set', async () => { - // Initialize localStorage + // Initialize component const targetSets = { '1234567890123': { name: '2nd target set', @@ -258,12 +234,10 @@ test('edit button should open target editor with the correct props for custom se ], }, }; - localStorage.setItem('running-tools.target-sets', JSON.stringify(targetSets)); - - // Initialize component const wrapper = shallowMount(TargetSetSelector, { propsData: { - modelValue: '1234567890123', + selectedTargetSet: '1234567890123', + targetSets, defaultUnitSystem: 'fake-unit-system', } }); @@ -281,8 +255,8 @@ test('edit button should open target editor with the correct props for custom se expect(targetEditor.vm.defaultUnitSystem).to.equal('fake-unit-system'); }); -test('should reload and sort target set before target editor is opened', async () => { - // Initialize localStorage +test('should sort target set before target editor is opened', async () => { + // Initialize component let targetSets = { '_split_targets': { name: '5K Mile Splits', @@ -295,19 +269,13 @@ test('should reload and sort target set before target editor is opened', async ( ], }, }; - localStorage.setItem('running-tools.target-sets', JSON.stringify(targetSets)); - - // Initialize component const wrapper = shallowMount(TargetSetSelector, { propsData: { - modelValue: '_split_targets', + selectedTargetSet: '_split_targets', + targetSets, } }); - // Update localStorage - targetSets._split_targets.name = '5K Mile Splits #2'; - localStorage.setItem('running-tools.target-sets', JSON.stringify(targetSets)); - // Mock showModal function wrapper.vm.dialogElement.showModal = vi.fn(); @@ -316,7 +284,7 @@ test('should reload and sort target set before target editor is opened', async ( // Assert target set was sorted expect(wrapper.findComponent({ name: 'target-editor' }).vm.modelValue).to.deep.equal({ - name: '5K Mile Splits #2', + name: '5K Mile Splits', targets: [ { result: 'time', distanceValue: 1, distanceUnit: 'miles' }, { result: 'time', distanceValue: 2, distanceUnit: 'miles' }, diff --git a/tests/unit/views/PaceCalculator.spec.js b/tests/unit/views/PaceCalculator.spec.js @@ -78,17 +78,20 @@ test('should correctly handle null target set', async () => { await wrapper.vm.reloadTargets(); // onActivated method not called in tests // Switch to invalid target set - await wrapper.findComponent({ name: 'target-set-selector' }).setValue('does_not_exist'); + await wrapper.findComponent({ name: 'target-set-selector' }) + .setValue('does_not_exist', 'selectedTargetSet'); // Assert empty array passed to SimpleTargetTable component expect(wrapper.findComponent({ name: 'simple-target-table' }).vm.targets).to.deep.equal([]); // Switch to valid target set - await wrapper.findComponent({ name: 'target-set-selector' }).setValue('_pace_targets'); + await wrapper.findComponent({ name: 'target-set-selector' }) + .setValue('_pace_targets', 'selectedTargetSet'); // Assert valid targets passed to SimpleTargetTable component const paceTargets = targetUtils.defaultTargetSets._pace_targets.targets; - expect(wrapper.findComponent({ name: 'simple-target-table' }).vm.targets).to.deep.equal(paceTargets); + expect(wrapper.findComponent({ name: 'simple-target-table' }).vm.targets) + .to.deep.equal(paceTargets); }); test('should load input pace from localStorage', async () => { @@ -130,9 +133,11 @@ test('should load selected target set from localStorage', async () => { await wrapper.vm.reloadTargets(); // Assert selection is loaded - expect(wrapper.findComponent({ name: 'target-set-selector' }).vm.modelValue).to.equal('_race_targets'); + expect(wrapper.findComponent({ name: 'target-set-selector' }).vm.selectedTargetSet) + .to.equal('_race_targets'); const raceTargets = targetUtils.defaultTargetSets._race_targets.targets; - expect(wrapper.findComponent({ name: 'simple-target-table' }).vm.targets).to.deep.equal(raceTargets); + expect(wrapper.findComponent({ name: 'simple-target-table' }).vm.targets) + .to.deep.equal(raceTargets); }); test('should save selected target set to localStorage when modified', async () => { @@ -140,10 +145,12 @@ test('should save selected target set to localStorage when modified', async () = const wrapper = shallowMount(PaceCalculator); // Select a new target set - await wrapper.findComponent({ name: 'target-set-selector' }).setValue('_race_targets'); + await wrapper.findComponent({ name: 'target-set-selector' }) + .setValue('_race_targets', 'selectedTargetSet'); // New selected target set should be saved to localStorage - expect(localStorage.getItem('running-tools.pace-calculator-target-set')).to.equal('"_race_targets"'); + expect(localStorage.getItem('running-tools.pace-calculator-target-set')) + .to.equal('"_race_targets"'); }); test('should save default units setting to localStorage when modified', async () => { diff --git a/tests/unit/views/RaceCalculator.spec.js b/tests/unit/views/RaceCalculator.spec.js @@ -78,17 +78,20 @@ test('should correctly handle null target set', async () => { await wrapper.vm.reloadTargets(); // onActivated method not called in tests // Switch to invalid target set - await wrapper.findComponent({ name: 'target-set-selector' }).setValue('does_not_exist'); + await wrapper.findComponent({ name: 'target-set-selector' }) + .setValue('does_not_exist', 'selectedTargetSet'); // Assert empty array passed to SimpleTargetTable component expect(wrapper.findComponent({ name: 'simple-target-table' }).vm.targets).to.deep.equal([]); // Switch to valid target set - await wrapper.findComponent({ name: 'target-set-selector' }).setValue('_race_targets'); + await wrapper.findComponent({ name: 'target-set-selector' }) + .setValue('_race_targets', 'selectedTargetSet'); // Assert valid targets passed to SimpleTargetTable component const raceTargets = targetUtils.defaultTargetSets._race_targets.targets; - expect(wrapper.findComponent({ name: 'simple-target-table' }).vm.targets).to.deep.equal(raceTargets); + expect(wrapper.findComponent({ name: 'simple-target-table' }).vm.targets) + .to.deep.equal(raceTargets); }); test('should correctly calculate race statistics', async () => { @@ -189,9 +192,11 @@ test('should load selected target set from localStorage', async () => { await wrapper.vm.reloadTargets(); // Assert selection is loaded - expect(wrapper.findComponent({ name: 'target-set-selector' }).vm.modelValue).to.equal('_pace_targets'); + expect(wrapper.findComponent({ name: 'target-set-selector' }).vm.selectedTargetSet) + .to.equal('_pace_targets'); const paceTargets = targetUtils.defaultTargetSets._pace_targets.targets; - expect(wrapper.findComponent({ name: 'simple-target-table' }).vm.targets).to.deep.equal(paceTargets); + expect(wrapper.findComponent({ name: 'simple-target-table' }).vm.targets) + .to.deep.equal(paceTargets); }); test('should save selected target set to localStorage when modified', async () => { @@ -199,10 +204,12 @@ test('should save selected target set to localStorage when modified', async () = const wrapper = shallowMount(RaceCalculator); // Select a new target set - await wrapper.findComponent({ name: 'target-set-selector' }).setValue('_pace_targets'); + await wrapper.findComponent({ name: 'target-set-selector' }) + .setValue('_pace_targets', 'selectedTargetSet'); // New selected target set should be saved to localStorage - expect(localStorage.getItem('running-tools.race-calculator-target-set')).to.equal('"_pace_targets"'); + expect(localStorage.getItem('running-tools.race-calculator-target-set')) + .to.equal('"_pace_targets"'); }); test('should save default units setting to localStorage when modified', async () => { @@ -226,7 +233,8 @@ test('should load advanced model options from localStorage', async () => { const wrapper = shallowMount(RaceCalculator); // Assert data loaded - expect(wrapper.find('select[aria-label="Prediction model"]').element.value).to.equal('PurdyPointsModel'); + expect(wrapper.find('select[aria-label="Prediction model"]').element.value) + .to.equal('PurdyPointsModel'); expect(wrapper.findComponent('[aria-label="Riegel exponent"]').vm.modelValue).to.equal(1.20); }); diff --git a/tests/unit/views/SplitCalculator.spec.js b/tests/unit/views/SplitCalculator.spec.js @@ -52,17 +52,20 @@ test('should correctly load split times from split targets', async () => { const rows = wrapper.findAll('tbody tr'); expect(rows[0].findAll('td')[0].element.textContent).to.equal('1 km'); expect(rows[0].findAll('td')[1].element.textContent).to.equal('3:00.00'); - expect(rows[0].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue).to.equal(180); + expect(rows[0].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue) + .to.equal(180); expect(rows[0].findAll('td')[3].element.textContent).to.equal('4:50 / mi'); expect(rows[0].findAll('td').length).to.equal(4); expect(rows[1].findAll('td')[0].element.textContent).to.equal('2 km'); expect(rows[1].findAll('td')[1].element.textContent).to.equal('6:10.00'); - expect(rows[1].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue).to.equal(190); + expect(rows[1].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue) + .to.equal(190); expect(rows[1].findAll('td')[3].element.textContent).to.equal('5:06 / mi'); expect(rows[1].findAll('td').length).to.equal(4); expect(rows[2].findAll('td')[0].element.textContent).to.equal('3000 m'); expect(rows[2].findAll('td')[1].element.textContent).to.equal('9:30.00'); - expect(rows[2].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue).to.equal(200); + expect(rows[2].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue) + .to.equal(200); expect(rows[2].findAll('td')[3].element.textContent).to.equal('5:22 / mi'); expect(rows[2].findAll('td').length).to.equal(4); expect(rows.length).to.equal(3); @@ -78,12 +81,14 @@ test('should correctly handle null target set', async () => { // Assert results are empty let rows = wrapper.findAll('tbody tr'); - expect(rows[0].findAll('td')[0].element.textContent.trim()).to.equal('There aren\'t any targets in this set yet.'); + expect(rows[0].findAll('td')[0].element.textContent.trim()) + .to.equal('There aren\'t any targets in this set yet.'); expect(rows[0].findAll('td').length).to.equal(1); expect(rows.length).to.equal(1); // Switch to valid target set - await wrapper.findComponent({ name: 'target-set-selector' }).setValue('_split_targets'); + await wrapper.findComponent({ name: 'target-set-selector' }) + .setValue('_split_targets', 'selectedTargetSet'); // Assert results are correct rows = wrapper.findAll('tbody tr'); @@ -108,17 +113,20 @@ test('should correctly calculate paces and cumulative times from entered split t const rows = wrapper.findAll('tbody tr'); expect(rows[0].findAll('td')[0].element.textContent).to.equal('1 mi'); expect(rows[0].findAll('td')[1].element.textContent).to.equal('7:00.00'); - expect(rows[0].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue).to.equal(420); + expect(rows[0].findAll('td')[2].findComponent({ name: 'time-input' }) + .vm.modelValue).to.equal(420); expect(rows[0].findAll('td')[3].element.textContent).to.equal('7:00 / mi'); expect(rows[0].findAll('td').length).to.equal(4); expect(rows[1].findAll('td')[0].element.textContent).to.equal('2 mi'); expect(rows[1].findAll('td')[1].element.textContent).to.equal('13:30.00'); - expect(rows[1].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue).to.equal(390); + expect(rows[1].findAll('td')[2].findComponent({ name: 'time-input' }) + .vm.modelValue).to.equal(390); expect(rows[1].findAll('td')[3].element.textContent).to.equal('6:30 / mi'); expect(rows[1].findAll('td').length).to.equal(4); expect(rows[2].findAll('td')[0].element.textContent).to.equal('5 km'); expect(rows[2].findAll('td')[1].element.textContent).to.equal('20:00.00'); - expect(rows[2].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue).to.equal(390); + expect(rows[2].findAll('td')[2].findComponent({ name: 'time-input' }) + .vm.modelValue).to.equal(390); expect(rows[2].findAll('td')[3].element.textContent).to.equal('5:52 / mi'); expect(rows[2].findAll('td').length).to.equal(4); expect(rows.length).to.equal(3); @@ -258,27 +266,31 @@ test('should update results when a new target set is selected', async () => { await wrapper.vm.reloadTargets(); // Assert default split targets are initially loaded - expect(wrapper.findComponent({ name: 'target-set-selector' }).vm.modelValue).to.equal('_split_targets'); + expect(wrapper.findComponent({ name: 'target-set-selector' }).vm.selectedTargetSet) + .to.equal('_split_targets'); expect(wrapper.findAll('tbody td')[0].element.textContent).to.equal('1 mi'); // Select a new target set - await wrapper.findComponent({ name: 'target-set-selector' }).setValue('B'); + await wrapper.findComponent({ name: 'target-set-selector' }).setValue('B', 'selectedTargetSet'); // Assert results are correct const rows = wrapper.findAll('tbody tr'); expect(rows[0].findAll('td')[0].element.textContent).to.equal('1 km'); expect(rows[0].findAll('td')[1].element.textContent).to.equal('3:00.00'); - expect(rows[0].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue).to.equal(180); + expect(rows[0].findAll('td')[2].findComponent({ name: 'time-input' }) + .vm.modelValue).to.equal(180); expect(rows[0].findAll('td')[3].element.textContent).to.equal('4:50 / mi'); expect(rows[0].findAll('td').length).to.equal(4); expect(rows[1].findAll('td')[0].element.textContent).to.equal('2 km'); expect(rows[1].findAll('td')[1].element.textContent).to.equal('6:10.00'); - expect(rows[1].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue).to.equal(190); + expect(rows[1].findAll('td')[2].findComponent({ name: 'time-input' }) + .vm.modelValue).to.equal(190); expect(rows[1].findAll('td')[3].element.textContent).to.equal('5:06 / mi'); expect(rows[1].findAll('td').length).to.equal(4); expect(rows[2].findAll('td')[0].element.textContent).to.equal('3000 m'); expect(rows[2].findAll('td')[1].element.textContent).to.equal('9:30.00'); - expect(rows[2].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue).to.equal(200); + expect(rows[2].findAll('td')[2].findComponent({ name: 'time-input' }) + .vm.modelValue).to.equal(200); expect(rows[2].findAll('td')[3].element.textContent).to.equal('5:22 / mi'); expect(rows[2].findAll('td').length).to.equal(4); expect(rows.length).to.equal(3); @@ -312,23 +324,26 @@ test('should load selected target set from localStorage', async () => { await wrapper.vm.reloadTargets(); // Assert selection is loaded - expect(wrapper.findComponent({ name: 'target-set-selector' }).vm.modelValue).to.equal('B'); + expect(wrapper.findComponent({ name: 'target-set-selector' }).vm.selectedTargetSet).to.equal('B'); // Assert results are correct const rows = wrapper.findAll('tbody tr'); expect(rows[0].findAll('td')[0].element.textContent).to.equal('1 km'); expect(rows[0].findAll('td')[1].element.textContent).to.equal('3:00.00'); - expect(rows[0].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue).to.equal(180); + expect(rows[0].findAll('td')[2].findComponent({ name: 'time-input' }) + .vm.modelValue).to.equal(180); expect(rows[0].findAll('td')[3].element.textContent).to.equal('4:50 / mi'); expect(rows[0].findAll('td').length).to.equal(4); expect(rows[1].findAll('td')[0].element.textContent).to.equal('2 km'); expect(rows[1].findAll('td')[1].element.textContent).to.equal('6:10.00'); - expect(rows[1].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue).to.equal(190); + expect(rows[1].findAll('td')[2].findComponent({ name: 'time-input' }) + .vm.modelValue).to.equal(190); expect(rows[1].findAll('td')[3].element.textContent).to.equal('5:06 / mi'); expect(rows[1].findAll('td').length).to.equal(4); expect(rows[2].findAll('td')[0].element.textContent).to.equal('3000 m'); expect(rows[2].findAll('td')[1].element.textContent).to.equal('9:30.00'); - expect(rows[2].findAll('td')[2].findComponent({ name: 'time-input' }).vm.modelValue).to.equal(200); + expect(rows[2].findAll('td')[2].findComponent({ name: 'time-input' }) + .vm.modelValue).to.equal(200); expect(rows[2].findAll('td')[3].element.textContent).to.equal('5:22 / mi'); expect(rows[2].findAll('td').length).to.equal(4); expect(rows.length).to.equal(3); @@ -340,10 +355,12 @@ test('should save selected target set to localStorage when modified', async () = await wrapper.vm.reloadTargets(); // Select a new target set - await wrapper.findComponent({ name: 'target-set-selector' }).setValue('_race_targets'); + await wrapper.findComponent({ name: 'target-set-selector' }) + .setValue('_race_targets', 'selectedTargetSet'); // New selected target set should be saved to localStorage - expect(localStorage.getItem('running-tools.split-calculator-target-set')).to.equal('"_race_targets"'); + expect(localStorage.getItem('running-tools.split-calculator-target-set')) + .to.equal('"_race_targets"'); }); test('should update paces according to default units setting', async () => {