Skip to content

Commit

Permalink
consolidate time validator functions to validator file
Browse files Browse the repository at this point in the history
make time validator function more generic
add tests for validator function
  • Loading branch information
duranb committed Jan 16, 2024
1 parent af835ff commit 0b34362
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 19 deletions.
30 changes: 12 additions & 18 deletions src/components/simulation/SimulationPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
} from '../../stores/simulation';
import { viewTogglePanel } from '../../stores/views';
import type { User } from '../../types/app';
import type { FieldStore, ValidationResult } from '../../types/form';
import type { FieldStore } from '../../types/form';
import type { FormParameter, ParametersMap } from '../../types/parameter';
import type {
Simulation,
Expand All @@ -35,7 +35,7 @@
import { getSimulationQueuePosition } from '../../utilities/simulation';
import { Status } from '../../utilities/status';
import { getDoyTime } from '../../utilities/time';
import { required, timestamp } from '../../utilities/validators';
import { required, timestamp, validateEndTime, validateStartTime } from '../../utilities/validators';
import Collapse from '../Collapse.svelte';
import DatePickerField from '../form/DatePickerField.svelte';
import GridMenu from '../menus/GridMenu.svelte';
Expand Down Expand Up @@ -65,20 +65,6 @@
let modelParametersMap: ParametersMap = {};
let filteredSimulationDatasets: SimulationDataset[] = [];
$: validateStartTime = function (startTime: string): Promise<ValidationResult> {
if (startTime >= endTimeDoy) {
return Promise.resolve('Simulation start must be before end');
}
return Promise.resolve(null);
};
$: validateEndTime = function (endTime: string): Promise<ValidationResult> {
if (endTime <= startTimeDoy) {
return Promise.resolve('Simulation end must be after start');
}
return Promise.resolve(null);
};
$: if (user !== null && $plan !== null) {
hasRunPermission = featurePermissions.simulation.canRun(user, $plan, $plan.model) && !$planReadOnly;
hasUpdatePermission = featurePermissions.simulation.canUpdate(user, $plan) && !$planReadOnly;
Expand All @@ -89,14 +75,22 @@
? getDoyTime(new Date($simulation.simulation_start_time))
: $plan.start_time_doy;
}
$: startTimeDoyField = field<string>(startTimeDoy, [required, timestamp, validateStartTime]);
$: startTimeDoyField = field<string>(startTimeDoy, [
required,
timestamp,
(startTime: string) => validateStartTime(startTime, endTimeDoy, 'Simulation'),
]);
$: if ($plan) {
endTimeDoy =
$simulation && $simulation.simulation_end_time
? getDoyTime(new Date($simulation.simulation_end_time))
: $plan.end_time_doy;
}
$: endTimeDoyField = field<string>(endTimeDoy, [required, timestamp, validateEndTime]);
$: endTimeDoyField = field<string>(endTimeDoy, [
required,
timestamp,
(endTime: string) => validateEndTime(startTimeDoy, endTime, 'Simulation'),
]);
$: numOfUserChanges = formParameters.reduce((previousHasChanges: number, formParameter) => {
return /user/.test(formParameter.valueSource) ? previousHasChanges + 1 : previousHasChanges;
}, 0);
Expand Down
52 changes: 51 additions & 1 deletion src/utilities/validators.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, test } from 'vitest';
import { min, required, timestamp } from './validators';
import { min, required, timestamp, validateEndTime, validateStartTime } from './validators';

describe('min', () => {
const value = 5;
Expand Down Expand Up @@ -70,3 +70,53 @@ describe('timestamp', () => {
expect(invalidMsg).toEqual(null);
});
});

describe('validateStartTime', () => {
const startTimeError = 'Simulation start must be before end';

test.each([
{ endTime: '2020-400T00:00:00.000', startTime: '2020-400T00:00:00.000' },
{ endTime: '2020-399T00:00:00.000', startTime: '2020-400T00:00:00.000' },
{ endTime: '2020-400T00:00:00.000', startTime: '2020-410T00:00:00.000' },
])(
'Should return an error message for out of order start/end ($startTime/$endTime) times',
async ({ endTime, startTime }) => {
expect(await validateStartTime(startTime, endTime, 'Simulation')).toEqual(startTimeError);
},
);

test.each([
{ endTime: '2020-401T00:00:00.000', startTime: '2020-400T00:00:00.000' },
{ endTime: '2020-411T00:00:00.000', startTime: '2020-410T00:00:00.000' },
])(
'Should not return an error for out of order start/end ($startTime/$endTime) times',
async ({ endTime, startTime }) => {
expect(await validateStartTime(startTime, endTime, 'Simulation')).toEqual(null);
},
);
});

describe('validateEndTime', () => {
const endTimeError = 'Simulation end must be after start';

test.each([
{ endTime: '2020-400T00:00:00.000', startTime: '2020-400T00:00:00.000' },
{ endTime: '2020-399T00:00:00.000', startTime: '2020-400T00:00:00.000' },
{ endTime: '2020-400T00:00:00.000', startTime: '2020-410T00:00:00.000' },
])(
'Should return an error message for out of order start/end ($startTime/$endTime) times',
async ({ endTime, startTime }) => {
expect(await validateEndTime(startTime, endTime, 'Simulation')).toEqual(endTimeError);
},
);

test.each([
{ endTime: '2020-401T00:00:00.000', startTime: '2020-400T00:00:00.000' },
{ endTime: '2020-411T00:00:00.000', startTime: '2020-410T00:00:00.000' },
])(
'Should not return an error for out of order start/end ($startTime/$endTime) times',
async ({ endTime, startTime }) => {
expect(await validateEndTime(startTime, endTime, 'Simulation')).toEqual(null);
},
);
});
18 changes: 18 additions & 0 deletions src/utilities/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,24 @@ export function hex(value: string): Promise<ValidationResult> {
});
}

export function validateStartTime(startTime: string, endTime: string, type: string): Promise<ValidationResult> {
return new Promise(resolve => {
if (startTime >= endTime) {
return resolve(`${type} start must be before end`);
}
return resolve(null);
});
}

export function validateEndTime(startTime: string, endTime: string, type: string): Promise<ValidationResult> {
return new Promise(resolve => {
if (endTime <= startTime) {
return resolve(`${type} end must be after start`);
}
return resolve(null);
});
}

export async function validateField<T>(field: Field<T>): Promise<string[]> {
const { validators, value } = field;
const errors: string[] = [];
Expand Down

0 comments on commit 0b34362

Please sign in to comment.