Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle typescript by default #7533

Merged
merged 3 commits into from
Dec 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- `[jest-haste-map]` [**BREAKING**] Remove name from hash in `HasteMap.getCacheFilePath` ([#7218](https://github.com/facebook/jest/pull/7218))
- `[babel-preset-jest]` [**BREAKING**] Export a function instead of an object for Babel 7 compatibility ([#7203](https://github.com/facebook/jest/pull/7203))
- `[jest-haste-map]` [**BREAKING**] Expose relative paths when getting the file iterator ([#7321](https://github.com/facebook/jest/pull/7321))
- `[jest-config]` Handle typescript (`ts` and `tsx`) by default ([#7533](https://github.com/facebook/jest/pull/7533))
- `[jest-validate]` Add support for comments in `package.json` using a `"//"` key ([#7295](https://github.com/facebook/jest/pull/7295))
- `[jest-config]` Add shorthand for watch plugins and runners ([#7213](https://github.com/facebook/jest/pull/7213))
- `[jest-jasmine2/jest-circus/jest-cli]` Add test.todo ([#6996](https://github.com/facebook/jest/pull/6996))
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ Jest can be used in projects that use [webpack](https://webpack.js.org/) to mana

### Using TypeScript

To use TypeScript in your tests you can use [ts-jest](https://github.com/kulshekhar/ts-jest).
To use TypeScript in your tests install `@babel/preset-typescript` and add it to your Babel config.

<!-- generated_getting_started_end -->

Expand Down
12 changes: 5 additions & 7 deletions docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,12 +367,10 @@ An array of directory names to be searched recursively up from the requiring mod

### `moduleFileExtensions` [array<string>]

Default: `["js", "json", "jsx", "node"]`
Default: `["js", "json", "jsx", "ts", "tsx", "node"]`

An array of file extensions your modules use. If you require modules without specifying a file extension, these are the extensions Jest will look for.

If you are using TypeScript this should be `["js", "jsx", "json", "ts", "tsx"]`, check [ts-jest's documentation](https://github.com/kulshekhar/ts-jest).

### `moduleNameMapper` [object<string, string>]

Default: `null`
Expand Down Expand Up @@ -832,9 +830,9 @@ Test environment options that will be passed to the `testEnvironment`. The relev

### `testMatch` [array<string>]

(default: `[ "**/__tests__/**/*.js?(x)", "**/?(*.)+(spec|test).js?(x)" ]`)
(default: `[ "**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)" ]`)

The glob patterns Jest uses to detect test files. By default it looks for `.js` and `.jsx` files inside of `__tests__` folders, as well as any files with a suffix of `.test` or `.spec` (e.g. `Component.test.js` or `Component.spec.js`). It will also find files called `test.js` or `spec.js`.
The glob patterns Jest uses to detect test files. By default it looks for `.js`, `.jsx`, `.ts` and `.tsx` files inside of `__tests__` folders, as well as any files with a suffix of `.test` or `.spec` (e.g. `Component.test.js` or `Component.spec.js`). It will also find files called `test.js` or `spec.js`.

See the [micromatch](https://github.com/jonschlinkert/micromatch) package for details of the patterns you can specify.

Expand All @@ -850,9 +848,9 @@ These pattern strings match against the full path. Use the `<rootDir>` string to

### `testRegex` [string | Array<string>]

Default: `(/__tests__/.*|(\\.|/)(test|spec))\\.jsx?$`
Default: `(/__tests__/.*|(\\.|/)(test|spec))\\.[jt]sx?$`

The pattern or patterns Jest uses to detect test files. By default it looks for `.js` and `.jsx` files inside of `__tests__` folders, as well as any files with a suffix of `.test` or `.spec` (e.g. `Component.test.js` or `Component.spec.js`). It will also find files called `test.js` or `spec.js`. See also [`testMatch` [array<string>]](#testmatch-array-string), but note that you cannot specify both options.
The pattern or patterns Jest uses to detect test files. By default it looks for `.js`, `.jsx`, `.ts` and `.tsx` files inside of `__tests__` folders, as well as any files with a suffix of `.test` or `.spec` (e.g. `Component.test.js` or `Component.spec.js`). It will also find files called `test.js` or `spec.js`. See also [`testMatch` [array<string>]](#testmatch-array-string), but note that you cannot specify both options.

The following is a visualization of the default regex:

Expand Down
4 changes: 3 additions & 1 deletion docs/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,6 @@ Jest can be used in projects that use [webpack](https://webpack.github.io/) to m

### Using TypeScript

To use TypeScript in your tests you can use [ts-jest](https://github.com/kulshekhar/ts-jest).
Jest supports TypeScript out of the box, via Babel.

However, there are some caveats to using Typescript with Babel, see http://artsy.github.io/blog/2017/11/27/Babel-7-and-TypeScript/. Another caveat is that Jest will not typecheck your tests. If you want that, you can use [ts-jest](https://github.com/kulshekhar/ts-jest).
8 changes: 5 additions & 3 deletions e2e/__tests__/__snapshots__/show_config.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ exports[`--showConfig outputs config info and exits 1`] = `
\\"js\\",
\\"json\\",
\\"jsx\\",
\\"ts\\",
\\"tsx\\",
\\"node\\"
],
\\"moduleNameMapper\\": {},
Expand All @@ -54,8 +56,8 @@ exports[`--showConfig outputs config info and exits 1`] = `
\\"testEnvironmentOptions\\": {},
\\"testLocationInResults\\": false,
\\"testMatch\\": [
\\"**/__tests__/**/*.js?(x)\\",
\\"**/?(*.)+(spec|test).js?(x)\\"
\\"**/__tests__/**/*.[jt]s?(x)\\",
\\"**/?(*.)+(spec|test).[tj]s?(x)\\"
],
\\"testPathIgnorePatterns\\": [
\\"/node_modules/\\"
Expand All @@ -66,7 +68,7 @@ exports[`--showConfig outputs config info and exits 1`] = `
\\"timers\\": \\"real\\",
\\"transform\\": [
[
\\"^.+\\\\\\\\.jsx?$\\",
\\"^.+\\\\\\\\.[jt]sx?$\\",
\\"<<REPLACED_JEST_PACKAGES_DIR>>/babel-jest/build/index.js\\"
]
],
Expand Down
13 changes: 0 additions & 13 deletions examples/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,5 @@
},
"scripts": {
"test": "jest"
},
"jest": {
Copy link
Member Author

@SimenB SimenB Dec 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is my "test plan". The tests still run (and pass)

"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"transform": {
"^.+\\.(ts|tsx)$": "babel-jest"
},
"testMatch": [
"**/__tests__/*.+(ts|tsx|js)"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ module.exports = {
// \\"js\\",
// \\"json\\",
// \\"jsx\\",
// \\"ts\\",
// \\"tsx\\",
// \\"node\\"
// ],

Expand Down Expand Up @@ -158,8 +160,8 @@ module.exports = {

// The glob patterns Jest uses to detect test files
// testMatch: [
// \\"**/__tests__/**/*.js?(x)\\",
// \\"**/?(*.)+(spec|test).js?(x)\\"
// \\"**/__tests__/**/*.[jt]s?(x)\\",
// \\"**/?(*.)+(spec|test).[tj]s?(x)\\"
// ],

// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
Expand Down Expand Up @@ -214,42 +216,3 @@ exports[`init project with package.json and no jest config some questions answer
}
"
`;

exports[`init typescript project should ask "typescript question" when has typescript in dependencies 1`] = `
Object {
"initial": true,
"message": "Typescript detected, would you like to setup Jest for Typescript?",
"name": "typescript",
"type": "confirm",
}
`;

exports[`init typescript project should ask "typescript question" when has typescript in devDependencies 1`] = `
Object {
"initial": true,
"message": "Typescript detected, would you like to setup Jest for Typescript?",
"name": "typescript",
"type": "confirm",
}
`;

exports[`init typescript project should create configuration for {typescript: true} 1`] = `
Object {
"globals": Object {
"ts-jest": Object {
"tsConfigFile": "tsconfig.json",
},
},
"moduleFileExtensions": Array [
"ts",
"tsx",
"js",
],
"testMatch": Array [
"**/__tests__/*.+(ts|tsx|js)",
],
"transform": Object {
"^.+\\\\.(ts|tsx)$": "ts-jest",
},
}
`;
33 changes: 0 additions & 33 deletions packages/jest-cli/src/lib/__tests__/init.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,37 +181,4 @@ describe('init', () => {
expect(questionsNames).not.toContain('scripts');
});
});

describe('typescript project', () => {
it('should ask "typescript question" when has typescript in dependencies', async () => {
prompts.mockReturnValueOnce({});

await init(resolveFromFixture('typescript_in_dependencies'));

const typescriptQuestion = prompts.mock.calls[0][0][0];

expect(typescriptQuestion).toMatchSnapshot();
});

it('should ask "typescript question" when has typescript in devDependencies', async () => {
prompts.mockReturnValueOnce({});

await init(resolveFromFixture('typescript_in_dev_dependencies'));

const typescriptQuestion = prompts.mock.calls[0][0][0];

expect(typescriptQuestion).toMatchSnapshot();
});

it('should create configuration for {typescript: true}', async () => {
prompts.mockReturnValueOnce({typescript: true});

await init(resolveFromFixture('typescript_in_dev_dependencies'));

const writtenJestConfig = fs.writeFileSync.mock.calls[0][1];
const evaluatedConfig = eval(writtenJestConfig);

expect(evaluatedConfig).toMatchSnapshot();
});
});
});
17 changes: 1 addition & 16 deletions packages/jest-cli/src/lib/init/generate_config_file.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,10 @@ const stringifyOption = (
};

const generateConfigFile = (results: {[string]: boolean}): string => {
const {typescript, coverage, clearMocks, environment} = results;
const {coverage, clearMocks, environment} = results;

const overrides: Object = {};

if (typescript) {
Object.assign(overrides, {
globals: {
'ts-jest': {
tsConfigFile: 'tsconfig.json',
},
},
moduleFileExtensions: ['ts', 'tsx', 'js'],
testMatch: ['**/__tests__/*.+(ts|tsx|js)'],
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest',
},
});
}

if (coverage) {
Object.assign(overrides, {
coverageDirectory: 'coverage',
Expand Down
19 changes: 1 addition & 18 deletions packages/jest-cli/src/lib/init/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ import chalk from 'chalk';
import fs from 'fs';
import path from 'path';
import prompts from 'prompts';
import defaultQuestions, {
typescriptQuestion,
testScriptQuestion,
} from './questions';
import defaultQuestions, {testScriptQuestion} from './questions';
import {NotFoundPackageJsonError, MalformedPackageJsonError} from './errors';
import {PACKAGE_JSON, JEST_CONFIG} from '../../constants';
import generateConfigFile from './generate_config_file';
Expand All @@ -25,7 +22,6 @@ type PromptsResults = {
coverage: boolean,
environment: boolean,
scripts: boolean,
typescript: boolean,
};

export default async (rootDir: string = process.cwd()) => {
Expand Down Expand Up @@ -82,19 +78,6 @@ export default async (rootDir: string = process.cwd()) => {
questions.unshift(testScriptQuestion);
}

// Try to detect typescript and add a question if needed
const deps: Object = {};

Object.assign(
deps,
projectPackageJson.dependencies,
projectPackageJson.devDependencies,
);

if (Object.keys(deps).includes('typescript')) {
questions.unshift(typescriptQuestion);
}

// Start the init process
console.log();
console.log(
Expand Down
7 changes: 0 additions & 7 deletions packages/jest-cli/src/lib/init/questions.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,3 @@ export const testScriptQuestion: Question = {
name: 'scripts',
type: 'confirm',
};

export const typescriptQuestion: Question = {
initial: true,
message: 'Typescript detected, would you like to setup Jest for Typescript?',
name: 'typescript',
type: 'confirm',
};
4 changes: 2 additions & 2 deletions packages/jest-config/src/Defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default ({
providesModuleNodeModules: [],
},
moduleDirectories: ['node_modules'],
moduleFileExtensions: ['js', 'json', 'jsx', 'node'],
moduleFileExtensions: ['js', 'json', 'jsx', 'ts', 'tsx', 'node'],
moduleNameMapper: {},
modulePathIgnorePatterns: [],
noStackTrace: false,
Expand All @@ -70,7 +70,7 @@ export default ({
testEnvironmentOptions: {},
testFailureExitCode: 1,
testLocationInResults: false,
testMatch: ['**/__tests__/**/*.js?(x)', '**/?(*.)+(spec|test).js?(x)'],
testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[tj]s?(x)'],
testPathIgnorePatterns: [NODE_MODULES_REGEXP],
testRegex: [],
testResultsProcessor: null,
Expand Down
8 changes: 4 additions & 4 deletions packages/jest-config/src/ValidConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default ({
lastCommit: false,
logHeapUsage: true,
moduleDirectories: ['node_modules'],
moduleFileExtensions: ['js', 'json', 'jsx', 'node'],
moduleFileExtensions: ['js', 'json', 'jsx', 'ts', 'tsx', 'node'],
moduleLoader: '<rootDir>',
moduleNameMapper: {
'^React$': '<rootDir>/node_modules/react',
Expand Down Expand Up @@ -100,12 +100,12 @@ export default ({
testEnvironmentOptions: {userAgent: 'Agent/007'},
testFailureExitCode: 1,
testLocationInResults: false,
testMatch: ['**/__tests__/**/*.js?(x)', '**/?(*.)+(spec|test).js?(x)'],
testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)'],
testNamePattern: 'test signature',
testPathIgnorePatterns: [NODE_MODULES_REGEXP],
testRegex: multipleValidOptions(
'(/__tests__/.*|(\\.|/)(test|spec))\\.jsx?$',
['/__tests__/\\.test\\.jsx?$', '/__tests__/\\.spec\\.jsx?$'],
'(/__tests__/.*|(\\.|/)(test|spec))\\.[jt]sx?$',
['/__tests__/\\.test\\.[jt]sx?$', '/__tests__/\\.spec\\.[jt]sx?$'],
),
testResultsProcessor: 'processor-node-module',
testRunner: 'jasmine2',
Expand Down
9 changes: 8 additions & 1 deletion packages/jest-config/src/__tests__/normalize.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1456,7 +1456,14 @@ describe('moduleFileExtensions', () => {
it('defaults to something useful', () => {
const {options} = normalize({rootDir: '/root'}, {});

expect(options.moduleFileExtensions).toEqual(['js', 'json', 'jsx', 'node']);
expect(options.moduleFileExtensions).toEqual([
'js',
'json',
'jsx',
'ts',
'tsx',
'node',
]);
});

it('throws if missing `js`', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-config/src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import path from 'path';

export const NODE_MODULES = path.sep + 'node_modules' + path.sep;
export const DEFAULT_JS_PATTERN = '^.+\\.jsx?$';
export const DEFAULT_JS_PATTERN = '^.+\\.[jt]sx?$';
export const DEFAULT_REPORTER_LABEL = 'default';
export const PACKAGE_JSON = 'package.json';
export const JEST_CONFIG = 'jest.config.js';
15 changes: 15 additions & 0 deletions packages/jest-config/src/normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ const setupBabelJest = (options: InitialOptions) => {
const regex = new RegExp(pattern);
return regex.test('a.js') || regex.test('a.jsx');
});
const customTSPattern = Object.keys(transform).find(pattern => {
const regex = new RegExp(pattern);
return regex.test('a.ts') || regex.test('a.tsx');
});

if (customJSPattern) {
const customJSTransformer = transform[customJSPattern];
Expand All @@ -148,6 +152,17 @@ const setupBabelJest = (options: InitialOptions) => {
babelJest = customJSTransformer;
}
}

if (customTSPattern) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure about this one. Is this correct?

Copy link
Collaborator

@thymikee thymikee Dec 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couldn't we just extend the customJSPattern check?

const customPattern = Object.keys(transform).find(pattern => {
  const regex = new RegExp(pattern);
  return regex.test('a.js') || regex.test('a.jsx') || regex.test('a.ts') || regex.test('a.tsx');
});

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that doesn't make sense

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if there are different patterns for js and ts, such as ts-jest?

const customTSTransformer = transform[customTSPattern];

if (customTSTransformer === 'babel-jest') {
babelJest = require.resolve('babel-jest');
transform[customTSPattern] = babelJest;
} else if (customTSTransformer.includes('babel-jest')) {
babelJest = customTSTransformer;
}
}
} else {
babelJest = require.resolve('babel-jest');
options.transform = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ exports[`Runtime requireModule with no extension throws error pointing out file
However, Jest was able to find:
'./RegularModuleWithWrongExt.txt'

You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'node'].
You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].

See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string"
`;
Loading