Skip to content

Commit

Permalink
Merge pull request #28 from educorvi/develop
Browse files Browse the repository at this point in the history
Update
  • Loading branch information
neferin12 authored Jun 21, 2024
2 parents 9ea2660 + 9a80335 commit 15ac48b
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 23 deletions.
10 changes: 10 additions & 0 deletions common/changes/@educorvi/rita/develop_2024-04-12-14-16.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@educorvi/rita",
"comment": "support length on anything that has a length, not just arrays",
"type": "patch"
}
],
"packageName": "@educorvi/rita"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@educorvi/rita",
"comment": "add ´allowDifferentTypes´ option to comparisons",
"type": "minor"
}
],
"packageName": "@educorvi/rita"
}
8 changes: 5 additions & 3 deletions rita-core/src/Assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ export function assertDuration(value: any): asserts value is Duration {
}
}

export function assertArray(value: any): asserts value is Array<any> {
if (!Array.isArray(value)) {
throw new TypeError();
export function hasLength(
value: any
): asserts value is Record<any, any> & { length: number } {
if (!value.hasOwnProperty('length')) {
throw new TypeError('Value does not have a length property');
}
}
9 changes: 3 additions & 6 deletions rita-core/src/Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,7 @@ export default class Parser {
throw new UsageError('Invalid Date: ' + parameter);
}
} else {
if (typeof parameter === 'number') {
params.push(parameter);
} else {
params.push(parameter);
}
params.push(parameter);
}
}
return params;
Expand All @@ -207,7 +203,8 @@ export default class Parser {
jsonRuleset['dates']
),
jsonRuleset['operation'],
jsonRuleset['dates']
jsonRuleset['dates'],
jsonRuleset['allowDifferentTypes']
);
}

Expand Down
18 changes: 14 additions & 4 deletions rita-core/src/logicElements/Comparison.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,29 @@ export class Comparison extends Formula {
*/
public dates: boolean;

/**
* Indicates if different types are allowed inside a comparison
*/
public allowDifferentTypes: boolean;

/**
* @constructor
* @param formulaArguments The arguments
* @param operation Type of the comparison
* @param dates Indicates if dates are compared
* @param allowDifferentTypes Indicates if different types are allowed inside a comparison
*/
constructor(
formulaArguments: Array<Atom | number | Date | string | Calculation>,
operation: comparisons,
dates: boolean = false
dates: boolean = false,
allowDifferentTypes: boolean = false
) {
super();
this.arguments = formulaArguments;
this.operation = operation;
this.dates = dates;
this.allowDifferentTypes = allowDifferentTypes;
}

toJsonReady(): Record<string, any> {
Expand All @@ -74,9 +82,11 @@ export class Comparison extends Formula {
if (p1 === undefined || p2 === undefined) return false;

if (typeof p1 !== typeof p2) {
throw new UsageError(
'Elements in comparison must have the same type'
);
if (!this.allowDifferentTypes) {
throw new UsageError(
'Elements in comparison must have the same type'
);
}
}

if (p1 instanceof Date) p1 = p1.getTime();
Expand Down
4 changes: 2 additions & 2 deletions rita-core/src/logicElements/Macro.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Formula, FormulaResults } from './Formula';
import { Atom } from './Atom';
import { assertArray } from '../Assertions';
import { hasLength } from '../Assertions';

export class Macro extends Formula {
/** Indicates the type of this atom **/
Expand All @@ -21,7 +21,7 @@ export class Macro extends Formula {
return new Date();
case 'length':
const ar = await this.array?.evaluate(data);
assertArray(ar);
hasLength(ar);
return ar.length;
}
}
Expand Down
5 changes: 5 additions & 0 deletions rita-core/src/schema/comparison.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
"type": "boolean",
"default": false
},
"allowDifferentTypes": {
"description": "Indicates if different types are allowed inside a comparison. This follows the JavaScript rules for comparison (´===´ is used for ´equals´).",
"type": "boolean",
"default": false
},
"arguments": {
"type": "array",
"minItems": 2,
Expand Down
24 changes: 16 additions & 8 deletions rita-core/test/implementationTests/comparison.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import {
Comparison,
comparisons,
evaluateAll,
Parser,
UsageError,
} from '../../src';
import { evaluateAll, Parser, UsageError } from '../../src';
// @ts-ignore
import { exampleData, ruleTemplate } from '../assets/exampleData';
// @ts-ignore
Expand Down Expand Up @@ -116,11 +110,25 @@ it('run math example', async () => {
});

it('error on different type', async () => {
const c = new Comparison([2, 'Test'], comparisons.equal);
const c = p.parseComparison({
type: 'comparison',
operation: 'smaller',
arguments: [2, '2'],
});
try {
await c.evaluate({});
expect(true).toBe(false);
} catch (e) {
expect(e).toBeInstanceOf(UsageError);
}
});

it('compare number with string', async () => {
const c = p.parseComparison({
type: 'comparison',
operation: 'equal',
allowDifferentTypes: true,
arguments: [2, '2'],
});
expect(await c.evaluate({})).toBe(false);
});
21 changes: 21 additions & 0 deletions rita-core/test/implementationTests/macro.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,27 @@ it("Expect 'length' to be correct", () => {
).resolves.toEqual(l);
});

it("Test 'length' for string", () => {
const m = p.parseMacro({
type: 'macro',
macro: {
type: 'length',
array: {
type: 'atom',
path: 'data',
},
},
});
const l = Math.round(Math.random() * 10 + 1);
const string = new Array(l + 1).join('e');

expect(
m.evaluate({
data: string,
})
).resolves.toEqual(l);
});

it('Example Ruleset is true', async () => {
const rs = p.parseRuleSet(macroRuleset);
expect((await evaluateAll(rs, exampleData)).result).toBe(true);
Expand Down

0 comments on commit 15ac48b

Please sign in to comment.