Skip to content

Commit 73df8eb

Browse files
remove compiler option (#1008)
1 parent 9182e1e commit 73df8eb

12 files changed

+61
-190
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CO
55
#### BREAKING CHANGES
66

77
* cucumber now waits for the event loop to drain before exiting. To exit immediately when the tests finish running use `--exit`. Use of this flag is discouraged. See [here](/docs/cli.md#exiting) for more information
8+
* remove `--compiler` option. See [here](/docs/cli.md#transpilers) for the new way to use transpilers
9+
10+
#### New Features
11+
12+
* can now use glob patterns for selecting what features to run
13+
* update `--require` to support glob patterns
14+
* add `--require-module` to require node modules before support code is loaded
815

916
#### Deprecations
1017

cucumber.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
var common = [
2-
'--compiler js:babel-register',
2+
'--require-module babel-register',
33
`--format ${process.env.CI ? 'progress' : 'progress-bar'}`,
44
'--format rerun:@rerun.txt',
55
'--format usage:usage.txt'

docs/cli.md

+8-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ needs to be required in your support files and globally installed modules cannot
1717

1818
## Running specific features
1919

20+
* Specify a [glob](https://github.com/isaacs/node-glob) pattern
21+
* `$ cucumber.js features/**/*.feature`
22+
* Specify a feature directory
23+
* `$ cucumber.js features/dir`
2024
* Specify a feature file
2125
* `$ cucumber.js features/my_feature.feature`
2226
* Specify a scenario by its line number
@@ -28,14 +32,13 @@ needs to be required in your support files and globally installed modules cannot
2832

2933
## Requiring support files
3034

31-
Use `--require <FILE|DIR>` to require files before executing the features.
35+
Use `--require <GLOB|DIR|FILE>` to require support files before executing the features. Uses [glob](https://github.com/isaacs/node-glob) patterns.
3236
If not used, the following files are required:
3337
* If the features live in a `features` directory (at any level)
34-
* all support files in the `features` directory
38+
* `features/**/*.js`
3539
* Otherwise
36-
* all support files in the directories of the features
40+
* `<DIR>/**/*.js` for each directory containing the selected features
3741

38-
Support files are defined as all `*.js` files and other extensions specified by `--compiler`.
3942
Automatic loading is disabled when this option is specified, and all loading becomes explicit.
4043

4144
## Formats
@@ -110,7 +113,7 @@ Use `--tags <EXPRESSION>` to run specific features or scenarios. This option is
110113

111114
## Transpilers
112115

113-
Step definitions and support files can be written in other languages that transpile to javascript. To do this use the CLI option `--compiler <file_extension>:<module_name>`. Running `require("<module_name>")`, should make it possible to require files with the given extension. As an example, load [CoffeeScript](https://www.npmjs.com/package/coffee-script) support files with `--compiler coffee:coffee-script/register`.
116+
Step definitions and support files can be written in other languages that transpile to javascript. To do this use the CLI option `--require-module <module_name>`, where `require("<module_name>")` should make it possible to require files for your language. Also use `--require features/**/*.<ext>` if your files end in an extension other than `js`. As an example, load [CoffeeScript](https://www.npmjs.com/package/coffee-script) support files with `--require-module coffee-script/register --require features/**/*.coffee`.
114117

115118
## World Parameters
116119

features/profiles.feature

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Feature: default command line arguments
1818
"""
1919
And a file named "cucumber.js" with:
2020
"""
21-
var common = '--compiler js:babel-register ';
21+
var common = '--require-module babel-register ';
2222
2323
module.exports = {
2424
'default': common + '--format summary',

features/compiler.feature renamed to features/require_module.feature

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ Feature: compilers
1818
1919
Given /^a step$/, ->
2020
"""
21-
When I run cucumber.js with `--compiler coffee:coffee-script/register`
21+
When I run cucumber.js with `--require-module coffee-script/register --require 'features/**/*.coffee'`
2222
Then the step "a step" has status "passed"

features/support/hooks.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Before(function() {
2424

2525
const tmpDirProfilePath = path.join(this.tmpDir, 'cucumber.js')
2626
const profileContent =
27-
'module.exports = {default: "--compiler js:babel-register"}'
27+
'module.exports = {default: "--require-module babel-register"}'
2828
fs.writeFileSync(tmpDirProfilePath, profileContent)
2929

3030
const tmpDirBabelRcPath = path.join(this.tmpDir, '.babelrc')

src/cli/argv_parser.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,9 @@ export default class ArgvParser {
4242
const program = new Command(path.basename(argv[1]))
4343

4444
program
45-
.usage('[options] [<DIR|FILE[:LINE]>...]')
45+
.usage('[options] [<GLOB|DIR|FILE[:LINE]>...]')
4646
.version(version, '-v, --version')
4747
.option('-b, --backtrace', 'show full backtrace for errors')
48-
.option(
49-
'--compiler <EXTENSION:MODULE>',
50-
'require files with the given EXTENSION after requiring MODULE (repeatable)',
51-
ArgvParser.collect,
52-
[]
53-
)
5448
.option('-d, --dry-run', 'invoke formatters without executing steps')
5549
.option(
5650
'--exit',
@@ -95,11 +89,17 @@ export default class ArgvParser {
9589
[]
9690
)
9791
.option(
98-
'-r, --require <FILE|DIR>',
92+
'-r, --require <GLOB|DIR|FILE>',
9993
'require files before executing features (repeatable)',
10094
ArgvParser.collect,
10195
[]
10296
)
97+
.option(
98+
'--require-module <NODE_MODULE>',
99+
'require node modules before requiring files (repeatable)',
100+
ArgvParser.collect,
101+
[]
102+
)
103103
.option(
104104
'-t, --tags <EXPRESSION>',
105105
'only execute the features or scenarios with tags matching the expression (repeatable)',

src/cli/configuration_builder.js

+33-27
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ import _ from 'lodash'
22
import ArgvParser from './argv_parser'
33
import fs from 'mz/fs'
44
import path from 'path'
5-
import PathExpander from './path_expander'
65
import OptionSplitter from './option_splitter'
7-
import Promise from 'bluebird'
6+
import Promise, { promisify } from 'bluebird'
7+
import glob from 'glob'
8+
9+
const globP = promisify(glob)
810

911
export default class ConfigurationBuilder {
1012
static async build(options) {
@@ -14,7 +16,6 @@ export default class ConfigurationBuilder {
1416

1517
constructor({ argv, cwd }) {
1618
this.cwd = cwd
17-
this.pathExpander = new PathExpander(cwd)
1819

1920
const parsedArgv = ArgvParser.parse(argv)
2021
this.args = parsedArgv.args
@@ -29,15 +30,16 @@ export default class ConfigurationBuilder {
2930
let supportCodePaths = []
3031
if (!listI18nKeywordsFor && !listI18nLanguages) {
3132
featurePaths = await this.expandFeaturePaths(unexpandedFeaturePaths)
32-
const featureDirectoryPaths = this.getFeatureDirectoryPaths(featurePaths)
33-
const unexpandedSupportCodePaths =
34-
this.options.require.length > 0
35-
? this.options.require
36-
: featureDirectoryPaths
37-
supportCodePaths = await this.expandSupportCodePaths(
38-
unexpandedSupportCodePaths
33+
let unexpandedSupportCodePaths = this.options.require
34+
if (unexpandedSupportCodePaths.length === 0) {
35+
unexpandedSupportCodePaths = this.getFeatureDirectoryPaths(featurePaths)
36+
}
37+
supportCodePaths = await this.expandPaths(
38+
unexpandedSupportCodePaths,
39+
'.js'
3940
)
4041
}
42+
this.options.requireModule.forEach(module => require(module))
4143
return {
4244
featureDefaultLanguage: this.options.language,
4345
featurePaths,
@@ -63,11 +65,28 @@ export default class ConfigurationBuilder {
6365
}
6466
}
6567

68+
async expandPaths(unexpandedPaths, defaultExtension) {
69+
const expandedPaths = await Promise.map(
70+
unexpandedPaths,
71+
async unexpandedPath => {
72+
const matches = await globP(unexpandedPath, {
73+
absolute: true,
74+
cwd: this.cwd
75+
})
76+
return await Promise.map(matches, async match => {
77+
if (path.extname(match) === '') {
78+
return await globP(`${match}/**/*${defaultExtension}`)
79+
}
80+
return match
81+
})
82+
}
83+
)
84+
return _.flattenDepth(expandedPaths, 2).map(x => path.normalize(x))
85+
}
86+
6687
async expandFeaturePaths(featurePaths) {
6788
featurePaths = featurePaths.map(p => p.replace(/(:\d+)*$/g, '')) // Strip line numbers
68-
return await this.pathExpander.expandPathsWithExtensions(featurePaths, [
69-
'feature'
70-
])
89+
return await this.expandPaths(featurePaths, '.feature')
7190
}
7291

7392
getFeatureDirectoryPaths(featurePaths) {
@@ -127,19 +146,6 @@ export default class ConfigurationBuilder {
127146
return featurePaths
128147
}
129148
}
130-
return ['features']
131-
}
132-
133-
async expandSupportCodePaths(supportCodePaths) {
134-
const extensions = ['js']
135-
this.options.compiler.forEach(compiler => {
136-
const [extension, module] = OptionSplitter.split(compiler)
137-
extensions.push(extension)
138-
require(module)
139-
})
140-
return await this.pathExpander.expandPathsWithExtensions(
141-
supportCodePaths,
142-
extensions
143-
)
149+
return ['features/**/*.feature']
144150
}
145151
}

src/cli/configuration_builder_spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ describe('Configuration', function() {
3434
listI18nKeywordsFor: '',
3535
listI18nLanguages: false,
3636
pickleFilterOptions: {
37-
featurePaths: ['features'],
37+
featurePaths: ['features/**/*.feature'],
3838
names: [],
3939
tagExpression: ''
4040
},

src/cli/option_splitter_spec.js

-15
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,6 @@ describe('OptionSplitter', function() {
2626
description: 'does not split a single absolute windows paths',
2727
input: 'C:\\custom\\formatter',
2828
output: ['C:\\custom\\formatter']
29-
},
30-
{
31-
description: 'splits extensions and modules',
32-
input: 'ts:typescript',
33-
output: ['ts', 'typescript']
34-
},
35-
{
36-
description: 'splits extension and module with an absolute windows path',
37-
input: 'ts:C:/typescript',
38-
output: ['ts', 'C:/typescript']
39-
},
40-
{
41-
description: 'splits more than 2 parts',
42-
input: 'part1:part2:part3',
43-
output: ['part1', 'part2', 'part3']
4429
}
4530
]
4631

src/cli/path_expander.js

-39
This file was deleted.

src/cli/path_expander_spec.js

-91
This file was deleted.

0 commit comments

Comments
 (0)