Giter Site home page Giter Site logo

gherkin-lint's Introduction

Gherkin lint

Run NodeJS Tests Coverage Status npm

Uses Gherkin to parse feature files and runs linting against the default rules, and the optional rules you specified in your .gherkin-lintrc file.

Installation

npm install gherkin-lint

Demo

To see the output for all the errors that the linter can detect run:

git clone https://github.com/gherkin-lint/gherkin-lint.git
npm run demo

Or check this: console

Available rules

Name Functionality
no-tags-on-backgrounds * Disallows tags on Background
one-feature-per-file * Disallows multiple Feature definitions in the same file
up-to-one-background-per-file * Disallows multiple Background definition in the same file
no-multiline-steps * Disallows mutiline Steps
allowed-tags Just the listed tags are allowed
file-name Restrict feature file names to a commmon style
indentation Allows the user to specify indentation rules
max-scenarios-per-file Allows the user to specify the max number of scenarios per feature file
name-length Allows restricting length of Feature/Scenario/Step names
new-line-at-eof Disallows/enforces new line at EOF
no-background-only-scenario Disallows background when there is just one scenario
no-dupe-feature-names Disallows duplicate Feature names
no-dupe-scenario-names Disallows duplicate Scenario names
no-duplicate-tags Disallows duplicate tags on the same Feature or Scenario
no-empty-background Disallows features with backgrounds without steps
no-empty-file Disallows empty feature files
no-examples-in-scenarios Disallow the use of "Examples" in Scenarios, only allowed in Scenario Outlines
no-files-without-scenarios Disallows files with no scenarios
no-homogenous-tags Disallows tags present on every Scenario in a Feature, rather than on the Feature itself
no-multiple-empty-lines Disallows multiple empty lines
no-partially-commented-tag-lines Disallows partially commented tag lines
no-restricted-patterns A list of patterns to disallow globally, or specifically in features, backgrounds, scenarios, or scenario outlines
no-restricted-tags Disallow use of particular @tags
no-scenario-outlines-without-examples Disallows scenario outlines without examples
no-superfluous-tags Disallows tags present on a Feature and a Scenario in that Feature
no-trailing-spaces Disallows trailing spaces
no-unnamed-features Disallows empty Feature name
no-unnamed-scenarios Disallows empty Scenario name
no-unused-variables Disallows unused variables in scenario outlines
one-space-between-tags Tags on the same line must be separated by a single space
required-tags Require tags/patterns of tags on Scenarios
scenario-size Allows restricting the maximum number of steps in a scenario, scenario outline and background
use-and Disallows repeated step names requiring use of And instead
keywords-in-logical-order Requires that Given, When and Then appear in logical sequence
only-one-when Requires that there is at most one When step for each scenario

* These rules cannot be turned off because they detect undocumented cucumber functionality that causes the gherkin parser to crash.

Rule Configuration

The not-configurable rules are turned on by default and cannot be turned off. Configurable rules can be customized using a file.

The configurable rules are off by default. To turn them on, you will need to create a json file, where you specify the name of each rule and its desired state (which can be "on" or "off"). Eg:

{
  "no-unnamed-features": "on"
}

will turn on the no-unnamed-features rule.

allowed-tags

allowed-tags should be configured with the list of allowed tags and patterns:

{
  "allowed-tags": ["on", {"tags": ["@watch", "@wip"], "patterns": ["^@todo$"]}]
}

Any tag not included in this list won't be allowed.

file-name

file-name is configured with a style to enforce. The default is PascalCase:

{
  "file-name": ["on", {"style": "PascalCase"}]
}

The list of supported styles is:

  • PascalCase - first letter of each word capitalized (no spaces) e.g. "MyFancyFeature.feature"
  • Title Case - first letter of each word capitalized (with spaces) e.g. "My Fancy Feature.feature"
  • camelCase - first letter of each word capitalized, except first e.g. "myFancyFeature.feature"
  • kebab-case - all lowercase, hyphen-delimited e.g. "my-fancy-feature.feature"
  • snake_case - all lowercase, underscore-delimited e.g. "my_fancy_feature.feature"

