Skip to content

Commit

Permalink
test: test coverage improved
Browse files Browse the repository at this point in the history
  • Loading branch information
palmcivet committed Apr 4, 2024
1 parent b7b7764 commit 9e5c3fe
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 24 deletions.
8 changes: 6 additions & 2 deletions src/utils/evaluate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ function compareArray<T>(leftValue: T, operation: ArrayOperation, rightValue: Ar
case OperationEnum.NOT_IN:
return !rightValue.includes(leftValue);
default:
throw new Error(`[spectra] Operation ${operation} is not supported.`);
throw new Error(
`[spectra] Operation is not supported. ${leftValue} ${operation} ${rightValue}`
);
}
}

Expand Down Expand Up @@ -60,7 +62,9 @@ export function compareValue<T = number>(
if (!Array.isArray(leftValue) && Array.isArray(rightValue)) {
return compareArray(leftValue, operation as ArrayOperation, rightValue);
} else {
throw new Error(`[spectra] Operation ${operation} is not supported.`);
throw new Error(
`[spectra] Operation is not supported. ${leftValue} ${operation} ${rightValue}`
);
}
}
}
36 changes: 22 additions & 14 deletions src/utils/expression.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
import {
ExpressionDefinition,
BinaryExpressionDefinition,
AndExpressionDefinition,
OrExpressionDefinition,
NotExpressionDefinition,
RefValue,
Operation,
} from '@getspectra/spectra-typings';
import {
BinaryExpression,
AndExpression,
OrExpression,
NotExpression,
} from '@/expressions';
import { ExpressionInterface } from '@/types';
import { ExpressionInterface, OperationEnum } from '@/types';

export function isRefValue(key: any): key is RefValue {
return key !== null && typeof key === 'object' && 'ref' in key;
}

export function isValidOperation(operation: any): operation is Operation {
return [
OperationEnum.EQ,
OperationEnum.NEQ,
OperationEnum.NEQ2,
OperationEnum.GT,
OperationEnum.GTE,
OperationEnum.LT,
OperationEnum.LTE,
OperationEnum.IN,
OperationEnum.NIN,
OperationEnum.NOT_IN,
].includes(operation);
}

export function isValidExpressionInterface(
expression: any
): expression is ExpressionInterface {
Expand Down Expand Up @@ -46,7 +61,7 @@ export function isValidBinaryExpressionDefinition(
return false;
}

if (typeof operation !== 'string') {
if (!isValidOperation(operation)) {
return false;
}

Expand Down Expand Up @@ -78,6 +93,10 @@ export function isValidAndExpressionDefinition(
return false;
}

if (expression.and.length <= 1) {
return false;
}

return true;
}

Expand All @@ -101,17 +120,6 @@ export function isValidNotExpressionDefinition(
return typeof expression === 'object' && expression.not !== undefined;
}

export function isValidExpressionDefine(
expression: any
): expression is ExpressionDefinition {
return (
isValidBinaryExpressionDefinition(expression) ||
isValidAndExpressionDefinition(expression) ||
isValidOrExpressionDefinition(expression) ||
isValidNotExpressionDefinition(expression)
);
}

/**
* @description Normalize an expression to an expression instance.
*/
Expand Down
11 changes: 8 additions & 3 deletions test/policies.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, test } from '@jest/globals';
import { Policy, BinaryExpression } from '@/index';
import { Policy, BinaryExpression, Spectra } from '@/index';

describe('Policies', () => {
test('getter', () => {
Expand All @@ -25,7 +25,12 @@ describe('Policies', () => {
effect: 'DENY',
});

expect(allowPolicy.getEffect()).toBe('ALLOW');
expect(denyPolicy.getEffect()).toBe('DENY');
const result = Spectra.validate(
[allowPolicy, denyPolicy],
{ load: () => ({ 'user.id': 1 }) },
'EDIT_FILE'
);

expect(result).toBe(true);
});
});
96 changes: 91 additions & 5 deletions test/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ import {
DataType,
Policy,
and,
or,
bisectArray,
getValueFromKey,
isRefValue,
isValidAndExpressionDefinition,
isValidBinaryExpressionDefinition,
isDataLoaderClass,
isDataLoaderFunction,
compareValue,
} from '@/index';

describe('Policy Utils', () => {
Expand All @@ -15,9 +22,18 @@ describe('Policy Utils', () => {
expect(strings).toEqual(['3', '4', '6']);
expect(numbers).toEqual([1, 2, 5, 7]);
});
});

