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:
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);
+ });
+});