feat(testing): support for vscode-jest integration

This commit is contained in:
Alexei Domratchev 2019-02-28 15:56:25 -05:00 committed by Victor Savkin
parent 256d83c3f9
commit c1aaed5c69
4 changed files with 245 additions and 118 deletions

View File

@ -6,33 +6,49 @@ Run Jest unit tests
### bail
Type: `boolean`
Alias(es): b
Exit the test suite immediately upon the first failing test suite. (https://jestjs.io/docs/en/cli#bail)
Type: `number`
Exit the test suite immediately after `n` number of failing tests. (https://jestjs.io/docs/en/cli#bail)
### ci
Type: `boolean`
Fail on missing snapshots. (https://jestjs.io/docs/en/cli#ci)
Whether to run Jest in continuous integration (CI) mode. This option is on by default in most popular CI environments. It will prevent snapshots from being written unless explicitly requested. (https://jestjs.io/docs/en/cli#ci)
### codeCoverage
Type: `boolean`
Export a code coverage report. (https://jestjs.io/docs/en/cli#coverage)
Indicates that test coverage information should be collected and reported in the output. (https://jestjs.io/docs/en/cli#coverage)
### color
Type: `boolean`
Forces test results output color highlighting (even if stdout is not a TTY). Set to false if you would like to have no colors. (https://jestjs.io/docs/en/cli#colors)
### jestConfig
Type: `string`
The path of the Jest configuration. (https://jestjs.io/docs/en/configuration.html)
The path of the Jest configuration. (https://jestjs.io/docs/en/configuration)
### json
Type: `boolean`
Prints the test results in JSON. This mode will send all other test output and user messages to stderr. (https://jestjs.io/docs/en/cli#json)
### maxWorkers
Alias(es): w
Type: `number`
Max number of workers to run tests across. Useful for CI. (https://jestjs.io/docs/en/cli.html#maxworkers-num)
Specifies the maximum number of workers the worker-pool will spawn for running tests. This defaults to the number of the cores available on your machine. Useful for CI. (its usually best not to override this default) (https://jestjs.io/docs/en/cli#maxworkers-num)
### onlyChanged
@ -40,25 +56,33 @@ Alias(es): o
Type: `boolean`
Isolate tests affected by uncommitted changes. (https://jestjs.io/docs/en/cli#onlychanged)
Attempts to identify which tests to run based on which files have changed in the current repository. Only works if you're running tests in a git or hg repository at the moment. (https://jestjs.io/docs/en/cli#onlychanged)
### outputFile
Type: `string`
Write test results to a file when the --json option is also specified. (https://jestjs.io/docs/en/cli#outputfile-filename)
### passWithNoTests
Type: `boolean`
Allow test suite to pass when no test files are found. (https://jestjs.io/docs/en/cli#passwithnotests)
Will not fail if no tests are found (for example while using `--testPathPattern`.) (https://jestjs.io/docs/en/cli#passwithnotests)
### runInBand
Alias(es): i
Type: `boolean`
Run tests in a single process as opposed to multiple workers. Useful for CI. (https://jestjs.io/docs/en/cli.html#runinband)
Run all tests serially in the current process (rather than creating a worker pool of child processes that run tests). This is sometimes useful for debugging, but such use cases are pretty rare. Useful for CI. (https://jestjs.io/docs/en/cli#runinband)
### setupFile
Type: `string`
The name of a setup file used by Jest. (https://jestjs.io/docs/en/configuration.html#setuptestframeworkscriptfile-string)
The name of a setup file used by Jest. (https://jestjs.io/docs/en/configuration#setupfilesafterenv-array)
### silent
@ -66,13 +90,19 @@ Type: `boolean`
Prevent tests from printing messages through the console. (https://jestjs.io/docs/en/cli#silent)
### testFile
Type: `string`
The name of the file to test.
### testNamePattern
Alias(es): t
Type: `string`
Run only tests with a name that matches the regex. (https://jestjs.io/docs/en/cli.html#testnamepattern-regex)
Run only tests with a name that matches the regex pattern. (https://jestjs.io/docs/en/cli#testnamepattern-regex)
### tsConfig
@ -86,12 +116,22 @@ Alias(es): u
Type: `boolean`
Re-record all failing snapshots. (https://jestjs.io/docs/en/cli#updatesnapshot)
Use this flag to re-record snapshots. Can be used together with a test suite pattern or with `--testNamePattern` to re-record snapshot for test matching the pattern. (https://jestjs.io/docs/en/cli#updatesnapshot)
### watch
Default: `false`
### useStderr
Type: `boolean`
Run tests when files change. (https://jestjs.io/docs/en/cli#watch)
Divert all output to stderr.
### watch
Type: `boolean`
Watch files for changes and rerun tests related to changed files. If you want to re-run all tests when a file has changed, use the `--watchAll` option. (https://jestjs.io/docs/en/cli#watch)
### watchAll
Type: `boolean`
Watch files for changes and rerun all tests when something changes. If you want to re-run only the tests that depend on the changed files, use the `--watch` option. (https://jestjs.io/docs/en/cli#watchall)

View File

@ -1,5 +1,6 @@
import JestBuilder from './jest.builder';
import { normalize } from '@angular-devkit/core';
import { TestLogger } from '@angular-devkit/architect/testing';
jest.mock('jest');
const { runCLI } = require('jest');
import * as path from 'path';
@ -8,7 +9,14 @@ describe('Jest Builder', () => {
let builder: JestBuilder;
beforeEach(() => {
builder = new JestBuilder();
builder = new JestBuilder({
host: <any>{},
logger: new TestLogger('test'),
workspace: <any>{
root: '/root'
},
architect: <any>{}
});
runCLI.mockReturnValue(
Promise.resolve({
results: {
@ -36,10 +44,7 @@ describe('Jest Builder', () => {
{
globals: JSON.stringify({
'ts-jest': {
tsConfig: path.join(
'<rootDir>',
path.relative(root, './tsconfig.test.json')
),
tsConfig: '/root/tsconfig.test.json',
stringifyContentPathRegex: '\\.html$',
astTransformers: [
'jest-preset-angular/InlineHtmlStripStylesTransformer'
@ -48,7 +53,47 @@ describe('Jest Builder', () => {
}),
watch: false
},
['./jest.config.js']
['/root/jest.config.js']
);
});
it('should send appropriate options to jestCLI when testFile is specified', () => {
const root = normalize('/root');
builder
.run({
root,
builder: '',
projectType: 'application',
options: {
testFile: 'lib.spec.ts',
jestConfig: './jest.config.js',
tsConfig: './tsconfig.test.json',
codeCoverage: false,
runInBand: true,
testNamePattern: 'should load',
watch: false
}
})
.toPromise();
expect(runCLI).toHaveBeenCalledWith(
{
_: ['lib.spec.ts'],
globals: JSON.stringify({
'ts-jest': {
tsConfig: '/root/tsconfig.test.json',
stringifyContentPathRegex: '\\.html$',
astTransformers: [
'jest-preset-angular/InlineHtmlStripStylesTransformer'
]
}
}),
coverage: false,
runInBand: true,
testNamePattern: 'should load',
watch: false
},
['/root/jest.config.js']
);
});
@ -62,17 +107,21 @@ describe('Jest Builder', () => {
options: {
jestConfig: './jest.config.js',
tsConfig: './tsconfig.test.json',
watch: false,
codeCoverage: true,
ci: true,
updateSnapshot: true,
onlyChanged: true,
passWithNoTests: true,
bail: true,
silent: true,
runInBand: true,
color: false,
ci: true,
json: true,
maxWorkers: 2,
testNamePattern: 'test'
onlyChanged: true,
outputFile: 'abc.txt',
passWithNoTests: true,
silent: true,
testNamePattern: 'test',
updateSnapshot: true,
useStderr: true,
watch: false,
watchAll: false
}
})
.toPromise();
@ -80,29 +129,30 @@ describe('Jest Builder', () => {
{
globals: JSON.stringify({
'ts-jest': {
tsConfig: path.join(
'<rootDir>',
path.relative(root, './tsconfig.test.json')
),
tsConfig: '/root/tsconfig.test.json',
stringifyContentPathRegex: '\\.html$',
astTransformers: [
'jest-preset-angular/InlineHtmlStripStylesTransformer'
]
}
}),
watch: false,
coverage: true,
ci: true,
updateSnapshot: true,
onlyChanged: true,
passWithNoTests: true,
bail: true,
silent: true,
runInBand: true,
color: false,
ci: true,
json: true,
maxWorkers: 2,
testNamePattern: 'test'
onlyChanged: true,
outputFile: 'abc.txt',
passWithNoTests: true,
silent: true,
testNamePattern: 'test',
updateSnapshot: true,
useStderr: true,
watch: false,
watchAll: false
},
['./jest.config.js']
['/root/jest.config.js']
);
});
@ -125,10 +175,7 @@ describe('Jest Builder', () => {
{
globals: JSON.stringify({
'ts-jest': {
tsConfig: path.join(
'<rootDir>',
path.relative(root, './tsconfig.test.json')
),
tsConfig: '/root/tsconfig.test.json',
stringifyContentPathRegex: '\\.html$',
astTransformers: [
'jest-preset-angular/InlineHtmlStripStylesTransformer'
@ -141,7 +188,7 @@ describe('Jest Builder', () => {
),
watch: false
},
['./jest.config.js']
['/root/jest.config.js']
);
});

View File

@ -1,11 +1,11 @@
import {
Builder,
BuildEvent,
BuilderConfiguration,
BuildEvent,
BuilderContext
} from '@angular-devkit/architect';
import { Observable, from } from 'rxjs';
import { from, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import * as path from 'path';
@ -17,32 +17,42 @@ try {
const { runCLI } = require('jest');
export interface JestBuilderOptions {
jestConfig: string;
tsConfig: string;
watch: boolean;
bail?: boolean;
ci?: boolean;
codeCoverage?: boolean;
onlyChanged?: boolean;
jestConfig: string;
testFile?: string;
setupFile?: string;
tsConfig: string;
bail?: number | boolean;
ci?: boolean;
color?: boolean;
json?: boolean;
maxWorkers?: number;
onlyChanged?: boolean;
outputFile?: string;
passWithNoTests?: boolean;
runInBand?: boolean;
setupFile?: string;
silent?: boolean;
updateSnapshot?: boolean;
testNamePattern?: string;
updateSnapshot?: boolean;
useStderr?: boolean;
watch?: boolean;
watchAll?: boolean;
}
export default class JestBuilder implements Builder<JestBuilderOptions> {
constructor(private context: BuilderContext) {}
run(
builderConfig: BuilderConfiguration<JestBuilderOptions>
): Observable<BuildEvent> {
const options = builderConfig.options;
options.jestConfig = path.resolve(
this.context.workspace.root,
options.jestConfig
);
const tsJestConfig = {
tsConfig: path.join(
'<rootDir>',
path.relative(builderConfig.root, options.tsConfig)
)
tsConfig: path.resolve(this.context.workspace.root, options.tsConfig)
};
// TODO: This is hacky, We should probably just configure it in the user's workspace
@ -56,29 +66,29 @@ export default class JestBuilder implements Builder<JestBuilderOptions> {
]
});
} catch (e) {}
const config: any = {
watch: options.watch,
coverage: options.codeCoverage,
bail: options.bail,
ci: options.ci,
updateSnapshot: options.updateSnapshot,
color: options.color,
json: options.json,
maxWorkers: options.maxWorkers,
onlyChanged: options.onlyChanged,
outputFile: options.outputFile,
passWithNoTests: options.passWithNoTests,
silent: options.silent,
runInBand: options.runInBand,
silent: options.silent,
testNamePattern: options.testNamePattern,
updateSnapshot: options.updateSnapshot,
useStderr: options.useStderr,
watch: options.watch,
watchAll: options.watchAll,
globals: JSON.stringify({
'ts-jest': tsJestConfig
})
};
if (options.maxWorkers) {
config.maxWorkers = options.maxWorkers;
}
if (options.testNamePattern) {
config.testNamePattern = options.testNamePattern;
}
if (options.setupFile) {
config.setupTestFrameworkScriptFile = path.join(
'<rootDir>',
@ -86,6 +96,10 @@ export default class JestBuilder implements Builder<JestBuilderOptions> {
);
}
if (options.testFile) {
config._ = [options.testFile];
}
return from(runCLI(config, [options.jestConfig])).pipe(
map((results: any) => {
return {

View File

@ -3,65 +3,91 @@
"description": "Jest target options for Build Facade",
"type": "object",
"properties": {
"codeCoverage": {
"description": "Indicates that test coverage information should be collected and reported in the output. (https://jestjs.io/docs/en/cli#coverage)",
"type": "boolean"
},
"jestConfig": {
"type": "string",
"description": "The path of the Jest configuration. (https://jestjs.io/docs/en/configuration.html)"
"description": "The path of the Jest configuration. (https://jestjs.io/docs/en/configuration)",
"type": "string"
},
"testFile": {
"description": "The name of the file to test.",
"type": "string"
},
"tsConfig": {
"type": "string",
"description": "The name of the Typescript configuration file."
"description": "The name of the Typescript configuration file.",
"type": "string"
},
"setupFile": {
"type": "string",
"description": "The name of a setup file used by Jest. (https://jestjs.io/docs/en/configuration.html#setuptestframeworkscriptfile-string)"
},
"watch": {
"type": "boolean",
"description": "Run tests when files change. (https://jestjs.io/docs/en/cli#watch)",
"default": false
},
"onlyChanged": {
"type": "boolean",
"alias": "o",
"description": "Isolate tests affected by uncommitted changes. (https://jestjs.io/docs/en/cli#onlychanged)"
},
"passWithNoTests": {
"type": "boolean",
"description": "Allow test suite to pass when no test files are found. (https://jestjs.io/docs/en/cli#passwithnotests)"
},
"codeCoverage": {
"type": "boolean",
"description": "Export a code coverage report. (https://jestjs.io/docs/en/cli#coverage)"
},
"updateSnapshot": {
"type": "boolean",
"alias": "u",
"description": "Re-record all failing snapshots. (https://jestjs.io/docs/en/cli#updatesnapshot)"
},
"ci": {
"type": "boolean",
"description": "Fail on missing snapshots. (https://jestjs.io/docs/en/cli#ci)"
"description": "The name of a setup file used by Jest. (https://jestjs.io/docs/en/configuration#setupfilesafterenv-array)",
"type": "string"
},
"bail": {
"type": "boolean",
"description": "Exit the test suite immediately upon the first failing test suite. (https://jestjs.io/docs/en/cli#bail)"
"alias": "b",
"description": "Exit the test suite immediately after `n` number of failing tests. (https://jestjs.io/docs/en/cli#bail)",
"type": ["number", "boolean"]
},
"silent": {
"type": "boolean",
"description": "Prevent tests from printing messages through the console. (https://jestjs.io/docs/en/cli#silent)"
"ci": {
"description": "Whether to run Jest in continuous integration (CI) mode. This option is on by default in most popular CI environments. It will prevent snapshots from being written unless explicitly requested. (https://jestjs.io/docs/en/cli#ci)",
"type": "boolean"
},
"runInBand": {
"type": "boolean",
"description": "Run tests in a single process as opposed to multiple workers. Useful for CI. (https://jestjs.io/docs/en/cli.html#runinband)"
"color": {
"description": "Forces test results output color highlighting (even if stdout is not a TTY). Set to false if you would like to have no colors. (https://jestjs.io/docs/en/cli#colors)",
"type": "boolean"
},
"json": {
"description": "Prints the test results in JSON. This mode will send all other test output and user messages to stderr. (https://jestjs.io/docs/en/cli#json)",
"type": "boolean"
},
"maxWorkers": {
"type": "number",
"description": "Max number of workers to run tests across. Useful for CI. (https://jestjs.io/docs/en/cli.html#maxworkers-num)"
"alias": "w",
"description": "Specifies the maximum number of workers the worker-pool will spawn for running tests. This defaults to the number of the cores available on your machine. Useful for CI. (its usually best not to override this default) (https://jestjs.io/docs/en/cli#maxworkers-num)",
"type": "number"
},
"onlyChanged": {
"alias": "o",
"description": "Attempts to identify which tests to run based on which files have changed in the current repository. Only works if you're running tests in a git or hg repository at the moment. (https://jestjs.io/docs/en/cli#onlychanged)",
"type": "boolean"
},
"outputFile": {
"description": "Write test results to a file when the --json option is also specified. (https://jestjs.io/docs/en/cli#outputfile-filename)",
"type": "string"
},
"passWithNoTests": {
"description": "Will not fail if no tests are found (for example while using `--testPathPattern`.) (https://jestjs.io/docs/en/cli#passwithnotests)",
"type": "boolean"
},
"runInBand": {
"alias": "i",
"description": "Run all tests serially in the current process (rather than creating a worker pool of child processes that run tests). This is sometimes useful for debugging, but such use cases are pretty rare. Useful for CI. (https://jestjs.io/docs/en/cli#runinband)",
"type": "boolean"
},
"silent": {
"description": "Prevent tests from printing messages through the console. (https://jestjs.io/docs/en/cli#silent)",
"type": "boolean"
},
"testNamePattern": {
"type": "string",
"alias": "t",
"description": "Run only tests with a name that matches the regex. (https://jestjs.io/docs/en/cli.html#testnamepattern-regex)"
"description": "Run only tests with a name that matches the regex pattern. (https://jestjs.io/docs/en/cli#testnamepattern-regex)",
"type": "string"
},
"updateSnapshot": {
"alias": "u",
"description": "Use this flag to re-record snapshots. Can be used together with a test suite pattern or with `--testNamePattern` to re-record snapshot for test matching the pattern. (https://jestjs.io/docs/en/cli#updatesnapshot)",
"type": "boolean"
},
"useStderr": {
"description": "Divert all output to stderr.",
"type": "boolean"
},
"watch": {
"description": "Watch files for changes and rerun tests related to changed files. If you want to re-run all tests when a file has changed, use the `--watchAll` option. (https://jestjs.io/docs/en/cli#watch)",
"type": "boolean"
},
"watchAll": {
"description": "Watch files for changes and rerun all tests when something changes. If you want to re-run only the tests that depend on the changed files, use the `--watch` option. (https://jestjs.io/docs/en/cli#watchall)",
"type": "boolean"
}
},
"required": ["jestConfig", "tsConfig"]