no-restricted-patterns

no-restricted-patterns is a list of exact or partial patterns whose matches are dissallowed in feature name and description, and in background, scenario and scenario outline name, description and steps. All patterns are treated as case insensitive. The rule can be configured like this:

{
  "no-restricted-patterns": ["on", {
    "Global": [
      "^globally restricted pattern"
    ],
    "Feature": [
      "poor description",
      "validate",
      "verify"
    ],
    "Background": [
      "show last response",
      "a debugging step"
    ],
    "Scenario": [
      "show last response",
      "a debugging step"
    ]
  }]
}

Notes:

  • Step keywords Given, When, Then and And should not be included in the patterns.
  • Description violations always get reported in the Feature/Scenario/etc definition line. This is due to the parsed gherkin tree not having information about which line the description appears.

indentation

indentation can be configured in a more granular level and uses following rules by default:

  • Expected indentation for Feature, Background, Scenario, Examples heading: 0 spaces
  • Expected indentation for Steps and each example: 2 spaces

You can override the defaults for indentation like this:

{
  "indentation" : [
    "on", {
      "Feature": 0,
      "Background": 0,
      "Scenario": 0,
      "Step": 2,
      "Examples": 0,
      "example": 2,
      "given": 2,
      "when": 2,
      "then": 2,
      "and": 2,
      "but": 2,
      "feature tag": 0,
      "scenario tag": 0
    }
  ]
}

There is no need to override all the defaults, as is done above, instead they can be overriden only where required. Step will be used as a fallback if the keyword of the step, eg. 'given', is not specified. If feature tag is not set then Feature is used as a fallback, and if scenario tag is not set then Scenario is used as a fallback.

This feature is able to handle all localizations of the gherkin steps.

max-scenarios-per-file

The max-scenarios-per-file supports some configuration options:

  • maxScenarios (number) the maximum scenarios per file after which the rule fails - defaults to 10
  • countOutlineExamples (boolean) whether to count every example row for a Scenario Outline, as opposed to just 1 for the whole block - defaults to true

The configuration looks like this (showing the defaults):

{
  "max-scenarios-per-file": ["on", {"maxScenarios": 10, "countOutlineExamples": true}]
}

name-length

name-length can be configured separately for Feature, Scenario and Step names. The default is 70 characters for each of these:

{
  "name-length" : ["on", { "Feature": 70, "Scenario": 70, "Step": 70 }]
}

new-line-at-eof

new-line-at-eof can be configured to enforce or disallow new lines at EOF.

  • To enforce new lines at EOF:
{
  "new-line-at-eof": ["on", "yes"]
}
  • To disallow new lines at EOF:
{
  "new-line-at-eof": ["on", "no"]
}

no-dupe-scenario-names

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 and patterns:

{
  "no-restricted-tags": ["on", {"tags": ["@watch", "@wip"], "patterns": ["^@todo$"]}]
}

required-tags

required-tags supports some configuration options:

  • tags (array) the array of tag patterns that must match at least one tag - defaults to []
  • ignoreUntagged (boolean) whether to ignore scenarios that have no tag - defaults to true
{
  "required-tags": ["on", {"tags": ["^@issue:[1-9]\\d*$"], "ignoreUntagged": false}]
}

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

The default name for the configuration file is .gherkin-lintrc and it's expected to be in your working directory.

The file contents must be valid JSON, though it does allow comments.

If you are using a file with a different name or a file in a different folder, you will need to specify the -c or --config option and pass in the relative path to your configuration file. Eg: gherkin-lint -c path/to/configuration/file.extention

You can find an example configuration file, that turns on all of the rules in the root of this repo (.gherkin-lintrc).

Ignoring Feature Files

There are 2 ways you can specify files that the linter should ignore:

  1. Add a .gherkin-lintignore file in your working directory and specify one glob pattern per file line
  2. Use the command line option-i or --ignore, pass in a comma separated list of glob patterns. If specified, the command line option will override the .gherkin-lintignore file.

