kibana/packages/kbn-cli-dev-mode/src/optimizer.test.ts
Pierre Gayvallet 41eb6e2b12
Remove core->cli dependency (#95145) (#95775)
* extract http_tools to package

* fix readme

* start moving stuff

* cleaning up `isDevCliParent`

* choose bootstrap script

* fix bootstrap script logic

* fix watch paths logic

* import REPO_ROOT from correct package

* create the @kbn/crypto package

* update core's `dev` config

* only export bootstrap function

* extract sslConfig to http-tools package

* fix core types

* fix optimizer tests

* fix cli_dev_mode tests

* fix basePath proxy tests

* update generated doc

* fix unit tests

* create @kbn/dev-cli-mode package

* remove useless comment

* self-review NITS

* update CODEOWNERS file

* add devOnly flag

* use variable for DEV_MODE_PATH

* review comments

* fix logger/log adapter

* fix log calls in base path proxy server

* address some review comments

* rename @kbn/http-tools to @kbn/server-http-tools

* more review comments

* move test to correct file

* add comment on getBootstrapScript

* fix lint

* lint

* add cli-dev-mode to eslint dev packages

* review comments

* update yarn.lock

* Revert "[ci] skip building ts refs when not necessary (#95739)"

This reverts commit e46a74f7
# Conflicts:
#	.github/CODEOWNERS
2021-03-30 09:48:48 -04:00

209 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { PassThrough } from 'stream';
import * as Rx from 'rxjs';
import { toArray } from 'rxjs/operators';
import { OptimizerUpdate } from '@kbn/optimizer';
import { observeLines, createReplaceSerializer } from '@kbn/dev-utils';
import { firstValueFrom } from '@kbn/std';
import { Optimizer, Options } from './optimizer';
jest.mock('@kbn/optimizer');
const realOptimizer = jest.requireActual('@kbn/optimizer');
const { runOptimizer, OptimizerConfig, logOptimizerState } = jest.requireMock('@kbn/optimizer');
logOptimizerState.mockImplementation(realOptimizer.logOptimizerState);
class MockOptimizerConfig {}
const mockOptimizerUpdate = (phase: OptimizerUpdate['state']['phase']) => {
return {
state: {
compilerStates: [],
durSec: 0,
offlineBundles: [],
onlineBundles: [],
phase,
startTime: 100,
},
};
};
const defaultOptions: Options = {
enabled: true,
cache: true,
dist: true,
oss: true,
pluginPaths: ['/some/dir'],
pluginScanDirs: ['/some-scan-path'],
quiet: true,
silent: true,
repoRoot: '/app',
runExamples: true,
watch: true,
};
function setup(options: Options = defaultOptions) {
const update$ = new Rx.Subject<OptimizerUpdate>();
OptimizerConfig.create.mockImplementation(() => new MockOptimizerConfig());
runOptimizer.mockImplementation(() => update$);
const optimizer = new Optimizer(options);
return { optimizer, update$ };
}
const subscriptions: Rx.Subscription[] = [];
expect.addSnapshotSerializer(createReplaceSerializer(/\[\d\d:\d\d:\d\d\.\d\d\d\]/, '[timestamp]'));
afterEach(() => {
for (const sub of subscriptions) {
sub.unsubscribe();
}
subscriptions.length = 0;
jest.clearAllMocks();
});
it('uses options to create valid OptimizerConfig', () => {
setup();
setup({
...defaultOptions,
cache: false,
dist: false,
runExamples: false,
oss: false,
pluginPaths: [],
pluginScanDirs: [],
repoRoot: '/foo/bar',
watch: false,
});
expect(OptimizerConfig.create.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
Object {
"cache": true,
"dist": true,
"examples": true,
"includeCoreBundle": true,
"oss": true,
"pluginPaths": Array [
"/some/dir",
],
"pluginScanDirs": Array [
"/some-scan-path",
],
"repoRoot": "/app",
"watch": true,
},
],
Array [
Object {
"cache": false,
"dist": false,
"examples": false,
"includeCoreBundle": true,
"oss": false,
"pluginPaths": Array [],
"pluginScanDirs": Array [],
"repoRoot": "/foo/bar",
"watch": false,
},
],
]
`);
});
it('is ready when optimizer phase is success or issue and logs in familiar format', async () => {
const writeLogTo = new PassThrough();
const linesPromise = firstValueFrom(observeLines(writeLogTo).pipe(toArray()));
const { update$, optimizer } = setup({
...defaultOptions,
quiet: false,
silent: false,
writeLogTo,
});
const history: any[] = ['<init>'];
subscriptions.push(
optimizer.isReady$().subscribe({
next(ready) {
history.push(`ready: ${ready}`);
},
error(error) {
throw error;
},
complete() {
history.push(`complete`);
},
})
);
subscriptions.push(
optimizer.run$.subscribe({
error(error) {
throw error;
},
})
);
history.push('<success>');
update$.next(mockOptimizerUpdate('success'));
history.push('<running>');
update$.next(mockOptimizerUpdate('running'));
history.push('<issue>');
update$.next(mockOptimizerUpdate('issue'));
update$.complete();
expect(history).toMatchInlineSnapshot(`
Array [
"<init>",
"<success>",
"ready: true",
"<running>",
"ready: false",
"<issue>",
"ready: true",
]
`);
writeLogTo.end();
const lines = await linesPromise;
expect(lines).toMatchInlineSnapshot(`
Array [
" np bld log [timestamp] [success][@kbn/optimizer] 0 bundles compiled successfully after 0 sec",
" np bld log [timestamp] [error][@kbn/optimizer] webpack compile errors",
]
`);
});
it('completes immedately and is immediately ready when disabled', () => {
const ready$ = new Rx.BehaviorSubject<undefined | boolean>(undefined);
const { optimizer, update$ } = setup({
...defaultOptions,
enabled: false,
});
subscriptions.push(optimizer.isReady$().subscribe(ready$));
expect(update$.observers).toHaveLength(0);
expect(runOptimizer).not.toHaveBeenCalled();
expect(ready$).toHaveProperty('isStopped', true);
expect(ready$.getValue()).toBe(true);
});