mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-22 07:29:08 +00:00
refactor: handle boolean comparisons
This commit is contained in:
committed by
Carlos Valente
parent
8ba65fa2bd
commit
eb0e5e6420
@@ -112,6 +112,26 @@ describe('testConditions()', () => {
|
|||||||
const result = testConditions([{ field: 'eventNow.title', operator: 'equals', value: '' }], 'all', mockStore);
|
const result = testConditions([{ field: 'eventNow.title', operator: 'equals', value: '' }], 'all', mockStore);
|
||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle trueness boolean comparisons', () => {
|
||||||
|
const mockStore = makeRuntimeStateData({ eventNow: { countToEnd: true } as PlayableEvent });
|
||||||
|
expect(
|
||||||
|
testConditions([{ field: 'eventNow.countToEnd', operator: 'equals', value: 'true' }], 'all', mockStore),
|
||||||
|
).toBe(true);
|
||||||
|
expect(
|
||||||
|
testConditions([{ field: 'eventNow.countToEnd', operator: 'equals', value: 'false' }], 'all', mockStore),
|
||||||
|
).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle falseness boolean comparisons', () => {
|
||||||
|
const mockStore = makeRuntimeStateData({ eventNow: { countToEnd: false } as PlayableEvent });
|
||||||
|
expect(
|
||||||
|
testConditions([{ field: 'eventNow.countToEnd', operator: 'equals', value: 'false' }], 'all', mockStore),
|
||||||
|
).toBe(true);
|
||||||
|
expect(
|
||||||
|
testConditions([{ field: 'eventNow.countToEnd', operator: 'equals', value: 'true' }], 'all', mockStore),
|
||||||
|
).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('not_equals operator', () => {
|
describe('not_equals operator', () => {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { isOntimeCloud } from '../../externals.js';
|
|||||||
import { emitOSC } from './clients/osc.client.js';
|
import { emitOSC } from './clients/osc.client.js';
|
||||||
import { emitHTTP } from './clients/http.client.js';
|
import { emitHTTP } from './clients/http.client.js';
|
||||||
import { getAutomationsEnabled, getAutomations, getAutomationTriggers } from './automation.dao.js';
|
import { getAutomationsEnabled, getAutomations, getAutomationTriggers } from './automation.dao.js';
|
||||||
import { isGreaterThan, isLessThan } from './automation.utils.js';
|
import { isBooleanEquals, isGreaterThan, isLessThan } from './automation.utils.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exposes a method for triggering actions based on a TimerLifeCycle event
|
* Exposes a method for triggering actions based on a TimerLifeCycle event
|
||||||
@@ -74,12 +74,18 @@ export function testConditions(
|
|||||||
|
|
||||||
function evaluateCondition(filter: AutomationFilter): boolean {
|
function evaluateCondition(filter: AutomationFilter): boolean {
|
||||||
const { field, operator, value } = filter;
|
const { field, operator, value } = filter;
|
||||||
|
const lowerCasedValue = value.toLowerCase();
|
||||||
const fieldValue = getPropertyFromPath(field, state);
|
const fieldValue = getPropertyFromPath(field, state);
|
||||||
|
|
||||||
// if value is empty string, the user could be meaning to check if the value does not exist
|
// if value is empty string, the user could be meaning to check if the value does not exist
|
||||||
// we use loose equality to be able to check for converted values (eg '10' == 10)
|
// we use loose equality to be able to check for converted values (eg '10' == 10)
|
||||||
switch (operator) {
|
switch (operator) {
|
||||||
case 'equals':
|
case 'equals':
|
||||||
|
// handle the case where we are comparing boolean strings
|
||||||
|
|
||||||
|
if (typeof fieldValue === 'boolean') {
|
||||||
|
return isBooleanEquals(fieldValue, lowerCasedValue);
|
||||||
|
}
|
||||||
// overload the edge case where we use empty string to check if a value does not exist
|
// overload the edge case where we use empty string to check if a value does not exist
|
||||||
if (value === '' && fieldValue === undefined) {
|
if (value === '' && fieldValue === undefined) {
|
||||||
return true;
|
return true;
|
||||||
@@ -88,14 +94,8 @@ export function testConditions(
|
|||||||
case 'not_equals':
|
case 'not_equals':
|
||||||
return fieldValue != value;
|
return fieldValue != value;
|
||||||
case 'greater_than':
|
case 'greater_than':
|
||||||
if (typeof fieldValue !== 'number') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return isGreaterThan(fieldValue, value);
|
return isGreaterThan(fieldValue, value);
|
||||||
case 'less_than':
|
case 'less_than':
|
||||||
if (typeof fieldValue !== 'number') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return isLessThan(fieldValue, value);
|
return isLessThan(fieldValue, value);
|
||||||
case 'contains':
|
case 'contains':
|
||||||
return typeof fieldValue === 'string' && fieldValue.includes(value);
|
return typeof fieldValue === 'string' && fieldValue.includes(value);
|
||||||
|
|||||||
@@ -79,7 +79,8 @@ export function parseTemplateNested(template: string, state: object, humanReadab
|
|||||||
value = undefined;
|
value = undefined;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
value = getPropertyFromPath(variableName, state);
|
// we cast to string since this will be used in a string context
|
||||||
|
value = getPropertyFromPath(variableName, state) as string;
|
||||||
}
|
}
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
parsedTemplate = parsedTemplate.replace(match[0], value);
|
parsedTemplate = parsedTemplate.replace(match[0], value);
|
||||||
@@ -140,17 +141,18 @@ const quickAliases: AliasesDefinition = {
|
|||||||
* @example isGreaterThan('5', '10') // false
|
* @example isGreaterThan('5', '10') // false
|
||||||
* @example isGreaterThan('Ontime', 'Cool') // false
|
* @example isGreaterThan('Ontime', 'Cool') // false
|
||||||
*/
|
*/
|
||||||
export function isGreaterThan(a: string, b: string): boolean {
|
export function isGreaterThan(a: unknown, b: string): boolean {
|
||||||
const aValue = Number(a);
|
// If either value is not a number, there is no logical comparison to be made
|
||||||
const bValue = Number(b);
|
if (typeof a !== 'number') {
|
||||||
|
return false;
|
||||||
// we check if the values encore numbers and compare them
|
|
||||||
if (!isNaN(aValue) && !isNaN(bValue)) {
|
|
||||||
return aValue > bValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If either value is not a number, there is no logical comparison to be made
|
const bValue = Number(b);
|
||||||
return false;
|
if (isNaN(bValue)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a > bValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -159,15 +161,33 @@ export function isGreaterThan(a: string, b: string): boolean {
|
|||||||
* @example isLessThan('5', '10') // true
|
* @example isLessThan('5', '10') // true
|
||||||
* @example isLessThan('Ontime', 'Cool') // false
|
* @example isLessThan('Ontime', 'Cool') // false
|
||||||
*/
|
*/
|
||||||
export function isLessThan(a: string, b: string): boolean {
|
export function isLessThan(a: unknown, b: string): boolean {
|
||||||
const aValue = Number(a);
|
// If either value is not a number, there is no logical comparison to be made
|
||||||
const bValue = Number(b);
|
if (typeof a !== 'number') {
|
||||||
|
return false;
|
||||||
// we check if the values encore numbers and compare them
|
|
||||||
if (!isNaN(aValue) && !isNaN(bValue)) {
|
|
||||||
return aValue < bValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If either value is not a number, there is no logical comparison to be made
|
const bValue = Number(b);
|
||||||
|
if (isNaN(bValue)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a < bValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility encapsulates logic for comparing two strings which may encode booleans
|
||||||
|
* @example isBooleanEquals(true, 'true') // true
|
||||||
|
* @example isBooleanEquals(true, 'false') // false
|
||||||
|
* @example isBooleanEquals(true, 'something') // false
|
||||||
|
*/
|
||||||
|
export function isBooleanEquals(a: boolean, b: string): boolean {
|
||||||
|
if (b === 'true') {
|
||||||
|
return a === true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b === 'false') {
|
||||||
|
return a === false;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user