Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

gherkin-lint

Package Overview
Dependencies
Maintainers
1
Versions
73
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gherkin-lint - npm Package Compare versions

Comparing version 3.1.0 to 3.2.0

dist/rules/scenario-size.js

29

dist/linter.js

@@ -9,2 +9,13 @@ 'use strict';

function readAndParseFile(fileName) {
var fileContent = fs.readFileSync(fileName, 'utf-8');
var file = {
name: fileName,
lines: fileContent.split(/\r\n|\r|\n/)
};
var feature = parser.parse(fileContent).feature || {};
return { feature, file };
}
function lint(files, configuration, additionalRulesDirs) {

@@ -14,11 +25,8 @@ var output = [];

files.forEach(function (fileName) {
var fileContent = fs.readFileSync(fileName, 'utf-8');
var file = {
name: fileName,
lines: fileContent.split(/\r\n|\r|\n/)
};
var errors = [];
try {
var feature = parser.parse(fileContent).feature || {};
var _readAndParseFile = readAndParseFile(fileName),
feature = _readAndParseFile.feature,
file = _readAndParseFile.file;
errors = rules.runAllEnabledRules(feature, file, configuration, additionalRulesDirs);

@@ -66,3 +74,3 @@ } catch (e) {

if (errors[i].message.indexOf('expected: #TagLine, #ScenarioLine, #ScenarioOutlineLine, #Comment, #Empty') > -1) {
index = i;
index = i + 1;
} else {

@@ -73,3 +81,3 @@ break;

}
return { errors: errors.slice(index, errors.length), errorMsgs: errorMsgs };
return { errors: errors.slice(index), errorMsgs: errorMsgs };
}

@@ -103,3 +111,4 @@

module.exports = {
lint: lint
lint: lint,
readAndParseFile: readAndParseFile
};

@@ -64,6 +64,8 @@ 'use strict';

test(examples.location, 'Examples');
test(examples.tableHeader.location, 'example');
examples.tableBody.forEach(function (row) {
test(row.location, 'example');
});
if (examples.tableHeader) {
test(examples.tableHeader.location, 'example');
examples.tableBody.forEach(function (row) {
test(row.location, 'example');
});
}
});

@@ -110,3 +112,3 @@ }

if (!feature || Object.keys(feature).length === 0) {
return;
return [];
}

@@ -113,0 +115,0 @@ var mergedConfiguration = mergeConfiguration(configuration);

@@ -23,32 +23,31 @@ 'use strict';

