mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
229 lines
7.4 KiB
TypeScript
229 lines
7.4 KiB
TypeScript
/*
|
|
* Licensed to Elasticsearch B.V. under one or more contributor
|
|
* license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright
|
|
* ownership. Elasticsearch B.V. licenses this file to you 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 { Executor } from './executor';
|
|
import * as expressionTypes from '../expression_types';
|
|
import * as expressionFunctions from '../expression_functions';
|
|
import { Execution } from '../execution';
|
|
import { ExpressionAstFunction, parseExpression } from '../ast';
|
|
import { MigrateFunction } from '../../../kibana_utils/common/persistable_state';
|
|
|
|
describe('Executor', () => {
|
|
test('can instantiate', () => {
|
|
new Executor();
|
|
});
|
|
|
|
describe('type registry', () => {
|
|
test('can register a type', () => {
|
|
const executor = new Executor();
|
|
executor.registerType(expressionTypes.datatable);
|
|
});
|
|
|
|
test('can register all types', () => {
|
|
const executor = new Executor();
|
|
for (const type of expressionTypes.typeSpecs) executor.registerType(type);
|
|
});
|
|
|
|
test('can retrieve all types', () => {
|
|
const executor = new Executor();
|
|
executor.registerType(expressionTypes.datatable);
|
|
const types = executor.getTypes();
|
|
expect(Object.keys(types)).toEqual(['datatable']);
|
|
});
|
|
|
|
test('can retrieve all types - 2', () => {
|
|
const executor = new Executor();
|
|
for (const type of expressionTypes.typeSpecs) executor.registerType(type);
|
|
const types = executor.getTypes();
|
|
expect(Object.keys(types).sort()).toEqual(
|
|
expressionTypes.typeSpecs.map((spec) => spec.name).sort()
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('function registry', () => {
|
|
test('can register a function', () => {
|
|
const executor = new Executor();
|
|
executor.registerFunction(expressionFunctions.clog);
|
|
});
|
|
|
|
test('can register all functions', () => {
|
|
const executor = new Executor();
|
|
for (const functionDefinition of expressionFunctions.functionSpecs)
|
|
executor.registerFunction(functionDefinition);
|
|
});
|
|
|
|
test('can retrieve all functions', () => {
|
|
const executor = new Executor();
|
|
executor.registerFunction(expressionFunctions.clog);
|
|
const functions = executor.getFunctions();
|
|
expect(Object.keys(functions)).toEqual(['clog']);
|
|
});
|
|
|
|
test('can retrieve all functions - 2', () => {
|
|
const executor = new Executor();
|
|
for (const functionDefinition of expressionFunctions.functionSpecs)
|
|
executor.registerFunction(functionDefinition);
|
|
const functions = executor.getFunctions();
|
|
expect(Object.keys(functions).sort()).toEqual(
|
|
expressionFunctions.functionSpecs.map((spec) => spec.name).sort()
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('context', () => {
|
|
test('context is empty by default', () => {
|
|
const executor = new Executor();
|
|
expect(executor.context).toEqual({});
|
|
});
|
|
|
|
test('can extend context', () => {
|
|
const executor = new Executor();
|
|
executor.extendContext({
|
|
foo: 'bar',
|
|
});
|
|
expect(executor.context).toEqual({
|
|
foo: 'bar',
|
|
});
|
|
});
|
|
|
|
test('can extend context multiple times with multiple keys', () => {
|
|
const executor = new Executor();
|
|
const abortSignal = {};
|
|
const env = {};
|
|
|
|
executor.extendContext({
|
|
foo: 'bar',
|
|
});
|
|
executor.extendContext({
|
|
abortSignal,
|
|
env,
|
|
});
|
|
|
|
expect(executor.context).toEqual({
|
|
foo: 'bar',
|
|
abortSignal,
|
|
env,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('execution', () => {
|
|
describe('createExecution()', () => {
|
|
test('returns Execution object from string', () => {
|
|
const executor = new Executor();
|
|
const execution = executor.createExecution('foo bar="baz"');
|
|
|
|
expect(execution).toBeInstanceOf(Execution);
|
|
expect(execution.state.get().ast.chain[0].function).toBe('foo');
|
|
});
|
|
|
|
test('returns Execution object from AST', () => {
|
|
const executor = new Executor();
|
|
const ast = parseExpression('foo bar="baz"');
|
|
const execution = executor.createExecution(ast);
|
|
|
|
expect(execution).toBeInstanceOf(Execution);
|
|
expect(execution.state.get().ast.chain[0].function).toBe('foo');
|
|
});
|
|
|
|
test('Execution inherits context from Executor', () => {
|
|
const executor = new Executor();
|
|
const foo = {};
|
|
executor.extendContext({ foo });
|
|
const execution = executor.createExecution('foo bar="baz"');
|
|
|
|
expect((execution.context as any).foo).toBe(foo);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('.inject', () => {
|
|
const executor = new Executor();
|
|
|
|
const injectFn = jest.fn().mockImplementation((args, references) => args);
|
|
const extractFn = jest.fn().mockReturnValue({ args: {}, references: [] });
|
|
const migrateFn = jest.fn().mockImplementation((args) => args);
|
|
|
|
const fooFn = {
|
|
name: 'foo',
|
|
help: 'test',
|
|
args: {
|
|
bar: {
|
|
types: ['string'],
|
|
help: 'test',
|
|
},
|
|
},
|
|
extract: (state: ExpressionAstFunction['arguments']) => {
|
|
return extractFn(state);
|
|
},
|
|
inject: (state: ExpressionAstFunction['arguments']) => {
|
|
return injectFn(state);
|
|
},
|
|
migrations: {
|
|
'7.10.0': (((state: ExpressionAstFunction, version: string): ExpressionAstFunction => {
|
|
return migrateFn(state, version);
|
|
}) as any) as MigrateFunction,
|
|
'7.10.1': (((state: ExpressionAstFunction, version: string): ExpressionAstFunction => {
|
|
return migrateFn(state, version);
|
|
}) as any) as MigrateFunction,
|
|
},
|
|
fn: jest.fn(),
|
|
};
|
|
executor.registerFunction(fooFn);
|
|
|
|
test('calls inject function for every expression function in expression', () => {
|
|
executor.inject(
|
|
parseExpression('foo bar="baz" | foo bar={foo bar="baz" | foo bar={foo bar="baz"}}'),
|
|
[]
|
|
);
|
|
expect(injectFn).toBeCalledTimes(5);
|
|
});
|
|
|
|
describe('.extract', () => {
|
|
test('calls extract function for every expression function in expression', () => {
|
|
executor.extract(
|
|
parseExpression('foo bar="baz" | foo bar={foo bar="baz" | foo bar={foo bar="baz"}}')
|
|
);
|
|
expect(extractFn).toBeCalledTimes(5);
|
|
});
|
|
});
|
|
|
|
describe('.migrate', () => {
|
|
test('calls migrate function for every expression function in expression', () => {
|
|
executor.migrate(
|
|
parseExpression('foo bar="baz" | foo bar={foo bar="baz" | foo bar={foo bar="baz"}}'),
|
|
'7.10.0'
|
|
);
|
|
expect(migrateFn).toBeCalledTimes(5);
|
|
});
|
|
});
|
|
|
|
describe('.migrateToLatest', () => {
|
|
test('calls extract function for every expression function in expression', () => {
|
|
migrateFn.mockClear();
|
|
executor.migrateToLatest(
|
|
parseExpression('foo bar="baz" | foo bar={foo bar="baz" | foo bar={foo bar="baz"}}'),
|
|
'7.10.0'
|
|
);
|
|
expect(migrateFn).toBeCalledTimes(10);
|
|
});
|
|
});
|
|
});
|
|
});
|