vitest-cucumber-plugin 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +12 -7
- package/README.md +0 -2
- package/RELEASE_NOTES.md +2 -0
- package/generate-parsers +6 -0
- package/package.json +5 -5
- package/rollup-tags-expression.js +10 -0
- package/run-tests +3 -2
- package/src/generate/example.js +2 -1
- package/src/generate/examples.js +3 -1
- package/src/generate/feature.js +4 -1
- package/src/generate/index.js +1 -1
- package/src/generate/{scenarioOutline.js → scenario-outline.js} +4 -1
- package/src/generate/util.js +3 -4
- package/src/gherkin.js +24 -50
- package/src/gherkin.ne +27 -10
- package/src/gherkin.umd.js +24 -10
- package/src/index.js +7 -3
- package/src/parse.js +1 -1
- package/src/tags-expression.js +58 -0
- package/src/tags-expression.ne +43 -0
- package/src/tags-expression.umd.js +46 -0
- package/src/tags.js +68 -0
- package/tests/background/package-lock.json +104 -867
- package/tests/background/package.json +5 -5
- package/tests/comments/package-lock.json +2 -36
- package/tests/comments/package.json +5 -5
- package/tests/data-tables/features/data-tables-escaping.feature +27 -0
- package/tests/data-tables/package-lock.json +2 -36
- package/tests/data-tables/package.json +5 -5
- package/tests/is-it-friday/package-lock.json +2 -36
- package/tests/is-it-friday/package.json +5 -5
- package/tests/is-it-friday-scenario-outline/package-lock.json +2 -36
- package/tests/is-it-friday-scenario-outline/package.json +5 -5
- package/tests/is-it-friday-two-scenarios/package-lock.json +2 -36
- package/tests/is-it-friday-two-scenarios/package.json +5 -5
- package/tests/is-it-friday-two-scenarios-multiple-feature-files/package-lock.json +2 -36
- package/tests/is-it-friday-two-scenarios-multiple-feature-files/package.json +5 -5
- package/tests/keyword-aliases/package-lock.json +2 -36
- package/tests/keyword-aliases/package.json +5 -5
- package/tests/tags/features/tags-scenario-outline.feature +10 -3
- package/tests/tags/features/tags.feature +2 -2
- package/tests/tags/package-lock.json +104 -867
- package/tests/tags/package.json +5 -5
- package/tests/tags/vite.config.js +1 -1
- package/tests/data-tables/vite.config.js.timestamp-1682359000824-3876ac2e9095b.mjs +0 -13
- /package/{rollup-nearley.js → rollup-gherkin.js} +0 -0
package/CONTRIBUTING.md
CHANGED
|
@@ -37,10 +37,15 @@ branching model. The 'main' branch the release branch and is only pushed to dur
|
|
|
37
37
|
## Doing a release
|
|
38
38
|
|
|
39
39
|
1. ```$ VERSION=<version>```
|
|
40
|
-
1. ```$ git flow release start $VERSION```
|
|
41
|
-
1.
|
|
42
|
-
1.
|
|
43
|
-
1.
|
|
44
|
-
|
|
45
|
-
1.
|
|
46
|
-
|
|
40
|
+
1. ```$ git flow release start v$VERSION```
|
|
41
|
+
1. ```$ npm pkg set version=$VERSION```
|
|
42
|
+
1. ```$ sed -i "1s/^/* v$VERSION : \!\!\! ADD RELEASE NOTE HERE \!\!\!\n/" RELEASE_NOTES.md```
|
|
43
|
+
1. ```$ emacs -nw RELEASE_NOTES.md```
|
|
44
|
+
2. ```$ npm test```
|
|
45
|
+
1. ```$ git add . ; git commit -m v$VERSION```
|
|
46
|
+
3. ```$ git flow release finish v$VERSION```
|
|
47
|
+
4. ```$ git push```
|
|
48
|
+
5. ```$ git checkout main```
|
|
49
|
+
6. ```$ git push```
|
|
50
|
+
7. ```$ git push origin v$VERSION```
|
|
51
|
+
8. ```$ npm publish```
|
package/README.md
CHANGED
|
@@ -109,5 +109,3 @@ work, but this configuration isn't tested.
|
|
|
109
109
|
This plugin is not yet feature complete. Here is the list of features from Cucumber which aren't yet implemented:
|
|
110
110
|
* Rule keyword
|
|
111
111
|
* Doc strings
|
|
112
|
-
* Data Table escape characters
|
|
113
|
-
* Boolean expression support for tags
|
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
* v0.1.6 : Implemented tags boolean expression support
|
|
2
|
+
* v0.1.5 : Implemented escape characters for Data Tables
|
|
1
3
|
* v0.1.4 : Changed README to point to RPM registry
|
|
2
4
|
* v0.1.3 : Import modules from generated code to make sure they are processed correctly
|
|
3
5
|
* v0.1.2 : Set default log level to warn and make it configurable
|
package/generate-parsers
ADDED
package/package.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vitest-cucumber-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Plugin for Vitest which allows for tests to be written in Cucumber format.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vite",
|
|
7
7
|
"vitest",
|
|
8
8
|
"cucumber"
|
|
9
9
|
],
|
|
10
|
-
"homepage": "https://github.com/
|
|
10
|
+
"homepage": "https://github.com/samuel-ziegler/vitest-cucumber-plugin#readme",
|
|
11
11
|
"bugs": {
|
|
12
|
-
"url": "https://github.com/
|
|
12
|
+
"url": "https://github.com/samuel-ziegler/vitest-cucumber-plugin/issues"
|
|
13
13
|
},
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"main": "src/index.js",
|
|
16
16
|
"type": "module",
|
|
17
17
|
"scripts": {
|
|
18
|
-
"nearley": "
|
|
18
|
+
"nearley": "./generate-parsers",
|
|
19
19
|
"test": "./run-tests"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
@@ -30,5 +30,5 @@
|
|
|
30
30
|
"@types/lodash": "^4.14.194",
|
|
31
31
|
"rollup": "^3.20.7"
|
|
32
32
|
},
|
|
33
|
-
"repository"
|
|
33
|
+
"repository": "https://github.com/samuel-ziegler/vitest-cucumber-plugin.git"
|
|
34
34
|
}
|
package/run-tests
CHANGED
package/src/generate/example.js
CHANGED
|
@@ -13,7 +13,8 @@ export const generateExample = (config,example) => {
|
|
|
13
13
|
|
|
14
14
|
const skip = shouldSkip(config,example.tags) ? '.skip' : '';
|
|
15
15
|
|
|
16
|
-
const code = `
|
|
16
|
+
const code = ` // tags : ${JSON.stringify(example.tags)}
|
|
17
|
+
describe${skip}('${escape(example.type.name)}: ${escape(example.name)}', () => {${tests}
|
|
17
18
|
});
|
|
18
19
|
`;
|
|
19
20
|
return code;
|
package/src/generate/examples.js
CHANGED
|
@@ -41,7 +41,9 @@ export const generateExamples = (config,steps,examplesStatement) => {
|
|
|
41
41
|
const skip = shouldSkip(config,examplesStatement.tags) ? '.skip' : '';
|
|
42
42
|
|
|
43
43
|
const allTests = generateAllTests(steps,parameters,parameterValues);
|
|
44
|
-
const code = `
|
|
44
|
+
const code = `
|
|
45
|
+
// tags : ${JSON.stringify(examplesStatement.tags)}
|
|
46
|
+
describe${skip}('${escape(examplesStatement.type.name)}: ${escape(examplesStatement.name)}', () => {${allTests}
|
|
45
47
|
});`;
|
|
46
48
|
return code;
|
|
47
49
|
}
|
package/src/generate/feature.js
CHANGED
|
@@ -11,6 +11,9 @@ export const generateFeature = (config,feature) => {
|
|
|
11
11
|
if (feature.background) {
|
|
12
12
|
statement = _.set('background',feature.background,statement);
|
|
13
13
|
}
|
|
14
|
+
|
|
15
|
+
statement = _.set('tags',_.concat(feature.tags,statement.tags),statement);
|
|
16
|
+
|
|
14
17
|
if (statement.type.type === 'example') {
|
|
15
18
|
return testStatements + generateExample(config,statement);
|
|
16
19
|
} else if (statement.type.type === 'scenarioOutline') {
|
|
@@ -36,10 +39,10 @@ const importStepDefinitions = async (config) => {
|
|
|
36
39
|
|
|
37
40
|
await importStepDefinitions(${configStr});
|
|
38
41
|
|
|
42
|
+
// tags : ${JSON.stringify(feature.tags)}
|
|
39
43
|
describe${skip}('${escape(feature.type.name)}: ${escape(name)}', () => {
|
|
40
44
|
${testStatements}});
|
|
41
45
|
`;
|
|
42
|
-
log.debug(code);
|
|
43
46
|
|
|
44
47
|
return code;
|
|
45
48
|
}
|
package/src/generate/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { generateTests } from './tests.js';
|
|
2
2
|
import { generateExample } from './example.js';
|
|
3
3
|
import { generateExamples } from './examples.js';
|
|
4
|
-
import { generateScenarioOutline } from './
|
|
4
|
+
import { generateScenarioOutline } from './scenario-outline.js';
|
|
5
5
|
import { generateFeature } from './feature.js';
|
|
6
6
|
|
|
7
7
|
export {
|
|
@@ -4,12 +4,15 @@ import { escape, shouldSkip } from './util.js';
|
|
|
4
4
|
|
|
5
5
|
export const generateScenarioOutline = (config,scenarioOutline) => {
|
|
6
6
|
const examplesStatements = _.reduce((examplesStatements,examplesStatement) => {
|
|
7
|
+
examplesStatement = _.set('tags',_.concat(scenarioOutline.tags,examplesStatement.tags),examplesStatement);
|
|
8
|
+
|
|
7
9
|
return examplesStatements + generateExamples(config,scenarioOutline.steps,examplesStatement);
|
|
8
10
|
},'')(scenarioOutline.examples);
|
|
9
11
|
|
|
10
12
|
const skip = shouldSkip(config,scenarioOutline.tags) ? '.skip' : '';
|
|
11
13
|
|
|
12
|
-
const code = `
|
|
14
|
+
const code = ` // tags : ${JSON.stringify(scenarioOutline.tags)}
|
|
15
|
+
describe${skip}('${escape(scenarioOutline.type.name)}: ${escape(scenarioOutline.name)}', () => {
|
|
13
16
|
${examplesStatements}
|
|
14
17
|
});
|
|
15
18
|
`;
|
package/src/generate/util.js
CHANGED
|
@@ -3,8 +3,7 @@ import { log } from '../logger.js';
|
|
|
3
3
|
|
|
4
4
|
export const escape = (str) => str.replace(/'/g,"\\'");
|
|
5
5
|
export const shouldSkip = (config,tags) => {
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return intersection.length > 0;
|
|
6
|
+
const result = !config.tagsFunction(tags);
|
|
7
|
+
log.debug('shouldSkip? '+result+' tags: '+JSON.stringify(tags));
|
|
8
|
+
return result;
|
|
10
9
|
}
|
package/src/gherkin.js
CHANGED
|
@@ -1,52 +1,12 @@
|
|
|
1
1
|
import require$$0 from 'lodash/fp.js';
|
|
2
2
|
import require$$1 from 'moo';
|
|
3
|
-
import pino from 'pino';
|
|
4
3
|
|
|
5
4
|
function getDefaultExportFromCjs (x) {
|
|
6
5
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
7
6
|
}
|
|
8
7
|
|
|
9
|
-
function getAugmentedNamespace(n) {
|
|
10
|
-
if (n.__esModule) return n;
|
|
11
|
-
var f = n.default;
|
|
12
|
-
if (typeof f == "function") {
|
|
13
|
-
var a = function a () {
|
|
14
|
-
if (this instanceof a) {
|
|
15
|
-
var args = [null];
|
|
16
|
-
args.push.apply(args, arguments);
|
|
17
|
-
var Ctor = Function.bind.apply(f, args);
|
|
18
|
-
return new Ctor();
|
|
19
|
-
}
|
|
20
|
-
return f.apply(this, arguments);
|
|
21
|
-
};
|
|
22
|
-
a.prototype = f.prototype;
|
|
23
|
-
} else a = {};
|
|
24
|
-
Object.defineProperty(a, '__esModule', {value: true});
|
|
25
|
-
Object.keys(n).forEach(function (k) {
|
|
26
|
-
var d = Object.getOwnPropertyDescriptor(n, k);
|
|
27
|
-
Object.defineProperty(a, k, d.get ? d : {
|
|
28
|
-
enumerable: true,
|
|
29
|
-
get: function () {
|
|
30
|
-
return n[k];
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
return a;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
8
|
var gherkin_umd$1 = {exports: {}};
|
|
38
9
|
|
|
39
|
-
const log = pino();
|
|
40
|
-
|
|
41
|
-
log.level = 'warn';
|
|
42
|
-
|
|
43
|
-
var logger = /*#__PURE__*/Object.freeze({
|
|
44
|
-
__proto__: null,
|
|
45
|
-
log: log
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
var require$$2 = /*@__PURE__*/getAugmentedNamespace(logger);
|
|
49
|
-
|
|
50
10
|
(function (module) {
|
|
51
11
|
// Generated automatically by nearley, version 2.20.1
|
|
52
12
|
// http://github.com/Hardmath123/nearley
|
|
@@ -54,7 +14,6 @@ var require$$2 = /*@__PURE__*/getAugmentedNamespace(logger);
|
|
|
54
14
|
|
|
55
15
|
const fp = require$$0;
|
|
56
16
|
const moo = require$$1;
|
|
57
|
-
require$$2.log;
|
|
58
17
|
const lexer = moo.compile({
|
|
59
18
|
emptyLine : { match: /^[ \t]*(?:\#[^\n]+)?\n/, lineBreaks : true },
|
|
60
19
|
newline : { match : '\n', lineBreaks : true },
|
|
@@ -63,10 +22,12 @@ var require$$2 = /*@__PURE__*/getAugmentedNamespace(logger);
|
|
|
63
22
|
colon : ':',
|
|
64
23
|
step : '*',
|
|
65
24
|
pipe : '|',
|
|
66
|
-
|
|
25
|
+
escapedPipe : '\\|',
|
|
26
|
+
escapedNewline : '\\n',
|
|
27
|
+
escapedBackSlash : '\\\\',
|
|
67
28
|
scenarioOutline : ['Scenario Outline','Scenario Template'],
|
|
68
29
|
word : {
|
|
69
|
-
match : /[^ \t\n
|
|
30
|
+
match : /[^ \t\n\:\|\@\*]+/,
|
|
70
31
|
type : moo.keywords({
|
|
71
32
|
feature : 'Feature',
|
|
72
33
|
examples : ['Examples','Scenarios'],
|
|
@@ -127,7 +88,15 @@ var require$$2 = /*@__PURE__*/getAugmentedNamespace(logger);
|
|
|
127
88
|
{"name": "dataTable", "symbols": ["dataTable", "dataTableRow"], "postprocess": data => fp.concat(data[0],[data[1]])},
|
|
128
89
|
{"name": "dataTableRow", "symbols": ["_", (lexer.has("pipe") ? {type: "pipe"} : pipe), "dataTableColumns", (lexer.has("newline") ? {type: "newline"} : newline)], "postprocess": data => data[2]},
|
|
129
90
|
{"name": "dataTableColumns", "symbols": [], "postprocess": data => []},
|
|
130
|
-
{"name": "dataTableColumns", "symbols": ["dataTableColumns", "
|
|
91
|
+
{"name": "dataTableColumns", "symbols": ["dataTableColumns", "dataTableColumnText", (lexer.has("pipe") ? {type: "pipe"} : pipe)], "postprocess": data => fp.concat(data[0],data[1].trim())},
|
|
92
|
+
{"name": "dataTableColumnText", "symbols": [], "postprocess": data => ''},
|
|
93
|
+
{"name": "dataTableColumnText", "symbols": ["dataTableColumnText", "escapedColumnCharaters"], "postprocess": data => data[0]+data[1]},
|
|
94
|
+
{"name": "dataTableColumnText", "symbols": ["dataTableColumnText", "keywords"], "postprocess": data => data[0]+data[1]},
|
|
95
|
+
{"name": "dataTableColumnText", "symbols": ["dataTableColumnText", (lexer.has("word") ? {type: "word"} : word)], "postprocess": data => data[0]+data[1].value},
|
|
96
|
+
{"name": "dataTableColumnText", "symbols": ["dataTableColumnText", (lexer.has("ws") ? {type: "ws"} : ws)], "postprocess": data => data[0]+data[1].value},
|
|
97
|
+
{"name": "escapedColumnCharaters", "symbols": [(lexer.has("escapedPipe") ? {type: "escapedPipe"} : escapedPipe)], "postprocess": data => '|'},
|
|
98
|
+
{"name": "escapedColumnCharaters", "symbols": [(lexer.has("escapedBackSlash") ? {type: "escapedBackSlash"} : escapedBackSlash)], "postprocess": data => '\\'},
|
|
99
|
+
{"name": "escapedColumnCharaters", "symbols": [(lexer.has("escapedNewline") ? {type: "escapedNewline"} : escapedNewline)], "postprocess": data => '\n'},
|
|
131
100
|
{"name": "steps", "symbols": ["stepAndTable", "moreSteps"], "postprocess": data => fp.concat(data[0],data[1])},
|
|
132
101
|
{"name": "moreSteps", "symbols": [], "postprocess": data => []},
|
|
133
102
|
{"name": "moreSteps", "symbols": ["moreSteps", "stepAndTable"], "postprocess": data => fp.concat(data[0],data[1])},
|
|
@@ -138,12 +107,17 @@ var require$$2 = /*@__PURE__*/getAugmentedNamespace(logger);
|
|
|
138
107
|
{"name": "text", "symbols": [], "postprocess": data => ''},
|
|
139
108
|
{"name": "text", "symbols": ["text", (lexer.has("word") ? {type: "word"} : word)], "postprocess": data => data[0]+data[1].value},
|
|
140
109
|
{"name": "text", "symbols": ["text", (lexer.has("ws") ? {type: "ws"} : ws)], "postprocess": data => data[0]+data[1].value},
|
|
141
|
-
{"name": "text", "symbols": ["text",
|
|
142
|
-
{"name": "text", "symbols": ["text", (lexer.has("
|
|
143
|
-
{"name": "text", "symbols": ["text", (lexer.has("
|
|
144
|
-
{"name": "text", "symbols": ["text", (lexer.has("
|
|
145
|
-
{"name": "text", "symbols": ["text", (lexer.has("
|
|
146
|
-
{"name": "
|
|
110
|
+
{"name": "text", "symbols": ["text", "keywords"], "postprocess": data => data[0]+data[1]},
|
|
111
|
+
{"name": "text", "symbols": ["text", (lexer.has("pipe") ? {type: "pipe"} : pipe)], "postprocess": data => data[0]+data[1].value},
|
|
112
|
+
{"name": "text", "symbols": ["text", (lexer.has("escapedPipe") ? {type: "escapedPipe"} : escapedPipe)], "postprocess": data => data[0]+data[1].value},
|
|
113
|
+
{"name": "text", "symbols": ["text", (lexer.has("escapedNewline") ? {type: "escapedNewline"} : escapedNewline)], "postprocess": data => data[0]+data[1].value},
|
|
114
|
+
{"name": "text", "symbols": ["text", (lexer.has("escapedBackSlash") ? {type: "escapedBackSlash"} : escapedBackSlash)], "postprocess": data => data[0]+data[1].value},
|
|
115
|
+
{"name": "keywords", "symbols": [(lexer.has("step") ? {type: "step"} : step)], "postprocess": data => data[0].value},
|
|
116
|
+
{"name": "keywords", "symbols": [(lexer.has("colon") ? {type: "colon"} : colon)], "postprocess": data => data[0].value},
|
|
117
|
+
{"name": "keywords", "symbols": [(lexer.has("example") ? {type: "example"} : example)], "postprocess": data => data[0].value},
|
|
118
|
+
{"name": "keywords", "symbols": [(lexer.has("examples") ? {type: "examples"} : examples)], "postprocess": data => data[0].value},
|
|
119
|
+
{"name": "keywords", "symbols": [(lexer.has("scenarioOutline") ? {type: "scenarioOutline"} : scenarioOutline)], "postprocess": data => data[0].value},
|
|
120
|
+
{"name": "keywords", "symbols": [(lexer.has("background") ? {type: "background"} : background)], "postprocess": data => data[0].value},
|
|
147
121
|
{"name": "bolText", "symbols": [(lexer.has("ws") ? {type: "ws"} : ws), (lexer.has("word") ? {type: "word"} : word)], "postprocess": data => data[1].value},
|
|
148
122
|
{"name": "bolText", "symbols": [(lexer.has("word") ? {type: "word"} : word)], "postprocess": data => data[0].value},
|
|
149
123
|
{"name": "freeform", "symbols": [], "postprocess": data => ''},
|
package/src/gherkin.ne
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
@{%
|
|
2
2
|
const fp = require('lodash/fp.js');
|
|
3
3
|
const moo = require('moo');
|
|
4
|
-
const log = require('./logger.js').log;
|
|
5
4
|
const lexer = moo.compile({
|
|
6
5
|
emptyLine : { match: /^[ \t]*(?:\#[^\n]+)?\n/, lineBreaks : true },
|
|
7
6
|
newline : { match : '\n', lineBreaks : true },
|
|
@@ -10,10 +9,12 @@ const lexer = moo.compile({
|
|
|
10
9
|
colon : ':',
|
|
11
10
|
step : '*',
|
|
12
11
|
pipe : '|',
|
|
13
|
-
|
|
12
|
+
escapedPipe : '\\|',
|
|
13
|
+
escapedNewline : '\\n',
|
|
14
|
+
escapedBackSlash : '\\\\',
|
|
14
15
|
scenarioOutline : ['Scenario Outline','Scenario Template'],
|
|
15
16
|
word : {
|
|
16
|
-
match : /[^ \t\n
|
|
17
|
+
match : /[^ \t\n\:\|\@\*]+/,
|
|
17
18
|
type : moo.keywords({
|
|
18
19
|
feature : 'Feature',
|
|
19
20
|
examples : ['Examples','Scenarios'],
|
|
@@ -90,7 +91,17 @@ dataTable -> null {% data => [] %}
|
|
|
90
91
|
dataTableRow -> _ %pipe dataTableColumns %newline {% data => data[2] %}
|
|
91
92
|
|
|
92
93
|
dataTableColumns -> null {% data => [] %}
|
|
93
|
-
| dataTableColumns
|
|
94
|
+
| dataTableColumns dataTableColumnText %pipe {% data => fp.concat(data[0],data[1].trim()) %}
|
|
95
|
+
|
|
96
|
+
dataTableColumnText -> null {% data => '' %}
|
|
97
|
+
| dataTableColumnText escapedColumnCharaters {% data => data[0]+data[1] %}
|
|
98
|
+
| dataTableColumnText keywords {% data => data[0]+data[1] %}
|
|
99
|
+
| dataTableColumnText %word {% data => data[0]+data[1].value %}
|
|
100
|
+
| dataTableColumnText %ws {% data => data[0]+data[1].value %}
|
|
101
|
+
|
|
102
|
+
escapedColumnCharaters -> %escapedPipe {% data => '|' %}
|
|
103
|
+
| %escapedBackSlash {% data => '\\' %}
|
|
104
|
+
| %escapedNewline {% data => '\n' %}
|
|
94
105
|
|
|
95
106
|
steps -> stepAndTable moreSteps {% data => fp.concat(data[0],data[1]) %}
|
|
96
107
|
|
|
@@ -106,12 +117,18 @@ stepKeyword -> %step {% (data) => { return { type : 'step', name : data[0].value
|
|
|
106
117
|
text -> null {% data => '' %}
|
|
107
118
|
| text %word {% data => data[0]+data[1].value %}
|
|
108
119
|
| text %ws {% data => data[0]+data[1].value %}
|
|
109
|
-
| text
|
|
110
|
-
| text %
|
|
111
|
-
| text %
|
|
112
|
-
| text %
|
|
113
|
-
| text %
|
|
114
|
-
|
|
120
|
+
| text keywords {% data => data[0]+data[1] %}
|
|
121
|
+
| text %pipe {% data => data[0]+data[1].value %}
|
|
122
|
+
| text %escapedPipe {% data => data[0]+data[1].value %}
|
|
123
|
+
| text %escapedNewline {% data => data[0]+data[1].value %}
|
|
124
|
+
| text %escapedBackSlash {% data => data[0]+data[1].value %}
|
|
125
|
+
|
|
126
|
+
keywords -> %step {% data => data[0].value %}
|
|
127
|
+
| %colon {% data => data[0].value %}
|
|
128
|
+
| %example {% data => data[0].value %}
|
|
129
|
+
| %examples {% data => data[0].value %}
|
|
130
|
+
| %scenarioOutline {% data => data[0].value %}
|
|
131
|
+
| %background {% data => data[0].value %}
|
|
115
132
|
|
|
116
133
|
bolText -> %ws %word {% data => data[1].value %}
|
|
117
134
|
| %word {% data => data[0].value %}
|
package/src/gherkin.umd.js
CHANGED
|
@@ -5,7 +5,6 @@ function id(x) { return x[0]; }
|
|
|
5
5
|
|
|
6
6
|
const fp = require('lodash/fp.js');
|
|
7
7
|
const moo = require('moo');
|
|
8
|
-
const log = require('./logger.js').log;
|
|
9
8
|
const lexer = moo.compile({
|
|
10
9
|
emptyLine : { match: /^[ \t]*(?:\#[^\n]+)?\n/, lineBreaks : true },
|
|
11
10
|
newline : { match : '\n', lineBreaks : true },
|
|
@@ -14,10 +13,12 @@ const lexer = moo.compile({
|
|
|
14
13
|
colon : ':',
|
|
15
14
|
step : '*',
|
|
16
15
|
pipe : '|',
|
|
17
|
-
|
|
16
|
+
escapedPipe : '\\|',
|
|
17
|
+
escapedNewline : '\\n',
|
|
18
|
+
escapedBackSlash : '\\\\',
|
|
18
19
|
scenarioOutline : ['Scenario Outline','Scenario Template'],
|
|
19
20
|
word : {
|
|
20
|
-
match : /[^ \t\n
|
|
21
|
+
match : /[^ \t\n\:\|\@\*]+/,
|
|
21
22
|
type : moo.keywords({
|
|
22
23
|
feature : 'Feature',
|
|
23
24
|
examples : ['Examples','Scenarios'],
|
|
@@ -78,7 +79,15 @@ var grammar = {
|
|
|
78
79
|
{"name": "dataTable", "symbols": ["dataTable", "dataTableRow"], "postprocess": data => fp.concat(data[0],[data[1]])},
|
|
79
80
|
{"name": "dataTableRow", "symbols": ["_", (lexer.has("pipe") ? {type: "pipe"} : pipe), "dataTableColumns", (lexer.has("newline") ? {type: "newline"} : newline)], "postprocess": data => data[2]},
|
|
80
81
|
{"name": "dataTableColumns", "symbols": [], "postprocess": data => []},
|
|
81
|
-
{"name": "dataTableColumns", "symbols": ["dataTableColumns", "
|
|
82
|
+
{"name": "dataTableColumns", "symbols": ["dataTableColumns", "dataTableColumnText", (lexer.has("pipe") ? {type: "pipe"} : pipe)], "postprocess": data => fp.concat(data[0],data[1].trim())},
|
|
83
|
+
{"name": "dataTableColumnText", "symbols": [], "postprocess": data => ''},
|
|
84
|
+
{"name": "dataTableColumnText", "symbols": ["dataTableColumnText", "escapedColumnCharaters"], "postprocess": data => data[0]+data[1]},
|
|
85
|
+
{"name": "dataTableColumnText", "symbols": ["dataTableColumnText", "keywords"], "postprocess": data => data[0]+data[1]},
|
|
86
|
+
{"name": "dataTableColumnText", "symbols": ["dataTableColumnText", (lexer.has("word") ? {type: "word"} : word)], "postprocess": data => data[0]+data[1].value},
|
|
87
|
+
{"name": "dataTableColumnText", "symbols": ["dataTableColumnText", (lexer.has("ws") ? {type: "ws"} : ws)], "postprocess": data => data[0]+data[1].value},
|
|
88
|
+
{"name": "escapedColumnCharaters", "symbols": [(lexer.has("escapedPipe") ? {type: "escapedPipe"} : escapedPipe)], "postprocess": data => '|'},
|
|
89
|
+
{"name": "escapedColumnCharaters", "symbols": [(lexer.has("escapedBackSlash") ? {type: "escapedBackSlash"} : escapedBackSlash)], "postprocess": data => '\\'},
|
|
90
|
+
{"name": "escapedColumnCharaters", "symbols": [(lexer.has("escapedNewline") ? {type: "escapedNewline"} : escapedNewline)], "postprocess": data => '\n'},
|
|
82
91
|
{"name": "steps", "symbols": ["stepAndTable", "moreSteps"], "postprocess": data => fp.concat(data[0],data[1])},
|
|
83
92
|
{"name": "moreSteps", "symbols": [], "postprocess": data => []},
|
|
84
93
|
{"name": "moreSteps", "symbols": ["moreSteps", "stepAndTable"], "postprocess": data => fp.concat(data[0],data[1])},
|
|
@@ -89,12 +98,17 @@ var grammar = {
|
|
|
89
98
|
{"name": "text", "symbols": [], "postprocess": data => ''},
|
|
90
99
|
{"name": "text", "symbols": ["text", (lexer.has("word") ? {type: "word"} : word)], "postprocess": data => data[0]+data[1].value},
|
|
91
100
|
{"name": "text", "symbols": ["text", (lexer.has("ws") ? {type: "ws"} : ws)], "postprocess": data => data[0]+data[1].value},
|
|
92
|
-
{"name": "text", "symbols": ["text",
|
|
93
|
-
{"name": "text", "symbols": ["text", (lexer.has("
|
|
94
|
-
{"name": "text", "symbols": ["text", (lexer.has("
|
|
95
|
-
{"name": "text", "symbols": ["text", (lexer.has("
|
|
96
|
-
{"name": "text", "symbols": ["text", (lexer.has("
|
|
97
|
-
{"name": "
|
|
101
|
+
{"name": "text", "symbols": ["text", "keywords"], "postprocess": data => data[0]+data[1]},
|
|
102
|
+
{"name": "text", "symbols": ["text", (lexer.has("pipe") ? {type: "pipe"} : pipe)], "postprocess": data => data[0]+data[1].value},
|
|
103
|
+
{"name": "text", "symbols": ["text", (lexer.has("escapedPipe") ? {type: "escapedPipe"} : escapedPipe)], "postprocess": data => data[0]+data[1].value},
|
|
104
|
+
{"name": "text", "symbols": ["text", (lexer.has("escapedNewline") ? {type: "escapedNewline"} : escapedNewline)], "postprocess": data => data[0]+data[1].value},
|
|
105
|
+
{"name": "text", "symbols": ["text", (lexer.has("escapedBackSlash") ? {type: "escapedBackSlash"} : escapedBackSlash)], "postprocess": data => data[0]+data[1].value},
|
|
106
|
+
{"name": "keywords", "symbols": [(lexer.has("step") ? {type: "step"} : step)], "postprocess": data => data[0].value},
|
|
107
|
+
{"name": "keywords", "symbols": [(lexer.has("colon") ? {type: "colon"} : colon)], "postprocess": data => data[0].value},
|
|
108
|
+
{"name": "keywords", "symbols": [(lexer.has("example") ? {type: "example"} : example)], "postprocess": data => data[0].value},
|
|
109
|
+
{"name": "keywords", "symbols": [(lexer.has("examples") ? {type: "examples"} : examples)], "postprocess": data => data[0].value},
|
|
110
|
+
{"name": "keywords", "symbols": [(lexer.has("scenarioOutline") ? {type: "scenarioOutline"} : scenarioOutline)], "postprocess": data => data[0].value},
|
|
111
|
+
{"name": "keywords", "symbols": [(lexer.has("background") ? {type: "background"} : background)], "postprocess": data => data[0].value},
|
|
98
112
|
{"name": "bolText", "symbols": [(lexer.has("ws") ? {type: "ws"} : ws), (lexer.has("word") ? {type: "word"} : word)], "postprocess": data => data[1].value},
|
|
99
113
|
{"name": "bolText", "symbols": [(lexer.has("word") ? {type: "word"} : word)], "postprocess": data => data[0].value},
|
|
100
114
|
{"name": "freeform", "symbols": [], "postprocess": data => ''},
|
package/src/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { parameterizeText } from './parameterize.js';
|
|
|
4
4
|
import { generateFeature } from './generate/index.js';
|
|
5
5
|
import { log, setLogLevel } from './logger.js';
|
|
6
6
|
import { parse } from './parse.js';
|
|
7
|
+
import { tagsFunction } from './tags.js';
|
|
7
8
|
|
|
8
9
|
const featureRegex = /\.feature$/;
|
|
9
10
|
|
|
@@ -12,8 +13,6 @@ const compileFeatureToJS = (config,featureSrc) => {
|
|
|
12
13
|
|
|
13
14
|
const code = generateFeature(config,feature);
|
|
14
15
|
|
|
15
|
-
log.debug(code);
|
|
16
|
-
|
|
17
16
|
return code;
|
|
18
17
|
}
|
|
19
18
|
|
|
@@ -47,15 +46,20 @@ export default function vitestCucumberPlugin() {
|
|
|
47
46
|
if (_.has('test.cucumber.logLevel',resolvedConfig)) {
|
|
48
47
|
setLogLevel(resolvedConfig.test.cucumber.logLevel);
|
|
49
48
|
}
|
|
50
|
-
|
|
49
|
+
|
|
51
50
|
config = _.get('test.cucumber',resolvedConfig);
|
|
52
51
|
config = _.set('root',resolvedConfig.root,config);
|
|
52
|
+
|
|
53
|
+
config = _.set('tagsFunction',tagsFunction(_.get('tags',config)),config);
|
|
54
|
+
|
|
53
55
|
log.debug('config: '+JSON.stringify(config));
|
|
54
56
|
},
|
|
55
57
|
transform : async (src,id) => {
|
|
56
58
|
if (featureRegex.test(id)) {
|
|
57
59
|
const code = compileFeatureToJS(config,src);
|
|
58
60
|
|
|
61
|
+
log.debug('transform '+id+' -> '+code);
|
|
62
|
+
|
|
59
63
|
return {
|
|
60
64
|
code
|
|
61
65
|
}
|
package/src/parse.js
CHANGED
|
@@ -11,7 +11,7 @@ export const parse = (src) => {
|
|
|
11
11
|
if (parser.results.length == 0) {
|
|
12
12
|
throw new Error('Unexpected end of file');
|
|
13
13
|
}
|
|
14
|
-
log.debug('parsing result: '+JSON.stringify(parser.results
|
|
14
|
+
log.debug('parsing result: '+JSON.stringify(parser.results));
|
|
15
15
|
if (parser.results.length > 1) {
|
|
16
16
|
throw new Error('Ambiguous parsing: '+parser.results.length);
|
|
17
17
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import 'lodash/fp.js';
|
|
2
|
+
import require$$1 from 'moo';
|
|
3
|
+
|
|
4
|
+
function getDefaultExportFromCjs (x) {
|
|
5
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
var tagsExpression_umd$1 = {exports: {}};
|
|
9
|
+
|
|
10
|
+
(function (module) {
|
|
11
|
+
// Generated automatically by nearley, version 2.20.1
|
|
12
|
+
// http://github.com/Hardmath123/nearley
|
|
13
|
+
(function () {
|
|
14
|
+
function id(x) { return x[0]; }
|
|
15
|
+
const moo = require$$1;
|
|
16
|
+
const lexer = moo.compile({
|
|
17
|
+
and : 'and',
|
|
18
|
+
or : 'or',
|
|
19
|
+
not : 'not',
|
|
20
|
+
openParen : '(',
|
|
21
|
+
closeParen : ')',
|
|
22
|
+
newline : { match : '\n', lineBreaks : true },
|
|
23
|
+
ws : /[ \t]+/,
|
|
24
|
+
tag : /\@[\w\.]+/,
|
|
25
|
+
});
|
|
26
|
+
var grammar = {
|
|
27
|
+
Lexer: lexer,
|
|
28
|
+
ParserRules: [
|
|
29
|
+
{"name": "main", "symbols": ["expression", (lexer.has("newline") ? {type: "newline"} : newline)], "postprocess": data => data[0]},
|
|
30
|
+
{"name": "expression", "symbols": ["tag"], "postprocess": data => data[0]},
|
|
31
|
+
{"name": "expression", "symbols": ["unaryOperation"], "postprocess": data => data[0]},
|
|
32
|
+
{"name": "expression", "symbols": ["binaryOperation"], "postprocess": data => data[0]},
|
|
33
|
+
{"name": "expression", "symbols": ["parenOperation"], "postprocess": data => data[0]},
|
|
34
|
+
{"name": "parenOperation", "symbols": [(lexer.has("openParen") ? {type: "openParen"} : openParen), "_", "expression", "_", (lexer.has("closeParen") ? {type: "closeParen"} : closeParen)], "postprocess": data => data[2]},
|
|
35
|
+
{"name": "unaryOperation", "symbols": [(lexer.has("not") ? {type: "not"} : not), (lexer.has("ws") ? {type: "ws"} : ws), "unaryExpression"], "postprocess": data => { return { operator : 'not', expression : data[2] } }},
|
|
36
|
+
{"name": "unaryExpression", "symbols": ["tag"], "postprocess": id},
|
|
37
|
+
{"name": "unaryExpression", "symbols": ["parenOperation"], "postprocess": id},
|
|
38
|
+
{"name": "binaryOperation", "symbols": ["expression", "_", "binaryOperator", "_", "expression"], "postprocess":
|
|
39
|
+
data => { return { operator : data[2], left : data[0], right : data[4] } }
|
|
40
|
+
},
|
|
41
|
+
{"name": "binaryOperator", "symbols": [(lexer.has("and") ? {type: "and"} : and)], "postprocess": data => data[0].value},
|
|
42
|
+
{"name": "binaryOperator", "symbols": [(lexer.has("or") ? {type: "or"} : or)], "postprocess": data => data[0].value},
|
|
43
|
+
{"name": "tag", "symbols": [(lexer.has("tag") ? {type: "tag"} : tag)], "postprocess": data => data[0].value.slice(1)},
|
|
44
|
+
{"name": "_", "symbols": []},
|
|
45
|
+
{"name": "_", "symbols": [(lexer.has("ws") ? {type: "ws"} : ws)]}
|
|
46
|
+
]
|
|
47
|
+
, ParserStart: "main"
|
|
48
|
+
};
|
|
49
|
+
{
|
|
50
|
+
module.exports = grammar;
|
|
51
|
+
}
|
|
52
|
+
})();
|
|
53
|
+
} (tagsExpression_umd$1));
|
|
54
|
+
|
|
55
|
+
var tagsExpression_umdExports = tagsExpression_umd$1.exports;
|
|
56
|
+
var tagsExpression_umd = /*@__PURE__*/getDefaultExportFromCjs(tagsExpression_umdExports);
|
|
57
|
+
|
|
58
|
+
export { tagsExpression_umd as default };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
@{%
|
|
2
|
+
const fp = require('lodash/fp.js');
|
|
3
|
+
const moo = require('moo');
|
|
4
|
+
const lexer = moo.compile({
|
|
5
|
+
and : 'and',
|
|
6
|
+
or : 'or',
|
|
7
|
+
not : 'not',
|
|
8
|
+
openParen : '(',
|
|
9
|
+
closeParen : ')',
|
|
10
|
+
newline : { match : '\n', lineBreaks : true },
|
|
11
|
+
ws : /[ \t]+/,
|
|
12
|
+
tag : /\@[\w\.]+/,
|
|
13
|
+
});
|
|
14
|
+
%}
|
|
15
|
+
|
|
16
|
+
@lexer lexer
|
|
17
|
+
|
|
18
|
+
main -> expression %newline {% data => data[0] %}
|
|
19
|
+
|
|
20
|
+
expression -> tag {% data => data[0] %}
|
|
21
|
+
| unaryOperation {% data => data[0] %}
|
|
22
|
+
| binaryOperation {% data => data[0] %}
|
|
23
|
+
| parenOperation {% data => data[0] %}
|
|
24
|
+
|
|
25
|
+
parenOperation -> %openParen _ expression _ %closeParen {% data => data[2] %}
|
|
26
|
+
|
|
27
|
+
unaryOperation -> %not %ws unaryExpression {% data => { return { operator : 'not', expression : data[2] } } %}
|
|
28
|
+
|
|
29
|
+
unaryExpression -> tag {% id %}
|
|
30
|
+
| parenOperation {% id %}
|
|
31
|
+
|
|
32
|
+
binaryOperation -> expression _ binaryOperator _ expression {%
|
|
33
|
+
data => { return { operator : data[2], left : data[0], right : data[4] } }
|
|
34
|
+
%}
|
|
35
|
+
|
|
36
|
+
binaryOperator -> %and {% data => data[0].value %}
|
|
37
|
+
| %or {% data => data[0].value %}
|
|
38
|
+
|
|
39
|
+
tag -> %tag {% data => data[0].value.slice(1) %}
|
|
40
|
+
|
|
41
|
+
_ -> null
|
|
42
|
+
| %ws
|
|
43
|
+
|