Skip to content

Commit

Permalink
fix: burst cache when file’s deps change (#2167)
Browse files Browse the repository at this point in the history
Construct cache key with additional information is resolved module name + resolved module's last modified time. When one of imported modules of a file changes, the file needs to be reprocessed to have type check properly

Closes #2118
Closes #1122
Closes #943
  • Loading branch information
ahnpnl committed Dec 7, 2020
1 parent f32ca9a commit ec70365
Show file tree
Hide file tree
Showing 9 changed files with 351 additions and 364 deletions.
18 changes: 15 additions & 3 deletions e2e/__tests__/__snapshots__/logger.test.ts.snap
Expand Up @@ -20,14 +20,18 @@ Array [
"[level:20] normalized typescript config via ts-jest option",
"[level:20] normalized custom AST transformers via ts-jest option",
"[level:20] file caching disabled",
"[level:20] created language service",
"[level:20] computing cache key for <cwd>/Hello.spec.ts",
"[level:20] getting resolved modules from TypeScript API for <cwd>/Hello.spec.ts",
"[level:20] updateMemoryCache: update memory cache for language service",
"[level:20] processing <cwd>/Hello.spec.ts",
"[level:20] created language service",
"[level:20] getCompiledOutput(): compiling using language service",
"[level:20] updateMemoryCache: update memory cache for language service",
"[level:20] visitSourceFileNode(): hoisting",
"[level:20] getCompiledOutput(): computing diagnostics using language service",
"[level:20] computing cache key for <cwd>/Hello.ts",
"[level:20] getting resolved modules from TypeScript API for <cwd>/Hello.ts",
"[level:20] updateMemoryCache: update memory cache for language service",
"[level:20] processing <cwd>/Hello.ts",
"[level:20] getCompiledOutput(): compiling using language service",
"[level:20] updateMemoryCache: update memory cache for language service",
Expand Down Expand Up @@ -60,15 +64,19 @@ Array [
"[level:20] normalized typescript config via ts-jest option",
"[level:20] normalized custom AST transformers via ts-jest option",
"[level:20] file caching disabled",
"[level:20] created language service",
"[level:20] computing cache key for <cwd>/Hello.spec.ts",
"[level:20] getting resolved modules from TypeScript API for <cwd>/Hello.spec.ts",
"[level:20] updateMemoryCache: update memory cache for language service",
"[level:20] processing <cwd>/Hello.spec.ts",
"[level:20] created language service",
"[level:20] getCompiledOutput(): compiling using language service",
"[level:20] updateMemoryCache: update memory cache for language service",
"[level:20] visitSourceFileNode(): hoisting",
"[level:20] getCompiledOutput(): computing diagnostics using language service",
"[level:20] calling babel-jest processor",
"[level:20] computing cache key for <cwd>/Hello.ts",
"[level:20] getting resolved modules from TypeScript API for <cwd>/Hello.ts",
"[level:20] updateMemoryCache: update memory cache for language service",
"[level:20] processing <cwd>/Hello.ts",
"[level:20] getCompiledOutput(): compiling using language service",
"[level:20] updateMemoryCache: update memory cache for language service",
Expand Down Expand Up @@ -103,15 +111,19 @@ Array [
"[level:20] normalized typescript config via ts-jest option",
"[level:20] normalized custom AST transformers via ts-jest option",
"[level:20] file caching disabled",
"[level:20] created language service",
"[level:20] computing cache key for <cwd>/Hello.spec.ts",
"[level:20] getting resolved modules from TypeScript API for <cwd>/Hello.spec.ts",
"[level:20] updateMemoryCache: update memory cache for language service",
"[level:20] processing <cwd>/Hello.spec.ts",
"[level:20] created language service",
"[level:20] getCompiledOutput(): compiling using language service",
"[level:20] updateMemoryCache: update memory cache for language service",
"[level:20] visitSourceFileNode(): hoisting",
"[level:20] getCompiledOutput(): computing diagnostics using language service",
"[level:20] calling babel-jest processor",
"[level:20] computing cache key for <cwd>/Hello.ts",
"[level:20] getting resolved modules from TypeScript API for <cwd>/Hello.ts",
"[level:20] updateMemoryCache: update memory cache for language service",
"[level:20] processing <cwd>/Hello.ts",
"[level:20] getCompiledOutput(): compiling using language service",
"[level:20] updateMemoryCache: update memory cache for language service",
Expand Down
62 changes: 0 additions & 62 deletions src/compiler/__snapshots__/ts-compiler.spec.ts.snap
Expand Up @@ -36,49 +36,6 @@ exports[`TsCompiler isolatedModule false allowJs option should compile js file f
================================================================================
`;

exports[`TsCompiler isolatedModule false diagnostics should not report diagnostics for test file which doesn't exist when compiling import module file 1`] = `
Array [
"[level:20] getCompiledOutput(): compiling using language service
",
"[level:20] updateMemoryCache: update memory cache for language service
",
"[level:20] visitSourceFileNode(): hoisting
",
"[level:20] getCompiledOutput(): computing diagnostics using language service
",
]
`;

exports[`TsCompiler isolatedModule false diagnostics should only report diagnostics for imported modules but not test files without cache 1`] = `
Array [
"[level:20] getCompiledOutput(): compiling using language service
",
"[level:20] updateMemoryCache: update memory cache for language service
",
"[level:20] visitSourceFileNode(): hoisting
",
"[level:20] getCompiledOutput(): computing diagnostics using language service
",
]
`;

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

exports[`TsCompiler isolatedModule false 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\`."
Expand All @@ -97,25 +54,6 @@ Array [
]
`;

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

exports[`TsCompiler isolatedModule false jsx option should compile tsx file for jsx preserve 1`] = `
===[ FILE: test-jsx.tsx ]=======================================================
"use strict";
Expand Down
129 changes: 1 addition & 128 deletions src/compiler/ts-compiler.spec.ts
@@ -1,7 +1,5 @@
import { readFileSync, renameSync } from 'fs'
import { readFileSync } from 'fs'
import { LogLevels } from 'bs-logger'
import { removeSync } from 'fs-extra'
import { join } from 'path'

import { TS_JEST_OUT_DIR } from '../config/config-set'
import { makeCompiler } from '../__helpers__/fakers'
Expand Down Expand Up @@ -284,131 +282,6 @@ const t: string = f(5)
const importedFileName = require.resolve('../__mocks__/thing.ts')
const importedFileContent = readFileSync(importedFileName, 'utf-8')

it(`should report diagnostics for imported modules as well as test files which use imported modules with cache`, async () => {
const testFileName = require.resolve('../__mocks__/thing1.spec.ts')
const testFileContent = readFileSync(testFileName, 'utf-8')
const cacheDir = join(process.cwd(), 'tmp')
/**
* Run the 1st compilation with Promise resolve setTimeout to stimulate 2 different test runs to test cached
* resolved modules
*/
async function firstCompile() {
return new Promise<void>((resolve) => {
const compiler1 = makeCompiler({
jestConfig: {
cache: true,
cacheDirectory: cacheDir,
},
tsJestConfig: baseTsJestConfig,
})

logTarget.clear()
compiler1.getCompiledOutput(testFileContent, testFileName)

// probably 300ms is enough to stimulate 2 separated runs after each other
setTimeout(() => resolve(), 300)
})
}

await firstCompile()

const compiler2 = makeCompiler({
jestConfig: {
cache: true,
cacheDirectory: cacheDir,
},
tsJestConfig: baseTsJestConfig,
})
logTarget.clear()

compiler2.getCompiledOutput(importedFileContent, importedFileName)

expect(logTarget.filteredLines(LogLevels.debug, Infinity)).toMatchSnapshot()

removeSync(cacheDir)
})

it(`should not report diagnostics for test file which doesn't exist when compiling import module file`, async () => {
const testFileName = require.resolve('../__mocks__/thing.spec.ts')
const testFileContent = readFileSync(testFileName, 'utf-8')
const cacheDir = join(process.cwd(), 'tmp')
/**
* Run the 1st compilation with Promise resolve setTimeout to stimulate 2 different test runs to test cached
* resolved modules
*/
async function firstCompile() {
return new Promise<void>((resolve) => {
const compiler1 = makeCompiler({
jestConfig: {
cache: true,
cacheDirectory: cacheDir,
},
tsJestConfig: baseTsJestConfig,
})

logTarget.clear()
compiler1.getCompiledOutput(testFileContent, testFileName)

// probably 300ms is enough to stimulate 2 separated runs after each other
setTimeout(() => resolve(), 300)
})
}

await firstCompile()

const newTestFileName = testFileName.replace('thing', 'thing2')
renameSync(testFileName, newTestFileName)

const compiler2 = makeCompiler({
jestConfig: {
cache: true,
cacheDirectory: cacheDir,
},
tsJestConfig: baseTsJestConfig,
})
logTarget.clear()

compiler2.getCompiledOutput(importedFileContent, importedFileName)

expect(logTarget.filteredLines(LogLevels.debug, Infinity)).toMatchSnapshot()

renameSync(newTestFileName, testFileName)
removeSync(cacheDir)
})

it(`should only report diagnostics for imported modules but not test files without cache`, () => {
const testFileName = require.resolve('../__mocks__/thing1.spec.ts')
const testFileContent = readFileSync(testFileName, 'utf-8')
const compiler1 = makeCompiler({
tsJestConfig: baseTsJestConfig,
})
logTarget.clear()
compiler1.getCompiledOutput(testFileContent, testFileName)

const compiler2 = makeCompiler({
tsJestConfig: baseTsJestConfig,
})
logTarget.clear()

compiler2.getCompiledOutput(importedFileContent, importedFileName)

expect(logTarget.filteredLines(LogLevels.debug, Infinity)).toMatchSnapshot()
})

it(`shouldn't report diagnostics for test file name that has been type checked before`, () => {
const testFileName = require.resolve('../__mocks__/thing1.spec.ts')
const testFileContent = readFileSync(testFileName, 'utf-8')
const compiler1 = makeCompiler({
tsJestConfig: baseTsJestConfig,
})
logTarget.clear()

compiler1.getCompiledOutput(testFileContent, testFileName)
compiler1.getCompiledOutput(testFileContent, testFileName)

expect(logTarget.filteredLines(LogLevels.debug, Infinity)).toMatchSnapshot()
})

it(`shouldn't report diagnostics when file name doesn't match diagnostic file pattern`, () => {
const compiler = makeCompiler({
tsJestConfig: {
Expand Down

0 comments on commit ec70365

Please sign in to comment.