Custom rules

You can specify one more more custom rules directories by using the -r or --rulesdir command line option. Rules in the given directories will be available additionally to the default rules.

Example:

gherkin-lint --rulesdir "/path/to/my/rulesdir" --rulesdir "from/cwd/rulesdir"

Paths can either be absolute or relative to the current working directory. Have a look at the src/rules/ directory for examples; The no-empty-file rule is a good example to start with.

gherkin-lint's People

Contributors

andrewnicols avatar bayandin avatar bloodsoul avatar cujarrett avatar davidjgoss avatar deivid-rodriguez avatar dependabot[bot] avatar guykisel avatar jhedstrom avatar joscha avatar josemenveg avatar juanmaruiz avatar mathieucouette avatar nene avatar opichals avatar ricmatsui avatar roryp2 avatar saily avatar simonstjg avatar timbru31 avatar ufomelkor avatar vsiakka avatar xgbuils avatar zooduck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gherkin-lint's Issues

extend config from a package

would you consider supporting including a rules definition from a package, maybe in a similar way to specifying --rulesdir? i could see support either through another cli option, like --rulespackage or through an extends property in the .gherkin-lintrc.

is this already possible in a way that i'm overlooking?

multilines not supported

multilines generates an error:
"errors":[{"message":"(17:0): unexpected end of file, expected: #DocStringSeparator, #Other","rule":"unexpected-error","line":"17"}]

Provide sensible default configuration

It's a bit of a drag the tool cannot be used without the configuration file. Maybe all the values could have their defaults and only if I want to override something I could add the file?

Indentation rule displays already found errors again

If the indentation rule finds an issue, it will display it again in the next feature file with other issues, too, although the issue is not present in this file. It seems like the error object is not empty when a new feature file is parsed.

/Users/timbru/work/project/__tests__/features/test1.feature
  19    Wrong indentation for "Step", expected 2 spaces, got 1    indentation


/Users/timbru/work/project/__tests__/features/test2.feature
  19    Wrong indentation for "Step", expected 2 spaces, got 1    indentation

The second file though is correctly indented.

Bug: one-space-between-tags rule fails when paired with indentation rule

Steps to reproduce:

  1. Turn all rules off except indentation and one-space-between-tags
  2. Execute npm run demo

The results incorrectly identify many features with correct tag spacing. Among them, the feature designed to NOT have violations:

gherkin-lint/test/rules/one-space-between-tags/NoViolations.feature
  1     There is more than one space between the tags @featuretag1 and @featuretag2            one-space-between-tags
  8     There is more than one space between the tags @scenariotag1 and @scenariotag2          one-space-between-tags
  9     There is more than one space between the tags @scenariotag3 and @scenariotag4          one-space-between-tags
  13    There is more than one space between the tags @scenariotag5 and @scenariotag6          one-space-between-tags

If you turn indentation off, one-space-between-tags appears to work fine.

Removing global variables in rules

Some rules like no-dupe-scenarios-names.js or no-dupe-feature-names.js depend on global variables. It means that once we require ther file with these rules, the global variables like scenarios or features are initialized and cannot be reseted.

This kind of things makes it difficult to execute isolated unit tests. For example, if we have a multiple tests that executes run method of no-dupe-feature-names.js, only the first test will have the features variable empty.

I want to convert the rules to classes and convert the global variables to properties initialize in theirs constructors. Then, I want to create the instances of this classes in getAllRules function. However, if we want to achieve te correct behaviour, getAllRules should be called just once per app execution. Then, we need to merge first the #122 PR that fixes this issue.

Cheers!

Compatibility with gherkin >=4.0.0

Gherkin 4.0.0 does not work with gherkin-lint, due to breaking change cucumber/gherkin-javascript@64f3e85

e.g. scenarioDefinitions is not anymore in the ast

Stacktrace:

/Users/timbru/work/project/node_modules/gherkin-lint/src/linter.js:20
        throw e;
        ^

