Skip to content

Commit

Permalink
feat(config): specify package.json location (kulshekhar#823)
Browse files Browse the repository at this point in the history
  • Loading branch information
JD Huntington committed Mar 4, 2019
1 parent 2dc4576 commit e3d0d8c
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/__helpers__/fakers.ts
Expand Up @@ -60,6 +60,7 @@ export function tsJestConfig(options?: Partial<TsJestConfig>): TsJestConfig {
transformers: [],
babelConfig: undefined,
tsConfig: undefined,
packageJson: undefined,
stringifyContentPathRegex: undefined,
diagnostics: { ignoreCodes: [], pretty: false, throws: true },
...options,
Expand Down
4 changes: 4 additions & 0 deletions src/config/__snapshots__/config-set.spec.ts.snap
Expand Up @@ -32,6 +32,10 @@ Object {
"throws": true,
},
"isolatedModules": false,
"packageJson": Object {
"kind": "file",
"value": undefined,
},
"stringifyContentPathRegex": undefined,
"transformers": Array [],
"tsConfig": Object {
Expand Down
34 changes: 33 additions & 1 deletion src/config/config-set.spec.ts
Expand Up @@ -103,6 +103,34 @@ describe('tsJest', () => {
})
}) // tsconfig

describe('packageJson', () => {
it('should be correct for default value', () => {
const EXPECTED = {
kind: 'file',
value: undefined,
}
expect(get().packageJson).toEqual(EXPECTED)
})

it('should be correct for given file', () => {
const FILE = 'bar/tsconfig.foo.json'
const EXPECTED = {
kind: 'file',
value: defaultResolve(FILE),
}
expect(get({ packageJson: FILE }).packageJson).toEqual(EXPECTED)
})

it('should be correct for inline config', () => {
const CONFIG = { foo: 'bar' }
const EXPECTED = {
kind: 'inline',
value: CONFIG,
}
expect(get({ packageJson: CONFIG as any }).packageJson).toEqual(EXPECTED)
})
}) // packageJson

describe('babelConfig', () => {
it('should be correct for default value', () => {
expect(get().babelConfig).toBeUndefined()
Expand Down Expand Up @@ -532,7 +560,7 @@ describe('cacheKey', () => {
cs.jsonValue.value = val
// digest is mocked in src/__mocks__/index.ts
expect(cs.cacheKey).toMatchInlineSnapshot(
'"{\\"digest\\":\\"a0d51ca854194df8191d0e65c0ca4730f510f332\\",\\"jest\\":{\\"__backported\\":true,\\"globals\\":{}},\\"projectDepVersions\\":{\\"dev\\":\\"1.2.5\\",\\"opt\\":\\"1.2.3\\",\\"peer\\":\\"1.2.4\\",\\"std\\":\\"1.2.6\\"},\\"transformers\\":[\\"hoisting-jest-mock@1\\"],\\"tsJest\\":{\\"compiler\\":\\"typescript\\",\\"diagnostics\\":{\\"ignoreCodes\\":[6059,18002,18003],\\"pretty\\":true,\\"throws\\":true},\\"isolatedModules\\":false,\\"transformers\\":[]},\\"tsconfig\\":{\\"declaration\\":false,\\"inlineSourceMap\\":false,\\"inlineSources\\":true,\\"module\\":1,\\"noEmit\\":false,\\"outDir\\":\\"$$ts-jest$$\\",\\"removeComments\\":false,\\"sourceMap\\":true,\\"target\\":1}}"',
'"{\\"digest\\":\\"a0d51ca854194df8191d0e65c0ca4730f510f332\\",\\"jest\\":{\\"__backported\\":true,\\"globals\\":{}},\\"projectDepVersions\\":{\\"dev\\":\\"1.2.5\\",\\"opt\\":\\"1.2.3\\",\\"peer\\":\\"1.2.4\\",\\"std\\":\\"1.2.6\\"},\\"transformers\\":[\\"hoisting-jest-mock@1\\"],\\"tsJest\\":{\\"compiler\\":\\"typescript\\",\\"diagnostics\\":{\\"ignoreCodes\\":[6059,18002,18003],\\"pretty\\":true,\\"throws\\":true},\\"isolatedModules\\":false,\\"packageJson\\":{\\"kind\\":\\"file\\"},\\"transformers\\":[]},\\"tsconfig\\":{\\"declaration\\":false,\\"inlineSourceMap\\":false,\\"inlineSources\\":true,\\"module\\":1,\\"noEmit\\":false,\\"outDir\\":\\"$$ts-jest$$\\",\\"removeComments\\":false,\\"sourceMap\\":true,\\"target\\":1}}"',
)
})
}) // cacheKey
Expand Down Expand Up @@ -579,6 +607,10 @@ Object {
"throws": true,
},
"isolatedModules": false,
"packageJson": Object {
"kind": "file",
"value": undefined,
},
"stringifyContentPathRegex": undefined,
"transformers": Array [],
"tsConfig": undefined,
Expand Down
52 changes: 44 additions & 8 deletions src/config/config-set.ts
Expand Up @@ -114,18 +114,38 @@ const toDiagnosticCodeList = (items: any, into: number[] = []): number[] => {
export class ConfigSet {
@Memoize()
get projectPackageJson(): Record<string, any> {
const {
tsJest: { packageJson },
} = this

if (packageJson && packageJson.kind === 'inline') {
return packageJson.value
}

if (packageJson && packageJson.kind === 'file' && packageJson.value) {
const path = this.resolvePath(packageJson.value)
if (existsSync(path)) {
return require(path)
}
this.logger.warn(Errors.UnableToFindProjectRoot)
return {}
}

const tsJestRoot = resolve(__dirname, '..', '..')
let pkgPath = resolve(tsJestRoot, '..', '..', 'package.json')
let exists = existsSync(pkgPath)
if (!exists) {
if (realpathSync(this.rootDir) === realpathSync(tsJestRoot)) {
pkgPath = resolve(tsJestRoot, 'package.json')
exists = true
} else {
this.logger.warn(Errors.UnableToFindProjectRoot)
if (existsSync(pkgPath)) {
return require(pkgPath)
}

if (realpathSync(this.rootDir) === realpathSync(tsJestRoot)) {
pkgPath = resolve(tsJestRoot, 'package.json')
if (existsSync(pkgPath)) {
return require(pkgPath)
}
}
return exists ? require(pkgPath) : {}

this.logger.warn(Errors.UnableToFindProjectRoot)
return {}
}

@Memoize()
Expand Down Expand Up @@ -183,6 +203,21 @@ export class ConfigSet {
}
}

// packageJson
const { packageJson: packageJsonOpt } = options
let packageJson: TsJestConfig['packageJson']
if (typeof packageJsonOpt === 'string' || packageJsonOpt == null || packageJsonOpt === true) {
packageJson = {
kind: 'file',
value: typeof packageJsonOpt === 'string' ? this.resolvePath(packageJsonOpt) : undefined,
}
} else if (typeof packageJsonOpt === 'object') {
packageJson = {
kind: 'inline',
value: packageJsonOpt,
}
}

// transformers
const transformers = (options.astTransformers || []).map(mod => this.resolvePath(mod, { nodeResolve: true }))

Expand Down Expand Up @@ -234,6 +269,7 @@ export class ConfigSet {
// parsed options
const res: TsJestConfig = {
tsConfig,
packageJson,
babelConfig,
diagnostics,
isolatedModules: !!options.isolatedModules,
Expand Down
18 changes: 18 additions & 0 deletions src/types.ts
Expand Up @@ -21,6 +21,14 @@ export interface TsJestGlobalOptions {
*/
tsConfig?: boolean | string | CompilerOptions

/**
* packageJson. It can be:
* - `true` (or `undefined`, it's the default): use default package.json file
* - `path/to/package.json`: path to a specific package.json file (<rootDir> can be used)
* - `{...}`: contents of a package.json
*/
packageJson?: boolean | string | object

/**
* Whether to compile files as isolated modules (disables some features and type-checking, default to `false`):
*/
Expand Down Expand Up @@ -93,10 +101,20 @@ interface TsJestConfig$babelConfig$inline {
value: BabelConfig
}
type TsJestConfig$babelConfig = TsJestConfig$babelConfig$file | TsJestConfig$babelConfig$inline | undefined
interface TsJestConfig$packageJson$file {
kind: 'file'
value: string | undefined
}
interface TsJestConfig$packageJson$inline {
kind: 'inline'
value: any
}
type TsJestConfig$packageJson = TsJestConfig$packageJson$file | TsJestConfig$packageJson$inline | undefined
type TsJestConfig$stringifyContentPathRegex = string | undefined

export interface TsJestConfig {
tsConfig: TsJestConfig$tsConfig
packageJson: TsJestConfig$packageJson
isolatedModules: boolean
compiler: string
diagnostics: TsJestConfig$diagnostics
Expand Down

0 comments on commit e3d0d8c

Please sign in to comment.