test('isArgumentRef', () => {});
describe('DataLoader Utils', () => {
test('isDataLoaderClass', () => {
expect(isDataLoaderClass({ load: () => {} })).toBeTruthy();
expect(isDataLoaderClass({ load: {} })).toBeFalsy();
expect(isDataLoaderFunction(() => {})).toBeTruthy();
expect(isDataLoaderFunction({})).toBeFalsy();
});
});

describe('Evaluate Utils', () => {
test('getValueFromKey', () => {
const data: DataType = {
'user.id': 1,
Expand All @@ -30,14 +46,73 @@ describe('Policy Utils', () => {
data['user.create_at']
);
});
});

describe('Compare Utils', () => {
test('compareValue', () => {});
test('compareArray', () => {
expect(compareValue<any>(2, 'in', [1, 2, 3])).toBeTruthy();
expect(compareValue<any>(4, 'nin', [1, 4])).toBeFalsy();
expect(compareValue<any>(4, 'not_in', [1, 2, 3, 4])).toBeFalsy();
expect(compareValue<any>('2', 'in', [1, 2, 3])).toBeFalsy();

let invalidCompareArray = false;
try {
compareValue<any>(2, 'in', 2);
} catch (error) {
invalidCompareArray = true;
}
expect(invalidCompareArray).toBeTruthy();

let invalidOperation = false;
try {
compareValue<any>(2, 'n_in' as any, [2, 3]);
} catch (error) {
invalidOperation = true;
}
expect(invalidOperation).toBeTruthy();
});

test('compareValue', () => {
expect(compareValue(2, '=', 2)).toBeTruthy();
expect(compareValue(2, '!=', 2)).toBeFalsy();
expect(compareValue(2, '!=', 3)).toBeTruthy();
expect(compareValue(2, '<>', 2)).toBeFalsy();
expect(compareValue(2, '>', 1)).toBeTruthy();
expect(compareValue(2, '>=', 2)).toBeTruthy();
expect(compareValue(2, '<', 3)).toBeTruthy();
expect(compareValue(2, '<=', 2)).toBeTruthy();
expect(compareValue<any>(2, '!=', '2')).toBeTruthy();
expect(compareValue<any>(2, '<>', '2')).toBeTruthy();
});
});

describe('Expression Utils', () => {
test('isValidExpressionDefine', () => {});
test('isRefValue', () => {
expect(isRefValue({ ref: 'user.id' })).toBeTruthy();
expect(isRefValue('user.id')).toBeFalsy();
expect(isRefValue(1)).toBeFalsy();
expect(isRefValue(true)).toBeFalsy();
expect(isRefValue(null)).toBeFalsy();
expect(isRefValue(undefined)).toBeFalsy();
expect(isRefValue([])).toBeFalsy();
expect(isRefValue({})).toBeFalsy();
expect(isRefValue(new Date())).toBeFalsy();
expect(isRefValue(new Error())).toBeFalsy();
});

test('isValidBinaryExpressionDefinition', () => {
expect(isValidBinaryExpressionDefinition(['user.role', '=', 'admin'])).toBeTruthy();
expect(isValidBinaryExpressionDefinition([])).toBeFalsy();
expect(isValidBinaryExpressionDefinition([1, 2, 3, 4])).toBeFalsy();
expect(isValidBinaryExpressionDefinition([1, 2, 4])).toBeFalsy();
expect(isValidBinaryExpressionDefinition(['1', '!', 4])).toBeFalsy();
});

test('isValidAndExpressionDefinition', () => {
const isValid = isValidAndExpressionDefinition;
expect(isValid('')).toBeFalsy();
expect(isValid({ and: [['user.role', '=', 'admin']] })).toBeFalsy();
expect(isValid({ and: [['user.role', '=', 'admin'], []] })).toBeTruthy();
expect(isValid({ and: ['user.role', '=', 'admin'] })).toBeTruthy();
});

test('normalizeExpression', () => {
const policy = new Policy({
Expand All @@ -51,5 +126,16 @@ describe('Expression Utils', () => {
effect: 'DENY',
});
expect(policy.getFilter()).toBeTruthy();

let invalidDefinition = false;
try {
or([
{ and: [['user.role', '=', 'admin'], []] },
{ a: ['user.role', '=', 'admin', ''] } as any,
]);
} catch (error) {
invalidDefinition = true;
}
expect(invalidDefinition).toBeTruthy();
});
});

0 comments on commit 9e5c3fe

Please sign in to comment.