TypeError: Cannot read property 'column' of undefined
    at test (/Users/timbru/work/project/node_modules/gherkin-lint/src/rules/indentation.js:20:23)
    at Object.indentation [as run] (/Users/timbru/work/project/node_modules/gherkin-lint/src/rules/indentation.js:32:3)
    at /Users/timbru/work/project/node_modules/gherkin-lint/src/rules.js:41:24
    at Array.forEach (native)
    at Object.runAllEnabledRules (/Users/timbru/work/project/node_modules/gherkin-lint/src/rules.js:39:17)
    at /Users/timbru/work/project/node_modules/gherkin-lint/src/linter.js:15:22
    at Array.forEach (native)
    at Object.lint (/Users/timbru/work/project/node_modules/gherkin-lint/src/linter.js:10:9)
    at Object.<anonymous> (/Users/timbru/work/project/node_modules/gherkin-lint/src/main.js:24:22)
    at Module._compile (module.js:409:26)

How to ignore node_module files?

When I try to ignore any folders o files, now the plugin add the node_modules in the list of feature to review. I try to ignore it with the .gherkin-lintignore rule but never it's happens.

Feature Request: Adding a warning option

Instead of just on and off in the config file, can we have a warning option as well like eslint. It will give people a chance to fix problems without failing it.

Support TAP

The TAP allows to report results in a standard format consumable by many other tools. If TAP is supported, users can pipe the tool output into any kind of obscure reporting format they need and the maintainer of the tool isn't burdened by supporting various output formats.

Add rule for no-examples-in-scenario-outline

The parser currently does not crash if a Scenario Outline defines no Examples. Instead the user should see a nicely formatted error message stating what's wrong with his feature and that he is missing Examples in his/her feature.

Example object of parsed feature file without examples:

{ type: 'Feature',
  tags:
   [ { type: 'Tag', location: [Object], name: '@Foo-135' },
     { type: 'Tag', location: [Object], name: '@bar' } ],
  location: { line: 3, column: 1 },
  language: 'en',
  keyword: 'Feature',
  name: 'Foo baz',
  description: undefined,
  children:
   [ { type: 'ScenarioOutline',
       tags: [Object],
       location: [Object],
       keyword: 'Scenario Outline',
       name: 'Scenario1 -Default bar baz',
       description: undefined,
       steps: [Object],
       examples: [] } ] }

Missing support for ScenarioOutlines

When running gherkin-lint for features that contains ScenarioOutlines I get results like this:

  1     Feature file does not have any Scenarios     no-files-without-scenarios
  10    Unknown gherkin node type ScenarioOutline    indentation
  22    Unknown gherkin node type ScenarioOutline    indentation
  34    Unknown gherkin node type ScenarioOutline    indentation

Add JSDoc

I think it would be useful to add JSDoc to the project. It would be easier to contribute and you could generate documentation automatically. What do you think?

Dependency inversion for allowing to perform unit tests and removing some coupled code.

In order to start to make unit tests and not functional or integration tests, we need to remove parts of code that are coupled with others.

It's dificult to test modules that requires other modules. We need to passing dependencies via constructor and delegate the construction of object to the top of the application. In the coming days, I'm going to do a PR with a refactor that removes module dependencies in rules.js, config-parser.js, config-verifier.js and linter.js.

The idea is inverting the dependencies for allowing unit testing in these parts of code. A side effect will be improving the performance avoiding to call getAllRules multiple times. Currently, getAllRules is called in the linter and in config-verifier through getRule and doesRuleExist methods.

Cheers.

don't find .feature files

it works perfectly if i pass the exact path...but if i launch only the command don't work properly (don't return anything...simply return the shell )

More user-friendly behavior when running without options

Currently when you run gherkin-lint in a random directory, you'll get a crash:

