|
|
|
@ -4,10 +4,10 @@ import { |
|
|
|
ExpressionProps, |
|
|
|
LogicGroupProps, |
|
|
|
} from '../../../../../src/data_sources/model/conditional_variables/DataCondition'; |
|
|
|
import { GenericOperation } from '../../../../../src/data_sources/model/conditional_variables/operators/GenericOperator'; |
|
|
|
import { LogicalOperation } from '../../../../../src/data_sources/model/conditional_variables/operators/LogicalOperator'; |
|
|
|
import { AnyTypeOperation } from '../../../../../src/data_sources/model/conditional_variables/operators/AnyTypeOperator'; |
|
|
|
import { BooleanOperation } from '../../../../../src/data_sources/model/conditional_variables/operators/BooleanOperator'; |
|
|
|
import { NumberOperation } from '../../../../../src/data_sources/model/conditional_variables/operators/NumberOperator'; |
|
|
|
import { StringOperation } from '../../../../../src/data_sources/model/conditional_variables/operators/StringOperations'; |
|
|
|
import { StringOperation } from '../../../../../src/data_sources/model/conditional_variables/operators/StringOperator'; |
|
|
|
import { DataVariableType } from '../../../../../src/data_sources/model/DataVariable'; |
|
|
|
import Editor from '../../../../../src/editor/model/Editor'; |
|
|
|
import EditorModel from '../../../../../src/editor/model/Editor'; |
|
|
|
@ -36,14 +36,14 @@ describe('DataCondition', () => { |
|
|
|
describe('Basic Functionality Tests', () => { |
|
|
|
test('should evaluate a simple boolean condition', () => { |
|
|
|
const condition = true; |
|
|
|
const dataCondition = new DataCondition(condition, 'Yes', 'No', { em }); |
|
|
|
const dataCondition = new DataCondition({ condition, ifTrue: 'Yes', ifFalse: 'No' }, { em }); |
|
|
|
|
|
|
|
expect(dataCondition.getDataValue()).toBe('Yes'); |
|
|
|
}); |
|
|
|
|
|
|
|
test('should return ifFalse when condition evaluates to false', () => { |
|
|
|
const condition = false; |
|
|
|
const dataCondition = new DataCondition(condition, 'Yes', 'No', { em }); |
|
|
|
const dataCondition = new DataCondition({ condition, ifTrue: 'Yes', ifFalse: 'No' }, { em }); |
|
|
|
|
|
|
|
expect(dataCondition.getDataValue()).toBe('No'); |
|
|
|
}); |
|
|
|
@ -51,8 +51,8 @@ describe('DataCondition', () => { |
|
|
|
|
|
|
|
describe('Operator Tests', () => { |
|
|
|
test('should evaluate using GenericOperation operators', () => { |
|
|
|
const condition: ExpressionProps = { left: 5, operator: GenericOperation.equals, right: 5 }; |
|
|
|
const dataCondition = new DataCondition(condition, 'Equal', 'Not Equal', { em }); |
|
|
|
const condition: ExpressionProps = { left: 5, operator: AnyTypeOperation.equals, right: 5 }; |
|
|
|
const dataCondition = new DataCondition({ condition, ifTrue: 'Equal', ifFalse: 'Not Equal' }, { em }); |
|
|
|
|
|
|
|
expect(dataCondition.getDataValue()).toBe('Equal'); |
|
|
|
}); |
|
|
|
@ -60,63 +60,61 @@ describe('DataCondition', () => { |
|
|
|
test('equals (false)', () => { |
|
|
|
const condition: ExpressionProps = { |
|
|
|
left: 'hello', |
|
|
|
operator: GenericOperation.equals, |
|
|
|
operator: AnyTypeOperation.equals, |
|
|
|
right: 'world', |
|
|
|
}; |
|
|
|
const dataCondition = new DataCondition(condition, 'true', 'false', { em }); |
|
|
|
expect(dataCondition.evaluate()).toBe(false); |
|
|
|
const dataCondition = new DataCondition({ condition, ifTrue: 'true', ifFalse: 'false' }, { em }); |
|
|
|
expect(dataCondition.isTrue()).toBe(false); |
|
|
|
}); |
|
|
|
|
|
|
|
test('should evaluate using StringOperation operators', () => { |
|
|
|
const condition: ExpressionProps = { left: 'apple', operator: StringOperation.contains, right: 'app' }; |
|
|
|
const dataCondition = new DataCondition(condition, 'Contains', "Doesn't contain", { em }); |
|
|
|
const dataCondition = new DataCondition({ condition, ifTrue: 'Contains', ifFalse: "Doesn't contain" }, { em }); |
|
|
|
|
|
|
|
expect(dataCondition.getDataValue()).toBe('Contains'); |
|
|
|
}); |
|
|
|
|
|
|
|
test('should evaluate using NumberOperation operators', () => { |
|
|
|
const condition: ExpressionProps = { left: 10, operator: NumberOperation.lessThan, right: 15 }; |
|
|
|
const dataCondition = new DataCondition(condition, 'Valid', 'Invalid', { em }); |
|
|
|
const dataCondition = new DataCondition({ condition, ifTrue: 'Valid', ifFalse: 'Invalid' }, { em }); |
|
|
|
|
|
|
|
expect(dataCondition.getDataValue()).toBe('Valid'); |
|
|
|
}); |
|
|
|
|
|
|
|
test('should evaluate using LogicalOperation operators', () => { |
|
|
|
const logicGroup: LogicGroupProps = { |
|
|
|
logicalOperator: LogicalOperation.and, |
|
|
|
logicalOperator: BooleanOperation.and, |
|
|
|
statements: [ |
|
|
|
{ left: true, operator: GenericOperation.equals, right: true }, |
|
|
|
{ left: true, operator: AnyTypeOperation.equals, right: true }, |
|
|
|
{ left: 5, operator: NumberOperation.greaterThan, right: 3 }, |
|
|
|
], |
|
|
|
}; |
|
|
|
|
|
|
|
const dataCondition = new DataCondition(logicGroup, 'Pass', 'Fail', { em }); |
|
|
|
const dataCondition = new DataCondition({ condition: logicGroup, ifTrue: 'Pass', ifFalse: 'Fail' }, { em }); |
|
|
|
expect(dataCondition.getDataValue()).toBe('Pass'); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
describe('Edge Case Tests', () => { |
|
|
|
test('should throw error for invalid condition type', () => { |
|
|
|
const invalidCondition: any = { randomField: 'randomValue' }; |
|
|
|
expect(() => new DataCondition(invalidCondition, 'Yes', 'No', { em })).toThrow('Invalid condition type.'); |
|
|
|
}); |
|
|
|
|
|
|
|
test('should evaluate complex nested conditions', () => { |
|
|
|
const nestedLogicGroup: LogicGroupProps = { |
|
|
|
logicalOperator: LogicalOperation.or, |
|
|
|
logicalOperator: BooleanOperation.or, |
|
|
|
statements: [ |
|
|
|
{ |
|
|
|
logicalOperator: LogicalOperation.and, |
|
|
|
logicalOperator: BooleanOperation.and, |
|
|
|
statements: [ |
|
|
|
{ left: 1, operator: NumberOperation.lessThan, right: 5 }, |
|
|
|
{ left: 'test', operator: GenericOperation.equals, right: 'test' }, |
|
|
|
{ left: 'test', operator: AnyTypeOperation.equals, right: 'test' }, |
|
|
|
], |
|
|
|
}, |
|
|
|
{ left: 10, operator: NumberOperation.greaterThan, right: 100 }, |
|
|
|
], |
|
|
|
}; |
|
|
|
|
|
|
|
const dataCondition = new DataCondition(nestedLogicGroup, 'Nested Pass', 'Nested Fail', { em }); |
|
|
|
const dataCondition = new DataCondition( |
|
|
|
{ condition: nestedLogicGroup, ifTrue: 'Nested Pass', ifFalse: 'Nested Fail' }, |
|
|
|
{ em }, |
|
|
|
); |
|
|
|
expect(dataCondition.getDataValue()).toBe('Nested Pass'); |
|
|
|
}); |
|
|
|
}); |
|
|
|
@ -124,74 +122,89 @@ describe('DataCondition', () => { |
|
|
|
describe('LogicalGroup Tests', () => { |
|
|
|
test('should correctly handle AND logical operator', () => { |
|
|
|
const logicGroup: LogicGroupProps = { |
|
|
|
logicalOperator: LogicalOperation.and, |
|
|
|
logicalOperator: BooleanOperation.and, |
|
|
|
statements: [ |
|
|
|
{ left: true, operator: GenericOperation.equals, right: true }, |
|
|
|
{ left: true, operator: AnyTypeOperation.equals, right: true }, |
|
|
|
{ left: 5, operator: NumberOperation.greaterThan, right: 3 }, |
|
|
|
], |
|
|
|
}; |
|
|
|
|
|
|
|
const dataCondition = new DataCondition(logicGroup, 'All true', 'One or more false', { em }); |
|
|
|
const dataCondition = new DataCondition( |
|
|
|
{ condition: logicGroup, ifTrue: 'All true', ifFalse: 'One or more false' }, |
|
|
|
{ em }, |
|
|
|
); |
|
|
|
expect(dataCondition.getDataValue()).toBe('All true'); |
|
|
|
}); |
|
|
|
|
|
|
|
test('should correctly handle OR logical operator', () => { |
|
|
|
const logicGroup: LogicGroupProps = { |
|
|
|
logicalOperator: LogicalOperation.or, |
|
|
|
logicalOperator: BooleanOperation.or, |
|
|
|
statements: [ |
|
|
|
{ left: true, operator: GenericOperation.equals, right: false }, |
|
|
|
{ left: true, operator: AnyTypeOperation.equals, right: false }, |
|
|
|
{ left: 5, operator: NumberOperation.greaterThan, right: 3 }, |
|
|
|
], |
|
|
|
}; |
|
|
|
|
|
|
|
const dataCondition = new DataCondition(logicGroup, 'At least one true', 'All false', { em }); |
|
|
|
const dataCondition = new DataCondition( |
|
|
|
{ condition: logicGroup, ifTrue: 'At least one true', ifFalse: 'All false' }, |
|
|
|
{ em }, |
|
|
|
); |
|
|
|
expect(dataCondition.getDataValue()).toBe('At least one true'); |
|
|
|
}); |
|
|
|
|
|
|
|
test('should correctly handle XOR logical operator', () => { |
|
|
|
const logicGroup: LogicGroupProps = { |
|
|
|
logicalOperator: LogicalOperation.xor, |
|
|
|
logicalOperator: BooleanOperation.xor, |
|
|
|
statements: [ |
|
|
|
{ left: true, operator: GenericOperation.equals, right: true }, |
|
|
|
{ left: true, operator: AnyTypeOperation.equals, right: true }, |
|
|
|
{ left: 5, operator: NumberOperation.lessThan, right: 3 }, |
|
|
|
{ left: false, operator: GenericOperation.equals, right: true }, |
|
|
|
{ left: false, operator: AnyTypeOperation.equals, right: true }, |
|
|
|
], |
|
|
|
}; |
|
|
|
|
|
|
|
const dataCondition = new DataCondition(logicGroup, 'Exactly one true', 'Multiple true or all false', { em }); |
|
|
|
const dataCondition = new DataCondition( |
|
|
|
{ condition: logicGroup, ifTrue: 'Exactly one true', ifFalse: 'Multiple true or all false' }, |
|
|
|
{ em }, |
|
|
|
); |
|
|
|
expect(dataCondition.getDataValue()).toBe('Exactly one true'); |
|
|
|
}); |
|
|
|
|
|
|
|
test('should handle nested logical groups', () => { |
|
|
|
const logicGroup: LogicGroupProps = { |
|
|
|
logicalOperator: LogicalOperation.and, |
|
|
|
logicalOperator: BooleanOperation.and, |
|
|
|
statements: [ |
|
|
|
{ left: true, operator: GenericOperation.equals, right: true }, |
|
|
|
{ left: true, operator: AnyTypeOperation.equals, right: true }, |
|
|
|
{ |
|
|
|
logicalOperator: LogicalOperation.or, |
|
|
|
logicalOperator: BooleanOperation.or, |
|
|
|
statements: [ |
|
|
|
{ left: 5, operator: NumberOperation.greaterThan, right: 3 }, |
|
|
|
{ left: false, operator: GenericOperation.equals, right: true }, |
|
|
|
{ left: false, operator: AnyTypeOperation.equals, right: true }, |
|
|
|
], |
|
|
|
}, |
|
|
|
], |
|
|
|
}; |
|
|
|
|
|
|
|
const dataCondition = new DataCondition(logicGroup, 'All true', 'One or more false', { em }); |
|
|
|
const dataCondition = new DataCondition( |
|
|
|
{ condition: logicGroup, ifTrue: 'All true', ifFalse: 'One or more false' }, |
|
|
|
{ em }, |
|
|
|
); |
|
|
|
expect(dataCondition.getDataValue()).toBe('All true'); |
|
|
|
}); |
|
|
|
|
|
|
|
test('should handle groups with false conditions', () => { |
|
|
|
const logicGroup: LogicGroupProps = { |
|
|
|
logicalOperator: LogicalOperation.and, |
|
|
|
logicalOperator: BooleanOperation.and, |
|
|
|
statements: [ |
|
|
|
{ left: true, operator: GenericOperation.equals, right: true }, |
|
|
|
{ left: false, operator: GenericOperation.equals, right: true }, |
|
|
|
{ left: true, operator: AnyTypeOperation.equals, right: true }, |
|
|
|
{ left: false, operator: AnyTypeOperation.equals, right: true }, |
|
|
|
{ left: 5, operator: NumberOperation.greaterThan, right: 3 }, |
|
|
|
], |
|
|
|
}; |
|
|
|
|
|
|
|
const dataCondition = new DataCondition(logicGroup, 'All true', 'One or more false', { em }); |
|
|
|
const dataCondition = new DataCondition( |
|
|
|
{ condition: logicGroup, ifTrue: 'All true', ifFalse: 'One or more false' }, |
|
|
|
{ em }, |
|
|
|
); |
|
|
|
expect(dataCondition.getDataValue()).toBe('One or more false'); |
|
|
|
}); |
|
|
|
}); |
|
|
|
@ -200,22 +213,22 @@ describe('DataCondition', () => { |
|
|
|
test('should return "Yes" when dataVariable matches expected value', () => { |
|
|
|
const condition: ExpressionProps = { |
|
|
|
left: { type: DataVariableType, path: 'USER_STATUS_SOURCE.USER_1.status' }, |
|
|
|
operator: GenericOperation.equals, |
|
|
|
operator: AnyTypeOperation.equals, |
|
|
|
right: 'active', |
|
|
|
}; |
|
|
|
|
|
|
|
const dataCondition = new DataCondition(condition, 'Yes', 'No', { em }); |
|
|
|
const dataCondition = new DataCondition({ condition, ifTrue: 'Yes', ifFalse: 'No' }, { em }); |
|
|
|
expect(dataCondition.getDataValue()).toBe('Yes'); |
|
|
|
}); |
|
|
|
|
|
|
|
test('should return "No" when dataVariable does not match expected value', () => { |
|
|
|
const condition: ExpressionProps = { |
|
|
|
left: { type: DataVariableType, path: 'USER_STATUS_SOURCE.USER_1.status' }, |
|
|
|
operator: GenericOperation.equals, |
|
|
|
operator: AnyTypeOperation.equals, |
|
|
|
right: 'inactive', |
|
|
|
}; |
|
|
|
|
|
|
|
const dataCondition = new DataCondition(condition, 'Yes', 'No', { em }); |
|
|
|
const dataCondition = new DataCondition({ condition, ifTrue: 'Yes', ifFalse: 'No' }, { em }); |
|
|
|
expect(dataCondition.getDataValue()).toBe('No'); |
|
|
|
}); |
|
|
|
|
|
|
|
@ -223,11 +236,11 @@ describe('DataCondition', () => { |
|
|
|
test.skip('should handle missing data variable gracefully', () => { |
|
|
|
const condition: ExpressionProps = { |
|
|
|
left: { type: DataVariableType, path: 'USER_STATUS_SOURCE.not_a_user.status' }, |
|
|
|
operator: GenericOperation.isDefined, |
|
|
|
operator: AnyTypeOperation.isDefined, |
|
|
|
right: undefined, |
|
|
|
}; |
|
|
|
|
|
|
|
const dataCondition = new DataCondition(condition, 'Found', 'Not Found', { em }); |
|
|
|
const dataCondition = new DataCondition({ condition, ifTrue: 'Found', ifFalse: 'Not Found' }, { em }); |
|
|
|
expect(dataCondition.getDataValue()).toBe('Not Found'); |
|
|
|
}); |
|
|
|
|
|
|
|
@ -237,7 +250,7 @@ describe('DataCondition', () => { |
|
|
|
operator: NumberOperation.greaterThan, |
|
|
|
right: 24, |
|
|
|
}; |
|
|
|
const dataCondition = new DataCondition(condition, 'Valid', 'Invalid', { em }); |
|
|
|
const dataCondition = new DataCondition({ condition, ifTrue: 'Valid', ifFalse: 'Invalid' }, { em }); |
|
|
|
expect(dataCondition.getDataValue()).toBe('Valid'); |
|
|
|
}); |
|
|
|
|
|
|
|
@ -249,11 +262,11 @@ describe('DataCondition', () => { |
|
|
|
dsm.add(dataSource2); |
|
|
|
|
|
|
|
const logicGroup: LogicGroupProps = { |
|
|
|
logicalOperator: LogicalOperation.and, |
|
|
|
logicalOperator: BooleanOperation.and, |
|
|
|
statements: [ |
|
|
|
{ |
|
|
|
left: { type: DataVariableType, path: 'USER_STATUS_SOURCE.USER_1.status' }, |
|
|
|
operator: GenericOperation.equals, |
|
|
|
operator: AnyTypeOperation.equals, |
|
|
|
right: 'active', |
|
|
|
}, |
|
|
|
{ |
|
|
|
@ -264,20 +277,23 @@ describe('DataCondition', () => { |
|
|
|
], |
|
|
|
}; |
|
|
|
|
|
|
|
const dataCondition = new DataCondition(logicGroup, 'All conditions met', 'Some conditions failed', { em }); |
|
|
|
const dataCondition = new DataCondition( |
|
|
|
{ condition: logicGroup, ifTrue: 'All conditions met', ifFalse: 'Some conditions failed' }, |
|
|
|
{ em }, |
|
|
|
); |
|
|
|
expect(dataCondition.getDataValue()).toBe('All conditions met'); |
|
|
|
}); |
|
|
|
|
|
|
|
test('should handle nested logical conditions with data variables', () => { |
|
|
|
const logicGroup: LogicGroupProps = { |
|
|
|
logicalOperator: LogicalOperation.or, |
|
|
|
logicalOperator: BooleanOperation.or, |
|
|
|
statements: [ |
|
|
|
{ |
|
|
|
logicalOperator: LogicalOperation.and, |
|
|
|
logicalOperator: BooleanOperation.and, |
|
|
|
statements: [ |
|
|
|
{ |
|
|
|
left: { type: DataVariableType, path: 'USER_STATUS_SOURCE.USER_2.status' }, |
|
|
|
operator: GenericOperation.equals, |
|
|
|
operator: AnyTypeOperation.equals, |
|
|
|
right: 'inactive', |
|
|
|
}, |
|
|
|
{ |
|
|
|
@ -289,21 +305,26 @@ describe('DataCondition', () => { |
|
|
|
}, |
|
|
|
{ |
|
|
|
left: { type: DataVariableType, path: 'USER_STATUS_SOURCE.USER_1.status' }, |
|
|
|
operator: GenericOperation.equals, |
|
|
|
operator: AnyTypeOperation.equals, |
|
|
|
right: 'inactive', |
|
|
|
}, |
|
|
|
], |
|
|
|
}; |
|
|
|
|
|
|
|
const dataCondition = new DataCondition(logicGroup, 'Condition met', 'Condition failed', { em }); |
|
|
|
const dataCondition = new DataCondition( |
|
|
|
{ condition: logicGroup, ifTrue: 'Condition met', ifFalse: 'Condition failed' }, |
|
|
|
{ em }, |
|
|
|
); |
|
|
|
expect(dataCondition.getDataValue()).toBe('Condition met'); |
|
|
|
}); |
|
|
|
|
|
|
|
test('should handle data variables as an ifTrue return value', () => { |
|
|
|
const dataCondition = new DataCondition( |
|
|
|
true, |
|
|
|
{ type: DataVariableType, path: 'USER_STATUS_SOURCE.USER_1.status' }, |
|
|
|
'No', |
|
|
|
{ |
|
|
|
condition: true, |
|
|
|
ifTrue: { type: DataVariableType, path: 'USER_STATUS_SOURCE.USER_1.status' }, |
|
|
|
ifFalse: 'No', |
|
|
|
}, |
|
|
|
{ em }, |
|
|
|
); |
|
|
|
expect(dataCondition.getDataValue()).toBe('active'); |
|
|
|
@ -311,11 +332,14 @@ describe('DataCondition', () => { |
|
|
|
|
|
|
|
test('should handle data variables as an ifFalse return value', () => { |
|
|
|
const dataCondition = new DataCondition( |
|
|
|
false, |
|
|
|
'Yes', |
|
|
|
{ type: DataVariableType, path: 'USER_STATUS_SOURCE.USER_1.status' }, |
|
|
|
{ |
|
|
|
condition: false, |
|
|
|
ifTrue: 'Yes', |
|
|
|
ifFalse: { type: DataVariableType, path: 'USER_STATUS_SOURCE.USER_1.status' }, |
|
|
|
}, |
|
|
|
{ em }, |
|
|
|
); |
|
|
|
|
|
|
|
expect(dataCondition.getDataValue()).toBe('active'); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|