Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat(config): specify package.json location (#823) (#1013)
* feat(config): specify package.json location (#823)

* fix(docs): package.json config option (#823)

Document the package.json config option.
  • Loading branch information
jdhuntington authored and GeeWee committed Mar 14, 2019
1 parent 279edcd commit fb7dd55
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 9 deletions.
2 changes: 2 additions & 0 deletions docs/user/config/index.md
Expand Up @@ -193,6 +193,7 @@ All options have default values which should fit most of the projects. Click on
| [**`diagnostics`**][diagnostics] | [Diagnostics related configuration.][diagnostics] | `boolean`\|`object` | `true` |
| [**`babelConfig`**][babelConfig] | [Babel(Jest) related configuration.][babelConfig] | `boolean`\|`object` | _disabled_ |
| [**`stringifyContentPathRegex`**][stringifyContentPathRegex] | [Files which will become modules returning self content.][stringifyContentPathRegex] | `string`\|`RegExp` | _disabled_ |
| [**`packageJson`**][packageJson] | [Package metadata.][packageJson] | `string`\|`object`\|`boolean` | _auto_ |

### Upgrading

Expand Down Expand Up @@ -222,3 +223,4 @@ npx ts-jest config:migrate package.json
[diagnostics]: diagnostics
[babelConfig]: babelConfig
[stringifyContentPathRegex]: stringifyContentPathRegex
[packageJson]: packageJson
69 changes: 69 additions & 0 deletions docs/user/config/packageJson.md
@@ -0,0 +1,69 @@
---
title: packageJson Config option
---

The `packageJson` option specifies the `package.json` file to use. An inline object may also be specified instead of a file path.

By default, the `package.json` file at the root of the project will be used. If it cannot be found, an empty project definition will be used instead.

### Examples

#### Path to a `packageJson` file

The path should be relative to the current working directory where you start Jest from. You can also use `<rootDir>` in the path to start from the project root dir.

<div class="row"><div class="col-md-6" markdown="block">

```js
// jest.config.js
module.exports = {
// [...]
globals: {
'ts-jest': {
packageJson: 'package.json'
}
}
};
```

</div><div class="col-md-6" markdown="block">

```js
// OR from a non-trivial path
// jest.config.js
module.exports = {
// [...]
globals: {
'ts-jest': {
packageJson: '<rootDir>/../../shared/package.json'
}
}
};
```

</div></div>

#### Inline package metadata

<div class="row"><div class="col-md-12" markdown="block">

```js
// jest.config.js
module.exports = {
// [...]
globals: {
'ts-jest': {
packageJson: {
"name": "my-project",
"version": "1.0.0",
"dependencies": {
// [...]
}
}
}
}
};
```

</div></div>

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 fb7dd55

Please sign in to comment.