$ gherkin-lint
/Users/nene/.nvm/versions/node/v6.9.1/lib/node_modules/gherkin-lint/src/config-parser.js:14
      throw new Error('Could not find default config file "' + defaultConfigFileName +'" in the working ' +
      ^

Error: Could not find default config file ".gherkin-lintrc" in the working directory. To use a custom name/location provide the config file using the "-c" arg
    at Object.getConfiguration (/Users/nene/.nvm/versions/node/v6.9.1/lib/node_modules/gherkin-lint/src/config-parser.js:14:13)
    at Object.<anonymous> (/Users/nene/.nvm/versions/node/v6.9.1/lib/node_modules/gherkin-lint/src/main.js:19:27)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:394:7)
    at startup (bootstrap_node.js:149:9)

Luckily the error message tells you exactly what's wrong, but it should be printed without the stack trace.

If you then run gherkin lint in a directory that contains a config file... you'll get no output:

$ gherkin-lint

This leaves one wondering whether everything perhaps just passed the linter. But in fact you just forgot to specify the feature files to lint. An error message would be in order to point out this mistake. I don't think there's a use-case for running the linter on no files at all.

Feature Request: allowed-tags

Essentially the opposite of no-restricted-tags; only tags defined in this rule's array can be used.

"allowed-tags": [ "on", { "tags": [ "@foo" ] } ]
@foo
Scenario: This will pass validation

@bar 
Scenario: This will fail validation

Linting of the step definition files

What are your thoughts about pulling JavaScript files also into the linting process?

Two things I'd like to check with a linter:

  • Unused step definitions (a step is defined in JS, but not used in any *.feature file).
  • Step definition keyword doesn't match with keyword used for that step in a *.feature file (e.g. a Then step is defined, but it's used as a When step).

I guess this question comes down to whether gherkin-lint should be agnostic of the implementation language. Would we expect gherkin-lint to be used outside the JavaScript ecosystem?

The other part of the question is whether these step definition files are consistent enough even inside JavaScript world.

cucumber-js docs show the following step definitions:

var {defineSupportCode} = require('cucumber');

defineSupportCode(function({Then, When}) {
  Then(/^Then the response status is (.*)$/, function (status) {
    // ...
  });
});

While chimp docs define steps as follows:

module.exports = function() {
  this.Then(/^Then the response status is (.*)$/, function (status) {
    // ...
  });
}

Cucumber.js docs actually also show that this.Then() syntax can also be used. Perhaps the vice versa is true for Chimp. I understand Chimp actually uses the same Cucumber.js under the hood.

Additional rules: problem verifying "availableConfigs"

I have been creating a new rule to check if a step have some key words and I have some problem launching this rule.

It seems that in the gherkin-lint/src/config-verifier.js file, when calling the getRule method, the additionalRulesDirs (which contains the path to my own rules) is not specified.

To fix it, it's needed to add the additionalRulesDirs parameter in all the getRule method calls, which implies add the parameter to verifyRuleConfiguration and testSubconfig methods.

I have fixed in my local version in this way

_var rules = require('./rules.js');

function verifyConfigurationFile(config, additionalRulesDirs) {
  var errors = [];
  for (var rule in config) {
    if (!rules.doesRuleExist(rule, additionalRulesDirs)) {
      errors.push('Rule "' + rule + '" does not exist');
    } else {
      verifyRuleConfiguration(rule, config[rule], additionalRulesDirs, errors);
    }
  }
  return errors;
}

function verifyRuleConfiguration(rule, ruleConfig, additionalRulesDirs, errors) {
  var enablingSettings = ['on', 'off'];
  var genericErrorMsg = 'Invalid rule configuration for "' + rule + '" - ';

  if (Array.isArray(ruleConfig)) {
    if (enablingSettings.indexOf(ruleConfig[0]) === -1) {
      errors.push(genericErrorMsg + 'The first part of the config should be "on" or "off"');
    }

    if (ruleConfig.length != 2 ) {
      errors.push(genericErrorMsg + ' The config should only have 2 parts.');
    }

    var ruleObj = rules.getRule(rule, additionalRulesDirs);
    var isValidSubConfig;

    if (typeof(ruleConfig[1]) === 'string') {
      isValidSubConfig = function(availableConfigs, subConfig) {
        return ruleObj.availableConfigs.indexOf(subConfig) > -1;
      };
      testSubconfig(genericErrorMsg, rule, ruleConfig[1], isValidSubConfig, additionalRulesDirs, errors);
    } else {
      isValidSubConfig = function(availableConfigs, subConfig) {
        return ruleObj.availableConfigs[subConfig] !== undefined;
      };
      for (var subConfig in ruleConfig[1]) {
        testSubconfig(genericErrorMsg, rule, subConfig, isValidSubConfig, additionalRulesDirs, errors);
      }
    }
  } else {
    if (enablingSettings.indexOf(ruleConfig) == -1) {
      errors.push(genericErrorMsg + 'The the config should be "on" or "off"');
    }
  }
}

