Skip to content

Commit 690aa00

Browse files
stephtrconnectdotz
authored andcommitted
Replace Settings class by getSettings function (#14)
* remove default values from Settings * remodel Settings * update changelog * update comment * add @jest/types dependency, fix small bugs * Revert use of @jest/types in Settings.js * add comment about Config class * update tests * fix flow error * typescript definition: export correct function * run prettier * fix eslint issues * update test
1 parent 52e61da commit 690aa00

File tree

8 files changed

+193
-219
lines changed

8 files changed

+193
-219
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ Bug-fixes within the same version aren't needed
2222
2323
* upgrade to the latest jest version (24.7.x) - connectdotz
2424
25+
* [breaking change] Replace the `Settings` class with a `getSettings` function - stephtr
26+
27+
`getSettings` now simply returns a promise resolving to jest's config.
28+
2529
-->
2630

2731
### 25.0.0

babel.config.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
module.exports = {
2-
presets: ['@babel/preset-env', '@babel/flow'],
2+
presets: [
3+
[
4+
'@babel/preset-env',
5+
{ useBuiltIns: 'usage' }
6+
],
7+
'@babel/flow',
8+
],
39
};

index.d.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import {EventEmitter} from 'events';
99
import {ChildProcess} from 'child_process';
10+
import {Config as JestConfig} from '@jest/types';
1011

1112
export interface SpawnOptions {
1213
shell?: boolean;
@@ -33,15 +34,12 @@ export class Runner extends EventEmitter {
3334
runJestWithUpdateForSnapshots(completion: () => void, args?: string[]): void;
3435
}
3536

36-
export class Settings extends EventEmitter {
37-
constructor(workspace: ProjectWorkspace, options?: Options);
38-
getConfig(completed: Function): void;
39-
jestVersionMajor: number | null;
40-
settings: {
41-
testRegex: string,
42-
testMatch: string[],
43-
};
44-
}
37+
export interface JestSettings {
38+
jestVersionMajor: number;
39+
configs: JestConfig.ProjectConfig[];
40+
};
41+
42+
export function getSettings(workspace: ProjectWorkspace, options?: Options): Promise<JestSettings>;
4543

4644
export class ProjectWorkspace {
4745
constructor(

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
},
5252
"dependencies": {
5353
"@babel/traverse": "^7.1.2",
54+
"@jest/types": "^24.8.0",
5455
"babylon": "^6.14.1",
55-
"jest-config": "^24.7.0",
5656
"jest-snapshot": "^24.7.0",
5757
"typescript": "^3.4.3"
5858
},

src/Settings.js

Lines changed: 63 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -7,113 +7,88 @@
77
* @flow
88
*/
99

10-
import {ChildProcess} from 'child_process';
11-
import EventEmitter from 'events';
12-
import {defaults as jestConfigDefaults} from 'jest-config';
13-
import type {Options, SpawnOptions} from './types';
10+
import type {Options} from './types';
1411
import ProjectWorkspace from './project_workspace';
1512
import {createProcess} from './Process';
1613

17-
// This class represents the the configuration of Jest's process
18-
// we want to start with the defaults then override whatever they output
19-
// the interface below can be used to show what we use, as currently the whole
20-
// settings object will be in memory.
21-
22-
// Ideally anything you care about adding should have a default in
23-
// the constructor see https://jestjs.io/docs/configuration.html
24-
// for full deets
25-
26-
// For now, this is all we care about inside the config
27-
2814
type Glob = string;
2915

30-
type ConfigRepresentation = {
16+
// This class represents the configuration of Jest's process.
17+
// The interface below can be used to show what we use, as currently the whole
18+
// settings object will be in memory.
19+
// As soon as the code will be converted to TypeScript, this will be removed
20+
// in favor of `@jest/types`, which exports the full config interface.
21+
22+
type ProjectConfiguration = {
3123
testRegex: string | Array<string>,
3224
testMatch: Array<Glob>,
3325
};
3426

35-
type ConfigRepresentations = Array<ConfigRepresentation>;
36-
37-
export default class Settings extends EventEmitter {
38-
getConfigProcess: ChildProcess;
39-
40-
jestVersionMajor: number | null;
41-
42-
_createProcess: (workspace: ProjectWorkspace, args: Array<string>, options: SpawnOptions) => ChildProcess;
43-
44-
configs: ConfigRepresentations;
45-
46-
settings: ConfigRepresentation;
47-
48-
workspace: ProjectWorkspace;
49-
50-
spawnOptions: SpawnOptions;
51-
52-
_jsonPattern: RegExp;
53-
54-
constructor(workspace: ProjectWorkspace, options?: Options) {
55-
super();
56-
this.workspace = workspace;
57-
this._createProcess = (options && options.createProcess) || createProcess;
58-
this.spawnOptions = {
59-
shell: options && options.shell,
60-
};
61-
62-
const {testMatch, testRegex} = jestConfigDefaults;
63-
64-
this.settings = {testMatch, testRegex};
65-
66-
this.configs = [this.settings];
67-
this._jsonPattern = new RegExp(/^[\s]*\{/gm);
68-
}
69-
70-
_parseConfig(text: string): void {
71-
let settings = null;
27+
type JestSettings = {
28+
jestVersionMajor: number,
29+
configs: ProjectConfiguration[],
30+
};
7231

73-
try {
74-
settings = JSON.parse(text);
75-
} catch (err) {
76-
// skip the non-json content, if any
77-
const idx = text.search(this._jsonPattern);
78-
if (idx > 0) {
79-
if (this.workspace.debug) {
80-
// eslint-disable-next-line no-console
81-
console.log(`skip config output noise: ${text.substring(0, idx)}`);
82-
}
83-
this._parseConfig(text.substring(idx));
84-
return;
32+
function parseSettings(text: string, debug: ?boolean = false): JestSettings {
33+
const jsonPattern = new RegExp(/^[\s]*\{/gm);
34+
let settings = null;
35+
36+
try {
37+
settings = JSON.parse(text);
38+
} catch (err) {
39+
// skip the non-json content, if any
40+
const idx = text.search(jsonPattern);
41+
if (idx > 0) {
42+
if (debug) {
43+
// eslint-disable-next-line no-console
44+
console.log(`skip config output noise: ${text.substring(0, idx)}`);
8545
}
86-
// eslint-disable-next-line no-console
87-
console.warn(`failed to parse config: \n${text}\nerror: ${err}`);
88-
throw err;
46+
return parseSettings(text.substring(idx));
8947
}
90-
this.jestVersionMajor = parseInt(settings.version.split('.').shift(), 10);
91-
this.configs = this.jestVersionMajor >= 21 ? settings.configs : [settings.config];
48+
// eslint-disable-next-line no-console
49+
console.warn(`failed to parse config: \n${text}\nerror: ${err}`);
50+
throw err;
51+
}
9252

93-
if (this.workspace.debug) {
94-
// eslint-disable-next-line no-console
95-
console.log(`found config jestVersionMajor=${this.jestVersionMajor}`);
96-
}
53+
const jestVersionMajor = parseInt(settings.version.split('.').shift(), 10);
54+
if (debug) {
55+
// eslint-disable-next-line no-console
56+
console.log(`found config jestVersionMajor=${jestVersionMajor}`);
9757
}
9858

99-
getConfigs(completed: any) {
100-
this.getConfigProcess = this._createProcess(this.workspace, ['--showConfig'], this.spawnOptions);
59+
return {
60+
jestVersionMajor,
61+
configs: Array.isArray(settings.configs) ? settings.configs : [settings.config],
62+
};
63+
}
64+
65+
export default function getSettings(workspace: ProjectWorkspace, options?: Options): Promise<JestSettings> {
66+
return new Promise((resolve, reject) => {
67+
const _createProcess = (options && options.createProcess) || createProcess;
68+
const spawnOptions = {
69+
shell: options && options.shell,
70+
};
71+
const getConfigProcess = _createProcess(workspace, ['--showConfig'], spawnOptions);
10172

102-
this.getConfigProcess.stdout.on('data', (data: Buffer) => {
103-
this._parseConfig(data.toString());
73+
let configString = '';
74+
getConfigProcess.stdout.on('data', (data: Buffer) => {
75+
configString += data.toString();
10476
});
10577

106-
// They could have an older build of Jest which
107-
// would error with `--showConfig`
108-
this.getConfigProcess.on('close', () => {
109-
completed();
78+
let rejected = false;
79+
getConfigProcess.stderr.on('data', (data: Buffer) => {
80+
rejected = true;
81+
reject(data.toString());
11082
});
111-
}
11283

113-
getConfig(completed: any, index: number = 0) {
114-
this.getConfigs(() => {
115-
this.settings = this.configs[index];
116-
completed();
84+
getConfigProcess.on('close', () => {
85+
if (!rejected) {
86+
try {
87+
resolve(parseSettings(configString, workspace.debug));
88+
} catch (err) {
89+
reject(err);
90+
}
91+
}
11792
});
118-
}
93+
});
11994
}

0 commit comments

Comments
 (0)