running-tools

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

commit ee74b3c9cd1bb4c43a21c861c57fb5103635be7e
parent 31034432931321fa8fe8f4327ef9e125c1400cf4
Author: ashermorgan <59518073+ashermorgan@users.noreply.github.com>
Date:   Mon, 23 Aug 2021 10:29:14 -0700

Reorganize unit tests

Diffstat:
Dtests/unit/DecimalInput.spec.js | 260-------------------------------------------------------------------------------
Dtests/unit/IntInput.spec.js | 238-------------------------------------------------------------------------------
Dtests/unit/PaceCalculator.spec.js | 32--------------------------------
Dtests/unit/RaceCalculator.spec.js | 35-----------------------------------
Dtests/unit/TimeInput.spec.js | 59-----------------------------------------------------------
Dtests/unit/TimeTable.spec.js | 34----------------------------------
Dtests/unit/UnitCalculator.spec.js | 100-------------------------------------------------------------------------------
Atests/unit/components/DecimalInput.spec.js | 260+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atests/unit/components/IntInput.spec.js | 238+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atests/unit/components/TimeInput.spec.js | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atests/unit/components/TimeTable.spec.js | 34++++++++++++++++++++++++++++++++++
Dtests/unit/pace.spec.js | 22----------------------
Atests/unit/utils/paces.spec.js | 22++++++++++++++++++++++
Rtests/unit/races.spec.js -> tests/unit/utils/races.spec.js | 0
Rtests/unit/units.spec.js -> tests/unit/utils/units.spec.js | 0
Atests/unit/views/PaceCalculator.spec.js | 32++++++++++++++++++++++++++++++++
Atests/unit/views/RaceCalculator.spec.js | 35+++++++++++++++++++++++++++++++++++
Atests/unit/views/UnitCalculator.spec.js | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
18 files changed, 780 insertions(+), 780 deletions(-)