function testSubconfig(genericErrorMsg, rule, subConfig, isValidSubConfig, additionalRulesDirs, errors) {
  var ruleObj = rules.getRule(rule, additionalRulesDirs);
  if (!isValidSubConfig(ruleObj.availableConfigs, subConfig)) {
    errors.push(genericErrorMsg + ' The rule does not have the specified configuration option "' + subConfig + '"');
  }
}

module.exports = verifyConfigurationFile;_

Problems with the pre-pull requests checks

I've created a pull request #137 and the checks have failed.

The rules are indentation rule and one space between tags rule which I haven't modified.

If I launch npm run test in local it works fine.

Any ideas?

Bug: Rule "no-unused-variables" does not recognize variables used in scenario name, step tables, or step strings

Rule "no-unused-variables" does not recognize when variables are used in:

  1. scenario names
  2. step tables
  3. step strings

Examples:

Feature: Rule "no-unused-variables" bugs

  Scenario Outline: Examples variable <variable> is in the scenario name
    Given this
    When I do that
    Then something should happen
    Examples:
      | variable |
      | foo      |
      | bar      |

  Scenario Outline: Examples variable is in a step table
    Given this:
      | <variable> |
    When I do that
    Then something should happen
    Examples:
      | variable |
      | foo      |
      | bar      |

  Scenario Outline: Examples variable is in a step string
    Given this
    When I do that
    Then this should display:
      """
        <variable>
      """
    Examples:
      | variable |
      | foo      |
      | bar      |

Result:

node ./node_modules/gherkin-lint ./features/testRule.feature -c ./.gherkin-lintrc
.../cucumber/features/testRule.feature
  8     Examples table variable "variable" is not used in any step    no-unused-variables
  18    Examples table variable "variable" is not used in any step    no-unused-variables
  30    Examples table variable "variable" is not used in any step    no-unused-variables

For Scenario Outline: Examples variable <variable> is in the scenario name, I'm not sure if this is best practice. My team seems to have gotten creative with naming conventions and this actually makes the report more clear with dynamic naming. I'll leave it up to the community to decide if this should be supported.

The other two examples seems clear cut bugs to me.

Limit the size of scenarios

Long scenarios are hard to read and they're a smell indicating there's something wrong with the approach you took when writing the Gherkins. It would be nice to have a rule ensuring the scenarios have no more than X steps. Analogous to cyclomatic complexity of code.

Capturing output

As far as I can tell there is no way to capture the output of the linter via normal unix redirects, like > out.txt since the linter raises npm errors which get sent to stderr.

I'm wondering if it would be better to report errors to stdout or at least have an option to do so.

Why to use console.error instead of console.log to print results

Hi, I would like to know why are you using console.error instead of console.log to print all the results.

function printResults(results) { console.error(JSON.stringify(results)); }

Maybe the confusion is because the name of the function in charge of print the messages. Is this function only used to print errors?

Best regards.

JuanMa

Feature Request: rules for codeformatting

Hi,

first of all, thanks for the project! ๐Ÿป

Is it possible to add some formatting/code style rules? EditorConfig can fix many of these issue, but it would be better if the linter would throw an error if there are

  • trailing spaces
  • no newlines at EOF
  • consecutive blank lines
  • the indention level is wrong

Do you think this is possible to add?

Feature request: Rule to prevent unused/incorrect example data

