From 1e6651e0a0039185d63ebe4f26f04937e82207fb Mon Sep 17 00:00:00 2001 From: Eddie Lebow Date: Tue, 17 Apr 2018 00:29:13 -0400 Subject: [PATCH] Add cucumber checker for cucumber files For now, it only detects undefined steps. The nearest `features` dir above the buffer file is loaded, so step definitions should be found correctly. Tested only with Cucumber for Ruby, but it should work for any cucumber that follows a substantially similar directory structure. --- README.md | 1 + ale_linters/cucumber/cucumber.vim | 45 +++++++++++++++++++ doc/ale.txt | 1 + .../test_cucumber_command_callback.vader | 25 +++++++++++ test/cucumber_fixtures/features/cuke.feature | 0 .../features/step_definitions/base_steps.rb | 0 test/handler/test_cucumber_handler.vader | 18 ++++++++ 7 files changed, 90 insertions(+) create mode 100644 ale_linters/cucumber/cucumber.vim create mode 100644 test/command_callback/test_cucumber_command_callback.vader create mode 100644 test/cucumber_fixtures/features/cuke.feature create mode 100644 test/cucumber_fixtures/features/step_definitions/base_steps.rb create mode 100644 test/handler/test_cucumber_handler.vader diff --git a/README.md b/README.md index 887af08..5a416ac 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ formatting. | CoffeeScript | [coffee](http://coffeescript.org/), [coffeelint](https://www.npmjs.com/package/coffeelint) | | Crystal | [crystal](https://crystal-lang.org/) !! | | CSS | [csslint](http://csslint.net/), [prettier](https://github.com/prettier/prettier), [stylelint](https://github.com/stylelint/stylelint) | +| Cucumber | [cucumber](https://cucumber.io/) | | Cython (pyrex filetype) | [cython](http://cython.org/) | | D | [dmd](https://dlang.org/dmd-linux.html) | | Dafny | [dafny](https://rise4fun.com/Dafny) !! | diff --git a/ale_linters/cucumber/cucumber.vim b/ale_linters/cucumber/cucumber.vim new file mode 100644 index 0000000..6708d32 --- /dev/null +++ b/ale_linters/cucumber/cucumber.vim @@ -0,0 +1,45 @@ +" Author: Eddie Lebow https://github.com/elebow +" Description: Cucumber, a BDD test tool + +function! ale_linters#cucumber#cucumber#GetCommand(buffer) abort + let l:features_dir = ale#path#FindNearestDirectory(a:buffer, 'features') + + if !empty(l:features_dir) + let l:features_arg = '-r ' . ale#Escape(l:features_dir) + else + let l:features_arg = '' + endif + + return 'cucumber --dry-run --quiet --strict --format=json ' + \ . l:features_arg . ' %t' +endfunction + +function! ale_linters#cucumber#cucumber#Handle(buffer, lines) abort + try + let l:json = ale#util#FuzzyJSONDecode(a:lines, {})[0] + catch + return [] + endtry + + let l:output = [] + for l:element in get(l:json, 'elements', []) + for l:step in l:element['steps'] + if l:step['result']['status'] is# 'undefined' + call add(l:output, { + \ 'lnum': l:step['line'], + \ 'code': 'E', + \ 'text': 'Undefined step' + \}) + endif + endfor + endfor + + return l:output +endfunction + +call ale#linter#Define('cucumber', { +\ 'name': 'cucumber', +\ 'executable': 'cucumber', +\ 'command_callback': 'ale_linters#cucumber#cucumber#GetCommand', +\ 'callback': 'ale_linters#cucumber#cucumber#Handle' +\}) diff --git a/doc/ale.txt b/doc/ale.txt index 0757101..3355e70 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -322,6 +322,7 @@ Notes: * CoffeeScript: `coffee`, `coffeelint` * Crystal: `crystal`!! * CSS: `csslint`, `prettier`, `stylelint` +* Cucumber: `cucumber` * Cython (pyrex filetype): `cython` * D: `dmd` * Dafny: `dafny`!! diff --git a/test/command_callback/test_cucumber_command_callback.vader b/test/command_callback/test_cucumber_command_callback.vader new file mode 100644 index 0000000..d09a571 --- /dev/null +++ b/test/command_callback/test_cucumber_command_callback.vader @@ -0,0 +1,25 @@ +Before: + runtime ale_linters/ruby/rubocop.vim + call ale#test#SetDirectory('/testplugin/test/') + +After: + Restore + + call ale#linter#Reset() + call ale#test#RestoreDirectory() + +Execute(Should require the nearest features dir, if one is found): + call ale#test#SetFilename('cucumber_fixtures/features/cuke.feature') + + AssertEqual + \ 'cucumber --dry-run --quiet --strict --format=json ' + \ . '-r ' . ale#Escape(ale#path#Simplify(g:dir . '/cucumber_fixtures/features/')) . ' %t', + \ ale_linters#cucumber#cucumber#GetCommand(bufnr('')) + +Execute(Should require nothing if no features dir is found): + call ale#test#SetFilename('something/without/a/features/dir') + + AssertEqual + \ 'cucumber --dry-run --quiet --strict --format=json ' + \ . ' %t', + \ ale_linters#cucumber#cucumber#GetCommand(bufnr('')) diff --git a/test/cucumber_fixtures/features/cuke.feature b/test/cucumber_fixtures/features/cuke.feature new file mode 100644 index 0000000..e69de29 diff --git a/test/cucumber_fixtures/features/step_definitions/base_steps.rb b/test/cucumber_fixtures/features/step_definitions/base_steps.rb new file mode 100644 index 0000000..e69de29 diff --git a/test/handler/test_cucumber_handler.vader b/test/handler/test_cucumber_handler.vader new file mode 100644 index 0000000..2b69a78 --- /dev/null +++ b/test/handler/test_cucumber_handler.vader @@ -0,0 +1,18 @@ +Before: + runtime ale_linters/cucumber/cucumber.vim + +After: + call ale#linter#Reset() + +Execute(The cucumber handler parses JSON correctly): + AssertEqual + \ [ + \ { + \ 'lnum': 13, + \ 'code': 'E', + \ 'text': 'Undefined step' + \ } + \ ], + \ ale_linters#cucumber#cucumber#Handle(bufnr(''), [ + \ '[{"elements": [{"steps": [{"result": {"status": "undefined"},"match": {"location": "features/cuke.feature:13"},"line": 13,"name": "Something undefined","keyword": "Given "},{"result": {"status": "skipped"},"match": {"location": "/var/lib/gems/2.3.0/gems/cucumber-3.1.0/lib/cucumber/step_match.rb:103"},"line": 14,"name": "I visit the profile page for Alice","keyword": "When "}],"type": "scenario","line": 12,"description": "","name": "Another scenario","keyword": "Scenario","id": "a-user-can-view-another-users-profile;another-scenario"}],"line": 1,"description": "","name": "A user can view another users profile","keyword": "Feature","id": "a-user-can-view-another-users-profile","uri": "features/cuke.feature"}]' + \ ])