Skip to content

Commit

Permalink
review updates
Browse files Browse the repository at this point in the history
  • Loading branch information
ppisljar committed Oct 28, 2020
1 parent 3afcbe8 commit 134e82c
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 35 deletions.
31 changes: 31 additions & 0 deletions src/plugins/expressions/common/executor/executor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ 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', () => {
Expand Down Expand Up @@ -158,6 +159,7 @@ describe('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',
Expand All @@ -174,6 +176,14 @@ describe('Executor', () => {
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);
Expand All @@ -194,5 +204,26 @@ describe('Executor', () => {
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);
});
});
});
});
22 changes: 15 additions & 7 deletions src/plugins/expressions/common/executor/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,11 @@ export class FunctionsRegistry implements IRegistry<ExpressionFunction> {

const semverGte = (semver1: string, semver2: string) => {
const regex = /^([0-9]+)\.([0-9]+)\.([0-9]+)$/;
const [major1, minor1, patch1] = semver1.match(regex) as RegExpMatchArray;
const [major2, minor2, patch2] = semver2.match(regex) as RegExpMatchArray;
const matches1 = regex.exec(semver1) as RegExpMatchArray;
const matches2 = regex.exec(semver2) as RegExpMatchArray;

const [, major1, minor1, patch1] = matches1;
const [, major2, minor2, patch2] = matches2;

return (
major1 > major2 ||
Expand Down Expand Up @@ -260,17 +263,22 @@ export class Executor<Context extends Record<string, unknown> = Record<string, u
return telemetryData;
}

migrate(ast: SerializableState, version: string) {
public migrate(ast: SerializableState, version: string) {
return this.walkAst(cloneDeep(ast) as ExpressionAstExpression, (fn, link) => {
link = fn.migrations[version](link) as ExpressionAstFunction;
if (!fn.migrations[version]) return link;
const updatedAst = fn.migrations[version](link) as ExpressionAstFunction;
link.arguments = updatedAst.arguments;
link.type = updatedAst.type;
});
}

migrateToLatest(ast: unknown, version: string) {
public migrateToLatest(ast: unknown, version: string) {
return this.walkAst(cloneDeep(ast) as ExpressionAstExpression, (fn, link) => {
for (const key in Object.keys(fn.migrations)) {
for (const key of Object.keys(fn.migrations)) {
if (semverGte(key, version)) {
link = fn.migrations[key](link) as ExpressionAstFunction;
const updatedAst = fn.migrations[key](link) as ExpressionAstFunction;
link.arguments = updatedAst.arguments;
link.type = updatedAst.type;
}
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import { i18n } from '@kbn/i18n';
import { ExpressionFunctionDefinition } from '../types';
import { ExpressionValueSearchContext } from '../../expression_types';
import { MigrateFunction } from '../../../../kibana_utils/common/persistable_state';

const toArray = <T>(query: undefined | T | T[]): T[] =>
!query ? [] : Array.isArray(query) ? query : [query];
Expand All @@ -33,23 +32,6 @@ export type ExpressionFunctionKibana = ExpressionFunctionDefinition<
ExpressionValueSearchContext
>;

type MYSTATE_7_10_0 = {
name: 'kibana';
args: {};
};

type MYSTATE_7_10_1 = {
name: 'kibana_input';
args: {};
};

const MIGRATE7_10_1: MigrateFunction<MYSTATE_7_10_0, MYSTATE_7_10_1> = (state) => {
return {
name: 'kibana_input',
args: state.args,
};
};

export const kibana: ExpressionFunctionKibana = {
name: 'kibana',
type: 'kibana_context',
Expand All @@ -62,10 +44,6 @@ export const kibana: ExpressionFunctionKibana = {

args: {},

migrations: {
'7.10.1': (MIGRATE7_10_1 as any) as MigrateFunction,
},

fn(input, _, { getSearchContext }) {
const output: ExpressionValueSearchContext = {
// TODO: This spread is left here for legacy reasons, possibly Lens uses it.
Expand Down
12 changes: 6 additions & 6 deletions src/plugins/expressions/common/service/expressions_services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,20 +304,20 @@ export class ExpressionsService implements PersistableState<ExpressionAstExpress
};

/**
* Injects saved object references into expression AST
* Runs the migration (if it exists) for specified version. This will run a single migration step (ie from 7.10.0 to 7.10.1)
* @param state expression AST to update
* @param references array of saved object references
* @returns new expression AST with references injected
* @param version defines which migration version to run
* @returns new migrated expression AST
*/
public readonly migrate = (state: SerializableState, version: string) => {
return this.executor.migrate(state, version);
};

/**
* Injects saved object references into expression AST
* Migrates expression to the latest version
* @param state expression AST to update
* @param references array of saved object references
* @returns new expression AST with references injected
* @param version the version of kibana in which expression was created
* @returns migrated expression AST
*/
public readonly migrateToLatest = (state: unknown, version: string) => {
return this.executor.migrateToLatest(state, version);
Expand Down

0 comments on commit 134e82c

Please sign in to comment.