mirror of
https://github.com/dense-analysis/ale.git
synced 2025-12-23 20:41:29 +08:00
Add Ruby linter with Steep (#4671)
* Add Ruby linter with Steep Fixes #3254 * Run steep instead of using language server LSP presents a few issues and this works around those. * Work around Steep path issue See https://github.com/soutaro/steep/pull/975 * Add simple tests for steep * Add steep to supported tools * Pass linter * Add a comment regarding Steep's column counting * Make lnum an integer * Add Steep handler test * Fix separator for Windows * Escape Windows path separators for substitute() * Use ALEInfo (I) group * Use fnameescape instead of quotes * Skip linting for files not under steep root * Add and pass tests covering proper steep root lookup * Fix separator discrepancy * Use strict operators (match case) * Fix ordering * Use `is#` instead of `==#`
This commit is contained in:
100
test/handler/test_steep_handler.vader
Normal file
100
test/handler/test_steep_handler.vader
Normal file
@@ -0,0 +1,100 @@
|
||||
Before:
|
||||
runtime ale_linters/ruby/steep.vim
|
||||
|
||||
After:
|
||||
call ale#linter#Reset()
|
||||
|
||||
Execute(The steep handler should parse lines correctly):
|
||||
AssertEqual
|
||||
\ [
|
||||
\ {
|
||||
\ 'lnum': 400,
|
||||
\ 'col': 18,
|
||||
\ 'end_col': 45,
|
||||
\ 'text': 'Method parameters are incompatible with declaration `(untyped, untyped, *untyped, **untyped) { () -> untyped } -> untyped`',
|
||||
\ 'code': 'Ruby::MethodArityMismatch',
|
||||
\ 'type': 'E',
|
||||
\ },
|
||||
\ {
|
||||
\ 'lnum': 20,
|
||||
\ 'col': 9,
|
||||
\ 'end_col': 17,
|
||||
\ 'text': 'Cannot find implementation of method `::Frobz::FooBarBaz#method_name`',
|
||||
\ 'code': 'Ruby::MethodDefinitionMissing',
|
||||
\ 'type': 'W',
|
||||
\ },
|
||||
\ {
|
||||
\ 'lnum': 30,
|
||||
\ 'col': 9,
|
||||
\ 'end_col': 17,
|
||||
\ 'text': 'Cannot find implementation of method `::Frobz::FooBarBaz#method_name`',
|
||||
\ 'code': 'Ruby::MethodDefinitionMissing',
|
||||
\ 'type': 'I',
|
||||
\ },
|
||||
\ {
|
||||
\ 'lnum': 40,
|
||||
\ 'col': 9,
|
||||
\ 'end_col': 17,
|
||||
\ 'text': 'Cannot find implementation of method `::Frobz::FooBarBaz#method_name`',
|
||||
\ 'code': 'Ruby::MethodDefinitionMissing',
|
||||
\ 'type': 'I',
|
||||
\ },
|
||||
\ ],
|
||||
\ ale_linters#ruby#steep#HandleOutput(347, [
|
||||
\ '# Type checking files:',
|
||||
\ '',
|
||||
\ '...............................................................................................................................F..........F.F...F.',
|
||||
\ '',
|
||||
\ 'lib/frobz/foobar_baz.rb:400:17: [error] Method parameters are incompatible with declaration `(untyped, untyped, *untyped, **untyped) { () -> untyped } -> untyped`',
|
||||
\ '│ Diagnostic ID: Ruby::MethodArityMismatch',
|
||||
\ '│',
|
||||
\ '└ def frobz(obj, suffix, *args, &block)',
|
||||
\ ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~',
|
||||
\ '',
|
||||
\ 'lib/frobz/foobar_baz.rb:20:8: [warning] Cannot find implementation of method `::Frobz::FooBarBaz#method_name`',
|
||||
\ '│ Diagnostic ID: Ruby::MethodDefinitionMissing',
|
||||
\ '│',
|
||||
\ '└ class FooBarBaz',
|
||||
\ ' ~~~~~~~~~',
|
||||
\ '',
|
||||
\ 'lib/frobz/foobar_baz.rb:30:8: [information] Cannot find implementation of method `::Frobz::FooBarBaz#method_name`',
|
||||
\ '│ Diagnostic ID: Ruby::MethodDefinitionMissing',
|
||||
\ '│',
|
||||
\ '└ class FooBarBaz',
|
||||
\ ' ~~~~~~~~~',
|
||||
\ '',
|
||||
\ 'lib/frobz/foobar_baz.rb:40:8: [hint] Cannot find implementation of method `::Frobz::FooBarBaz#method_name`',
|
||||
\ '│ Diagnostic ID: Ruby::MethodDefinitionMissing',
|
||||
\ '│',
|
||||
\ '└ class FooBarBaz',
|
||||
\ ' ~~~~~~~~~',
|
||||
\ '',
|
||||
\ 'Detected 4 problems from 1 file',
|
||||
\ ])
|
||||
|
||||
Execute(The steep handler should handle when files are checked and no offenses are found):
|
||||
AssertEqual
|
||||
\ [],
|
||||
\ ale_linters#ruby#steep#HandleOutput(347, [
|
||||
\ '# Type checking files:',
|
||||
\ '',
|
||||
\ '.............................................................................................................................................',
|
||||
\ '',
|
||||
\ 'No type error detected. 🧉',
|
||||
\ ])
|
||||
|
||||
Execute(The steep handler should handle when no files are checked):
|
||||
AssertEqual
|
||||
\ [],
|
||||
\ ale_linters#ruby#steep#HandleOutput(347, [
|
||||
\ '# Type checking files:',
|
||||
\ '',
|
||||
\ '',
|
||||
\ '',
|
||||
\ 'No type error detected. 🧉',
|
||||
\ ])
|
||||
|
||||
Execute(The steep handler should handle empty output):
|
||||
AssertEqual [], ale_linters#ruby#steep#HandleOutput(347, [''])
|
||||
AssertEqual [], ale_linters#ruby#steep#HandleOutput(347, [])
|
||||
|
||||
69
test/linter/test_ruby_steep.vader
Normal file
69
test/linter/test_ruby_steep.vader
Normal file
@@ -0,0 +1,69 @@
|
||||
" Author: Loic Nageleisen <https://github.com/lloeki>
|
||||
" Description: Tests for steep linter.
|
||||
Before:
|
||||
call ale#assert#SetUpLinterTest('ruby', 'steep')
|
||||
|
||||
let g:ale_ruby_steep_executable = 'steep'
|
||||
|
||||
After:
|
||||
call ale#assert#TearDownLinterTest()
|
||||
|
||||
Execute(Executable should default to steep):
|
||||
call ale#test#SetFilename('../test-files/ruby/nested/foo/dummy.rb')
|
||||
AssertLinter 'steep', ale#Escape('steep')
|
||||
\ . ' check '
|
||||
\ . ' dummy.rb'
|
||||
|
||||
Execute(Should be able to set a custom executable):
|
||||
let g:ale_ruby_steep_executable = 'bin/steep'
|
||||
|
||||
call ale#test#SetFilename('../test-files/ruby/nested/foo/dummy.rb')
|
||||
AssertLinter 'bin/steep' , ale#Escape('bin/steep')
|
||||
\ . ' check '
|
||||
\ . ' dummy.rb'
|
||||
|
||||
Execute(Setting bundle appends 'exec steep'):
|
||||
let g:ale_ruby_steep_executable = 'path to/bundle'
|
||||
|
||||
call ale#test#SetFilename('../test-files/ruby/nested/foo/dummy.rb')
|
||||
AssertLinter 'path to/bundle', ale#Escape('path to/bundle')
|
||||
\ . ' exec steep'
|
||||
\ . ' check '
|
||||
\ . ' dummy.rb'
|
||||
|
||||
Execute(should accept options):
|
||||
let g:ale_ruby_steep_options = '--severity-level=hint'
|
||||
|
||||
call ale#test#SetFilename('../test-files/ruby/nested/foo/dummy.rb')
|
||||
AssertLinter 'steep', ale#Escape('steep')
|
||||
\ . ' check'
|
||||
\ . ' --severity-level=hint'
|
||||
\ . ' dummy.rb'
|
||||
|
||||
Execute(Should not lint files out of steep root):
|
||||
call ale#test#SetFilename('../test-files/ruby/nested/dummy.rb')
|
||||
AssertLinter 'steep', ''
|
||||
|
||||
Execute(Should lint files at top steep root):
|
||||
call ale#test#SetFilename('../test-files/ruby/nested/foo/dummy.rb')
|
||||
AssertLinter 'steep', ale#Escape('steep')
|
||||
\ . ' check '
|
||||
\ . ' dummy.rb'
|
||||
|
||||
Execute(Should lint files below top steep root):
|
||||
call ale#test#SetFilename('../test-files/ruby/nested/foo/one/dummy.rb')
|
||||
AssertLinter 'steep', ale#Escape('steep')
|
||||
\ . ' check '
|
||||
\ . ' one' . (has('win32') ? '\' : '/') . 'dummy.rb'
|
||||
|
||||
Execute(Should lint files at nested steep root):
|
||||
call ale#test#SetFilename('../test-files/ruby/nested/foo/two/dummy.rb')
|
||||
AssertLinter 'steep', ale#Escape('steep')
|
||||
\ . ' check '
|
||||
\ . ' dummy.rb'
|
||||
|
||||
Execute(Should lint files below nested steep root):
|
||||
call ale#test#SetFilename('../test-files/ruby/nested/foo/two/three/dummy.rb')
|
||||
AssertLinter 'steep', ale#Escape('steep')
|
||||
\ . ' check '
|
||||
\ . ' three' . (has('win32') ? '\' : '/') . 'dummy.rb'
|
||||
0
test/test-files/ruby/nested/dummy.rb
Normal file
0
test/test-files/ruby/nested/dummy.rb
Normal file
0
test/test-files/ruby/nested/foo/Steepfile
Normal file
0
test/test-files/ruby/nested/foo/Steepfile
Normal file
0
test/test-files/ruby/nested/foo/dummy.rb
Normal file
0
test/test-files/ruby/nested/foo/dummy.rb
Normal file
0
test/test-files/ruby/nested/foo/one/dummy.rb
Normal file
0
test/test-files/ruby/nested/foo/one/dummy.rb
Normal file
0
test/test-files/ruby/nested/foo/two/Steepfile
Normal file
0
test/test-files/ruby/nested/foo/two/Steepfile
Normal file
0
test/test-files/ruby/nested/foo/two/dummmy.rb
Normal file
0
test/test-files/ruby/nested/foo/two/dummmy.rb
Normal file
0
test/test-files/ruby/nested/foo/two/three/dummy.rb
Normal file
0
test/test-files/ruby/nested/foo/two/three/dummy.rb
Normal file
Reference in New Issue
Block a user