unit tests (#627)

* evaluator tests

* extension service tests

* cleanup scripts
This commit is contained in:
Denys Vuika
2018-09-13 10:31:51 +01:00
committed by GitHub
parent 6e98721a62
commit 4af9628b9b
9 changed files with 641 additions and 36 deletions

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/aca-dev-tools",
"lib": {
"entryFile": "src/public_api.ts"
}
}

View File

@@ -25,7 +25,18 @@ module.exports = function (config) {
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
browsers: [/*'Chrome',*/ 'ChromeHeadless'],
customLaunchers: {
ChromeHeadless: {
base: 'Chrome',
flags: [
'--no-sandbox',
'--headless',
'--disable-gpu',
'--remote-debugging-port=9222'
]
}
},
singleRun: false
});
};

View File

@@ -1,8 +0,0 @@
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/@alfresco/adf-extensions",
"lib": {
"languageLevel": ["dom", "es2017"],
"entryFile": "src/public_api.ts"
}
}

View File

@@ -0,0 +1,237 @@
/*!
* @license
* Copyright 2016 - 2018 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { every, not, some } from './core.evaluators';
import { RuleParameter } from '../config/rule.extensions';
describe('Core Evaluators', () => {
const context: any = {
getEvaluator(key: string) {
switch (key) {
case 'positive':
return () => true;
case 'negative':
return () => false;
default:
return null;
}
}
};
describe('not', () => {
it('should evaluate a single rule to [true]', () => {
const parameter: RuleParameter = {
type: 'primitive',
value: 'negative'
};
const result = not(context, parameter);
expect(result).toBeTruthy();
});
it('should evaluate to [false] when no parameters provided', () => {
const result = not(context);
expect(result).toBeFalsy();
});
it('should evaluate to [false] when evaluator not available', () => {
const parameter: RuleParameter = {
type: 'primitive',
value: 'missing'
};
const result = not(context, parameter);
expect(result).toBeFalsy();
});
it('should evaluate a single rule to [false]', () => {
const parameter: RuleParameter = {
type: 'primitive',
value: 'positive'
};
const result = not(context, parameter);
expect(result).toBeFalsy();
});
it('should evaluate multiple rules to [true]', () => {
const parameter1: RuleParameter = {
type: 'primitive',
value: 'negative'
};
const parameter2: RuleParameter = {
type: 'primitive',
value: 'negative'
};
const parameter3: RuleParameter = {
type: 'primitive',
value: 'negative'
};
const result = not(context, parameter1, parameter2, parameter3);
expect(result).toBeTruthy();
});
it('should evaluate to [false] when one of the rules fails', () => {
const parameter1: RuleParameter = {
type: 'primitive',
value: 'negative'
};
const parameter2: RuleParameter = {
type: 'primitive',
value: 'negative'
};
const parameter3: RuleParameter = {
type: 'primitive',
value: 'positive'
};
const result = not(context, parameter1, parameter2, parameter3);
expect(result).toBeFalsy();
});
});
describe('every', () => {
it('should evaluate a single rule to [true]', () => {
const parameter: RuleParameter = {
type: 'primitive',
value: 'positive'
};
const result = every(context, parameter);
expect(result).toBeTruthy();
});
it('should evaluate to [false] when no parameters provided', () => {
const result = every(context);
expect(result).toBeFalsy();
});
it('should evaluate to [false] when evaluator not available', () => {
const parameter: RuleParameter = {
type: 'primitive',
value: 'missing'
};
const result = every(context, parameter);
expect(result).toBeFalsy();
});
it('should evaluate a single rule to [false]', () => {
const parameter: RuleParameter = {
type: 'primitive',
value: 'negative'
};
const result = every(context, parameter);
expect(result).toBeFalsy();
});
it('should evaluate multiple rules to [true]', () => {
const parameter1: RuleParameter = {
type: 'primitive',
value: 'positive'
};
const parameter2: RuleParameter = {
type: 'primitive',
value: 'positive'
};
const parameter3: RuleParameter = {
type: 'primitive',
value: 'positive'
};
const result = every(context, parameter1, parameter2, parameter3);
expect(result).toBeTruthy();
});
it('should evaluate to [false] when one of the rules fails', () => {
const parameter1: RuleParameter = {
type: 'primitive',
value: 'positive'
};
const parameter2: RuleParameter = {
type: 'primitive',
value: 'positive'
};
const parameter3: RuleParameter = {
type: 'primitive',
value: 'negative'
};
const result = every(context, parameter1, parameter2, parameter3);
expect(result).toBeFalsy();
});
});
describe('some', () => {
it('should evaluate a single rule to [true]', () => {
const parameter: RuleParameter = {
type: 'primitive',
value: 'positive'
};
const result = some(context, parameter);
expect(result).toBeTruthy();
});
it('should evaluate to [false] when no parameters provided', () => {
const result = some(context);
expect(result).toBeFalsy();
});
it('should evaluate to [false] when evaluator not available', () => {
const parameter: RuleParameter = {
type: 'primitive',
value: 'missing'
};
const result = some(context, parameter);
expect(result).toBeFalsy();
});
it('should evaluate to [true] if any rule succeeds', () => {
const parameter1: RuleParameter = {
type: 'primitive',
value: 'negative'
};
const parameter2: RuleParameter = {
type: 'primitive',
value: 'positive'
};
const parameter3: RuleParameter = {
type: 'primitive',
value: 'negative'
};
const result = some(context, parameter1, parameter2, parameter3);
expect(result).toBeTruthy();
});
});
});

View File

@@ -27,6 +27,7 @@ export function not(context: RuleContext, ...args: RuleParameter[]): boolean {
const evaluator = context.getEvaluator(arg.value);
if (!evaluator) {
console.warn('evaluator not found: ' + arg.value);
return false;
}
return !evaluator(context, ...(arg.parameters || []));
});
@@ -42,6 +43,7 @@ export function every(context: RuleContext, ...args: RuleParameter[]): boolean {
const evaluator = context.getEvaluator(arg.value);
if (!evaluator) {
console.warn('evaluator not found: ' + arg.value);
return false;
}
return evaluator(context, ...(arg.parameters || []));
});
@@ -57,6 +59,7 @@ export function some(context: RuleContext, ...args: RuleParameter[]): boolean {
const evaluator = context.getEvaluator(arg.value);
if (!evaluator) {
console.warn('evaluator not found: ' + arg.value);
return false;
}
return evaluator(context, ...(arg.parameters || []));
});

View File

@@ -0,0 +1,379 @@
/*!
* @license
* Copyright 2016 - 2018 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ExtensionService } from './extension.service';
import { ExtensionLoaderService } from './extension-loader.service';
import { ExtensionConfig } from '../config/extension.config';
import { RuleRef } from '../config/rule.extensions';
import { RouteRef } from '../config/routing.extensions';
import { ActionRef } from '../config/action.extensions';
describe('ExtensionService', () => {
const blankConfig: ExtensionConfig = {
$name: 'test.config',
$version: '1.0.0'
};
let loader: ExtensionLoaderService;
let service: ExtensionService;
beforeEach(() => {
loader = new ExtensionLoaderService(null);
service = new ExtensionService(loader);
});
it('should load and setup a config', async () => {
spyOn(loader, 'load').and.callFake(() => {
return Promise.resolve(blankConfig);
});
spyOn(service, 'setup').and.stub();
await service.load();
expect(loader.load).toHaveBeenCalled();
expect(service.setup).toHaveBeenCalledWith(blankConfig);
});
it('should raise warning if setting up with missing config', () => {
spyOn(console, 'warn').and.stub();
service.setup(null);
expect(console.warn).toHaveBeenCalledWith('Extension configuration not found');
});
it('should setup default evaluators', () => {
service.setup(blankConfig);
const evaluators = ['core.every', 'core.some', 'core.not'];
evaluators.forEach(key => {
expect(service.getEvaluator(key)).toBeDefined(`Evaluator ${key} is missing`);
});
});
it('should set custom evaluators', () => {
const evaluator1 = () => true;
const evaluator2 = () => false;
service.setEvaluators({
'eval1': evaluator1,
'eval2': evaluator2
});
expect(service.getEvaluator('eval1')).toBe(evaluator1);
expect(service.getEvaluator('eval2')).toBe(evaluator2);
});
it('should override existing evaluators', () => {
const evaluator1 = () => true;
const evaluator2 = () => false;
service.setup(blankConfig);
expect(service.getEvaluator('core.every')).toBeDefined();
expect(service.getEvaluator('core.every')).not.toBe(evaluator1);
service.setEvaluators({
'core.every': evaluator1,
'eval2': evaluator2
});
expect(service.getEvaluator('core.every')).toBe(evaluator1);
expect(service.getEvaluator('eval2')).toBe(evaluator2);
});
it('should negate existing evaluator', () => {
const positive = () => true;
service.setEvaluators({
'positive': positive
});
let evaluator = service.getEvaluator('positive');
expect(evaluator(null)).toBe(true);
evaluator = service.getEvaluator('!positive');
expect(evaluator(null, 'param1', 'param2')).toBe(false);
});
it('should not update evaluators with null value', () => {
service.setup(blankConfig);
service.setEvaluators(null);
expect(service.getEvaluator('core.every')).toBeDefined();
});
it('should set authentication guards', () => {
let registered = service.getAuthGuards(['guard1']);
expect(registered.length).toBe(0);
const guard1: any = {};
const guard2: any = {};
service.setAuthGuards({
'auth1': guard1,
'auth2': guard2
});
registered = service.getAuthGuards(['auth1', 'auth2']);
expect(registered.length).toBe(2);
expect(registered[0]).toBe(guard1);
expect(registered[1]).toBe(guard2);
});
it('should overwrite authentication guards', () => {
const guard1: any = {};
const guard2: any = {};
service.setAuthGuards({
'auth': guard1
});
expect(service.getAuthGuards(['auth'])).toEqual([guard1]);
service.setAuthGuards({
'auth': guard2
});
expect(service.getAuthGuards(['auth'])).toEqual([guard2]);
});
it('should not set authentication guards with null value', () => {
const guard1: any = {};
service.setAuthGuards({
'auth': guard1
});
service.setAuthGuards(null);
expect(service.getAuthGuards(['auth'])).toEqual([guard1]);
});
it('should not fetch auth guards for missing ids', () => {
const guards = service.getAuthGuards(null);
expect(guards).toEqual([]);
});
it('should set components', () => {
const component: any = {};
service.setComponents({
'component1': component
});
expect(service.getComponentById('component1')).toBe(component);
});
it('should overwrite components', () => {
const component1: any = {};
const component2: any = {};
service.setComponents({
'component': component1
});
expect(service.getComponentById('component')).toBe(component1);
service.setComponents({
'component': component2
});
expect(service.getComponentById('component')).toBe(component2);
});
it('should not set components with null value', () => {
const component: any = {};
service.setComponents({
'component1': component
});
expect(service.getComponentById('component1')).toBe(component);
service.setComponents(null);
expect(service.getComponentById('component1')).toBe(component);
});
it('should fetch route by id', () => {
const route: RouteRef = {
id: 'test.route',
component: 'component',
path: '/ext/route1'
};
spyOn(loader, 'getRoutes').and.returnValue([route]);
service.setup(blankConfig);
expect(service.getRouteById('test.route')).toBe(route);
});
it('should fetch action by id', () => {
const action: ActionRef = {
id: 'test.action',
type: 'action'
};
spyOn(loader, 'getActions').and.returnValue([action]);
service.setup(blankConfig);
expect(service.getActionById('test.action')).toBe(action);
});
it('should fetch rule by id', () => {
const rule: RuleRef = {
id: 'test.rule',
type: 'core.every'
};
spyOn(loader, 'getRules').and.returnValue([rule]);
service.setup(blankConfig);
expect(service.getRuleById('test.rule')).toBe(rule);
});
it('should evaluate condition', () => {
const condition = () => true;
service.setEvaluators({
'test.condition': condition
});
const context: any = {
getEvaluator(key: string) {
return service.getEvaluator(key);
}
};
const result = service.evaluateRule('test.condition', context);
expect(result).toBe(true);
});
it('should evaluate missing condition as [false]', () => {
const context: any = {
getEvaluator(key: string) {
return service.getEvaluator(key);
}
};
const result = service.evaluateRule('missing.condition', context);
expect(result).toBe(false);
});
it('should evaluate rule by reference', () => {
const ruleRef: RuleRef = {
id: 'test.rule',
type: 'core.every',
parameters: [
{
type: 'rule',
value: 'test.condition'
}
]
};
spyOn(loader, 'getRules').and.returnValue([ruleRef]);
service.setup(blankConfig);
const condition = () => true;
service.setEvaluators({
'test.condition': condition
});
const context: any = {
getEvaluator(key: string) {
return service.getEvaluator(key);
}
};
const result = service.evaluateRule('test.rule', context);
expect(result).toBe(true);
});
it('should evaluate rule ref with missing condition as [false]', () => {
const ruleRef: RuleRef = {
id: 'test.rule',
type: 'missing.evaluator'
};
spyOn(loader, 'getRules').and.returnValue([ruleRef]);
service.setup(blankConfig);
const context: any = {
getEvaluator(key: string) {
return service.getEvaluator(key);
}
};
const result = service.evaluateRule('test.rule', context);
expect(result).toBe(false);
});
it('should evaluate rule ref with missing evaluator as [false]', () => {
const ruleRef: RuleRef = {
id: 'test.rule',
type: 'core.every',
parameters: [
{
type: 'rule',
value: 'missing.condition'
}
]
};
spyOn(loader, 'getRules').and.returnValue([ruleRef]);
service.setup(blankConfig);
const context: any = {
getEvaluator(key: string) {
return service.getEvaluator(key);
}
};
const result = service.evaluateRule('test.rule', context);
expect(result).toBe(false);
});
describe('expressions', () => {
it('should eval static value', () => {
const value = service.runExpression('hello world');
expect(value).toBe('hello world');
});
it('should eval string as an expression', () => {
const value = service.runExpression('$( "hello world" )');
expect(value).toBe('hello world');
});
it('should eval expression with no context', () => {
const value = service.runExpression('$( 1 + 1 )');
expect(value).toBe(2);
});
it('should eval expression with context', () => {
const context = {
a: 'hey',
b: 'there'
};
const expression = '$( context.a + " " + context.b + "!" )';
const value = service.runExpression(expression, context);
expect(value).toBe('hey there!');
});
});
});

View File

@@ -49,7 +49,7 @@ export class ExtensionService {
setup(config: ExtensionConfig) {
if (!config) {
console.error('Extension configuration not found');
console.warn('Extension configuration not found');
return;
}