function nameLength(feature, unused, configuration) {
if (!feature || Object.keys(feature).length === 0) {
return;
}
var mergedConfiguration = _.merge(availableConfigs, configuration);
errors = [];
if (feature && Object.keys(feature).length !== 0) {
var mergedConfiguration = _.merge(availableConfigs, configuration);
// Check Feature name length
test(feature.name, feature.location, mergedConfiguration, 'Feature');
// Check Feature name length
test(feature.name, feature.location, mergedConfiguration, 'Feature');
feature.children.forEach(function (child) {
switch (child.type) {
case 'Scenario':
case 'ScenarioOutline':
// Check Scenario name length
test(child.name, child.location, mergedConfiguration, 'Scenario');
break;
case 'Background':
break;
default:
errors.push({ message: 'Unknown gherkin node type ' + child.type,
rule: rule,
line: child.location.line });
break;
}
feature.children.forEach(function (child) {
switch (child.type) {
case 'Scenario':
case 'ScenarioOutline':
// Check Scenario name length
test(child.name, child.location, mergedConfiguration, 'Scenario');
break;
case 'Background':
break;
default:
errors.push({ message: 'Unknown gherkin node type ' + child.type,
rule: rule,
line: child.location.line });
break;
}
child.steps.forEach(function (step) {
// Check Step name length
test(step.text, step.location, mergedConfiguration, 'Step');
child.steps.forEach(function (step) {
// Check Step name length
test(step.text, step.location, mergedConfiguration, 'Step');
});
});
});
}

@@ -55,0 +54,0 @@ return errors;

@@ -10,2 +10,3 @@ 'use strict';

function newLineAtEOF(unused, file, configuration) {
var errors = [];
if (_.indexOf(availableConfigs, configuration) === -1) {

@@ -25,6 +26,10 @@ logger.boldError(rule + ' requires an extra configuration value.\nAvailable configurations: ' + availableConfigs.join(', ') + '\nFor syntax please look at the documentation.');

if (errormsg !== '') {
return { message: errormsg,
errors.push({
message: errormsg,
rule: rule,
line: file.lines.length };
line: file.lines.length
});
}
return errors;
}

@@ -31,0 +36,0 @@

@@ -7,9 +7,12 @@ 'use strict';

function noDuplicateFeatureNames(feature, file) {
if (feature.name) {
var errors = [];
if (feature && feature.name) {
if (feature.name in features) {
var dupes = features[feature.name].files.join(', ');
features[feature.name].files.push(file.name);
return { message: 'Feature name is already used in: ' + dupes,
errors.push({
message: 'Feature name is already used in: ' + dupes,
rule: rule,
line: feature.location.line };
line: feature.location.line
});
} else {

@@ -19,2 +22,3 @@ features[feature.name] = { files: [file.name] };

}
return errors;
}

@@ -21,0 +25,0 @@

@@ -5,6 +5,10 @@ 'use strict';

var scenarios = [];
var availableConfigs = ['anywhere', 'in-feature'];
function noDuplicateScenarioNames(feature, file) {
if (feature.children) {
var errors = [];
function noDuplicateScenarioNames(feature, file, configuration) {
var errors = [];
if (configuration === 'in-feature') {
scenarios = [];
}
if (feature && feature.children) {
feature.children.forEach(function (scenario) {

@@ -23,4 +27,4 @@ if (scenario.name) {

});
return errors;
}
return errors;
}

@@ -38,3 +42,4 @@

name: rule,
run: noDuplicateScenarioNames
run: noDuplicateScenarioNames,
availableConfigs: availableConfigs
};

@@ -5,10 +5,13 @@ 'use strict';

var rule = 'no-empty-file';
var suppressOtherRules = true;
function noEmptyFiles(feature) {
var errors = [];
if (_.isEmpty(feature)) {
return { message: 'Empty feature files are disallowed',
errors.push({
message: 'Empty feature files are disallowed',
rule: rule,
line: 1 };
line: 1
});
}
return errors;
}

@@ -18,4 +21,3 @@

name: rule,
run: noEmptyFiles,
suppressOtherRules: suppressOtherRules
run: noEmptyFiles
};

@@ -10,7 +10,11 @@ 'use strict';

function noFilesWithoutScenarios(feature) {
var errors = [];
if (!feature.children || !feature.children.some(filterScenarios)) {
return { message: 'Feature file does not have any Scenarios',
errors.push({
message: 'Feature file does not have any Scenarios',
rule: rule,
line: 1 };
line: 1
});
}
return errors;
}

@@ -17,0 +21,0 @@

@@ -7,3 +7,3 @@ 'use strict';

var errors = [];
if (feature.children) {
if (feature && feature.children) {
feature.children.forEach(function (scenario) {

@@ -13,3 +13,3 @@ if (scenario.tags) {

if (tag.name.indexOf('#') > 0) {
errors.push({ message: 'Partially commented tag lines not allowed ',
errors.push({ message: 'Partially commented tag lines not allowed',
rule: rule,

@@ -16,0 +16,0 @@ line: tag.location.line });

'use strict';
var _ = require('lodash');
var rule = 'no-scenario-outlines-without-examples';

@@ -8,4 +9,5 @@

var errors = [];
feature.children.forEach(function (scenario) {
if (scenario.type === 'ScenarioOutline' && !scenario.examples.length) {
if (scenario.type === 'ScenarioOutline' && (!_.find(scenario.examples, 'tableBody') || !_.find(scenario.examples, 'tableBody')['tableBody'].length)) {
errors.push({ message: 'Scenario Outline does not have any Examples',

@@ -12,0 +14,0 @@ rule: rule,

@@ -6,7 +6,10 @@ 'use strict';

function noUnNamedFeatures(feature) {
var errors = [];
if (!feature || !feature.name) {
return { message: 'Missing Feature name',
errors.push({
message: 'Missing Feature name',
rule: rule,
line: feature.location && feature.location.line || 0 };
line: feature.location && feature.location.line || 0 });
}
return errors;
}

@@ -13,0 +16,0 @@

@@ -6,4 +6,4 @@ 'use strict';

function noUnNamedScenarios(feature) {
if (feature.children) {
var errors = [];
var errors = [];
if (feature && feature.children) {
feature.children.forEach(function (scenario) {

@@ -16,4 +16,4 @@ if (!scenario.name && scenario.type === 'Scenario') {

});
return errors;
}
return errors;
}

@@ -20,0 +20,0 @@

{
"name": "gherkin-lint",
"version": "3.1.0",
"version": "3.2.0",
"description": "A Gherkin linter/validator written in javascript",

@@ -82,2 +82,3 @@ "author": "Vasiliki Siakka",

"mocha-sinon": "2.1.0",
"nyc": "14.0.0",
"sinon": "6.2.0"

@@ -93,2 +94,3 @@ },

"mocha": "mocha --recursive",
"code-coverage": "nyc --reporter=text --include=dist/** mocha --recursive",
"prepublish": "npm run build",

@@ -95,0 +97,0 @@ "test": "npm run lint && npm run build && npm run mocha"

@@ -12,3 +12,2 @@ # Gherkin lint

npm install gherkin-lint
```

@@ -44,3 +43,3 @@

| `no-dupe-feature-names` | Disallows duplicate Feature names |
| `no-dupe-scenario-names` | Disallows duplicate Scenario names |
| [`no-dupe-scenario-names`](#no-dupe-scenario-names)| Disallows duplicate Scenario names |
| `no-duplicate-tags` | Disallows duplicate tags on the same Feature or Scenario |

@@ -60,2 +59,3 @@ | `no-empty-background` | Disallows features with backgrounds without steps |

| `no-unused-variables` | Disallows unused variables in scenario outlines |
| [`scenario-size`](#scenario-size) | Allows restricting the maximum number of steps in a scenario, scenario outline and background |
| `one-space-between-tags` | Tags on the same time must be separated by a single space |

@@ -147,3 +147,3 @@ | `use-and` | Disallows repeated step names requiring use of And instead |

`new-line-at-eof` can also be configured to enforcing or disallowing new lines at EOF.
`new-line-at-eof` can be configured to enforce or disallow new lines at EOF.
- To enforce new lines at EOF:

@@ -163,8 +163,34 @@ ```

### no-restricted-tags
### no-dupe-scenario-names
`no-restricted-tags` must be configured with list of tags for it to have any effect:
`no-dupe-scenario-names` can be configured to search for duplicates in each individual feature or amongst all feature files.
To enable searching for duplicates in each individual feature (same scenario name in different features won't raise an error) you need to configure the rule like this:
```
{
"no-dupe-scenario-names": ["on", "in-feature"]
}
```
The default case is testing against all the features (same scenario name in different features will raise an error). To get that behavor use the following configuration:
```
{
"no-dupe-scenario-names": "on"
}
```
or
```
{
"no-dupe-scenario-names": ["on", "anywhere"]
}
```
### no-restricted-tags
`no-restricted-tags` should be configured with the list of restricted tags:
```
{
"no-restricted-tags": ["on", {"tags": ["@watch", "@wip", "@todo"]}]

@@ -175,2 +201,11 @@ }

### scenario-size
`scenario-size` lets you specify a maximum step length for scenarios and backgrounds. The `Scenario` configuration applies to both scenarios and scenario outlines:
```
{
"scenario-size": ["on", { "steps-length": { "Background": 15, "Scenario": 15 }}]
}
```
## Configuration File

@@ -177,0 +212,0 @@ The default name for the configuration file is `.gherkin-lintrc` and it's expected to be in your working directory.

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc