Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
([#5154](https://github.com/facebook/jest/pull/5154))
* `[jest-jasmine2]` Support generator functions as specs.
([#5166](https://github.com/facebook/jest/pull/5166))
* `[jest-config]` Allow configuration objects inside `projects` array
([#5176](https://github.com/facebook/jest/pull/5176))

### Chore & Maintenance

Expand Down
25 changes: 25 additions & 0 deletions integration_tests/__tests__/multi_project_runner.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,31 @@ test('"No tests found" message for projects', () => {
);
});

test('objects in project configuration', () => {
writeFiles(DIR, {
'__tests__/file1.test.js': `
test('foo', () => {});
`,
'__tests__/file2.test.js': `
test('foo', () => {});
`,
'jest.config.js': `module.exports = {
projects: [
{ testMatch: ['<rootDir>/__tests__/file1.test.js$'] },
{ testMatch: ['<rootDir>/__tests__/file2.test.js$'] },
]
};`,
'package.json': '{}',
});

const {stdout, stderr} = runJest(DIR);
expect(stderr).toEqual('');
expect(stdout).toContain(
' 2 files checked across 2 projects. ' +
'Run with `--verbose` for more details.',
);
});

test('resolves projects and their <rootDir> properly', () => {
writeFiles(DIR, {
'.watchmanconfig': '',
Expand Down
10 changes: 8 additions & 2 deletions packages/jest-cli/src/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,9 @@ const ensureNoDuplicateConfigs = (parsedConfigs, projects) => {
});
throw new Error(message);
}
configPathSet.add(configPath);
if (configPath !== null) {
configPathSet.add(configPath);
}
}
};

Expand All @@ -225,9 +227,11 @@ const getConfigs = (
let hasDeprecationWarnings;
let configs: Array<ProjectConfig> = [];
let projects = projectsFromCLIArgs;
let configPath: ?Path;

if (projectsFromCLIArgs.length === 1) {
const parsedConfig = readConfig(argv, projects[0]);
configPath = parsedConfig.configPath;

if (parsedConfig.globalConfig.projects) {
// If this was a single project, and its config has `projects`
Expand All @@ -246,7 +250,9 @@ const getConfigs = (
}

if (projects.length > 1) {
const parsedConfigs = projects.map(root => readConfig(argv, root, true));
const parsedConfigs = projects.map(root =>
readConfig(argv, root, true, configPath)
);
ensureNoDuplicateConfigs(parsedConfigs, projects);
configs = parsedConfigs.map(({projectConfig}) => projectConfig);
if (!hasDeprecationWarnings) {
Expand Down
31 changes: 23 additions & 8 deletions packages/jest-config/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
*/

import type {Argv} from 'types/Argv';
import type {GlobalConfig, Path, ProjectConfig} from 'types/Config';
import type {
GlobalConfig,
InitialOptions,
Path,
ProjectConfig,
} from 'types/Config';

import {getTestEnvironment, isJSONString} from './utils';
import normalize from './normalize';
Expand All @@ -17,24 +22,34 @@ import readConfigFileAndSetRootDir from './read_config_file_and_set_root_dir';

function readConfig(
argv: Argv,
packageRoot: string,
packageRootOrConfig: Path | InitialOptions,
// Whether it needs to look into `--config` arg passed to CLI.
// It only used to read initial config. If the initial config contains
// `project` property, we don't want to read `--config` value and rather
// read individual configs for every project.
skipArgvConfigOption?: boolean,
parentConfigPath?: ?Path,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does ? on both sides mean? From my understanding name: ?type allows null, undefined or a value, while name?: type allows undefined or a value.

https://flow.org/en/docs/types/primitives/#toc-maybe-types

Copy link
Copy Markdown
Contributor Author

@azz azz Dec 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very proficient with Flow. I just added the ? on the LHS to satisfy the checker. Maybe I can remove the one left, but the property is optional so I think I'll get an error when it's not explicitly passed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think so 🙂

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing it worked.

): {
configPath: ?Path,
globalConfig: GlobalConfig,
hasDeprecationWarnings: boolean,
projectConfig: ProjectConfig,
} {
let rawOptions;
let configPath;
let configPath = null;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there anywhere that requires a configPath to be set other than readConfigFileAndSetRootDir?


// A JSON string was passed to `--config` argument and we can parse it
// and use as is.
if (isJSONString(argv.config)) {
if (typeof packageRootOrConfig !== 'string') {
if (parentConfigPath) {
rawOptions = packageRootOrConfig;
rawOptions.rootDir = parentConfigPath;
} else {
throw new Error(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we have a test for this (mostly for coverage)?

'jest: Cannot use configuration as an object without a file path',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you end this sentence with a full stop (.) ?

Also, please capitalize Jest.

);
}
} else if (isJSONString(argv.config)) {
// A JSON string was passed to `--config` argument and we can parse it
// and use as is.
let config;
try {
config = JSON.parse(argv.config);
Expand All @@ -45,7 +60,7 @@ function readConfig(
}

// NOTE: we might need to resolve this dir to an absolute path in the future
config.rootDir = config.rootDir || packageRoot;
config.rootDir = config.rootDir || packageRootOrConfig;
rawOptions = config;
// A string passed to `--config`, which is either a direct path to the config
// or a path to directory containing `package.json` or `jest.conf.js`
Expand All @@ -54,7 +69,7 @@ function readConfig(
rawOptions = readConfigFileAndSetRootDir(configPath);
} else {
// Otherwise just try to find config in the current rootDir.
configPath = resolveConfigPath(packageRoot, process.cwd());
configPath = resolveConfigPath(packageRootOrConfig, process.cwd());
rawOptions = readConfigFileAndSetRootDir(configPath);
}

Expand Down
3 changes: 2 additions & 1 deletion packages/jest-config/src/normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,8 @@ export default function normalize(options: InitialOptions, argv: Argv) {
// Project can be specified as globs. If a glob matches any files,
// We expand it to these paths. If not, we keep the original path
// for the future resolution.
const globMatches = glob.sync(project);
const globMatches =
typeof project === 'string' ? glob.sync(project) : [];
return projects.concat(globMatches.length ? globMatches : project);
}, []);
break;
Expand Down