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

fix(compiler): use resolveModuleNames TypeScript API to get resolved modules for test files #1784

Merged
merged 2 commits into from Jul 8, 2020
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 0 additions & 7 deletions e2e/__cases__/diagnostics/warn/main.spec.ts

This file was deleted.

2 changes: 0 additions & 2 deletions e2e/__cases__/diagnostics/warn/main.ts

This file was deleted.

4 changes: 2 additions & 2 deletions e2e/__cases__/test-helpers/deprecated.spec.ts
@@ -1,6 +1,6 @@
import { mocked } from 'ts-jest'
import { foo } from './to-mock'
jest.mock('./to-mock')
import { foo } from './pass-to-mock'
jest.mock('./pass-to-mock')

test('foo', () => {
foo()
Expand Down
25 changes: 25 additions & 0 deletions e2e/__cases__/test-helpers/pass-to-mock.ts
@@ -0,0 +1,25 @@
export const foo = () => 'foo'

export function bar() {
return 'bar'
}
export namespace bar {
export function dummy() {
return 'dummy'
}
export namespace dummy {
export const deep = {
deeper: (one: string = '1') => `deeper ${one}`
}
}
}

export class MyClass {
constructor(s: string) {
this.myProperty = 3
this.myStr = s
}
somethingClassy() { return this.myStr }
public myProperty: number;
public myStr: string;
}
4 changes: 2 additions & 2 deletions e2e/__cases__/test-helpers/pass.spec.ts
@@ -1,6 +1,6 @@
import { mocked } from 'ts-jest/utils'
import { foo, bar, MyClass } from './to-mock'
jest.mock('./to-mock')
import { foo, bar, MyClass } from './pass-to-mock'
jest.mock('./pass-to-mock')

test('foo', () => {
// real returns 'foo', mocked returns 'bar'
Expand Down
6 changes: 3 additions & 3 deletions e2e/__tests__/__snapshots__/diagnostics.test.ts.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`With diagnostics throw should fail using template "default" 1`] = `
× jest
× jest --no-cache
↳ exit code: 1
===[ STDOUT ]===================================================================

Expand All @@ -28,7 +28,7 @@ exports[`With diagnostics throw should fail using template "default" 1`] = `
`;

exports[`With diagnostics throw should fail using template "with-babel-7" 1`] = `
× jest
× jest --no-cache
↳ exit code: 1
===[ STDOUT ]===================================================================

Expand All @@ -55,7 +55,7 @@ exports[`With diagnostics throw should fail using template "with-babel-7" 1`] =
`;

exports[`With diagnostics throw should fail using template "with-babel-7-string-config" 1`] = `
× jest
× jest --no-cache
↳ exit code: 1
===[ STDOUT ]===================================================================

Expand Down
6 changes: 4 additions & 2 deletions e2e/__tests__/diagnostics.test.ts
Expand Up @@ -2,7 +2,9 @@ import { allValidPackageSets } from '../__helpers__/templates'
import { configureTestCase } from '../__helpers__/test-case'

describe('With diagnostics throw', () => {
const testCase = configureTestCase('diagnostics/throw')
const testCase = configureTestCase('diagnostics', {
noCache: true, // warnings shown only on first compilation
})

testCase.runWithTemplates(allValidPackageSets, 1, (runTest, { testLabel }) => {
it(testLabel, () => {
Expand All @@ -14,7 +16,7 @@ describe('With diagnostics throw', () => {
})

describe('With diagnostics warn only', () => {
const testCase = configureTestCase('diagnostics/warn', {
const testCase = configureTestCase('diagnostics', {
tsJestConfig: {
diagnostics: { warnOnly: true },
},
Expand Down
44 changes: 35 additions & 9 deletions src/__helpers__/fakers.ts
Expand Up @@ -26,7 +26,7 @@ export function tsJestConfig(options?: Partial<TsJestConfig>): TsJestConfig {
}
}

export function getJestConfig<T extends Config.ProjectConfig>(
function getJestConfig<T extends Config.ProjectConfig>(
options?: Partial<Config.InitialOptions | Config.ProjectConfig>,
tsJestOptions?: TsJestGlobalOptions,
): T {
Expand All @@ -53,6 +53,39 @@ export function importReason(text = '[[BECAUSE]]'): ImportReasons {
return text as any
}

export const defaultResolve = (path: string): string => `resolved:${path}`

export function createConfigSet({
jestConfig,
tsJestConfig,
parentConfig,
resolve = defaultResolve,
...others
}: {
jestConfig?: Partial<Config.ProjectConfig>
tsJestConfig?: TsJestGlobalOptions
parentConfig?: TsJestGlobalOptions
resolve?: ((path: string) => string) | null
[key: string]: any
} = {}): ConfigSet {
const defaultTestRegex = ['(/__tests__/.*|(\\\\.|/)(test|spec))\\\\.[jt]sx?$']
const defaultTestMatch = ['**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[jt]s?(x)']
jestConfig = {
...jestConfig,
testMatch: jestConfig?.testMatch ? [...jestConfig.testMatch, ...defaultTestMatch] : defaultTestMatch,
testRegex: jestConfig?.testRegex ? [...defaultTestRegex, ...jestConfig.testRegex] : defaultTestRegex,
}
const cs = new ConfigSet(getJestConfig(jestConfig, tsJestConfig), parentConfig)
if (resolve) {
cs.resolvePath = resolve
}
Object.keys(others).forEach((key) => {
Object.defineProperty(cs, key, { value: others[key] })
})

return cs
}

// not really unit-testing here, but it's hard to mock all those values :-D
export function makeCompiler({
jestConfig,
Expand All @@ -68,14 +101,7 @@ export function makeCompiler({
...(tsJestConfig.diagnostics as any),
pretty: false,
}
const testRegex = ['^.+\\.[tj]sx?$']
const testMatch = ['^.+\\.tsx?$']
jestConfig = {
...jestConfig,
testMatch: jestConfig?.testMatch ? [...jestConfig.testMatch, ...testMatch] : testMatch,
testRegex: jestConfig?.testRegex ? [...testRegex, ...jestConfig.testRegex] : testRegex,
}
const cs = new ConfigSet(getJestConfig(jestConfig, tsJestConfig), parentConfig)
const cs = createConfigSet({ jestConfig, tsJestConfig, parentConfig, resolve: null })

return createCompilerInstance(cs)
}
3 changes: 0 additions & 3 deletions src/__mocks__/changed-modules/main.spec.ts

This file was deleted.

3 changes: 0 additions & 3 deletions src/__mocks__/changed-modules/main.ts

This file was deleted.

4 changes: 1 addition & 3 deletions src/__mocks__/thing.spec.ts
@@ -1,5 +1,3 @@
interface Thing {
a: number
}
import { Thing } from './thing'

export const thing: Thing = { a: 1 }
@@ -1,3 +1,4 @@
export interface Thing {
a: number
b: number
}
3 changes: 3 additions & 0 deletions src/__mocks__/thing1.spec.ts
@@ -0,0 +1,3 @@
import { Thing } from './thing'

export const thing: Thing = { a: 1, b: 2 }
3 changes: 0 additions & 3 deletions src/__mocks__/unchanged-modules/main.spec.ts

This file was deleted.

86 changes: 78 additions & 8 deletions src/compiler/__snapshots__/language-service.spec.ts.snap
Expand Up @@ -36,7 +36,84 @@ exports[`Language service allowJs option should compile js file for allowJs true
================================================================================
`;

exports[`Language service diagnostics should report diagnostics related to typings with pathRegex config matches file name 1`] = `"test-diagnostics.ts(3,7): error TS2322: Type 'number' is not assignable to type 'string'."`;
exports[`Language service diagnostics should only report diagnostics for imported modules but not test files without cache 1`] = `
Array [
"[level:20] compileAndUpdateOutput(): get compile output
",
"[level:20] compileFn(): compiling using language service
",
"[level:20] updateMemoryCache(): update memory cache for language service
",
"[level:20] visitSourceFileNode(): hoisting
",
"[level:20] compileFn(): computing diagnostics using language service
",
]
`;

exports[`Language service diagnostics should report diagnostics for imported modules as well as test files which use imported modules with cache 1`] = `
Array [
"[level:20] compileAndUpdateOutput(): get compile output
",
"[level:20] compileFn(): compiling using language service
",
"[level:20] updateMemoryCache(): update memory cache for language service
",
"[level:20] visitSourceFileNode(): hoisting
",
"[level:20] compileFn(): computing diagnostics using language service
",
"[level:20] updateMemoryCache(): update memory cache for language service
",
"[level:20] compileFn(): computing diagnostics using language service for test file which uses the module
",
]
`;

exports[`Language service diagnostics should throw error when cannot compile 1`] = `
"Unable to require \`.d.ts\` file for file: test-cannot-compile.d.ts.
This is usually the result of a faulty configuration or import. Make sure there is a \`.js\`, \`.json\` or another executable extension available alongside \`test-cannot-compile.d.ts\`."
`;

exports[`Language service diagnostics shouldn't report diagnostic when processing file isn't used by any test files 1`] = `
Array [
"[level:20] compileAndUpdateOutput(): get compile output
",
"[level:20] compileFn(): compiling using language service
",
"[level:20] updateMemoryCache(): update memory cache for language service
",
"[level:20] visitSourceFileNode(): hoisting
",
"[level:20] compileFn(): computing diagnostics using language service
",
]
`;

exports[`Language service diagnostics shouldn't report diagnostics for test file name that has been type checked before 1`] = `
Array [
"[level:20] compileAndUpdateOutput(): get compile output
",
"[level:20] compileFn(): compiling using language service
",
"[level:20] updateMemoryCache(): update memory cache for language service
",
"[level:20] visitSourceFileNode(): hoisting
",
"[level:20] compileFn(): computing diagnostics using language service
",
"[level:20] compileAndUpdateOutput(): get compile output
",
"[level:20] compileFn(): compiling using language service
",
"[level:20] updateMemoryCache(): update memory cache for language service
",
"[level:20] visitSourceFileNode(): hoisting
",
"[level:20] compileFn(): computing diagnostics using language service
",
]
`;

exports[`Language service jsx option should compile tsx file for jsx preserve 1`] = `
===[ FILE: test-jsx.tsx ]=======================================================
Expand Down Expand Up @@ -85,10 +162,3 @@ exports[`Language service jsx option should compile tsx file for other jsx optio
version: 3
================================================================================
`;

exports[`Language service should do type check for the test file when imported module has changed 1`] = `"src/__mocks__/changed-modules/main.spec.ts(3,14): error TS2741: Property 'b' is missing in type '{ a: number; }' but required in type 'Thing'."`;

exports[`Language service should throw error when cannot compile 1`] = `
"Unable to require \`.d.ts\` file for file: test-cannot-compile.d.ts.
This is usually the result of a faulty configuration or import. Make sure there is a \`.js\`, \`.json\` or another executable extension available alongside \`test-cannot-compile.d.ts\`."
`;
52 changes: 0 additions & 52 deletions src/compiler/compiler-utils.ts

This file was deleted.