diff --git a/tests/unit/DecimalInput.spec.js b/tests/unit/DecimalInput.spec.js @@ -1,260 +0,0 @@ -import { expect } from 'chai'; -import { mount } from '@vue/test-utils'; -import DecimalInput from '@/components/DecimalInput.vue'; - -describe('DecimalInput.vue', () => { - it('value should be 0.0 by default', () => { - // Initialize component - const wrapper = mount(DecimalInput); - - // Assert value is 0.0 - expect(wrapper.find('input').element.value).to.equal('0.0'); - }); - - it('should read value prop', () => { - // Initialize component - const wrapper = mount(DecimalInput, { - propsData: { value: 1 }, - }); - - // Assert value is 1.0 - expect(wrapper.find('input').element.value).to.equal('1.0'); - }); - - it('up arrow should increment value', async () => { - // Initialize component - const wrapper = mount(DecimalInput); - - // Press up arrow - await wrapper.trigger('keydown', { key: 'ArrowUp' }); - - // Assert value is 1.0 and input event was emitted - expect(wrapper.find('input').element.value).to.equal('1.0'); - expect(wrapper.emitted().input).to.deep.equal([[1.0]]); - }); - - it('down arrow should increment value', async () => { - // Initialize component - const wrapper = mount(DecimalInput); - - // Press down arrow - await wrapper.trigger('keydown', { key: 'ArrowDown' }); - - // Assert value is -1.0 and input event was emitted - expect(wrapper.find('input').element.value).to.equal('-1.0'); - expect(wrapper.emitted().input).to.deep.equal([[-1.0]]); - }); - - it('should fire input event when value changes', async () => { - // Initialize component - const wrapper = mount(DecimalInput); - - // Set value to 1 - wrapper.find('input').element.value = '1.0'; - await wrapper.find('input').trigger('input'); - - // Assert input event was emitted - expect(wrapper.emitted().input).to.deep.equal([[1.0]]); - }); - - it('should accept numerical values', async () => { - // Initialize component - const wrapper = mount(DecimalInput); - - // Try to set value to 1 - wrapper.find('input').element.value = '1'; - await wrapper.find('input').trigger('input'); - - // Assert value was accepted and input event was emitted - expect(wrapper.find('input').element.value).to.equal('1'); - expect(wrapper.emitted().input).to.deep.equal([[1.0]]); - }); - - it('should accept decimal values', async () => { - // Initialize component - const wrapper = mount(DecimalInput, { - propsData: { value: 1 }, - }); - - // Try to set value to 1.5 - wrapper.find('input').element.value = '1.5'; - await wrapper.find('input').trigger('input'); - - // Assert value was accepted and input event was emitted - expect(wrapper.find('input').element.value).to.equal('1.5'); - expect(wrapper.emitted().input).to.deep.equal([[1.5]]); - }); - - it('should not accept non numerical values', async () => { - // Initialize component - const wrapper = mount(DecimalInput, { - propsData: { value: 1 }, - }); - - // Try to set value to a - wrapper.find('input').element.value = 'a'; - await wrapper.find('input').trigger('input'); - - // Assert value was not accepted and no events were emitted - expect(wrapper.find('input').element.value).to.equal('1.0'); - expect(wrapper.emitted().input).to.equal(undefined); - }); - - it('should format input value on blur', async () => { - // Initialize component - const wrapper = mount(DecimalInput, { - propsData: { value: 1, padding: 3, digits: 2 }, - }); - - // Set value to '01' - wrapper.find('input').element.value = '01'; - await wrapper.find('input').trigger('input'); - - // Assert value was not updated and no events were emitted - expect(wrapper.find('input').element.value).to.equal('01'); - expect(wrapper.emitted().input).to.equal(undefined); - - // Trigger blur event - await wrapper.find('input').trigger('blur'); - - // Assert value was formatted but no events were emitted - expect(wrapper.find('input').element.value).to.equal('001.00'); - expect(wrapper.emitted().input).to.equal(undefined); - }); - - it('should allow input to be empty until blur', async () => { - // Initialize component - const wrapper = mount(DecimalInput, { - propsData: { value: 5 }, - }); - - // Set value to '' - wrapper.find('input').element.value = ''; - await wrapper.find('input').trigger('input'); - - // Assert value is '' and input event was emitted with default value - expect(wrapper.find('input').element.value).to.equal(''); - expect(wrapper.emitted().input).to.deep.equal([[0.0]]); - - // Trigger blur event - await wrapper.find('input').trigger('blur'); - - // Assert value is the default value but no new events were emitted - expect(wrapper.find('input').element.value).to.equal('0.0'); - expect(wrapper.emitted().input).to.deep.equal([[0.0]]); - }); - - it('should allow input to be "-" until blur', async () => { - // Initialize component - const wrapper = mount(DecimalInput, { - propsData: { value: 5 }, - }); - - // Set value to '-' - wrapper.find('input').element.value = '-'; - await wrapper.find('input').trigger('input'); - - // Assert value is '-' and input event was emitted with default value - expect(wrapper.find('input').element.value).to.equal('-'); - expect(wrapper.emitted().input).to.deep.equal([[0.0]]); - - // Trigger blur event - await wrapper.find('input').trigger('blur'); - - // Assert value is the default value but no new events were emitted - expect(wrapper.find('input').element.value).to.equal('0.0'); - expect(wrapper.emitted().input).to.deep.equal([[0.0]]); - }); - - it('should allow input to be "." until blur', async () => { - // Initialize component - const wrapper = mount(DecimalInput, { - propsData: { value: 5 }, - }); - - // Set value to '.' - wrapper.find('input').element.value = '.'; - await wrapper.find('input').trigger('input'); - - // Assert value is '.' and input event was emitted with default value - expect(wrapper.find('input').element.value).to.equal('.'); - expect(wrapper.emitted().input).to.deep.equal([[0.0]]); - - // Trigger blur event - await wrapper.find('input').trigger('blur'); - - // Assert value is the default value but no new events were emitted - expect(wrapper.find('input').element.value).to.equal('0.0'); - expect(wrapper.emitted().input).to.deep.equal([[0.0]]); - }); - - it('default value should be the minimum if 0.0 is not valid', async () => { - // Initialize component - const wrapper = mount(DecimalInput, { - propsData: { value: 3, max: 4, min: 2 }, - }); - - // Set value to '' and trigger blur event so value must be updated - wrapper.find('input').element.value = ''; - await wrapper.find('input').trigger('input'); - await wrapper.find('input').trigger('blur'); - - // Assert value is 2 and input event was emitted - expect(wrapper.find('input').element.value).to.equal('2.0'); - expect(wrapper.emitted().input).to.deep.equal([[2.0]]); - }); - - it('should not allow input to be below the minimum', async () => { - // Initialize component - const wrapper = mount(DecimalInput, { - propsData: { min: 10, value: 20 }, - }); - - // Try to set value to 9, which is below the minimum - wrapper.find('input').element.value = '9.0'; - await wrapper.find('input').trigger('input'); - - // Assert value is 10 and input event was emitted - expect(wrapper.find('input').element.value).to.equal('10.0'); - expect(wrapper.emitted().input).to.deep.equal([[10.0]]); - - // Try to decrement value - await wrapper.trigger('keydown', { key: 'ArrowDown' }); - - // Assert value is still 10 and no new event were emitted - expect(wrapper.find('input').element.value).to.equal('10.0'); - expect(wrapper.emitted().input).to.deep.equal([[10.0]]); - }); - - it('should not allow input to be above the maximum', async () => { - // Initialize component - const wrapper = mount(DecimalInput, { - propsData: { max: 10 }, - }); - - // Try to set value to 11, which is above the maximum - wrapper.find('input').element.value = '11.0'; - await wrapper.find('input').trigger('input'); - - // Assert value is 10 and input event was emitted - expect(wrapper.find('input').element.value).to.equal('10.0'); - expect(wrapper.emitted().input).to.deep.equal([[10.0]]); - - // Try to increment value - await wrapper.trigger('keydown', { key: 'ArrowUp' }); - - // Assert value is still 10 and no new events were emitted - expect(wrapper.find('input').element.value).to.equal('10.0'); - expect(wrapper.emitted().input).to.deep.equal([[10.0]]); - }); - - it('should format value according to padding and digits props', async () => { - // Initialize component - const wrapper = mount(DecimalInput, { - propsData: { padding: 2, digits: 3 }, - }); - - // Assert value is correctly formatted - expect(wrapper.find('input').element.value).to.equal('00.000'); - }); -}); diff --git a/tests/unit/IntInput.spec.js b/tests/unit/IntInput.spec.js @@ -1,238 +0,0 @@ -import { expect } from 'chai'; -import { mount } from '@vue/test-utils'; -import IntInput from '@/components/IntInput.vue'; - -describe('IntInput.vue', () => { - it('value should be 0 by default', () => { - // Initialize component - const wrapper = mount(IntInput); - - // Assert value is 0 - expect(wrapper.find('input').element.value).to.equal('0'); - }); - - it('should read value prop', () => { - // Initialize component - const wrapper = mount(IntInput, { - propsData: { value: 1 }, - }); - - // Assert value is 1 - expect(wrapper.find('input').element.value).to.equal('1'); - }); - - it('up arrow should increment value', async () => { - // Initialize component - const wrapper = mount(IntInput); - - // Press up arrow - await wrapper.trigger('keydown', { key: 'ArrowUp' }); - - // Assert value is 1 and input event was emitted - expect(wrapper.find('input').element.value).to.equal('1'); - expect(wrapper.emitted().input).to.deep.equal([[1]]); - }); - - it('down arrow should increment value', async () => { - // Initialize component - const wrapper = mount(IntInput); - - // Press down arrow - await wrapper.trigger('keydown', { key: 'ArrowDown' }); - - // Assert value is -1 and input event was emitted - expect(wrapper.find('input').element.value).to.equal('-1'); - expect(wrapper.emitted().input).to.deep.equal([[-1]]); - }); - - it('should fire input event when value changes', async () => { - // Initialize component - const wrapper = mount(IntInput); - - // Set value to 1 - wrapper.find('input').element.value = '1'; - await wrapper.find('input').trigger('input'); - - // Assert input event was emitted - expect(wrapper.emitted().input).to.deep.equal([[1]]); - }); - - it('should accept numerical values', async () => { - // Initialize component - const wrapper = mount(IntInput); - - // Try to set value to 1 - wrapper.find('input').element.value = '1'; - await wrapper.find('input').trigger('input'); - - // Assert value was accepted and input event was emitted - expect(wrapper.find('input').element.value).to.equal('1'); - expect(wrapper.emitted().input).to.deep.equal([[1]]); - }); - - it('should not accept decimal values', async () => { - // Initialize component - const wrapper = mount(IntInput, { - propsData: { value: 1 }, - }); - - // Try to set value to 1.5 - wrapper.find('input').element.value = '1.5'; - await wrapper.find('input').trigger('input'); - - // Assert value was not accepted and no events were emitted - expect(wrapper.find('input').element.value).to.equal('1'); - expect(wrapper.emitted().input).to.equal(undefined); - }); - - it('should not accept non numerical values', async () => { - // Initialize component - const wrapper = mount(IntInput, { - propsData: { value: 1 }, - }); - - // Try to set value to a - wrapper.find('input').element.value = 'a'; - await wrapper.find('input').trigger('input'); - - // Assert value was not accepted and no events were emitted - expect(wrapper.find('input').element.value).to.equal('1'); - expect(wrapper.emitted().input).to.equal(undefined); - }); - - it('should format input value on blur', async () => { - // Initialize component - const wrapper = mount(IntInput, { - propsData: { value: 1, padding: 3 }, - }); - - // Set value to '01' - wrapper.find('input').element.value = '01'; - await wrapper.find('input').trigger('input'); - - // Assert value was not updated and no events were emitted - expect(wrapper.find('input').element.value).to.equal('01'); - expect(wrapper.emitted().input).to.equal(undefined); - - // Trigger blur event - await wrapper.find('input').trigger('blur'); - - // Assert value was formatted but no events were emitted - expect(wrapper.find('input').element.value).to.equal('001'); - expect(wrapper.emitted().input).to.equal(undefined); - }); - - it('should allow input to be empty until blur', async () => { - // Initialize component - const wrapper = mount(IntInput, { - propsData: { value: 5 }, - }); - - // Set value to '' - wrapper.find('input').element.value = ''; - await wrapper.find('input').trigger('input'); - - // Assert value is '' and input event was emitted with default value - expect(wrapper.find('input').element.value).to.equal(''); - expect(wrapper.emitted().input).to.deep.equal([[0]]); - - // Trigger blur event - await wrapper.find('input').trigger('blur'); - - // Assert value is the default value but no new events were emitted - expect(wrapper.find('input').element.value).to.equal('0'); - expect(wrapper.emitted().input).to.deep.equal([[0]]); - }); - - it('should allow input to be "-" until blur', async () => { - // Initialize component - const wrapper = mount(IntInput, { - propsData: { value: 5 }, - }); - - // Set value to '-' - wrapper.find('input').element.value = '-'; - await wrapper.find('input').trigger('input'); - - // Assert value is '-' and input event was emitted with default value - expect(wrapper.find('input').element.value).to.equal('-'); - expect(wrapper.emitted().input).to.deep.equal([[0]]); - - // Trigger blur event - await wrapper.find('input').trigger('blur'); - - // Assert value is the default value but no new events were emitted - expect(wrapper.find('input').element.value).to.equal('0'); - expect(wrapper.emitted().input).to.deep.equal([[0]]); - }); - - it('default value should be the minimum if 0 is not valid', async () => { - // Initialize component - const wrapper = mount(IntInput, { - propsData: { value: 3, max: 4, min: 2 }, - }); - - // Set value to '' and trigger blur event so value must be updated - wrapper.find('input').element.value = ''; - await wrapper.find('input').trigger('input'); - await wrapper.find('input').trigger('blur'); - - // Assert value is 2 and input event was emitted - expect(wrapper.find('input').element.value).to.equal('2'); - expect(wrapper.emitted().input).to.deep.equal([[2]]); - }); - - it('should not allow input to be below the minimum', async () => { - // Initialize component - const wrapper = mount(IntInput, { - propsData: { min: 10, value: 20 }, - }); - - // Try to set value to 9, which is below the minimum - wrapper.find('input').element.value = '9'; - await wrapper.find('input').trigger('input'); - - // Assert value is 10 and input event was emitted - expect(wrapper.find('input').element.value).to.equal('10'); - expect(wrapper.emitted().input).to.deep.equal([[10]]); - - // Try to decrement value - await wrapper.trigger('keydown', { key: 'ArrowDown' }); - - // Assert value is still 10 and no new event were emitted - expect(wrapper.find('input').element.value).to.equal('10'); - expect(wrapper.emitted().input).to.deep.equal([[10]]); - }); - - it('should not allow input to be above the maximum', async () => { - // Initialize component - const wrapper = mount(IntInput, { - propsData: { max: 10 }, - }); - - // Try to set value to 11, which is above the maximum - wrapper.find('input').element.value = '11'; - await wrapper.find('input').trigger('input'); - - // Assert value is 10 and input event was emitted - expect(wrapper.find('input').element.value).to.equal('10'); - expect(wrapper.emitted().input).to.deep.equal([[10]]); - - // Try to increment value - await wrapper.trigger('keydown', { key: 'ArrowUp' }); - - // Assert value is still 10 and no new events were emitted - expect(wrapper.find('input').element.value).to.equal('10'); - expect(wrapper.emitted().input).to.deep.equal([[10]]); - }); - - it('should format value according to padding prop', async () => { - // Initialize component - const wrapper = mount(IntInput, { - propsData: { padding: 2 }, - }); - - // Assert value is correctly formatted - expect(wrapper.find('input').element.value).to.equal('00'); - }); -}); diff --git a/tests/unit/PaceCalculator.spec.js b/tests/unit/PaceCalculator.spec.js @@ -1,32 +0,0 @@ -/* eslint-disable no-underscore-dangle */ - -import { expect } from 'chai'; -import { shallowMount } from '@vue/test-utils'; -import PaceCalculator from '@/views/PaceCalculator.vue'; - -describe('PaceCalculator.vue', () => { - it('should correctly calculate paces', async () => { - // Initialize component - const wrapper = shallowMount(PaceCalculator); - - // Override input values - await wrapper.setData({ - inputDistance: 1, - inputUnit: 'kilometers', - inputTime: 100, - }); - - // Calculate paces - const result = wrapper.vm.calculatePace({ - distanceValue: 20, - distanceUnit: 'meters', - }); - - // Assert result is correct - expect(result).to.deep.equal({ - distanceValue: 20, - distanceUnit: 'meters', - time: 2, - }); - }); -}); diff --git a/tests/unit/RaceCalculator.spec.js b/tests/unit/RaceCalculator.spec.js @@ -1,35 +0,0 @@ -/* eslint-disable no-underscore-dangle */ - -import { expect } from 'chai'; -import { shallowMount } from '@vue/test-utils'; -import raceUtils from '@/utils/races'; -import RaceCalculator from '@/views/RaceCalculator.vue'; - -describe('RaceCalculator.vue', () => { - it('should correctly predict race times', async () => { - // Initialize component - const wrapper = shallowMount(RaceCalculator); - - // Override input values - await wrapper.setData({ - inputDistance: 5, - inputUnit: 'kilometers', - inputTime: 20 * 60, - }); - - // Predict race times - const result = wrapper.vm.predictTime({ - distanceValue: 10, - distanceUnit: 'kilometers', - }); - - // Assert result is correct - const riegel = raceUtils.RiegelFormula(5000, 20 * 60, 10000); - const cameron = raceUtils.CameronFormula(5000, 20 * 60, 10000); - expect(result).to.deep.equal({ - distanceValue: 10, - distanceUnit: 'kilometers', - time: (riegel + cameron) / 2, - }); - }); -}); diff --git a/tests/unit/TimeInput.spec.js b/tests/unit/TimeInput.spec.js @@ -1,59 +0,0 @@ -/* eslint-disable no-underscore-dangle */ - -import { expect } from 'chai'; -import { shallowMount } from '@vue/test-utils'; -import TimeInput from '@/components/TimeInput.vue'; - -describe('TimeInput.vue', () => { - it('value should be 0:00:0.00 by default', () => { - // Initialize component - const wrapper = shallowMount(TimeInput); - - // Assert value is 0:00:00.00 - expect(wrapper.vm._data.hours).to.equal(0); - expect(wrapper.vm._data.minutes).to.equal(0); - expect(wrapper.vm._data.seconds).to.equal(0.00); - }); - - it('should read value prop', () => { - // Initialize component - const wrapper = shallowMount(TimeInput, { - propsData: { value: 3600 + 60 + 1.5 }, - }); - - // Assert value is 1:01:01.50 - expect(wrapper.vm._data.hours).to.equal(1); - expect(wrapper.vm._data.minutes).to.equal(1); - expect(wrapper.vm._data.seconds).to.equal(1.50); - }); - - it('should update when value prop changes', async () => { - // Initialize component - const wrapper = shallowMount(TimeInput); - - // Set value prop to 60 - await wrapper.setProps({ value: 60 }); - - // Assert value is 0:01:00.00 - expect(wrapper.vm._data.hours).to.equal(0); - expect(wrapper.vm._data.minutes).to.equal(1); - expect(wrapper.vm._data.seconds).to.equal(0.00); - }); - - it('should emit input event when value changes', async () => { - // Initialize component - const wrapper = shallowMount(TimeInput); - - // Change value to 1:00:00.00 - await wrapper.setData({ hours: 1 }); - - // Assert input event was emitted - expect(wrapper.emitted().input).to.deep.equal([[3600.00]]); - - // Change value to 1:00:01.50 - await wrapper.setData({ seconds: 1.5 }); - - // Assert another input event was emitted - expect(wrapper.emitted().input).to.deep.equal([[3600.00], [3601.50]]); - }); -}); diff --git a/tests/unit/TimeTable.spec.js b/tests/unit/TimeTable.spec.js @@ -1,34 +0,0 @@ -/* eslint-disable no-underscore-dangle */ - -import { expect } from 'chai'; -import { shallowMount } from '@vue/test-utils'; -import TimeTable from '@/components/TimeTable.vue'; - -describe('TimeTable.vue', () => { - it('results should be correct and sorted by time', () => { - // Initialize component - const wrapper = shallowMount(TimeTable, { - propsData: { - calculateResult: (row) => ({ - distanceValue: row.distanceValue, - distanceUnit: row.distanceUnit, - time: row.distanceValue + 1, - }), - defaultTargets: [ - { distanceValue: 20, distanceUnit: 'meters' }, - { distanceValue: 100, distanceUnit: 'meters' }, - { distanceValue: 1, distanceUnit: 'kilometers' }, - { distanceValue: 10, distanceUnit: 'meters' }, - ], - }, - }); - - // Assert results are correct - expect(wrapper.vm._computedWatchers.results.value).to.deep.equal([ - { distanceValue: 1, distanceUnit: 'kilometers', time: 2 }, - { distanceValue: 10, distanceUnit: 'meters', time: 11 }, - { distanceValue: 20, distanceUnit: 'meters', time: 21 }, - { distanceValue: 100, distanceUnit: 'meters', time: 101 }, - ]); - }); -}); diff --git a/tests/unit/UnitCalculator.spec.js b/tests/unit/UnitCalculator.spec.js @@ -1,100 +0,0 @@ -/* eslint-disable no-underscore-dangle */ - -import { expect } from 'chai'; -import { shallowMount } from '@vue/test-utils'; -import UnitCalculator from '@/views/UnitCalculator.vue'; - -describe('UnitCalculator.vue', () => { - it('should correctly update controls when category changes', async () => { - // Initialize component - const wrapper = shallowMount(UnitCalculator); - - // Change category - await wrapper.setData({ category: 'time' }); - - // Assert controls are correct - expect(wrapper.vm._data.inputValue).to.equal(1); - expect(wrapper.vm._data.inputUnit).to.equal('seconds'); - expect(wrapper.vm._data.outputUnit).to.equal('hh:mm:ss'); - - // Change category - await wrapper.setData({ category: 'speed_and_pace' }); - - // Assert controls are correct - expect(wrapper.vm._data.inputValue).to.equal(1); - expect(wrapper.vm._data.inputUnit).to.equal('miles_per_hour'); - expect(wrapper.vm._data.outputUnit).to.equal('seconds_per_mile'); - - // Change category - await wrapper.setData({ category: 'distance' }); - - // Assert controls are correct - expect(wrapper.vm._data.inputValue).to.equal(1); - expect(wrapper.vm._data.inputUnit).to.equal('miles'); - expect(wrapper.vm._data.outputUnit).to.equal('meters'); - }); - - it('outputValue should be correct', async () => { - // Initialize component - const wrapper = shallowMount(UnitCalculator); - - // Change category and update input - await wrapper.setData({ category: 'distance' }); - await wrapper.setData({ - inputValue: 2, - inputUnit: 'kilometers', - outputUnit: 'meters', - }); - - // Assert controls are correct - expect(wrapper.vm._computedWatchers.outputValue.value).to.equal(2000); - - // Change category and update input - await wrapper.setData({ category: 'time' }); - await wrapper.setData({ - inputValue: 3, - inputUnit: 'minutes', - outputUnit: 'seconds', - }); - - // Assert controls are correct - expect(wrapper.vm._computedWatchers.outputValue.value).to.equal(3 * 60); - - // Change category and update input - await wrapper.setData({ category: 'speed_and_pace' }); - await wrapper.setData({ - inputValue: 2, - inputUnit: 'miles_per_hour', - outputUnit: 'seconds_per_mile', - }); - - // Assert controls are correct - expect(wrapper.vm._computedWatchers.outputValue.value).to.be.closeTo(30 * 60, 0.001); - }); - - it('should correctly convert to and from hh:mm:ss', async () => { - // Initialize component - const wrapper = shallowMount(UnitCalculator); - - // Change category and update input - await wrapper.setData({ category: 'time' }); - await wrapper.setData({ - inputValue: 60, - inputUnit: 'hh:mm:ss', - outputUnit: 'minutes', - }); - - // Assert controls are correct - expect(wrapper.vm._computedWatchers.outputValue.value).to.equal(1); - - // Update input - await wrapper.setData({ - inputValue: 1, - inputUnit: 'minutes', - outputUnit: 'hh:mm:ss', - }); - - // Assert controls are correct - expect(wrapper.vm._computedWatchers.outputValue.value).to.equal(60); - }); -}); diff --git a/tests/unit/components/DecimalInput.spec.js b/tests/unit/components/DecimalInput.spec.js @@ -0,0 +1,260 @@ +import { expect } from 'chai'; +import { mount } from '@vue/test-utils'; +import DecimalInput from '@/components/DecimalInput.vue'; + +describe('components/DecimalInput.vue', () => { + it('value should be 0.0 by default', () => { + // Initialize component + const wrapper = mount(DecimalInput); + + // Assert value is 0.0 + expect(wrapper.find('input').element.value).to.equal('0.0'); + }); + + it('should read value prop', () => { + // Initialize component + const wrapper = mount(DecimalInput, { + propsData: { value: 1 }, + }); + + // Assert value is 1.0 + expect(wrapper.find('input').element.value).to.equal('1.0'); + }); + + it('up arrow should increment value', async () => { + // Initialize component + const wrapper = mount(DecimalInput); + + // Press up arrow + await wrapper.trigger('keydown', { key: 'ArrowUp' }); + + // Assert value is 1.0 and input event was emitted + expect(wrapper.find('input').element.value).to.equal('1.0'); + expect(wrapper.emitted().input).to.deep.equal([[1.0]]); + }); + + it('down arrow should increment value', async () => { + // Initialize component + const wrapper = mount(DecimalInput); + + // Press down arrow + await wrapper.trigger('keydown', { key: 'ArrowDown' }); + + // Assert value is -1.0 and input event was emitted + expect(wrapper.find('input').element.value).to.equal('-1.0'); + expect(wrapper.emitted().input).to.deep.equal([[-1.0]]); + }); + + it('should fire input event when value changes', async () => { + // Initialize component + const wrapper = mount(DecimalInput); + + // Set value to 1 + wrapper.find('input').element.value = '1.0'; + await wrapper.find('input').trigger('input'); + + // Assert input event was emitted + expect(wrapper.emitted().input).to.deep.equal([[1.0]]); + }); + + it('should accept numerical values', async () => { + // Initialize component + const wrapper = mount(DecimalInput); + + // Try to set value to 1 + wrapper.find('input').element.value = '1'; + await wrapper.find('input').trigger('input'); + + // Assert value was accepted and input event was emitted + expect(wrapper.find('input').element.value).to.equal('1'); + expect(wrapper.emitted().input).to.deep.equal([[1.0]]); + }); + + it('should accept decimal values', async () => { + // Initialize component + const wrapper = mount(DecimalInput, { + propsData: { value: 1 }, + }); + + // Try to set value to 1.5 + wrapper.find('input').element.value = '1.5'; + await wrapper.find('input').trigger('input'); + + // Assert value was accepted and input event was emitted + expect(wrapper.find('input').element.value).to.equal('1.5'); + expect(wrapper.emitted().input).to.deep.equal([[1.5]]); + }); + + it('should not accept non numerical values', async () => { + // Initialize component + const wrapper = mount(DecimalInput, { + propsData: { value: 1 }, + }); + + // Try to set value to a + wrapper.find('input').element.value = 'a'; + await wrapper.find('input').trigger('input'); + + // Assert value was not accepted and no events were emitted + expect(wrapper.find('input').element.value).to.equal('1.0'); + expect(wrapper.emitted().input).to.equal(undefined); + }); + + it('should format input value on blur', async () => { + // Initialize component + const wrapper = mount(DecimalInput, { + propsData: { value: 1, padding: 3, digits: 2 }, + }); + + // Set value to '01' + wrapper.find('input').element.value = '01'; + await wrapper.find('input').trigger('input'); + + // Assert value was not updated and no events were emitted + expect(wrapper.find('input').element.value).to.equal('01'); + expect(wrapper.emitted().input).to.equal(undefined); + + // Trigger blur event + await wrapper.find('input').trigger('blur'); + + // Assert value was formatted but no events were emitted + expect(wrapper.find('input').element.value).to.equal('001.00'); + expect(wrapper.emitted().input).to.equal(undefined); + }); + + it('should allow input to be empty until blur', async () => { + // Initialize component + const wrapper = mount(DecimalInput, { + propsData: { value: 5 }, + }); + + // Set value to '' + wrapper.find('input').element.value = ''; + await wrapper.find('input').trigger('input'); + + // Assert value is '' and input event was emitted with default value + expect(wrapper.find('input').element.value).to.equal(''); + expect(wrapper.emitted().input).to.deep.equal([[0.0]]); + + // Trigger blur event + await wrapper.find('input').trigger('blur'); + + // Assert value is the default value but no new events were emitted + expect(wrapper.find('input').element.value).to.equal('0.0'); + expect(wrapper.emitted().input).to.deep.equal([[0.0]]); + }); + + it('should allow input to be "-" until blur', async () => { + // Initialize component + const wrapper = mount(DecimalInput, { + propsData: { value: 5 }, + }); + + // Set value to '-' + wrapper.find('input').element.value = '-'; + await wrapper.find('input').trigger('input'); + + // Assert value is '-' and input event was emitted with default value + expect(wrapper.find('input').element.value).to.equal('-'); + expect(wrapper.emitted().input).to.deep.equal([[0.0]]); + + // Trigger blur event + await wrapper.find('input').trigger('blur'); + + // Assert value is the default value but no new events were emitted + expect(wrapper.find('input').element.value).to.equal('0.0'); + expect(wrapper.emitted().input).to.deep.equal([[0.0]]); + }); + + it('should allow input to be "." until blur', async () => { + // Initialize component + const wrapper = mount(DecimalInput, { + propsData: { value: 5 }, + }); + + // Set value to '.' + wrapper.find('input').element.value = '.'; + await wrapper.find('input').trigger('input'); + + // Assert value is '.' and input event was emitted with default value + expect(wrapper.find('input').element.value).to.equal('.'); + expect(wrapper.emitted().input).to.deep.equal([[0.0]]); + + // Trigger blur event + await wrapper.find('input').trigger('blur'); + + // Assert value is the default value but no new events were emitted + expect(wrapper.find('input').element.value).to.equal('0.0'); + expect(wrapper.emitted().input).to.deep.equal([[0.0]]); + }); + + it('default value should be the minimum if 0.0 is not valid', async () => { + // Initialize component + const wrapper = mount(DecimalInput, { + propsData: { value: 3, max: 4, min: 2 }, + }); + + // Set value to '' and trigger blur event so value must be updated + wrapper.find('input').element.value = ''; + await wrapper.find('input').trigger('input'); + await wrapper.find('input').trigger('blur'); + + // Assert value is 2 and input event was emitted + expect(wrapper.find('input').element.value).to.equal('2.0'); + expect(wrapper.emitted().input).to.deep.equal([[2.0]]); + }); + + it('should not allow input to be below the minimum', async () => { + // Initialize component + const wrapper = mount(DecimalInput, { + propsData: { min: 10, value: 20 }, + }); + + // Try to set value to 9, which is below the minimum + wrapper.find('input').element.value = '9.0'; + await wrapper.find('input').trigger('input'); + + // Assert value is 10 and input event was emitted + expect(wrapper.find('input').element.value).to.equal('10.0'); + expect(wrapper.emitted().input).to.deep.equal([[10.0]]); + + // Try to decrement value + await wrapper.trigger('keydown', { key: 'ArrowDown' }); + + // Assert value is still 10 and no new event were emitted + expect(wrapper.find('input').element.value).to.equal('10.0'); + expect(wrapper.emitted().input).to.deep.equal([[10.0]]); + }); + + it('should not allow input to be above the maximum', async () => { + // Initialize component + const wrapper = mount(DecimalInput, { + propsData: { max: 10 }, + }); + + // Try to set value to 11, which is above the maximum + wrapper.find('input').element.value = '11.0'; + await wrapper.find('input').trigger('input'); + + // Assert value is 10 and input event was emitted + expect(wrapper.find('input').element.value).to.equal('10.0'); + expect(wrapper.emitted().input).to.deep.equal([[10.0]]); + + // Try to increment value + await wrapper.trigger('keydown', { key: 'ArrowUp' }); + + // Assert value is still 10 and no new events were emitted + expect(wrapper.find('input').element.value).to.equal('10.0'); + expect(wrapper.emitted().input).to.deep.equal([[10.0]]); + }); + + it('should format value according to padding and digits props', async () => { + // Initialize component + const wrapper = mount(DecimalInput, { + propsData: { padding: 2, digits: 3 }, + }); + + // Assert value is correctly formatted + expect(wrapper.find('input').element.value).to.equal('00.000'); + }); +}); diff --git a/tests/unit/components/IntInput.spec.js b/tests/unit/components/IntInput.spec.js @@ -0,0 +1,238 @@ +import { expect } from 'chai'; +import { mount } from '@vue/test-utils'; +import IntInput from '@/components/IntInput.vue'; + +describe('components/IntInput.vue', () => { + it('value should be 0 by default', () => { + // Initialize component + const wrapper = mount(IntInput); + + // Assert value is 0 + expect(wrapper.find('input').element.value).to.equal('0'); + }); + + it('should read value prop', () => { + // Initialize component + const wrapper = mount(IntInput, { + propsData: { value: 1 }, + }); + + // Assert value is 1 + expect(wrapper.find('input').element.value).to.equal('1'); + }); + + it('up arrow should increment value', async () => { + // Initialize component + const wrapper = mount(IntInput); + + // Press up arrow + await wrapper.trigger('keydown', { key: 'ArrowUp' }); + + // Assert value is 1 and input event was emitted + expect(wrapper.find('input').element.value).to.equal('1'); + expect(wrapper.emitted().input).to.deep.equal([[1]]); + }); + + it('down arrow should increment value', async () => { + // Initialize component + const wrapper = mount(IntInput); + + // Press down arrow + await wrapper.trigger('keydown', { key: 'ArrowDown' }); + + // Assert value is -1 and input event was emitted + expect(wrapper.find('input').element.value).to.equal('-1'); + expect(wrapper.emitted().input).to.deep.equal([[-1]]); + }); + + it('should fire input event when value changes', async () => { + // Initialize component + const wrapper = mount(IntInput); + + // Set value to 1 + wrapper.find('input').element.value = '1'; + await wrapper.find('input').trigger('input'); + + // Assert input event was emitted + expect(wrapper.emitted().input).to.deep.equal([[1]]); + }); + + it('should accept numerical values', async () => { + // Initialize component + const wrapper = mount(IntInput); + + // Try to set value to 1 + wrapper.find('input').element.value = '1'; + await wrapper.find('input').trigger('input'); + + // Assert value was accepted and input event was emitted + expect(wrapper.find('input').element.value).to.equal('1'); + expect(wrapper.emitted().input).to.deep.equal([[1]]); + }); + + it('should not accept decimal values', async () => { + // Initialize component + const wrapper = mount(IntInput, { + propsData: { value: 1 }, + }); + + // Try to set value to 1.5 + wrapper.find('input').element.value = '1.5'; + await wrapper.find('input').trigger('input'); + + // Assert value was not accepted and no events were emitted + expect(wrapper.find('input').element.value).to.equal('1'); + expect(wrapper.emitted().input).to.equal(undefined); + }); + + it('should not accept non numerical values', async () => { + // Initialize component + const wrapper = mount(IntInput, { + propsData: { value: 1 }, + }); + + // Try to set value to a + wrapper.find('input').element.value = 'a'; + await wrapper.find('input').trigger('input'); + + // Assert value was not accepted and no events were emitted + expect(wrapper.find('input').element.value).to.equal('1'); + expect(wrapper.emitted().input).to.equal(undefined); + }); + + it('should format input value on blur', async () => { + // Initialize component + const wrapper = mount(IntInput, { + propsData: { value: 1, padding: 3 }, + }); + + // Set value to '01' + wrapper.find('input').element.value = '01'; + await wrapper.find('input').trigger('input'); + + // Assert value was not updated and no events were emitted + expect(wrapper.find('input').element.value).to.equal('01'); + expect(wrapper.emitted().input).to.equal(undefined); + + // Trigger blur event + await wrapper.find('input').trigger('blur'); + + // Assert value was formatted but no events were emitted + expect(wrapper.find('input').element.value).to.equal('001'); + expect(wrapper.emitted().input).to.equal(undefined); + }); + + it('should allow input to be empty until blur', async () => { + // Initialize component + const wrapper = mount(IntInput, { + propsData: { value: 5 }, + }); + + // Set value to '' + wrapper.find('input').element.value = ''; + await wrapper.find('input').trigger('input'); + + // Assert value is '' and input event was emitted with default value + expect(wrapper.find('input').element.value).to.equal(''); + expect(wrapper.emitted().input).to.deep.equal([[0]]); + + // Trigger blur event + await wrapper.find('input').trigger('blur'); + + // Assert value is the default value but no new events were emitted + expect(wrapper.find('input').element.value).to.equal('0'); + expect(wrapper.emitted().input).to.deep.equal([[0]]); + }); + + it('should allow input to be "-" until blur', async () => { + // Initialize component + const wrapper = mount(IntInput, { + propsData: { value: 5 }, + }); + + // Set value to '-' + wrapper.find('input').element.value = '-'; + await wrapper.find('input').trigger('input'); + + // Assert value is '-' and input event was emitted with default value + expect(wrapper.find('input').element.value).to.equal('-'); + expect(wrapper.emitted().input).to.deep.equal([[0]]); + + // Trigger blur event + await wrapper.find('input').trigger('blur'); + + // Assert value is the default value but no new events were emitted + expect(wrapper.find('input').element.value).to.equal('0'); + expect(wrapper.emitted().input).to.deep.equal([[0]]); + }); + + it('default value should be the minimum if 0 is not valid', async () => { + // Initialize component + const wrapper = mount(IntInput, { + propsData: { value: 3, max: 4, min: 2 }, + }); + + // Set value to '' and trigger blur event so value must be updated + wrapper.find('input').element.value = ''; + await wrapper.find('input').trigger('input'); + await wrapper.find('input').trigger('blur'); + + // Assert value is 2 and input event was emitted + expect(wrapper.find('input').element.value).to.equal('2'); + expect(wrapper.emitted().input).to.deep.equal([[2]]); + }); + + it('should not allow input to be below the minimum', async () => { + // Initialize component + const wrapper = mount(IntInput, { + propsData: { min: 10, value: 20 }, + }); + + // Try to set value to 9, which is below the minimum + wrapper.find('input').element.value = '9'; + await wrapper.find('input').trigger('input'); + + // Assert value is 10 and input event was emitted + expect(wrapper.find('input').element.value).to.equal('10'); + expect(wrapper.emitted().input).to.deep.equal([[10]]); + + // Try to decrement value + await wrapper.trigger('keydown', { key: 'ArrowDown' }); + + // Assert value is still 10 and no new event were emitted + expect(wrapper.find('input').element.value).to.equal('10'); + expect(wrapper.emitted().input).to.deep.equal([[10]]); + }); + + it('should not allow input to be above the maximum', async () => { + // Initialize component + const wrapper = mount(IntInput, { + propsData: { max: 10 }, + }); + + // Try to set value to 11, which is above the maximum + wrapper.find('input').element.value = '11'; + await wrapper.find('input').trigger('input'); + + // Assert value is 10 and input event was emitted + expect(wrapper.find('input').element.value).to.equal('10'); + expect(wrapper.emitted().input).to.deep.equal([[10]]); + + // Try to increment value + await wrapper.trigger('keydown', { key: 'ArrowUp' }); + + // Assert value is still 10 and no new events were emitted + expect(wrapper.find('input').element.value).to.equal('10'); + expect(wrapper.emitted().input).to.deep.equal([[10]]); + }); + + it('should format value according to padding prop', async () => { + // Initialize component + const wrapper = mount(IntInput, { + propsData: { padding: 2 }, + }); + + // Assert value is correctly formatted + expect(wrapper.find('input').element.value).to.equal('00'); + }); +}); diff --git a/tests/unit/components/TimeInput.spec.js b/tests/unit/components/TimeInput.spec.js @@ -0,0 +1,59 @@ +/* eslint-disable no-underscore-dangle */ + +import { expect } from 'chai'; +import { shallowMount } from '@vue/test-utils'; +import TimeInput from '@/components/TimeInput.vue'; + +describe('components/TimeInput.vue', () => { + it('value should be 0:00:0.00 by default', () => { + // Initialize component + const wrapper = shallowMount(TimeInput); + + // Assert value is 0:00:00.00 + expect(wrapper.vm._data.hours).to.equal(0); + expect(wrapper.vm._data.minutes).to.equal(0); + expect(wrapper.vm._data.seconds).to.equal(0.00); + }); + + it('should read value prop', () => { + // Initialize component + const wrapper = shallowMount(TimeInput, { + propsData: { value: 3600 + 60 + 1.5 }, + }); + + // Assert value is 1:01:01.50 + expect(wrapper.vm._data.hours).to.equal(1); + expect(wrapper.vm._data.minutes).to.equal(1); + expect(wrapper.vm._data.seconds).to.equal(1.50); + }); + + it('should update when value prop changes', async () => { + // Initialize component + const wrapper = shallowMount(TimeInput); + + // Set value prop to 60 + await wrapper.setProps({ value: 60 }); + + // Assert value is 0:01:00.00 + expect(wrapper.vm._data.hours).to.equal(0); + expect(wrapper.vm._data.minutes).to.equal(1); + expect(wrapper.vm._data.seconds).to.equal(0.00); + }); + + it('should emit input event when value changes', async () => { + // Initialize component + const wrapper = shallowMount(TimeInput); + + // Change value to 1:00:00.00 + await wrapper.setData({ hours: 1 }); + + // Assert input event was emitted + expect(wrapper.emitted().input).to.deep.equal([[3600.00]]); + + // Change value to 1:00:01.50 + await wrapper.setData({ seconds: 1.5 }); + + // Assert another input event was emitted + expect(wrapper.emitted().input).to.deep.equal([[3600.00], [3601.50]]); + }); +}); diff --git a/tests/unit/components/TimeTable.spec.js b/tests/unit/components/TimeTable.spec.js @@ -0,0 +1,34 @@ +/* eslint-disable no-underscore-dangle */ + +import { expect } from 'chai'; +import { shallowMount } from '@vue/test-utils'; +import TimeTable from '@/components/TimeTable.vue'; + +describe('components/TimeTable.vue', () => { + it('results should be correct and sorted by time', () => { + // Initialize component + const wrapper = shallowMount(TimeTable, { + propsData: { + calculateResult: (row) => ({ + distanceValue: row.distanceValue, + distanceUnit: row.distanceUnit, + time: row.distanceValue + 1, + }), + defaultTargets: [ + { distanceValue: 20, distanceUnit: 'meters' }, + { distanceValue: 100, distanceUnit: 'meters' }, + { distanceValue: 1, distanceUnit: 'kilometers' }, + { distanceValue: 10, distanceUnit: 'meters' }, + ], + }, + }); + + // Assert results are correct + expect(wrapper.vm._computedWatchers.results.value).to.deep.equal([ + { distanceValue: 1, distanceUnit: 'kilometers', time: 2 }, + { distanceValue: 10, distanceUnit: 'meters', time: 11 }, + { distanceValue: 20, distanceUnit: 'meters', time: 21 }, + { distanceValue: 100, distanceUnit: 'meters', time: 101 }, + ]); + }); +}); diff --git a/tests/unit/pace.spec.js b/tests/unit/pace.spec.js @@ -1,22 +0,0 @@ -import { expect } from 'chai'; -import pace from '@/utils/paces'; - -describe('utils/pace.js', () => { - describe('getPace method', () => { - it('2 meters in 6 seconds should equal 3 seconds per meter', () => { - expect(pace.getPace(2, 6)).to.equal(3); - }); - }); - - describe('getTime method', () => { - it('2 meters at 3 seconds per meter should equal 6 seconds', () => { - expect(pace.getTime(3, 2)).to.equal(6); - }); - }); - - describe('getDistance method', () => { - it('6 seconds at 3 seconds per meter should equal 2 meters', () => { - expect(pace.getDistance(3, 6)).to.equal(2); - }); - }); -}); diff --git a/tests/unit/utils/paces.spec.js b/tests/unit/utils/paces.spec.js @@ -0,0 +1,22 @@ +import { expect } from 'chai'; +import paces from '@/utils/paces'; + +describe('utils/paces.js', () => { + describe('getPace method', () => { + it('2 meters in 6 seconds should equal 3 seconds per meter', () => { + expect(paces.getPace(2, 6)).to.equal(3); + }); + }); + + describe('getTime method', () => { + it('2 meters at 3 seconds per meter should equal 6 seconds', () => { + expect(paces.getTime(3, 2)).to.equal(6); + }); + }); + + describe('getDistance method', () => { + it('6 seconds at 3 seconds per meter should equal 2 meters', () => { + expect(paces.getDistance(3, 6)).to.equal(2); + }); + }); +}); diff --git a/tests/unit/races.spec.js b/tests/unit/utils/races.spec.js diff --git a/tests/unit/units.spec.js b/tests/unit/utils/units.spec.js diff --git a/tests/unit/views/PaceCalculator.spec.js b/tests/unit/views/PaceCalculator.spec.js @@ -0,0 +1,32 @@ +/* eslint-disable no-underscore-dangle */ + +import { expect } from 'chai'; +import { shallowMount } from '@vue/test-utils'; +import PaceCalculator from '@/views/PaceCalculator.vue'; + +describe('views/PaceCalculator.vue', () => { + it('should correctly calculate paces', async () => { + // Initialize component + const wrapper = shallowMount(PaceCalculator); + + // Override input values + await wrapper.setData({ + inputDistance: 1, + inputUnit: 'kilometers', + inputTime: 100, + }); + + // Calculate paces + const result = wrapper.vm.calculatePace({ + distanceValue: 20, + distanceUnit: 'meters', + }); + + // Assert result is correct + expect(result).to.deep.equal({ + distanceValue: 20, + distanceUnit: 'meters', + time: 2, + }); + }); +}); diff --git a/tests/unit/views/RaceCalculator.spec.js b/tests/unit/views/RaceCalculator.spec.js @@ -0,0 +1,35 @@ +/* eslint-disable no-underscore-dangle */ + +import { expect } from 'chai'; +import { shallowMount } from '@vue/test-utils'; +import raceUtils from '@/utils/races'; +import RaceCalculator from '@/views/RaceCalculator.vue'; + +describe('views/RaceCalculator.vue', () => { + it('should correctly predict race times', async () => { + // Initialize component + const wrapper = shallowMount(RaceCalculator); + + // Override input values + await wrapper.setData({ + inputDistance: 5, + inputUnit: 'kilometers', + inputTime: 20 * 60, + }); + + // Predict race times + const result = wrapper.vm.predictTime({ + distanceValue: 10, + distanceUnit: 'kilometers', + }); + + // Assert result is correct + const riegel = raceUtils.RiegelFormula(5000, 20 * 60, 10000); + const cameron = raceUtils.CameronFormula(5000, 20 * 60, 10000); + expect(result).to.deep.equal({ + distanceValue: 10, + distanceUnit: 'kilometers', + time: (riegel + cameron) / 2, + }); + }); +}); diff --git a/tests/unit/views/UnitCalculator.spec.js b/tests/unit/views/UnitCalculator.spec.js @@ -0,0 +1,100 @@ +/* eslint-disable no-underscore-dangle */ + +import { expect } from 'chai'; +import { shallowMount } from '@vue/test-utils'; +import UnitCalculator from '@/views/UnitCalculator.vue'; + +describe('views/UnitCalculator.vue', () => { + it('should correctly update controls when category changes', async () => { + // Initialize component + const wrapper = shallowMount(UnitCalculator); + + // Change category + await wrapper.setData({ category: 'time' }); + + // Assert controls are correct + expect(wrapper.vm._data.inputValue).to.equal(1); + expect(wrapper.vm._data.inputUnit).to.equal('seconds'); + expect(wrapper.vm._data.outputUnit).to.equal('hh:mm:ss'); + + // Change category + await wrapper.setData({ category: 'speed_and_pace' }); + + // Assert controls are correct + expect(wrapper.vm._data.inputValue).to.equal(1); + expect(wrapper.vm._data.inputUnit).to.equal('miles_per_hour'); + expect(wrapper.vm._data.outputUnit).to.equal('seconds_per_mile'); + + // Change category + await wrapper.setData({ category: 'distance' }); + + // Assert controls are correct + expect(wrapper.vm._data.inputValue).to.equal(1); + expect(wrapper.vm._data.inputUnit).to.equal('miles'); + expect(wrapper.vm._data.outputUnit).to.equal('meters'); + }); + + it('outputValue should be correct', async () => { + // Initialize component + const wrapper = shallowMount(UnitCalculator); + + // Change category and update input + await wrapper.setData({ category: 'distance' }); + await wrapper.setData({ + inputValue: 2, + inputUnit: 'kilometers', + outputUnit: 'meters', + }); + + // Assert controls are correct + expect(wrapper.vm._computedWatchers.outputValue.value).to.equal(2000); + + // Change category and update input + await wrapper.setData({ category: 'time' }); + await wrapper.setData({ + inputValue: 3, + inputUnit: 'minutes', + outputUnit: 'seconds', + }); + + // Assert controls are correct + expect(wrapper.vm._computedWatchers.outputValue.value).to.equal(3 * 60); + + // Change category and update input + await wrapper.setData({ category: 'speed_and_pace' }); + await wrapper.setData({ + inputValue: 2, + inputUnit: 'miles_per_hour', + outputUnit: 'seconds_per_mile', + }); + + // Assert controls are correct + expect(wrapper.vm._computedWatchers.outputValue.value).to.be.closeTo(30 * 60, 0.001); + }); + + it('should correctly convert to and from hh:mm:ss', async () => { + // Initialize component + const wrapper = shallowMount(UnitCalculator); + + // Change category and update input + await wrapper.setData({ category: 'time' }); + await wrapper.setData({ + inputValue: 60, + inputUnit: 'hh:mm:ss', + outputUnit: 'minutes', + }); + + // Assert controls are correct + expect(wrapper.vm._computedWatchers.outputValue.value).to.equal(1); + + // Update input + await wrapper.setData({ + inputValue: 1, + inputUnit: 'minutes', + outputUnit: 'hh:mm:ss', + }); + + // Assert controls are correct + expect(wrapper.vm._computedWatchers.outputValue.value).to.equal(60); + }); +});