Introduce Jest integration tests. (#16735)

This commit is contained in:
Aleh Zasypkin 2018-02-19 17:02:01 +01:00 committed by GitHub
parent e135657d1f
commit f2fda4aca3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 188 additions and 150 deletions

View file

@ -15,6 +15,5 @@
/packages/eslint-plugin-kibana-custom
/packages/kbn-pm/dist
/packages/kbn-pm/vendor
/packages/kbn-pm/**/fixtures
/packages/kbn-plugin-generator/sao_template/template
!/.eslintrc.js

View file

@ -9,7 +9,7 @@ jest.mock('../utils/link_project_executables', () => ({
import { resolve } from 'path';
import {
absolutePathSnaphotSerializer,
absolutePathSnapshotSerializer,
stripAnsiSnapshotSerializer,
} from '../test_helpers';
import { run } from './bootstrap';
@ -28,7 +28,7 @@ const createProject = (fields, path = '.') =>
resolve(__dirname, path)
);
expect.addSnapshotSerializer(absolutePathSnaphotSerializer);
expect.addSnapshotSerializer(absolutePathSnapshotSerializer);
expect.addSnapshotSerializer(stripAnsiSnapshotSerializer);
const noop = () => {};

View file

@ -1,58 +0,0 @@
import expect from 'expect.js';
import tempy from 'tempy';
import copy from 'cpy';
import { resolve } from 'path';
import globby from 'globby';
import { buildProductionProjects } from '../build_production_projects';
import { getProjects } from '../../utils/projects';
// This is specifically a Mocha test instead of a Jest test because it's slow
// and more integration-y, as we're trying to not add very slow tests to our
// Jest unit tests.
describe('kbn-pm production', function() {
it('builds and copies projects for production', async function() {
this.timeout(60 * 1000);
const tmpDir = tempy.directory();
const buildRoot = tempy.directory();
const fixturesPath = resolve(__dirname, 'fixtures');
// console.log({ tmpDir, buildRoot, __dirname });
// Copy all the test fixtures into a tmp dir, as we will be mutating them
await copy(['**/*'], tmpDir, {
cwd: fixturesPath,
parents: true,
nodir: true,
dot: true,
});
const projects = await getProjects(tmpDir, ['./packages/*']);
for (const project of projects.values()) {
// This will both install dependencies and generate `yarn.lock` files
await project.installDependencies({
extraArgs: ['--silent', '--no-progress'],
});
}
await buildProductionProjects({ kibanaRoot: tmpDir, buildRoot });
const files = await globby(['**/*', '!**/node_modules/**'], {
cwd: buildRoot,
});
expect(files).to.eql([
'packages/bar/package.json',
'packages/bar/src/index.js',
'packages/bar/target/index.js',
'packages/bar/yarn.lock',
'packages/foo/package.json',
'packages/foo/src/index.js',
'packages/foo/target/index.js',
'packages/foo/yarn.lock',
]);
});
});

View file

@ -1,5 +0,0 @@
import bar from '@elastic/bar';
export default function (val) {
return 'test [' + val + '] (' + bar(val) + ')';
}

View file

@ -1,5 +1,5 @@
import _ from 'lodash';
export default function (val) {
export default function(val) {
return `test second: ${_.upperCase(val)}`;
}

View file

@ -0,0 +1,5 @@
import bar from '@elastic/bar'; // eslint-disable-line import/no-unresolved
export default function(val) {
return 'test [' + val + '] (' + bar(val) + ')';
}

View file

@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`kbn-pm production builds and copies projects for production 1`] = `
Array [
"packages/bar/package.json",
"packages/bar/src/index.js",
"packages/bar/target/index.js",
"packages/bar/yarn.lock",
"packages/foo/package.json",
"packages/foo/src/index.js",
"packages/foo/target/index.js",
"packages/foo/yarn.lock",
]
`;

View file

@ -0,0 +1,44 @@
import tempy from 'tempy';
import copy from 'cpy';
import { resolve } from 'path';
import globby from 'globby';
import { buildProductionProjects } from '../build_production_projects';
import { getProjects } from '../../utils/projects';
describe('kbn-pm production', function() {
test(
'builds and copies projects for production',
async function() {
const tmpDir = tempy.directory();
const buildRoot = tempy.directory();
const fixturesPath = resolve(__dirname, '__fixtures__');
// Copy all the test fixtures into a tmp dir, as we will be mutating them
await copy(['**/*'], tmpDir, {
cwd: fixturesPath,
parents: true,
nodir: true,
dot: true,
});
const projects = await getProjects(tmpDir, ['./packages/*']);
for (const project of projects.values()) {
// This will both install dependencies and generate `yarn.lock` files
await project.installDependencies({
extraArgs: ['--silent', '--no-progress'],
});
}
await buildProductionProjects({ kibanaRoot: tmpDir, buildRoot });
const files = await globby(['**/*', '!**/node_modules/**'], {
cwd: buildRoot,
});
expect(files.sort()).toMatchSnapshot();
},
60 * 1000
);
});

View file

@ -21,7 +21,7 @@ const normalizePaths = value => {
};
};
export const absolutePathSnaphotSerializer = {
export const absolutePathSnapshotSerializer = {
print: (value, serialize) => {
return serialize(normalizePaths(value).clone);
},

View file

@ -1,5 +1,5 @@
export {
absolutePathSnaphotSerializer,
} from './absolute_path_snaphot_serializer';
absolutePathSnapshotSerializer,
} from './absolute_path_snapshot_serializer';
export { stripAnsiSnapshotSerializer } from './strip_ansi_snapshot_serializer';

View file

@ -1,4 +1,4 @@
import { resolve, relative, dirname } from 'path';
import { resolve, relative, dirname, sep } from 'path';
import chalk from 'chalk';
@ -30,11 +30,13 @@ export async function linkProjectExecutables(projectsByName, projectGraph) {
const dest = resolve(binsDir, name);
// Get relative project path with normalized path separators.
const projectRelativePath = relative(project.path, srcPath)
.split(sep)
.join('/');
console.log(
chalk`{dim [${project.name}]} ${name} -> {dim ${relative(
project.path,
srcPath
)}}`
chalk`{dim [${project.name}]} ${name} -> {dim ${projectRelativePath}}`
);
await mkdirp(dirname(dest));

View file

@ -1,7 +1,7 @@
import { resolve } from 'path';
import {
absolutePathSnaphotSerializer,
absolutePathSnapshotSerializer,
stripAnsiSnapshotSerializer,
} from '../test_helpers';
import { linkProjectExecutables } from './link_project_executables';
@ -58,7 +58,7 @@ function getFsMockCalls() {
return fsMockCalls;
}
expect.addSnapshotSerializer(absolutePathSnaphotSerializer);
expect.addSnapshotSerializer(absolutePathSnapshotSerializer);
expect.addSnapshotSerializer(stripAnsiSnapshotSerializer);
jest.mock('./fs');

View file

@ -10,5 +10,8 @@
//
// See all cli options in https://facebook.github.io/jest/docs/cli.html
const { resolve } = require('path');
process.argv.push('--config', resolve(__dirname, '../src/dev/jest/config.js'));
require('../src/babel-register');
require('../src/dev/jest/cli');

17
scripts/jest_integration.js Executable file
View file

@ -0,0 +1,17 @@
// # Run Jest integration tests
//
// All args will be forwarded directly to Jest, e.g. to watch tests run:
//
// node scripts/jest_integration --watch
//
// or to build code coverage:
//
// node scripts/jest_integration --coverage
//
// See all cli options in https://facebook.github.io/jest/docs/cli.html
const { resolve } = require('path');
process.argv.push('--config', resolve(__dirname, '../src/dev/jest/config.integration.js'));
require('../src/babel-register');
require('../src/dev/jest/cli');

View file

@ -1,8 +1,3 @@
import jest from 'jest';
import { resolve } from 'path';
const argv = process.argv.slice(2);
argv.push('--config', resolve(__dirname, './config.json'));
jest.run(argv);
jest.run(process.argv.slice(2));

View file

@ -0,0 +1,15 @@
import config from './config';
export default {
...config,
testMatch: [
'**/integration_tests/**/*.test.js',
],
testPathIgnorePatterns: config.testPathIgnorePatterns.filter(
(pattern) => !pattern.includes('integration_tests')
),
reporters: [
'default',
['<rootDir>/src/dev/jest/junit_reporter.js', { reportName: 'Jest Integration Tests' }],
],
};

64
src/dev/jest/config.js Normal file
View file

@ -0,0 +1,64 @@
export default {
rootDir: '../../..',
roots: [
'<rootDir>/src/ui',
'<rootDir>/src/core_plugins',
'<rootDir>/ui_framework/',
'<rootDir>/packages',
],
collectCoverageFrom: [
'ui_framework/src/components/**/*.js',
'!ui_framework/src/components/index.js',
'!ui_framework/src/components/**/*/index.js',
'ui_framework/src/services/**/*.js',
'!ui_framework/src/services/index.js',
'!ui_framework/src/services/**/*/index.js',
],
moduleNameMapper: {
'^ui_framework/components': '<rootDir>/ui_framework/components',
'^ui_framework/services': '<rootDir>/ui_framework/services',
'^ui_framework/test': '<rootDir>/ui_framework/test',
'^ui/(.*)': '<rootDir>/src/ui/public/$1',
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/src/dev/jest/mocks/file_mock.js',
'\\.(css|less|scss)$': '<rootDir>/src/dev/jest/mocks/style_mock.js',
},
setupFiles: [
'<rootDir>/src/dev/jest/setup/babel_polyfill.js',
'<rootDir>/src/dev/jest/setup/enzyme.js',
'<rootDir>/src/dev/jest/setup/throw_on_console_error.js',
],
coverageDirectory: '<rootDir>/target/jest-coverage',
coverageReporters: [
'html',
],
moduleFileExtensions: [
'js',
'json',
],
modulePathIgnorePatterns: [
'__fixtures__/',
],
testMatch: [
'**/*.test.js',
],
testPathIgnorePatterns: [
'<rootDir>/ui_framework/dist/',
'<rootDir>/ui_framework/doc_site/',
'<rootDir>/ui_framework/generator-kui/',
'<rootDir>/packages/kbn-pm/(dist|vendor)/',
'integration_tests/'
],
transform: {
'^.+\\.js$': '<rootDir>/src/dev/jest/babel_transform.js',
},
transformIgnorePatterns: [
'[/\\\\]node_modules[/\\\\].+\\.js$',
],
snapshotSerializers: [
'<rootDir>/node_modules/enzyme-to-json/serializer',
],
reporters: [
'default',
'<rootDir>/src/dev/jest/junit_reporter.js',
],
};

View file

@ -1,62 +0,0 @@
{
"rootDir": "../../..",
"roots": [
"<rootDir>/src/ui",
"<rootDir>/src/core_plugins",
"<rootDir>/ui_framework/",
"<rootDir>/packages"
],
"collectCoverageFrom": [
"ui_framework/src/components/**/*.js",
"!ui_framework/src/components/index.js",
"!ui_framework/src/components/**/*/index.js",
"ui_framework/src/services/**/*.js",
"!ui_framework/src/services/index.js",
"!ui_framework/src/services/**/*/index.js"
],
"moduleNameMapper": {
"^ui_framework/components": "<rootDir>/ui_framework/components",
"^ui_framework/services": "<rootDir>/ui_framework/services",
"^ui_framework/test": "<rootDir>/ui_framework/test",
"^ui/(.*)": "<rootDir>/src/ui/public/$1",
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/src/dev/jest/mocks/file_mock.js",
"\\.(css|less|scss)$": "<rootDir>/src/dev/jest/mocks/style_mock.js"
},
"setupFiles": [
"<rootDir>/src/dev/jest/setup/babel_polyfill.js",
"<rootDir>/src/dev/jest/setup/enzyme.js",
"<rootDir>/src/dev/jest/setup/throw_on_console_error.js"
],
"coverageDirectory": "<rootDir>/target/jest-coverage",
"coverageReporters": [
"html"
],
"moduleFileExtensions": [
"js",
"json"
],
"modulePathIgnorePatterns": [
"__fixtures__/"
],
"testMatch": [
"**/*.test.js"
],
"testPathIgnorePatterns": [
"<rootDir>/ui_framework/dist/",
"<rootDir>/ui_framework/doc_site/",
"<rootDir>/ui_framework/generator-kui/"
],
"transform": {
"^.+\\.js$": "<rootDir>/src/dev/jest/babel_transform.js"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.js$"
],
"snapshotSerializers": [
"<rootDir>/node_modules/enzyme-to-json/serializer"
],
"reporters": [
"default",
"<rootDir>/src/dev/jest/junit_reporter.js"
]
}

View file

@ -33,6 +33,7 @@ module.exports = function (grunt) {
'licenses',
'test:server',
'test:jest',
'test:jest_integration',
'test:browser-ci',
'test:api',
'verifyTranslations',

View file

@ -42,6 +42,7 @@ module.exports = function (grunt) {
'test:server',
'test:ui',
'test:jest',
'test:jest_integration',
'test:browser',
'test:api'
]);

View file

@ -3,15 +3,18 @@ const { resolve } = require('path');
module.exports = function (grunt) {
grunt.registerTask('test:jest', function () {
const done = this.async();
runJest().then(done, done);
runJest(resolve(__dirname, '../scripts/jest.js')).then(done, done);
});
function runJest() {
grunt.registerTask('test:jest_integration', function () {
const done = this.async();
runJest(resolve(__dirname, '../scripts/jest_integration.js')).then(done, done);
});
function runJest(jestScript) {
const serverCmd = {
cmd: 'node',
args: [
resolve(__dirname, '../scripts/jest.js')
],
args: [jestScript],
opts: { stdio: 'inherit' }
};