I lost some time yesterday due to a tab header in an example set being different after a 'Step_arg` name change. It occurs to me this is the kind of problem a computer should solve instead of a human and it shouldn't (might) not be too hard to write a rule to check if there are any example headings not needed/used in the scenario above.

I need help because I haven't dealt with parsers and don't know what the js objects look like that burp outputs. I've tried looking at the docs but I haven't been able to find what the output objects look like.

I totally don't mind putting some time into this because it would be awesome, but I'm a bit of a noob so I could use some help :P

Allow no-dupe-scenario-names to only flag duplicate scenarios inside one feature

The current rule looks for scenario name duplicates globally. For my purposes I don't find this useful as I have several features where I want to test the same scenario. But I can imagine some might want all their scenarios to be uniquely named, and it's fine.

However if there are duplicate scenario names within the same feature, then that's clearly an error and I'd like gherkin-lint to catch this.

I'd propose configuration syntax like:

"no-dupe-scenario-names": ["on", "global"], // the default (current behavior)
"no-dupe-scenario-names": ["on", "feature-local"],

Or perhaps:

"no-dupe-scenario-names": ["on", "anywhere"], // the default (current behavior)
"no-dupe-scenario-names": ["on", "in-feature"],

Not really sure what the good names for these config options should be.

An alternative would be to have a completely separate rule, but that wouldn't make sense as one would never combine the two rules.

I'm willing to do a PR for this, but I'd like to settle the naming question first.

Support for custom rules

Hello!

I love that this gherkin linter exists, but I was wondering if there was any planned support for custom rules. I have some very specific app-related things I want to lint for that shouldn't be included in this project, but still would love to lint for.

Feature Request: Expand Indentation rule to check docstring

It would be nice to enforce consistency with docstrings, too:

{
  "indentation" : [
    "on", {
      "Feature": 0,
      "Scenario": 2,
      "Step": 4,
      "docstring": 6
    }
  ]
}

Example:

Feature: My team is never consistent with anything
  
  Scenario: Quotes are indented 6 spaces
    When I use this docstring:
      """
      This is a docstring
      """
    Then the rule should pass

  Scenario: Quotes are indented 4 spaces
    When I use this docstring:
    """
    This is a docstring
    """
    Then the rule should fail

  Scenario: Quotes are indented 6 spaces but parts of the string are LESS than 6
    When I use this docstring:
      """
    {
"bad": "json",
    "is": "bad"
      }
      """
    Then the rule should fail

  Scenario: Quotes are indented 6 spaces and all parts of the string are AT LEAST 6
    When I use this docstring:
      """
      {
        "good": "json",
        "is": "good"
      }
      """
    Then the rule should pass

Switch to ES6

I've tried to follow the existing code convention of using only ES5 features, but that's kinda painful when you're used to writing ES6 all day. It's also my pet-peeve as I'm the maintainer of Lebab.

  • The obvious route is to use Babel for transpiling the code.
  • Another option is to only support Node >= 6. I don't see a required Node version specified in package.json, but .travis.yml lists all kinds of old versions. Given that gherkin-lint is less than a year old and it's not a library, I doubt there's an actual a need to support these old versions.

Either way, I'm happy to help out with the conversion.

Bug or feature request

Trying to call it in the grunt task but I am not getting error but not getting error exit code 1 like:

Running "gklint" task
/Users/linj/redbox_spa/redbox_angular/test/e2e/features/time/timecard/estimates.feature
  46    Missing Scenario name    no-unamed-scenarios
Done, without errors.

Here is my code:

  grunt.registerTask('gklint', function () {
    var done = this.async();
    nodeCommandRunner(['node_modules/gherkin-lint', '.'], done);
  });

  var nodeCommandRunner = function (flags, done) {
    var runner = grunt.util.spawn({
      cmd: 'node',
      args: flags
    }, function() {
      done();
    });

    runner.stdout.pipe(process.stdout);
    runner.stderr.pipe(process.stderr);
  };

Did I do something wrong? Or it is a bug?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.