100 lines
3.9 KiB
TypeScript
100 lines
3.9 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import { TemplateRenderer } from '../../../src/card-controller/templates';
|
|
import { renderTimePeriodToSeconds } from '../../../src/condition-trigger/common/time-period';
|
|
import { createHASS, createStateEntity } from '../../test-utils';
|
|
|
|
// @vitest-environment jsdom
|
|
describe('renderTimePeriodToSeconds', () => {
|
|
const createRenderer = (): TemplateRenderer => new TemplateRenderer();
|
|
|
|
const createStateWithDelay = (delay: string) => ({
|
|
hass: createHASS({ 'input_number.delay': createStateEntity({ state: delay }) }),
|
|
});
|
|
|
|
// Without `hass` the value is parsed as-is, matching HA's `cv.time_period`.
|
|
it('should accept a number of seconds', () => {
|
|
expect(renderTimePeriodToSeconds(createRenderer(), 5)).toBe(5);
|
|
expect(renderTimePeriodToSeconds(createRenderer(), 0)).toBe(0);
|
|
});
|
|
|
|
it('should reject a negative period', () => {
|
|
expect(renderTimePeriodToSeconds(createRenderer(), -1)).toBeNull();
|
|
expect(renderTimePeriodToSeconds(createRenderer(), { seconds: -5 })).toBeNull();
|
|
});
|
|
|
|
it('should parse a bare numeric string as seconds', () => {
|
|
expect(renderTimePeriodToSeconds(createRenderer(), '5')).toBe(5);
|
|
});
|
|
|
|
it('should read HH:MM and HH:MM:SS (two parts are hours:minutes, as in HA)', () => {
|
|
expect(renderTimePeriodToSeconds(createRenderer(), '01:30')).toBe(5400);
|
|
expect(renderTimePeriodToSeconds(createRenderer(), '00:05')).toBe(300);
|
|
expect(renderTimePeriodToSeconds(createRenderer(), '00:00:05')).toBe(5);
|
|
expect(renderTimePeriodToSeconds(createRenderer(), '1:00:00')).toBe(3600);
|
|
});
|
|
|
|
it('should reject unparseable, empty-part, or over-long strings', () => {
|
|
expect(renderTimePeriodToSeconds(createRenderer(), 'not-a-duration')).toBeNull();
|
|
expect(renderTimePeriodToSeconds(createRenderer(), '1:ab')).toBeNull();
|
|
expect(renderTimePeriodToSeconds(createRenderer(), '1:2:3:4')).toBeNull();
|
|
expect(renderTimePeriodToSeconds(createRenderer(), '5:')).toBeNull();
|
|
expect(renderTimePeriodToSeconds(createRenderer(), '')).toBeNull();
|
|
});
|
|
|
|
it('should accept a {days, hours, minutes, seconds, milliseconds} dict', () => {
|
|
expect(renderTimePeriodToSeconds(createRenderer(), { seconds: 5 })).toBe(5);
|
|
expect(renderTimePeriodToSeconds(createRenderer(), { hours: 1, minutes: 30 })).toBe(
|
|
5400,
|
|
);
|
|
expect(renderTimePeriodToSeconds(createRenderer(), { days: 1 })).toBe(86400);
|
|
expect(renderTimePeriodToSeconds(createRenderer(), { milliseconds: 500 })).toBe(0.5);
|
|
expect(renderTimePeriodToSeconds(createRenderer(), {})).toBe(0);
|
|
});
|
|
|
|
it('should coerce a numeric-string dict field', () => {
|
|
expect(renderTimePeriodToSeconds(createRenderer(), { minutes: '2' })).toBe(120);
|
|
expect(renderTimePeriodToSeconds(createRenderer(), { minutes: 'nope' })).toBeNull();
|
|
});
|
|
|
|
// With `hass`, templates are rendered against the current state before parsing.
|
|
it('should render and parse a template string', () => {
|
|
expect(
|
|
renderTimePeriodToSeconds(
|
|
createRenderer(),
|
|
"{{ states('input_number.delay') }}",
|
|
createStateWithDelay('5'),
|
|
),
|
|
).toBe(5);
|
|
});
|
|
|
|
it('should render and parse template fields in a dict', () => {
|
|
expect(
|
|
renderTimePeriodToSeconds(
|
|
createRenderer(),
|
|
{ minutes: "{{ states('input_number.delay') }}" },
|
|
createStateWithDelay('2'),
|
|
),
|
|
).toBe(120);
|
|
});
|
|
|
|
it('should return null when a template renders to a non-duration value', () => {
|
|
// A string that is not a number.
|
|
expect(
|
|
renderTimePeriodToSeconds(
|
|
createRenderer(),
|
|
"{{ states('input_number.delay') }}",
|
|
createStateWithDelay('nope'),
|
|
),
|
|
).toBeNull();
|
|
// A value that is neither a number, string nor dict (here, a boolean).
|
|
expect(
|
|
renderTimePeriodToSeconds(
|
|
createRenderer(),
|
|
"{{ is_state('input_number.delay', 'x') }}",
|
|
createStateWithDelay('5'),
|
|
),
|
|
).toBeNull();
|
|
});
|
|
});
|