commit 3d696cb56c466a5006ae98ca8537bc7b70d719e2
parent 01d69427eed244b3c3ff18627f39662902f6052e
Author: ashermorgan <59518073+ashermorgan@users.noreply.github.com>
Date: Sat, 16 Mar 2024 13:22:29 -0700
Improve component tests
Diffstat:
4 files changed, 427 insertions(+), 171 deletions(-)
diff --git a/src/components/TargetEditor.vue b/src/components/TargetEditor.vue
@@ -56,7 +56,7 @@
<button title="Add distance target" @click="addDistanceTarget">
Add distance target
</button>
- <button v-if="timeTargets" title="Add time target" @click="addTimeTarget">
+ <button title="Add time target" @click="addTimeTarget">
Add time target
</button>
<br/>
@@ -95,14 +95,6 @@ export default {
},
/**
- * Whether to allow the user to add time based targets
- */
- timeTargets: {
- type: Boolean,
- default: true,
- },
-
- /**
* Whether the target set is a custom or default set
*/
isCustomSet: {
diff --git a/tests/unit/components/SimpleTargetTable.spec.js b/tests/unit/components/SimpleTargetTable.spec.js
@@ -1,5 +1,5 @@
import { test, expect } from 'vitest';
-import { mount, shallowMount } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
import SimpleTargetTable from '@/components/SimpleTargetTable.vue';
test('results should be correct and sorted by time', () => {
@@ -7,65 +7,117 @@ test('results should be correct and sorted by time', () => {
const wrapper = shallowMount(SimpleTargetTable, {
propsData: {
calculateResult: (row) => ({
- distanceValue: row.distanceValue ? row.distanceValue : row.time + 1,
+ distanceValue: row.distanceValue ? row.distanceValue : row.time / 300,
distanceUnit: row.distanceUnit ? row.distanceUnit : 'miles',
- time: row.time ? row.time : row.distanceValue + 1,
+ time: row.time ? row.time : row.distanceValue * 300,
result: row.result,
}),
targets: [
- { result: 'time', distanceValue: 20, distanceUnit: 'meters' },
- { result: 'time', distanceValue: 100, distanceUnit: 'meters' },
- { result: 'time', distanceValue: 1, distanceUnit: 'kilometers' },
- { result: 'time', distanceValue: 10, distanceUnit: 'meters' },
- { result: 'distance', time: 1 },
- { result: 'distance', time: 10 },
+ { result: 'time', distanceValue: 5, distanceUnit: 'kilometers' },
+ { result: 'time', distanceValue: 1, distanceUnit: 'miles' },
+ { result: 'time', distanceValue: 3, distanceUnit: 'miles' },
+ { result: 'distance', time: 1230 },
],
},
});
- // Assert results are correct
- expect(wrapper.vm.results).to.deep.equal([
- { result: 'distance', distanceValue: 2, distanceUnit: 'miles', time: 1 },
- { result: 'time', distanceValue: 1, distanceUnit: 'kilometers', time: 2 },
- { result: 'distance', distanceValue: 11, distanceUnit: 'miles', time: 10 },
- { result: 'time', distanceValue: 10, distanceUnit: 'meters', time: 11 },
- { result: 'time', distanceValue: 20, distanceUnit: 'meters', time: 21 },
- { result: 'time', distanceValue: 100, distanceUnit: 'meters', time: 101 },
- ]);
+ // Assert results are correctly rendered
+ 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('5:00.00');
+ expect(rows[0].findAll('td').length).to.equal(2);
+ expect(rows[1].findAll('td')[0].element.textContent).to.equal('3 mi');
+ expect(rows[1].findAll('td')[1].element.textContent).to.equal('15:00.00');
+ expect(rows[1].findAll('td').length).to.equal(2);
+ expect(rows[2].findAll('td')[0].element.textContent).to.equal('4.10 mi');
+ expect(rows[2].findAll('td')[1].element.textContent).to.equal('20:30');
+ expect(rows[2].findAll('td').length).to.equal(2);
+ expect(rows[3].findAll('td')[0].element.textContent).to.equal('5 km');
+ expect(rows[3].findAll('td')[1].element.textContent).to.equal('25:00.00');
+ expect(rows[3].findAll('td').length).to.equal(2);
+ expect(rows.length).to.equal(4);
});
-test('getPace should return correct imerial paces', () => {
+test('should show correct imperial paces when showPace is true', () => {
// Initialize component
- const wrapper = mount(SimpleTargetTable, {
+ const wrapper = shallowMount(SimpleTargetTable, {
propsData: {
- calculateResult: () => {},
+ calculateResult: (row) => ({
+ distanceValue: row.distanceValue ? row.distanceValue : row.time / 300,
+ distanceUnit: row.distanceUnit ? row.distanceUnit : 'miles',
+ time: row.time ? row.time : row.distanceValue * 300,
+ result: row.result,
+ }),
+ targets: [
+ { result: 'time', distanceValue: 5, distanceUnit: 'kilometers' },
+ { result: 'time', distanceValue: 1, distanceUnit: 'miles' },
+ { result: 'time', distanceValue: 3, distanceUnit: 'miles' },
+ { result: 'distance', time: 1230 },
+ ],
defaultUnitSystem: 'imperial',
+ showPace: true,
},
});
- // Assert paces are correct
- const result = wrapper.vm.getPace({
- distanceValue: 1,
- distanceUnit: 'kilometers',
- time: 300,
- });
- expect(result).to.be.closeTo(482.81, 0.01);
+ // Assert results are correctly rendered
+ 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('5:00.00');
+ expect(rows[0].findAll('td')[2].element.textContent).to.equal('5:00 / mi');
+ expect(rows[0].findAll('td').length).to.equal(3);
+ expect(rows[1].findAll('td')[0].element.textContent).to.equal('3 mi');
+ expect(rows[1].findAll('td')[1].element.textContent).to.equal('15:00.00');
+ expect(rows[1].findAll('td')[2].element.textContent).to.equal('5:00 / mi');
+ expect(rows[1].findAll('td').length).to.equal(3);
+ expect(rows[2].findAll('td')[0].element.textContent).to.equal('4.10 mi');
+ expect(rows[2].findAll('td')[1].element.textContent).to.equal('20:30');
+ expect(rows[2].findAll('td')[2].element.textContent).to.equal('5:00 / mi');
+ expect(rows[2].findAll('td').length).to.equal(3);
+ expect(rows[3].findAll('td')[0].element.textContent).to.equal('5 km');
+ expect(rows[3].findAll('td')[1].element.textContent).to.equal('25:00.00');
+ expect(rows[3].findAll('td')[2].element.textContent).to.equal('8:03 / mi');
+ expect(rows[3].findAll('td').length).to.equal(3);
+ expect(rows.length).to.equal(4);
});
-test('getPace should return correct metric paces', () => {
+test('should show correct metric paces when showPace is true', () => {
// Initialize component
- const wrapper = mount(SimpleTargetTable, {
+ const wrapper = shallowMount(SimpleTargetTable, {
propsData: {
- calculateResult: () => {},
+ calculateResult: (row) => ({
+ distanceValue: row.distanceValue ? row.distanceValue : row.time / 300,
+ distanceUnit: row.distanceUnit ? row.distanceUnit : 'miles',
+ time: row.time ? row.time : row.distanceValue * 300,
+ result: row.result,
+ }),
+ targets: [
+ { result: 'time', distanceValue: 5, distanceUnit: 'kilometers' },
+ { result: 'time', distanceValue: 1, distanceUnit: 'miles' },
+ { result: 'time', distanceValue: 3, distanceUnit: 'miles' },
+ { result: 'distance', time: 1230 },
+ ],
defaultUnitSystem: 'metric',
+ showPace: true,
},
});
- // Assert paces are correct
- const result = wrapper.vm.getPace({
- distanceValue: 1,
- distanceUnit: 'miles',
- time: 600,
- });
- expect(result).to.be.closeTo(372.82, 0.01);
+ // Assert results are correctly rendered
+ 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('5:00.00');
+ expect(rows[0].findAll('td')[2].element.textContent).to.equal('3:06 / km');
+ expect(rows[0].findAll('td').length).to.equal(3);
+ expect(rows[1].findAll('td')[0].element.textContent).to.equal('3 mi');
+ expect(rows[1].findAll('td')[1].element.textContent).to.equal('15:00.00');
+ expect(rows[1].findAll('td')[2].element.textContent).to.equal('3:06 / km');
+ expect(rows[1].findAll('td').length).to.equal(3);
+ expect(rows[2].findAll('td')[0].element.textContent).to.equal('4.10 mi');
+ expect(rows[2].findAll('td')[1].element.textContent).to.equal('20:30');
+ expect(rows[2].findAll('td')[2].element.textContent).to.equal('3:06 / km');
+ expect(rows[2].findAll('td').length).to.equal(3);
+ expect(rows[3].findAll('td')[0].element.textContent).to.equal('5 km');
+ expect(rows[3].findAll('td')[1].element.textContent).to.equal('25:00.00');
+ expect(rows[3].findAll('td')[2].element.textContent).to.equal('5:00 / km');
+ expect(rows[3].findAll('td').length).to.equal(3);
+ expect(rows.length).to.equal(4);
});
diff --git a/tests/unit/components/TargetEditor.spec.js b/tests/unit/components/TargetEditor.spec.js
@@ -1,32 +1,73 @@
import { test, expect } from 'vitest';
-import { shallowMount, mount } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
import TargetEditor from '@/components/TargetEditor.vue';
-test('revert method should emit revert event', async () => {
+test('should correctly render target set', async () => {
+ // Initialize component
+ const wrapper = shallowMount(TargetEditor, {
+ propsData: {
+ modelValue: {
+ name: 'My target set',
+ targets: [
+ { distanceUnit: 'kilometers', distanceValue: 1.61, result: 'time' },
+ { distanceUnit: 'miles', distanceValue: 3.11, result: 'time' },
+ { time: 600, result: 'distance' },
+ ],
+ },
+ },
+ });
+
+ // Assert target set correctly rendered
+ expect(wrapper.find('input').element.value).to.equal('My target set');
+ const rows = wrapper.findAll('tbody tr');
+ expect(rows[0].findComponent({ name: 'decimal-input' }).vm.modelValue).to.equal(1.61);
+ expect(rows[0].find('select').element.value).to.equal('kilometers');
+ expect(rows[1].findComponent({ name: 'decimal-input' }).vm.modelValue).to.equal(3.11);
+ expect(rows[1].find('select').element.value).to.equal('miles');
+ expect(rows[2].findComponent({ name: 'time-input' }).vm.modelValue).to.equal(600);
+ expect(rows.length).to.equal(3);
+});
+
+test('revert button should emit revert event', async () => {
// Initialize component
const wrapper = shallowMount(TargetEditor);
- // Call revert method
- await wrapper.vm.revert();
+ // Click revert button
+ await wrapper.find('button[title="Revert target set"]').trigger('click');
+
+ // Assert revert event was emitted
+ expect(wrapper.emitted().revert.length).to.equal(1);
+});
+
+test('delete button should emit revert event', async () => {
+ // Initialize component
+ const wrapper = shallowMount(TargetEditor, {
+ propsData: {
+ isCustomSet: true,
+ }
+ });
+
+ // Click delete button
+ await wrapper.find('button[title="Delete target set"]').trigger('click');
// Assert revert event was emitted
expect(wrapper.emitted().revert.length).to.equal(1);
});
-test('close method should emit close event', async () => {
+test('close button should emit close event', async () => {
// Initialize component
const wrapper = shallowMount(TargetEditor);
// Call close method
- await wrapper.vm.close();
+ await wrapper.find('button[title="Close"]').trigger('click');
// Assert close event was emitted
expect(wrapper.emitted().close.length).to.equal(1);
});
-test('addDistanceTarget method should correctly add imperial distance target', async () => {
+test('add distance target button should correctly add imperial distance target', async () => {
// Initialize component
- const wrapper = mount(TargetEditor, {
+ const wrapper = shallowMount(TargetEditor, {
propsData: {
modelValue: {
name: 'My target set',
@@ -40,7 +81,7 @@ test('addDistanceTarget method should correctly add imperial distance target', a
});
// Add distance target
- await wrapper.vm.addDistanceTarget();
+ await wrapper.find('button[title="Add distance target"]').trigger('click');
// Assert input event was emitted
expect(wrapper.emitted()['update:modelValue']).to.deep.equal([
@@ -55,9 +96,9 @@ test('addDistanceTarget method should correctly add imperial distance target', a
]);
});
-test('addDistanceTarget method should correctly add metric distance target', async () => {
+test('add distance target button should correctly add metric distance target', async () => {
// Initialize component
- const wrapper = mount(TargetEditor, {
+ const wrapper = shallowMount(TargetEditor, {
propsData: {
modelValue: {
name: 'My target set',
@@ -71,7 +112,7 @@ test('addDistanceTarget method should correctly add metric distance target', asy
});
// Add distance target
- await wrapper.vm.addDistanceTarget();
+ await wrapper.find('button[title="Add distance target"]').trigger('click');
// Assert input event was emitted
expect(wrapper.emitted()['update:modelValue']).to.deep.equal([
@@ -86,9 +127,9 @@ test('addDistanceTarget method should correctly add metric distance target', asy
]);
});
-test('addTimeTarget method should correctly add time target', async () => {
+test('add time target button should correctly add time target', async () => {
// Initialize component
- const wrapper = mount(TargetEditor, {
+ const wrapper = shallowMount(TargetEditor, {
propsData: {
modelValue: {
name: 'My target set',
@@ -101,7 +142,7 @@ test('addTimeTarget method should correctly add time target', async () => {
});
// Add time target
- await wrapper.vm.addTimeTarget();
+ await wrapper.find('button[title="Add time target"]').trigger('click');
// Assert input event was emitted
expect(wrapper.emitted()['update:modelValue']).to.deep.equal([
@@ -117,7 +158,7 @@ test('addTimeTarget method should correctly add time target', async () => {
test('Should emit input event when targets are updated', async () => {
// Initialize component
- const wrapper = mount(TargetEditor, {
+ const wrapper = shallowMount(TargetEditor, {
propsData: {
modelValue: {
name: 'My target set',
@@ -129,8 +170,7 @@ test('Should emit input event when targets are updated', async () => {
});
// Update distance value
- wrapper.vm.internalValue.targets[0].distanceValue = 3;
- await wrapper.vm.$nextTick();
+ await wrapper.findComponent({ name: 'decimal-input' }).setValue(3);
// Assert input event was emitted
expect(wrapper.emitted()['update:modelValue']).to.deep.equal([
@@ -147,7 +187,7 @@ test('Should emit input event when targets are updated', async () => {
test('Should emit input event when target set name is updated', async () => {
// Initialize component
- const wrapper = mount(TargetEditor, {
+ const wrapper = shallowMount(TargetEditor, {
propsData: {
modelValue: {
name: 'My target set',
@@ -159,8 +199,7 @@ test('Should emit input event when target set name is updated', async () => {
});
// Update distance value
- wrapper.vm.internalValue.name = 'My target set #2';
- await wrapper.vm.$nextTick();
+ await wrapper.find('input').setValue('My target set #2');
// Assert input event was emitted
expect(wrapper.emitted()['update:modelValue']).to.deep.equal([
@@ -175,7 +214,7 @@ test('Should emit input event when target set name is updated', async () => {
]);
});
-test('removeTarget method should correctly remove target', async () => {
+test('removeTarget button should correctly remove target', async () => {
// Initialize component
const wrapper = shallowMount(TargetEditor, {
propsData: {
@@ -191,7 +230,7 @@ test('removeTarget method should correctly remove target', async () => {
});
// Remove 2nd target
- await wrapper.vm.removeTarget(1);
+ await wrapper.findAll('button[title="Remove target"]')[1].trigger('click');
// Assert input event was emitted
expect(wrapper.emitted()['update:modelValue']).to.deep.equal([
diff --git a/tests/unit/components/TargetSetSelector.spec.js b/tests/unit/components/TargetSetSelector.spec.js
@@ -1,102 +1,215 @@
-import { test, expect } from 'vitest';
-import { mount } from '@vue/test-utils';
+import { beforeEach, test, expect, vi } from 'vitest';
+import { shallowMount } from '@vue/test-utils';
import TargetSetSelector from '@/components/TargetSetSelector.vue';
-test('Create New Target Set option should correctly add target set', async () => {
+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 = mount(TargetSetSelector, {
- data() {
- return {
- internalValue: 'A',
- editingTargetSets: false,
- 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' },
- ],
- },
- },
- };
+ const wrapper = shallowMount(TargetSetSelector, {
+ propsData: {
+ modelValue: 'B',
+ }
+ });
+
+ // Assert select element populated with target sets
+ const options = wrapper.findAll('option');
+ expect(options[0].element.text).to.equal('1st target set');
+ expect(options[0].element.value).to.equal('A');
+ expect(options[1].element.text).to.equal('2nd target set');
+ expect(options[1].element.value).to.equal('B');
+ expect(options[2].element.text).to.equal('[ Create New Target Set ]');
+ expect(options[2].element.value).to.equal('_new');
+ expect(options.length).to.equal(3);
+
+ // Assert correct target set is selected
+ expect(wrapper.find('select').element.value).to.equal('B');
+});
+
+test('Create New Target Set option should correctly add target set', async () => {
+ // Initialize localStorage
+ let 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: 'A',
+ }
});
// Add target set
- wrapper.vm.internalValue = '_new';
- await wrapper.vm.$nextTick();
+ await wrapper.find('select').setValue('_new');
- // Assert target set was added
- expect(wrapper.vm.targetSets['A']).to.deep.equal({
- name: '1st target set',
- targets: [
- { result: 'time', distanceValue: 1, distanceUnit: 'miles' },
- { result: 'time', distanceValue: 2, distanceUnit: 'miles' },
- { result: 'time', distanceValue: 3, distanceUnit: 'miles' },
- ],
- });
- const keys = Object.keys(wrapper.vm.targetSets)
- expect(keys.length).to.equal(2);
- expect(wrapper.vm.targetSets[keys[1]]).to.deep.equal({
+ // Assert target set options were correctly updated
+ const options = wrapper.findAll('option');
+ expect(options[0].element.text).to.equal('1st target set');
+ expect(options[0].element.value).to.equal('A');
+ expect(options[1].element.text).to.equal('2nd target set');
+ expect(options[1].element.value).to.equal('B');
+ expect(options[2].element.text).to.equal('New target set');
+ expect(options[2].element.value).to.match(/\d{12,14}/);
+ expect(options[3].element.text).to.equal('[ Create New Target Set ]');
+ expect(options[3].element.value).to.equal('_new');
+ expect(options.length).to.equal(4);
+
+ // Assert target sets were correctly updated
+ targetSets[options[2].element.value] = {
name: 'New target set',
targets: [],
- });
+ };
+ expect(localStorage.getItem('running-tools.target-sets')).to.equal(JSON.stringify(targetSets));
- // Assert new target set was selected
- expect(wrapper.vm.internalValue).to.equal(keys[1]);
+ // Assert targets-updated event was emitted
+ expect(wrapper.emitted()['targets-updated'].length).to.equal(1);
});
-test('revertTargetSet method should correctly reset target sets', async () => {
- // Initialize component
- const wrapper = mount(TargetSetSelector, {
- data() {
- return {
- internalValue: 'A',
- editingTargetSets: false,
- 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' },
- ],
- },
- '_split_targets': {
- name: '5K Kilometer Splits',
- targets: [
- { result: 'time', distanceValue: 2, distanceUnit: 'Kilometer' },
- { result: 'time', distanceValue: 4, distanceUnit: 'Kilometer' },
- { result: 'time', distanceValue: 5, distanceUnit: 'kilometers' },
- ],
- },
- },
- };
+test('Revert event should correctly reset a default target set', async () => {
+ // Initialize localStorage
+ let targetSets = {
+ '_split_targets': {
+ name: '1st target set',
+ targets: [
+ { result: 'time', distanceValue: 1, distanceUnit: 'miles' },
+ { result: 'time', distanceValue: 2, distanceUnit: 'miles' },
+ { result: 'time', distanceValue: 3, distanceUnit: 'miles' },
+ ],
},
+ '1234567890123': {
+ 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: '_split_targets',
+ }
});
- // Revert first target set
- await wrapper.vm.revertTargetSet();
+ // Add target set
+ await wrapper.findComponent({ name: 'target-editor' }).trigger('revert');
+
+ // Assert target set options were correctly updated
+ const options = wrapper.findAll('option');
+ expect(options[0].element.text).to.equal('5K Mile Splits');
+ expect(options[0].element.value).to.equal('_split_targets');
+ expect(options[1].element.text).to.equal('2nd target set');
+ expect(options[1].element.value).to.equal('1234567890123');
+ expect(options[2].element.text).to.equal('[ Create New Target Set ]');
+ expect(options[2].element.value).to.equal('_new');
+ expect(options.length).to.equal(3);
- // Assert first target set was removed
- expect(wrapper.vm.targetSets).to.deep.equal({
+ // Assert target sets were correctly updated
+ targetSets._split_targets.name = '5K Mile Splits';
+ targetSets._split_targets.targets[2] = {
+ result: 'time',
+ 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);
+});
+
+test('Revert event should correctly delete a custom target set', async () => {
+ // Initialize localStorage
+ let targetSets = {
'_split_targets': {
- name: '5K Kilometer Splits',
+ name: '1st target set',
targets: [
- { result: 'time', distanceValue: 2, distanceUnit: 'Kilometer' },
- { result: 'time', distanceValue: 4, distanceUnit: 'Kilometer' },
+ { result: 'time', distanceValue: 1, distanceUnit: 'miles' },
+ { result: 'time', distanceValue: 2, distanceUnit: 'miles' },
+ { result: 'time', distanceValue: 3, distanceUnit: 'miles' },
+ ],
+ },
+ '1234567890123': {
+ 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: '1234567890123',
+ }
});
- expect(wrapper.vm.internalValue).to.equal('_split_targets');
- // Revert second target set
- await wrapper.vm.revertTargetSet();
+ // Add target set
+ await wrapper.findComponent({ name: 'target-editor' }).trigger('revert');
+
+ // Assert target set options were correctly updated
+ const options = wrapper.findAll('option');
+ expect(options[0].element.text).to.equal('1st target set');
+ expect(options[0].element.value).to.equal('_split_targets');
+ expect(options[1].element.text).to.equal('[ Create New Target Set ]');
+ expect(options[1].element.value).to.equal('_new');
+ expect(options.length).to.equal(2);
+
+ // Assert target sets were correctly updated
+ delete targetSets['1234567890123'];
+ expect(localStorage.getItem('running-tools.target-sets')).to.equal(JSON.stringify(targetSets));
- // Assert second target set was reset
- expect(wrapper.vm.targetSets).to.deep.equal({
+ // Assert targets-updated event was emitted
+ expect(wrapper.emitted()['targets-updated'].length).to.equal(1);
+});
+
+test('edit button should open target editor with the correct props for default set', async () => {
+ // Initialize localStorage
+ const targetSets = {
'_split_targets': {
name: '5K Mile Splits',
targets: [
@@ -105,47 +218,107 @@ test('revertTargetSet method should correctly reset target sets', async () => {
{ result: 'time', distanceValue: 5, distanceUnit: 'kilometers' },
],
},
+ };
+ localStorage.setItem('running-tools.target-sets', JSON.stringify(targetSets));
+
+ // Initialize component
+ const wrapper = shallowMount(TargetSetSelector, {
+ propsData: {
+ modelValue: '_split_targets',
+ defaultUnitSystem: 'fake-unit-system',
+ }
});
- expect(wrapper.vm.internalValue).to.equal('_split_targets');
+
+ // Mock showModal function
+ wrapper.vm.$refs.dialog.showModal = vi.fn();
+
+ // Click edit button
+ await wrapper.find('button').trigger('click');
+
+ // Assert target editor props are correct
+ const targetEditor = wrapper.findComponent({ name: 'target-editor' });
+ expect(targetEditor.vm.modelValue).to.deep.equal(targetSets._split_targets);
+ expect(targetEditor.vm.isCustomSet).to.equal(false);
+ expect(targetEditor.vm.defaultUnitSystem).to.equal('fake-unit-system');
});
-test('sortTargetSet method should correctly sort target sets', async () => {
- // Initialize component
- const wrapper = mount(TargetSetSelector, {
- data() {
- return {
- internalValue: '_split_targets',
- editingTargetSets: false,
- targetSets: {
- '_split_targets': {
- name: '5K Mile Splits',
- targets: [
- { result: 'distance', timeValue: 60 },
- { result: 'time', distanceValue: 1, distanceUnit: 'miles' },
- { result: 'time', distanceValue: 2, distanceUnit: 'miles' },
- { result: 'time', distanceValue: 5, distanceUnit: 'kilometers' },
- { result: 'time', distanceValue: 3, distanceUnit: 'miles' },
- ],
- },
- },
- };
+test('edit button should open target editor with the correct props for custom set', async () => {
+ // Initialize localStorage
+ const targetSets = {
+ '1234567890123': {
+ 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: '1234567890123',
+ defaultUnitSystem: 'fake-unit-system',
+ }
});
- // Sort target set
- await wrapper.vm.sortTargetSet();
+ // Mock showModal function
+ wrapper.vm.$refs.dialog.showModal = vi.fn();
- // Assert target set was sorted
- expect(wrapper.vm.targetSets).to.deep.equal({
+ // Click edit button
+ await wrapper.find('button').trigger('click');
+
+ // Assert target editor props are correct
+ const targetEditor = wrapper.findComponent({ name: 'target-editor' });
+ expect(targetEditor.vm.modelValue).to.deep.equal(targetSets['1234567890123']);
+ expect(targetEditor.vm.isCustomSet).to.equal(true);
+ expect(targetEditor.vm.defaultUnitSystem).to.equal('fake-unit-system');
+});
+
+test('should reload and sort target set before target editor is opened', async () => {
+ // Initialize localStorage
+ let targetSets = {
'_split_targets': {
name: '5K Mile Splits',
targets: [
+ { result: 'distance', timeValue: 60 },
{ result: 'time', distanceValue: 1, distanceUnit: 'miles' },
{ result: 'time', distanceValue: 2, distanceUnit: 'miles' },
- { result: 'time', distanceValue: 3, distanceUnit: 'miles' },
{ result: 'time', distanceValue: 5, distanceUnit: 'kilometers' },
- { result: 'distance', timeValue: 60 },
+ { result: 'time', distanceValue: 3, distanceUnit: 'miles' },
],
},
+ };
+ localStorage.setItem('running-tools.target-sets', JSON.stringify(targetSets));
+
+ // Initialize component
+ const wrapper = shallowMount(TargetSetSelector, {
+ propsData: {
+ modelValue: '_split_targets',
+ }
+ });
+
+ // Update localStorage
+ targetSets._split_targets.name = '5K Mile Splits #2';
+ localStorage.setItem('running-tools.target-sets', JSON.stringify(targetSets));
+
+ // Mock showModal function
+ wrapper.vm.$refs.dialog.showModal = vi.fn();
+
+ // Click edit button
+ await wrapper.find('button').trigger('click');
+
+ // Assert target set was sorted
+ expect(wrapper.findComponent({ name: 'target-editor' }).vm.modelValue).to.deep.equal({
+ name: '5K Mile Splits #2',
+ targets: [
+ { result: 'time', distanceValue: 1, distanceUnit: 'miles' },
+ { result: 'time', distanceValue: 2, distanceUnit: 'miles' },
+ { result: 'time', distanceValue: 3, distanceUnit: 'miles' },
+ { result: 'time', distanceValue: 5, distanceUnit: 'kilometers' },
+ { result: 'distance', timeValue: 60 },
+ ],
});
});