1
0
mirror of https://github.com/amix/vimrc synced 2025-08-02 02:44:59 +08:00

Update Ale.

This commit is contained in:
Kurtis Moxley
2022-05-19 21:16:38 +08:00
parent 0071859401
commit dd26bc4697
1324 changed files with 56041 additions and 437 deletions

View File

@ -0,0 +1,28 @@
Before:
runtime! ale/handlers/actionlint.vim
After:
call ale#linter#Reset()
Execute(Problems should be parsed correctly for actionlint):
AssertEqual
\ [
\ {
\ 'lnum': 2,
\ 'col': 1,
\ 'type': 'E',
\ 'text': '"jobs" section is missing in workflow',
\ 'code': 'syntax-check',
\ },
\ {
\ 'lnum': 56,
\ 'col': 23,
\ 'type': 'E',
\ 'text': 'property "unknown_input" is not defined in object type {input7: bool; input0: any; input1: any; input2: string; input3: any; input4: any; input5: number; input6: number}',
\ 'code': 'expression',
\ },
\ ],
\ ale#handlers#actionlint#Handle(bufnr(''), [
\ '.codecov.yaml:2:1: "jobs" section is missing in workflow [syntax-check]',
\ 'workflow_call_event.yaml:56:23: property "unknown_input" is not defined in object type {input7: bool; input0: any; input1: any; input2: string; input3: any; input4: any; input5: number; input6: number} [expression]',
\ ])

View File

@ -0,0 +1,36 @@
Before:
runtime ale_linters/ada/gcc.vim
After:
call ale#linter#Reset()
Execute(The gcc handler for Ada should parse input correctly):
AssertEqual
\ [
\ {
\ 'bufnr': 0,
\ 'lnum': 8,
\ 'col': 5,
\ 'type': 'W',
\ 'text': 'variable "X" is assigned but never read',
\ },
\ {
\ 'bufnr': 0,
\ 'lnum': 6,
\ 'col': 22,
\ 'type': 'E',
\ 'text': 'type definition expected',
\ },
\ {
\ 'bufnr': 0,
\ 'lnum': 8,
\ 'col': 9,
\ 'type': 'E',
\ 'text': 'aspect specifications not allowed here',
\ },
\ ],
\ ale_linters#ada#gcc#Handle(0, [
\ 'foobar.adb:8:05: warning: variable "X" is assigned but never read',
\ 'foobar.ads:6:22: type definition expected',
\ 'foobar.ads:8:09: aspect specifications not allowed here',
\ ])

View File

@ -0,0 +1,54 @@
Execute(The alex handler should handle the example from the alex README):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 5,
\ 'end_lnum': 1,
\ 'end_col': 13,
\ 'type': 'W',
\ 'text': '`boogeyman` may be insensitive, use `boogey` instead (retext-equality)',
\ },
\ {
\ 'lnum': 1,
\ 'col': 42,
\ 'end_lnum': 1,
\ 'end_col': 47,
\ 'type': 'W',
\ 'text': '`master` / `slaves` may be insensitive, use `primary` / `replica` instead (retext-equality)',
\ },
\ {
\ 'lnum': 1,
\ 'col': 69,
\ 'end_lnum': 1,
\ 'end_col': 74,
\ 'type': 'W',
\ 'text': 'Dont use “slaves”, its profane (retext-profanities)',
\ },
\ {
\ 'lnum': 2,
\ 'col': 52,
\ 'end_lnum': 2,
\ 'end_col': 53,
\ 'type': 'W',
\ 'text': '`he` may be insensitive, use `they`, `it` instead (retext-equality)',
\ },
\ {
\ 'lnum': 2,
\ 'col': 61,
\ 'end_lnum': 2,
\ 'end_col': 67,
\ 'type': 'W',
\ 'text': '`cripple` may be insensitive, use `person with a limp` instead (retext-equality)',
\ },
\ ],
\ ale#handlers#alex#Handle(bufnr(''), [
\ 'example.md',
\ ' 1:5-1:14 warning `boogeyman` may be insensitive, use `boogey` instead boogeyman-boogeywoman retext-equality',
\ ' 1:42-1:48 warning `master` / `slaves` may be insensitive, use `primary` / `replica` instead master-slave retext-equality',
\ ' 1:69-1:75 warning Dont use “slaves”, its profane slaves retext-profanities',
\ ' 2:52-2:54 warning `he` may be insensitive, use `they`, `it` instead he-she retext-equality',
\ ' 2:61-2:68 warning `cripple` may be insensitive, use `person with a limp` instead cripple retext-equality',
\ '',
\ '⚠ 5 warnings',
\ ])

View File

@ -0,0 +1,44 @@
Before:
runtime ale_linters/crystal/ameba.vim
After:
unlet! g:lines
call ale#linter#Reset()
Execute(The ameba handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 24,
\ 'col': 28,
\ 'end_col': 29,
\ 'text': 'Trailing whitespace detected',
\ 'code': 'Layout/TrailingWhitespace',
\ 'type': 'W',
\ },
\ ],
\ ale_linters#crystal#ameba#HandleAmebaOutput(123, [
\ '{"sources":[{"path":"my_file_with_issues.cr","issues":[{"rule_name":"Layout/TrailingWhitespace","message":"Trailing whitespace detected","location":{"line":24,"column":28},"end_location":{"line":null,"column":null}}]},{"path":"my_file_without_issues.cr","issues":[]}],"metadata":{"ameba_version":"0.8.1","crystal_version":"0.26.1"},"summary":{"target_sources_count":2,"issues_count":1}}'
\ ])
Execute(The ameba handler should handle when files are checked and no offenses are found):
AssertEqual
\ [],
\ ale_linters#crystal#ameba#HandleAmebaOutput(123, [
\ '{"sources":[{"path":"my_file_with_issues.cr",issues":[]},{"path":"my_file_without_issues.cr",issues":[]}],"metadata":{ameba_version":"0.8.1",crystal_version":"0.26.1"},"summary":{target_sources_count":2,issues_count":0}}'
\ ])
Execute(The ameba handler should handle when no files are checked):
AssertEqual
\ [],
\ ale_linters#crystal#ameba#HandleAmebaOutput(123, [
\ '{"sources":[],"metadata":{ameba_version":"0.8.1",crystal_version":"0.26.1"},"summary":{target_sources_count":0,issues_count":0}}'
\ ])
Execute(The ameba handler should handle blank output without any errors):
AssertEqual
\ [],
\ ale_linters#crystal#ameba#HandleAmebaOutput(123, ['{}'])
AssertEqual
\ [],
\ ale_linters#crystal#ameba#HandleAmebaOutput(123, [])

View File

@ -0,0 +1,95 @@
Before:
runtime ale_linters/ansible/ansible_lint.vim
call ale#test#SetFilename('test_playbook.yml')
let b:ale_warn_about_trailing_whitespace = 1
After:
unlet! b:ale_warn_about_trailing_whitespace
call ale#linter#Reset()
Execute(The ansible-lint handler for version group <5 should handle basic errors):
AssertEqual
\ [
\ {
\ 'lnum': 35,
\ 'col': 0,
\ 'type': 'E',
\ 'text': 'Trailing whitespace',
\ 'code': 'EANSIBLE0002',
\ },
\ ],
\ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [4, 1, 2], [
\ fnamemodify(tempname(), ':h') . '/test_playbook.yml:35: [EANSIBLE0002] Trailing whitespace',
\ ])
Execute(The ansible-lint handler for version group <5 should supress trailing whitespace output when the option is used):
let b:ale_warn_about_trailing_whitespace = 0
AssertEqual
\ [
\ ],
\ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [4, 1, 2], [
\ fnamemodify(tempname(), ':h') . '/test_playbook.yml:35: [EANSIBLE0002] Trailing whitespace',
\ ])
Execute(The ansible-lint handler for version group >=5 should handle basic errors):
AssertEqual
\ [
\ {
\ 'lnum': 35,
\ 'col': 0,
\ 'type': 'E',
\ 'text': 'File permissions unset or incorrect',
\ 'code': 'risky-file-permissions',
\ },
\ ],
\ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [5, 1, 2], [
\ fnamemodify(tempname(), ':h') . '/test_playbook.yml:35: [risky-file-permissions] [VERY_HIGH] File permissions unset or incorrect',
\ ])
Before:
runtime ale_linters/ansible/ansible_lint.vim
call ale#test#SetFilename('test playbook.yml')
After:
call ale#linter#Reset()
Execute (The ansible-lint handler for version group <5 should handle names with spaces):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 6,
\ 'type': 'E',
\ 'text': 'indentation is not a multiple of four',
\ 'code': 'E111',
\ },
\ ],
\ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [4, 1, 2], [
\ fnamemodify(tempname(), ':h') . '/test playbook.yml:6:6: E111 indentation is not a multiple of four',
\ ])
Execute (The ansible-lint handler for version group >=5 should handle names with spaces):
AssertEqual
\ [
\ {
\ 'lnum': 3,
\ 'col': 148,
\ 'type': 'E',
\ 'text': "'var' is not a valid attribute for a Play",
\ 'code': 'syntax-check',
\ },
\ ],
\ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [5, 1, 2], [
\ fnamemodify(tempname(), ':h') . "/test playbook.yml:3:148: [syntax-check] [VERY_HIGH] 'var' is not a valid attribute for a Play",
\ ])
Execute (The ansible-lint handler should ignore errors from other files):
AssertEqual
\ [
\ ],
\ ale_linters#ansible#ansible_lint#Handle(bufnr(''), [5, 1, 2], [
\ '/foo/bar/roles/test_playbook.yml:6: [command-instead-of-module] [VERY_LOW] curl used in place of get_url or uri module',
\ ])

View File

@ -0,0 +1,28 @@
Before:
runtime ale_linters/swift/appleswiftformat.vim
After:
call ale#linter#Reset()
Execute(The appleswiftformat handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 4,
\ 'col': 21,
\ 'type': 'W',
\ 'code': 'DoNotUseSemicolons',
\ 'text': 'remove '';'' and move the next statement to the new line',
\ },
\ {
\ 'lnum': 3,
\ 'col': 12,
\ 'type': 'W',
\ 'code': 'Spacing',
\ 'text': 'remove 1 space'
\ },
\ ],
\ ale_linters#swift#appleswiftformat#Handle(bufnr(''), [
\ 'Sources/main.swift:4:21: warning: [DoNotUseSemicolons] remove '';'' and move the next statement to the new line',
\ 'Sources/main.swift:3:12: warning: [Spacing] remove 1 space',
\ ])

View File

@ -0,0 +1,26 @@
Before:
runtime ale_linters/asm/gcc.vim
After:
call ale#linter#Reset()
Execute(The asm GCC handler should parse lines from GCC 6.3.1 correctly):
AssertEqual
\ [
\ {
\ 'lnum': 38,
\ 'text': "too many memory references for `mov'",
\ 'type': 'E',
\ },
\ {
\ 'lnum': 42,
\ 'text': "incorrect register `%ax' used with `l' suffix",
\ 'type': 'E',
\ },
\ ],
\ ale_linters#asm#gcc#Handle(357, [
\ "{standard input}: Assembler messages:",
\ "{standard_input}:38: Error: too many memory references for `mov'",
\ "{standard input}:42: Error: incorrect register `%ax' used with `l' suffix",
\ ])

View File

@ -0,0 +1,85 @@
Before:
runtime autoload/ale/handlers/atools.vim
After:
call ale#linter#Reset()
Execute(The atools handler should handle basic errors or warings):
AssertEqual
\ [
\ {
\ 'lnum': 2,
\ 'text': 'trailing whitespace',
\ 'type': 'E',
\ 'code': 'AL8',
\ },
\ {
\ 'lnum': 15,
\ 'text': '$pkgname should not be used in the source url',
\ 'type': 'W',
\ 'code': 'AL29',
\ },
\ ],
\ ale#handlers#atools#Handle(bufnr(''), [
\ 'IC:[AL8]:APKBUILD:2:trailing whitespace',
\ 'MC:[AL29]:APKBUILD:15:$pkgname should not be used in the source url',
\ ])
" Regardless of the severity, if the certainty is [P]ossible and not [C]ertain
" or if regardless of the Certainity the Severity is not [I]mportant or [S]erious
" then it must be a [W]arning
Execute(If we are not Certain or Importantly Serious, be a Warning):
AssertEqual
\ [
\ {
\ 'lnum': 3,
\ 'text': 'This violation is Serious but Possible false positive, I am a Warning!',
\ 'type': 'W',
\ 'code': 'AL',
\ },
\ {
\ 'lnum': 4,
\ 'text': 'This violation is Important but Possible false positive, I am a Warning!',
\ 'type': 'W',
\ 'code': 'AL',
\ },
\ {
\ 'lnum': 5,
\ 'text': 'This violation is Minor, I am a Warning!',
\ 'type': 'W',
\ 'code': 'AL',
\ },
\ {
\ 'lnum': 6,
\ 'text': 'This violation is Style, I am a Warning!',
\ 'type': 'W',
\ 'code': 'AL',
\ },
\ ],
\ ale#handlers#atools#Handle(bufnr(''), [
\ 'SP:[AL]:APKBUILD:3:This violation is Serious but Possible false positive, I am a Warning!',
\ 'IP:[AL]:APKBUILD:4:This violation is Important but Possible false positive, I am a Warning!',
\ 'MC:[AL]:APKBUILD:5:This violation is Minor, I am a Warning!',
\ 'TC:[AL]:APKBUILD:6:This violation is Style, I am a Warning!',
\ ])
Execute(We should be error if we are Certain it is Serious or Important):
AssertEqual
\ [
\ {
\ 'lnum': 7,
\ 'text': 'This is Certainly Serious, I am an Error!',
\ 'type': 'E',
\ 'code': 'AL',
\ },
\ {
\ 'lnum': 8,
\ 'text': 'This is Certainly Important, I am an Error!',
\ 'type': 'E',
\ 'code': 'AL',
\ },
\ ],
\ ale#handlers#atools#Handle(bufnr(''), [
\ 'SC:[AL]:APKBUILD:7:This is Certainly Serious, I am an Error!',
\ 'IC:[AL]:APKBUILD:8:This is Certainly Important, I am an Error!',
\ ])

View File

@ -0,0 +1,24 @@
Before:
runtime ale_linters/avra/avra.vim
After:
call ale#linter#Reset()
Execute(The avra handler should parse errors correctly):
AssertEqual
\ [
\ {
\ 'lnum': 3,
\ 'text': "Unknown device: atmega3228p",
\ 'type': 'E'
\ },
\ {
\ 'lnum': 12,
\ 'text': "Unknown directive: .EQ",
\ 'type': 'E'
\ }
\ ],
\ ale_linters#avra#avra#Handle(bufnr(''), [
\ "main.asm(3) : Error : Unknown device: atmega3228p",
\ "main.asm(12) : Error : Unknown directive: .EQ"
\ ])

View File

@ -0,0 +1,42 @@
Before:
runtime ale_linters/python/bandit.vim
After:
call ale#linter#Reset()
Execute(The bandit handler for Python should parse input correctly):
AssertEqual
\ [
\ {
\ 'bufnr': 0,
\ 'lnum': 2,
\ 'code': 'B404',
\ 'type': 'I',
\ 'text': 'Consider possible security implications associated with subprocess module.',
\ },
\ {
\ 'bufnr': 0,
\ 'lnum': 4,
\ 'code': 'B305',
\ 'type': 'W',
\ 'text': 'Use of insecure cipher mode cryptography.hazmat.primitives.ciphers.modes.ECB.',
\ },
\ {
\ 'bufnr': 0,
\ 'lnum': 6,
\ 'code': 'B609',
\ 'type': 'E',
\ 'text': 'Possible wildcard injection in call: subprocess.Popen',
\ },
\ ],
\ ale_linters#python#bandit#Handle(0, [
\ '[main] INFO profile include tests: None',
\ '[main] INFO profile exclude tests: None',
\ '[main] INFO cli include tests: None',
\ '[main] INFO cli exclude tests: None',
\ '[main] INFO running on Python 3.7.2',
\ '[node_visitor] INFO Unable to find qualified name for module: <stdin>',
\ '2:B404:LOW:Consider possible security implications associated with subprocess module.',
\ '4:B305:MEDIUM:Use of insecure cipher mode cryptography.hazmat.primitives.ciphers.modes.ECB.',
\ '6:B609:HIGH:Possible wildcard injection in call: subprocess.Popen',
\ ])

View File

@ -0,0 +1,36 @@
Before:
runtime ale_linters/sh/bashate.vim
After:
call ale#linter#Reset()
Execute(The bashate handler should handle basic errors):
AssertEqual
\ [
\ {
\ 'lnum': 777,
\ 'col': 1,
\ 'text': 'E003 Indent not multiple of 4',
\ },
\ {
\ 'lnum': 783,
\ 'col': 1,
\ 'text': 'E020 Function declaration not in format ^function name {$',
\ },
\ {
\ 'lnum': 786,
\ 'col': 1,
\ 'text': 'E010 The "do" should be on same line as for',
\ },
\ {
\ 'lnum': 791,
\ 'col': 1,
\ 'text': 'E006 Line too long',
\ },
\ ],
\ ale_linters#sh#bashate#Handle(bufnr(''), [
\ 'run:777:1: E003 Indent not multiple of 4',
\ 'run:783:1: E020 Function declaration not in format ^function name {$',
\ 'run:786:1: E010 The "do" should be on same line as for',
\ 'run:791:1: E006 Line too long',
\ ])

View File

@ -0,0 +1,88 @@
Before:
runtime ale_linters/bib/bibclean.vim
After:
call ale#linter#Reset()
Execute(The bibclean handler should parse lines from bibclean <= v2.11.4 correctly):
AssertEqual
\ [
\ {
\ 'lnum': '60',
\ 'type': 'W',
\ 'text': 'Unexpected value in ``month = "09"''''.',
\ 'col': '17'
\ },
\ {
\ 'lnum': '63',
\ 'type': 'E',
\ 'text': 'Expected comma after last field ``keywords''''.',
\ 'col': ' 1'
\ },
\ {
\ 'lnum': '176',
\ 'type': 'W',
\ 'text': 'Unexpected DOI in URL value ``"https://doi.org/DOI"'''': move to separate DOI = "..." key/value in this entry.',
\ 'col': '14'
\ }
\ ],
\ ale_linters#bib#bibclean#Handle(255, [
\ "%% \"stdin\", line 60: Unexpected value in ``month = \"09\"''.",
\ "%% File positions: input [main.bib] output [stdout]",
\ "%% Entry input byte=1681 line=50 column= 1 output byte=1680 line=50 column= 0",
\ "%% Value input byte=2137 line=60 column=17 output byte=2137 line=60 column=17",
\ "%% Current input byte=2139 line=60 column=19 output byte=2137 line=60 column=17",
\ "?? \"stdin\", line 71: Expected comma after last field ``keywords''.",
\ "?? File positions: input [main.bib] output [stdout]",
\ "?? Entry input byte=2145 line=63 column= 1 output byte=2146 line=63 column= 0",
\ "?? Value input byte=2528 line=71 column= 2 output byte=2527 line=70 column=49",
\ "?? Current input byte=2529 line=71 column= 3 output byte=2528 line=70 column=50",
\ "%% \"stdin\", line 176: Unexpected DOI in URL value ``\"https://doi.org/DOI\"'': move to separate DOI = \"...\" key/value in this entry.",
\ "%% File positions: input [stdin] output [stdout]",
\ "%% Entry input byte=6813 line=174 column= 1 output byte=8543 line=227 column= 0",
\ "%% Value input byte=6890 line=176 column=14 output byte=8641 line=229 column=17",
\ "%% Current input byte=6938 line=176 column=62 output byte=8641 line=229 column=17"
\ ])
Execute(The bibclean handler should parse lines of bibclean > v2.11.4 correctly):
AssertEqual
\ [
\ {
\ 'lnum': '60',
\ 'type': 'W',
\ 'text': 'Unexpected value in ``month = "09"''''.',
\ 'col': '17'
\ },
\ {
\ 'lnum': '63',
\ 'type': 'E',
\ 'text': 'Expected comma after last field ``keywords''''.',
\ 'col': ' 1'
\ },
\ {
\ 'lnum': '176',
\ 'type': 'W',
\ 'text': 'Unexpected DOI in URL value ``"https://doi.org/DOI"'''': move to separate DOI = "..." key/value in this entry.',
\ 'col': '14'
\ }
\ ],
\ ale_linters#bib#bibclean#Handle(255, [
\ "%% stdin:60:Unexpected value in ``month = \"09\"''.",
\ "%% File positions: input [main.bib] output [stdout]",
\ "%% Entry input byte=1681 line=50 column= 1 output byte=1680 line=50 column= 0",
\ "%% Value input byte=2137 line=60 column=17 output byte=2137 line=60 column=17",
\ "%% Current input byte=2139 line=60 column=19 output byte=2137 line=60 column=17",
\ "?? stdin:71:Expected comma after last field ``keywords''.",
\ "?? File positions: input [main.bib] output [stdout]",
\ "?? Entry input byte=2145 line=63 column= 1 output byte=2146 line=63 column= 0",
\ "?? Value input byte=2528 line=71 column= 2 output byte=2527 line=70 column=49",
\ "?? Current input byte=2529 line=71 column= 3 output byte=2528 line=70 column=50",
\ "%% stdin:176:Unexpected DOI in URL value ``\"https://doi.org/DOI\"'': move to separate DOI = \"...\" key/value in this entry.",
\ "%% File positions: input [stdin] output [stdout]",
\ "%% Entry input byte=6813 line=174 column= 1 output byte=8543 line=227 column= 0",
\ "%% Value input byte=6890 line=176 column=14 output byte=8641 line=229 column=17",
\ "%% Current input byte=6938 line=176 column=62 output byte=8641 line=229 column=17"
\ ])

View File

@ -0,0 +1,28 @@
Before:
runtime ale_linters/bitbake/oelint_adv.vim
After:
Restore
call ale#linter#Reset()
Execute(The oelint_adv handler should handle warnings):
AssertEqual
\ [
\ {
\ 'lnum': 1234,
\ 'type': 'I',
\ 'code': 'oelint.var.suggestedvar.BUGTRACKER',
\ 'text': 'Variable ''BUGTRACKER'' should be set',
\ },
\ {
\ 'lnum': 17,
\ 'type': 'E',
\ 'code': 'oelint.var.mandatoryvar.DESCRIPTION',
\ 'text': 'Variable ''DESCRIPTION'' should be set',
\ },
\ ],
\ ale_linters#bitbake#oelint_adv#Handle(1, [
\ '/meta-x/recipes-y/example/example_1.0.bb:1234:info:oelint.var.suggestedvar.BUGTRACKER:Variable ''BUGTRACKER'' should be set',
\ 'example2_1.1.bb:17:error:oelint.var.mandatoryvar.DESCRIPTION:Variable ''DESCRIPTION'' should be set',
\ ])

View File

@ -0,0 +1,83 @@
Before:
call ale#test#SetDirectory('/testplugin/test/handler')
runtime ale_linters/ruby/brakeman.vim
After:
call ale#test#RestoreDirectory()
call ale#linter#Reset()
Execute(The brakeman handler should parse JSON correctly):
call ale#test#SetFilename('../test-files/ruby/valid_rails_app/app/models/thing.rb')
AssertEqual
\ [
\ {
\ 'filename': expand('%:p'),
\ 'lnum': 84,
\ 'text': 'SQL Injection Possible SQL injection (Medium)',
\ 'type': 'W',
\ },
\ {
\ 'filename': expand('%:p'),
\ 'lnum': 1,
\ 'text': 'Mass Assignment Potentially dangerous attribute available for mass assignment (Weak)',
\ 'type': 'W',
\ }
\ ],
\ ale_linters#ruby#brakeman#Handle(bufnr(''), [
\ '{',
\ '"warnings": [',
\ '{',
\ '"warning_type": "SQL Injection",',
\ '"warning_code": 0,',
\ '"fingerprint": "1234",',
\ '"check_name": "SQL",',
\ '"message": "Possible SQL injection",',
\ '"file": "' . substitute(ale#path#Simplify('app/models/thing.rb'), '\\', '\\\\', 'g') . '",',
\ '"line": 84,',
\ '"link": "http://brakemanscanner.org/docs/warning_types/sql_injection/",',
\ '"code": "Thing.connection.execute(params[:data])",',
\ '"render_path": null,',
\ '"location": {',
\ '"type": "method",',
\ '"class": "Thing",',
\ '"method": "run_raw_sql_from_internet"',
\ '},',
\ '"user_input": "whatever",',
\ '"confidence": "Medium"',
\ '},',
\ '{',
\ '"warning_type": "Mass Assignment",',
\ '"warning_code": 60,',
\ '"fingerprint": "1235",',
\ '"check_name": "ModelAttrAccessible",',
\ '"message": "Potentially dangerous attribute available for mass assignment",',
\ '"file": "' . substitute(ale#path#Simplify('app/models/thing.rb'), '\\', '\\\\', 'g') . '",',
\ '"line": null,',
\ '"link": "http://brakemanscanner.org/docs/warning_types/mass_assignment/",',
\ '"code": ":name",',
\ '"render_path": null,',
\ '"location": {',
\ '"type": "model",',
\ '"model": "Thing"',
\ '},',
\ '"user_input": null,',
\ '"confidence": "Weak"',
\ '}',
\ ']',
\ '}'
\ ])
Execute(The brakeman handler should parse JSON correctly when there is no output from brakeman):
AssertEqual
\ [],
\ ale_linters#ruby#brakeman#Handle(347, [
\ ])
\
Execute(The brakeman handler should handle garbage output):
AssertEqual
\ [],
\ ale_linters#ruby#brakeman#Handle(347, [
\ 'No such command in 2.4.1 of ruby',
\ ])

View File

@ -0,0 +1,33 @@
Before:
runtime! ale_linters/cloudformation/cfn_python_lint.vim
call ale#test#SetFilename('sample.template.yaml')
After:
call ale#linter#Reset()
Execute(The cfn_python_lint handler should parse items correctly):
AssertEqual
\ [
\ {
\ 'lnum': '96',
\ 'col': '7',
\ 'end_lnum': '96',
\ 'end_col': '15',
\ 'text': 'Property Resources/Sample/Properties/FromPort should be of type Integer',
\ 'code': 'E3012',
\ 'type': 'E',
\ },
\ {
\ 'lnum': '97',
\ 'col': '7',
\ 'end_lnum': '97',
\ 'end_col': '15',
\ 'text': 'AllowedPattern and/or AllowedValues for Parameter should be specified at Parameters/SampleIpAddress. Example for AllowedPattern "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$"',
\ 'code': 'W2509',
\ 'type': 'W',
\ },
\ ],
\ ale_linters#cloudformation#cfn_python_lint#Handle(bufnr(''), [
\ fnamemodify(tempname(), ':h') . '/sample.template.yaml:96:7:96:15:E3012:Property Resources/Sample/Properties/FromPort should be of type Integer',
\ fnamemodify(tempname(), ':h') . '/sample.template.yaml:97:7:97:15:W2509:AllowedPattern and/or AllowedValues for Parameter should be specified at Parameters/SampleIpAddress. Example for AllowedPattern "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$"',
\ ])

View File

@ -0,0 +1,23 @@
Before:
runtime ale_linters/make/checkmake.vim
After:
call ale#linter#Reset()
Execute(Parsing checkmake errors should work):
silent file Makefile
AssertEqual
\ [
\ {
\ 'bufnr': 42,
\ 'lnum': 1,
\ 'type': 'E',
\ 'code': 'woops',
\ 'text': 'an error has occurred',
\ }
\ ],
\ ale_linters#make#checkmake#Handle(42, [
\ 'This shouldnt match',
\ '1:woops:an error has occurred',
\ ])

View File

@ -0,0 +1,66 @@
Before:
runtime ale_linters/terraform/checkov.vim
call ale#test#SetFilename('main.tf')
After:
call ale#linter#Reset()
Execute(The JSON output of checkov should be handled correctly):
AssertEqual
\ [
\ {
\ 'filename': '/main.tf',
\ 'lnum': 22,
\ 'end_lnum': 27,
\ 'text': 'Enable VPC Flow Logs and Intranode Visibility [CKV_GCP_61]',
\ 'detail': "CKV_GCP_61: Enable VPC Flow Logs and Intranode Visibility\n" .
\ 'For more information, see: https://docs.bridgecrew.io/docs/enable-vpc-flow-logs-and-intranode-visibility',
\ 'type': 'W',
\ }
\ ],
\ ale_linters#terraform#checkov#Handle(bufnr(''), [
\'{',
\' "check_type": "terraform",',
\' "results": {',
\' "failed_checks": [',
\' {',
\' "check_id": "CKV_GCP_61",',
\' "bc_check_id": "BC_GCP_KUBERNETES_18",',
\' "check_name": "Enable VPC Flow Logs and Intranode Visibility",',
\' "check_result": {',
\' "result": "FAILED",',
\' "evaluated_keys": [',
\' "enable_intranode_visibility"',
\' ]',
\' },',
\' "file_path": "/main.tf",',
\' "repo_file_path": "/main.tf",',
\' "file_line_range": [',
\' 22,',
\' 27',
\' ],',
\' "resource": "google_container_cluster.cluster-name",',
\' "evaluations": null,',
\' "check_class": "checkov.terraform.checks.resource.gcp.GKEEnableVPCFlowLogs",',
\' "entity_tags": null,',
\' "resource_address": null,',
\' "guideline": "https://docs.bridgecrew.io/docs/enable-vpc-flow-logs-and-intranode-visibility"',
\' }',
\' ]',
\' }',
\'}'
\ ])
Execute(Handle output for no findings correctly):
AssertEqual
\ [],
\ ale_linters#terraform#checkov#Handle(bufnr(''), [
\'{',
\' "passed": 0,',
\' "failed": 0,',
\' "skipped": 0,',
\' "parsing_errors": 0,',
\' "resource_count": 0,',
\' "checkov_version": "2.0.632"',
\'}'
\])

View File

@ -0,0 +1,53 @@
Before:
runtime ale_linters/java/checkstyle.vim
After:
call ale#linter#Reset()
Execute(The checkstyle handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 101,
\ 'col': 0,
\ 'text': '''method def rcurly'' has incorrect indentation level 4, expected level should be 2.',
\ 'code': 'Indentation',
\ 'type': 'W',
\ 'sub_type': 'style',
\ },
\ {
\ 'lnum': 63,
\ 'col': 3,
\ 'text': 'Missing a Javadoc comment.',
\ 'code': 'JavadocMethod',
\ 'type': 'W',
\ 'sub_type': 'style',
\ },
\ {
\ 'lnum': 11,
\ 'col': 7,
\ 'text': 'WhitespaceAround: ''if'' is not followed by whitespace.',
\ 'code': 'WhitespaceAround',
\ 'type': 'W',
\ 'sub_type': 'style',
\ },
\ ],
\ ale_linters#java#checkstyle#Handle(666, [
\ '[WARN] whatever:101: ''method def rcurly'' has incorrect indentation level 4, expected level should be 2. [Indentation]',
\ '[WARN] whatever:63:3: Missing a Javadoc comment. [JavadocMethod]',
\ '[WARN] whatever:11:7: WhitespaceAround: ''if'' is not followed by whitespace. [WhitespaceAround]',
\ ])
Execute(The checkstyle handler should parse lines from older checkstyle versions correctly):
AssertEqual
\ [
\ {
\ 'lnum': 289,
\ 'text': '''method def modifier'' have incorrect indentation level 4, expected level should be 2.',
\ 'type': 'W',
\ 'sub_type': 'style',
\ },
\ ],
\ ale_linters#java#checkstyle#Handle(666, [
\ '/home/languitar/src/rsb-java/rsb-java/src/main/java/rsb/Listener.java:289: warning: ''method def modifier'' have incorrect indentation level 4, expected level should be 2.',
\ ])

View File

@ -0,0 +1,39 @@
Before:
runtime ale_linters/yaml/circleci.vim
After:
call ale#linter#Reset()
Execute(The circlei handler should return nothing when configs are valid):
AssertEqual
\ [],
\ ale_linters#yaml#circleci#Handle(0, [
\ 'Config input is valid.',
\ ])
Execute(The circlei handler put errors at the top when something is wrong):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': '[#/jobs] expected type: Mapping, found: Integer',
\ 'detail': join([
\ '[#/jobs] expected type: Mapping, found: Integer',
\ 'Jobs is a map',
\ 'SCHEMA:',
\ ' type: object',
\ 'INPUT:',
\ ' 4',
\ ], "\n"),
\ },
\ ],
\ ale_linters#yaml#circleci#Handle(0, [
\ 'Error: ERROR IN CONFIG FILE:',
\ '[#/jobs] expected type: Mapping, found: Integer',
\ 'Jobs is a map',
\ 'SCHEMA:',
\ ' type: object',
\ 'INPUT:',
\ ' 4',
\ ])

View File

@ -0,0 +1,30 @@
Execute(clang errors from included files should be parsed correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 1,
\ 'filename': './b.h',
\ 'type': 'E',
\ 'text': 'expected identifier or ''(''',
\ },
\ {
\ 'lnum': 3,
\ 'text': 'Error found in header. See :ALEDetail',
\ 'detail': join([
\ 'In file included from <stdin>:3:',
\ 'In file included from ./a.h:1:',
\ './b.h:1:1: error: expected identifier or ''(''',
\ '{{{',
\ '^',
\ ], "\n"),
\ },
\ ],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ 'In file included from <stdin>:3:',
\ 'In file included from ./a.h:1:',
\ './b.h:1:1: error: expected identifier or ''(''',
\ '{{{',
\ '^',
\ '1 error generated.',
\ ])

View File

@ -0,0 +1,89 @@
Before:
runtime ale_linters/clojure/clj_kondo.vim
After:
call ale#linter#Reset()
Execute(the clojure clj-kondo handler should be able to handle errors):
AssertEqual
\ [
\ {
\ 'lnum': 123,
\ 'col': 44,
\ 'type': 'E',
\ 'text': 'error: Unexpected )',
\ },
\ ],
\ ale_linters#clojure#clj_kondo#HandleCljKondoFormat(0, [
\ 'test.clj:123:44: error: Unexpected )',
\ ])
Execute(the clojure clj-kondo handler should be able to handle warnings):
AssertEqual
\ [
\ {
\ 'lnum': 654,
\ 'col': 321,
\ 'type': 'W',
\ 'text': 'warning: inline def',
\ }
\ ],
\ ale_linters#clojure#clj_kondo#HandleCljKondoFormat(0, [
\ 'test.clj:654:321: warning: inline def'
\ ])
Execute(the clojure clj-kondo handler should be able to handle exceptions):
AssertEqual
\ [
\ {
\ 'lnum': 123,
\ 'col': 321,
\ 'type': 'E',
\ 'text': 'Exception: something horrible happen',
\ }
\ ],
\ ale_linters#clojure#clj_kondo#HandleCljKondoFormat(0, [
\ 'test.clj:123:321: Exception: something horrible happen'
\ ])
Execute(the clojure clj-kondo handler should be able to handle errors from stdin):
AssertEqual
\ [
\ {
\ 'lnum': 16,
\ 'col': 1,
\ 'type': 'E',
\ 'text': 'error: Unexpected )',
\ },
\ ],
\ ale_linters#clojure#clj_kondo#HandleCljKondoFormat(0, [
\ '<stdin>:16:1: error: Unexpected )',
\ ])
Execute(the clojure clj-kondo handler should be able to handle windows files):
AssertEqual
\ [
\ {
\ 'lnum': 123,
\ 'col': 44,
\ 'type': 'E',
\ 'text': 'error: Unexpected )',
\ }
\ ],
\ ale_linters#clojure#clj_kondo#HandleCljKondoFormat(0, [
\ 'C:\my\operating\system\is\silly\core.clj:123:44: error: Unexpected )',
\ ])
Execute(the clojure clj-kondo handler should be able to lines without row/col):
AssertEqual
\ [
\ {
\ 'lnum': 0,
\ 'col': 0,
\ 'type': 'E',
\ 'text': 'error: Unexpected )',
\ },
\ ],
\ ale_linters#clojure#clj_kondo#HandleCljKondoFormat(0, [
\ 'test.clj::: error: Unexpected )',
\ ])

View File

@ -0,0 +1,75 @@
Before:
runtime ale_linters/clojure/joker.vim
After:
call ale#linter#Reset()
Execute(the clojure joker handler should be able to handle errors):
AssertEqual
\ [
\ {
\ 'lnum': 123,
\ 'col': 44,
\ 'type': 'E',
\ 'text': 'Read error: Unexpected )',
\ },
\ ],
\ ale_linters#clojure#joker#HandleJokerFormat(0, [
\ 'test.clj:123:44: Read error: Unexpected )',
\ ])
Execute(the clojure joker handler should be able to handle warnings):
AssertEqual
\ [
\ {
\ 'lnum': 654,
\ 'col': 321,
\ 'type': 'W',
\ 'text': 'Parse warning: let form with empty body',
\ }
\ ],
\ ale_linters#clojure#joker#HandleJokerFormat(0, [
\ 'test.clj:654:321: Parse warning: let form with empty body'
\ ])
Execute(the clojure joker handler should be able to handle exceptions):
AssertEqual
\ [
\ {
\ 'lnum': 123,
\ 'col': 321,
\ 'type': 'E',
\ 'text': 'Exception: something horrible happen',
\ }
\ ],
\ ale_linters#clojure#joker#HandleJokerFormat(0, [
\ 'test.clj:123:321: Exception: something horrible happen'
\ ])
Execute(the clojure joker handler should be able to handle errors from stdin):
AssertEqual
\ [
\ {
\ 'lnum': 16,
\ 'col': 1,
\ 'type': 'E',
\ 'text': 'Read error: Unexpected )',
\ },
\ ],
\ ale_linters#clojure#joker#HandleJokerFormat(0, [
\ '<stdin>:16:1: Read error: Unexpected )',
\ ])
Execute(the clojure joker handler should be able to handle windows files):
AssertEqual
\ [
\ {
\ 'lnum': 123,
\ 'col': 44,
\ 'type': 'E',
\ 'text': 'Read error: Unexpected )',
\ }
\ ],
\ ale_linters#clojure#joker#HandleJokerFormat(0, [
\ 'C:\my\operating\system\is\silly\core.clj:123:44: Read error: Unexpected )',
\ ])

View File

@ -0,0 +1,30 @@
Before:
runtime ale_linters/cmake/cmake_lint.vim
After:
Restore
call ale#linter#Reset()
Execute(The cmake_lint handler should handle basic warnings):
AssertEqual
\ [
\ {
\ 'lnum': 126,
\ 'col': 0,
\ 'type': 'W',
\ 'code': 'C0301',
\ 'text': 'Line too long (136/80)',
\ },
\ {
\ 'lnum': 139,
\ 'col': 4,
\ 'type': 'W',
\ 'code': 'C0113',
\ 'text': 'Missing COMMENT in statement which allows it',
\ },
\ ],
\ ale_linters#cmake#cmake_lint#Handle(1, [
\ 'CMakeLists.txt:126: [C0301] Line too long (136/80)',
\ 'CMakeLists.txt:139,04: [C0113] Missing COMMENT in statement which allows it',
\ ])

View File

@ -0,0 +1,20 @@
Before:
runtime ale_linters/coffee/coffeelint.vim
After:
call ale#linter#Reset()
Execute(The coffeelint handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 125,
\ 'text': "Line exceeds maximum allowed length Length is 122, max is 120.",
\ 'type': 'E',
\ },
\ ],
\ ale_linters#coffee#coffeelint#Handle(347, [
\ "path,lineNumber,lineNumberEnd,level,message",
\ "stdin,125,,error,Line exceeds maximum allowed length Length is 122, max is 120.",
\ ])

View File

@ -0,0 +1,181 @@
Execute(HandleCSSLintFormat should handle CSS errors):
AssertEqual
\ [
\ {
\ 'lnum': 2,
\ 'col': 1,
\ 'type': 'E',
\ 'text': 'Expected RBRACE at line 2, col 1.',
\ 'code': 'errors',
\ },
\ {
\ 'lnum': 2,
\ 'col': 5,
\ 'type': 'W',
\ 'text': 'Expected ... but found ''wat''.',
\ 'code': 'known-properties',
\ },
\ ],
\ ale#handlers#css#HandleCSSLintFormat(42, [
\ 'something.css: line 2, col 1, Error - Expected RBRACE at line 2, col 1. (errors)',
\ 'something.css: line 2, col 5, Warning - Expected ... but found ''wat''. (known-properties)',
\ ])
Execute(HandleCSSLintFormat should handle CSS errors without groups):
AssertEqual
\ [
\ {
\ 'lnum': 7,
\ 'col': 3,
\ 'type': 'W',
\ 'text': 'Unknown property ''fill''.',
\ },
\ {
\ 'lnum': 8,
\ 'col': 3,
\ 'type': 'W',
\ 'text': 'Unknown property ''fill-opacity''.',
\ },
\ ],
\ ale#handlers#css#HandleCSSLintFormat(42, [
\ 'something.css: line 7, col 3, Warning - Unknown property ''fill''.',
\ 'something.css: line 8, col 3, Warning - Unknown property ''fill-opacity''.',
\ ])
Execute (HandleGCCFormat should handle the correct lines of output):
AssertEqual
\ [
\ {
\ 'lnum': 8,
\ 'col': 5,
\ 'type': 'W',
\ 'text': 'conversion lacks type at end of format [-Wformat=]',
\ },
\ {
\ 'lnum': 10,
\ 'col': 27,
\ 'type': 'E',
\ 'text': 'invalid operands to binary - (have ''int'' and ''char *'')',
\ },
\ ],
\ ale#handlers#gcc#HandleGCCFormat(42, [
\ '<stdin>:8:5: warning: conversion lacks type at end of format [-Wformat=]',
\ '<stdin>:10:27: error: invalid operands to binary - (have int and char *)',
\ ])
Execute (HandleGCCFormat should replace Unicode quotes):
AssertEqual
\ [
\ {
\ 'lnum': 8,
\ 'col': 5,
\ 'type': 'W',
\ 'text': "'''' \"\"",
\ },
\ ],
\ ale#handlers#gcc#HandleGCCFormat(42, ['<stdin>:8:5: warning: `´ “”'])
Execute (HandleUnixFormatAsError should handle some example lines of output):
AssertEqual
\ [
\ {
\ 'lnum': 27,
\ 'col': 0,
\ 'type': 'E',
\ 'text': 'missing argument for Printf("%s"): format reads arg 2, have only 1 args',
\ },
\ {
\ 'lnum': 53,
\ 'col': 10,
\ 'type': 'E',
\ 'text': 'if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)',
\ },
\ {
\ 'lnum': 1,
\ 'col': 1,
\ 'type': 'E',
\ 'text': '".b" is not a valid class name. Class names must begin with "-", "_" or a letter and can only contain "_", "-", a-z and 0-9.',
\ },
\ ],
\ ale#handlers#unix#HandleAsError(42, [
\ 'file.go:27: missing argument for Printf("%s"): format reads arg 2, have only 1 args',
\ 'file.go:53:10: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)',
\ 'test.pug:1:1 ".b" is not a valid class name. Class names must begin with "-", "_" or a letter and can only contain "_", "-", a-z and 0-9.',
\ ])
Execute (HandleUnixFormatAsError should handle lines with no space after the colon):
AssertEqual
\ [
\ {
\ 'lnum': 27,
\ 'col': 0,
\ 'type': 'E',
\ 'text': 'foo',
\ },
\ {
\ 'lnum': 53,
\ 'col': 10,
\ 'type': 'E',
\ 'text': 'bar',
\ },
\ ],
\ ale#handlers#unix#HandleAsError(42, [
\ 'some_file.xyz:27:foo',
\ 'some_file.xyz:53:10:bar',
\ ])
Execute (HandleUnixFormatAsError should handle names with spaces):
AssertEqual
\ [
\ {
\ 'lnum': 13,
\ 'col': 90,
\ 'type': 'E',
\ 'text': 'leonard.exclamation.30ppm More than 30 ppm of exclamations. Keep them under control.',
\ },
\ ],
\ ale#handlers#unix#HandleAsError(42, [
\ '/Users/rrj/Notes/Astro/Taurus December SM.txt:13:90: leonard.exclamation.30ppm More than 30 ppm of exclamations. Keep them under control.',
\ ])
Execute (HandleUnixFormatAsWarning should handle some example lines of output):
AssertEqual
\ [
\ {
\ 'lnum': 27,
\ 'col': 0,
\ 'type': 'W',
\ 'text': 'missing argument for Printf("%s"): format reads arg 2, have only 1 args',
\ },
\ {
\ 'lnum': 53,
\ 'col': 10,
\ 'type': 'W',
\ 'text': 'if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)',
\ },
\ ],
\ ale#handlers#unix#HandleAsWarning(42, [
\ 'file.go:27: missing argument for Printf("%s"): format reads arg 2, have only 1 args',
\ 'file.go:53:10: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)',
\ ])
Execute (Unix format functions should handle Windows paths):
AssertEqual
\ [
\ {
\ 'lnum': 27,
\ 'col': 0,
\ 'type': 'E',
\ 'text': 'foo',
\ },
\ {
\ 'lnum': 53,
\ 'col': 10,
\ 'type': 'E',
\ 'text': 'foo',
\ },
\ ],
\ ale#handlers#unix#HandleAsError(42, [
\ 'C:\Users\w0rp\AppData\Local\Temp\Xyz123.go:27: foo',
\ 'C:\Users\w0rp\AppData\Local\Temp\Xyz123.go:53:10: foo',
\ ])

View File

@ -0,0 +1,22 @@
Before:
runtime ale_linters/chef/cookstyle.vim
After:
call ale#linter#Reset()
Execute(Basic warnings should be handled):
AssertEqual
\ [
\ {
\ 'lnum': 58,
\ 'col': 24,
\ 'code': 'Style/UnneededInterpolation',
\ 'type': 'W',
\ 'end_col': 40,
\ 'text': 'Style/UnneededInterpolation: Prefer `to_s` over string interpolation.',
\ }
\ ],
\ ale_linters#chef#cookstyle#Handle(bufnr(''), [
\ '{"metadata":{"rubocop_version":"0.62.0","ruby_engine":"ruby","ruby_version":"2.6.0","ruby_patchlevel":"0","ruby_platform":"x86_64-linux"},"files":[{"path":"recipes/default.rb","offenses":[{"severity":"convention","message":"Style/UnneededInterpolation: Prefer `to_s` over string interpolation.","cop_name":"Style/UnneededInterpolation","corrected":false,"location":{"start_line":58,"start_column":24,"last_line":58,"last_column":40,"length":17,"line":58,"column":24}}]}],"summary":{"offense_count":1,"target_file_count":1,"inspected_file_count":1}}'
\ ])

View File

@ -0,0 +1,93 @@
Before:
call ale#test#SetDirectory('/testplugin/test/handler')
After:
call ale#test#RestoreDirectory()
Execute(Basic errors should be handled by cppcheck):
call ale#test#SetFilename('test.cpp')
AssertEqual
\ [
\ {
\ 'lnum': 974,
\ 'col' : 6,
\ 'type': 'E',
\ 'sub_type': '',
\ 'text': 'Array ''n[3]'' accessed at index 3, which is out of bounds.',
\ 'code': 'arrayIndexOutOfBounds'
\ },
\ {
\ 'lnum': 1185,
\ 'col' : 10,
\ 'type': 'W',
\ 'sub_type': 'style',
\ 'text': 'The scope of the variable ''indxStr'' can be reduced.',
\ 'code': 'variableScope'
\ },
\ ],
\ ale#handlers#cppcheck#HandleCppCheckFormat(bufnr(''), [
\ 'test.cpp:974:6: error: Array ''n[3]'' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\',
\ ' n[3]=3;',
\ ' ^',
\ 'test.cpp:1185:10: style: The scope of the variable ''indxStr'' can be reduced. [variableScope]\',
\ ' char indxStr[16];',
\ ' ^',
\ ])
AssertEqual
\ [
\ {
\ 'lnum': 974,
\ 'col' : 1,
\ 'type': 'E',
\ 'sub_type': '',
\ 'text': 'inconclusive Array ''n[3]'' accessed at index 3, which is out of bounds.',
\ 'code': 'arrayIndexOutOfBounds'
\ },
\ {
\ 'lnum': 1185,
\ 'col' : 1,
\ 'type': 'W',
\ 'sub_type': 'style',
\ 'text': 'The scope of the variable ''indxStr'' can be reduced.',
\ 'code': 'variableScope'
\ },
\ ],
\ ale#handlers#cppcheck#HandleCppCheckFormat(bufnr(''), [
\ 'test.cpp:974:{column}: error:inconclusive Array ''n[3]'' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\',
\ ' n[3]=3;',
\ ' ^',
\ 'test.cpp:1185:{column}: style:{inconclusive:inconclusive} The scope of the variable ''indxStr'' can be reduced. [variableScope]\',
\ ' char indxStr[16];',
\ ' ^',
\ ])
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col' : 16,
\ 'type': 'W',
\ 'sub_type': 'style',
\ 'text': 'misra violation (use --rule-texts=<file> to get proper output)',
\ 'code': 'misra-c2012-2.7'
\ },
\ ],
\ ale#handlers#cppcheck#HandleCppCheckFormat(bufnr(''), [
\ 'test.cpp:1:16: style: misra violation (use --rule-texts=<file> to get proper output) [misra-c2012-2.7]\',
\ 'void test( int parm ) {}',
\ ' ^',
\ ])
Execute(Problems from other files should be ignored by cppcheck):
call ale#test#SetFilename('test.cpp')
AssertEqual
\ [
\ ],
\ ale#handlers#cppcheck#HandleCppCheckFormat(bufnr(''), [
\ 'bar.cpp:974:6: error: Array ''n[3]'' accessed at index 3, which is out of bounds. [arrayIndexOutOfBounds]\',
\ ' n[3]=3;',
\ ' ^',
\ ])

View File

@ -0,0 +1,29 @@
Before:
runtime ale_linters/cpp/cpplint.vim
After:
call ale#linter#Reset()
Execute(cpplint warnings from included files should be parsed correctly):
AssertEqual
\ [
\ {
\ 'lnum': 5,
\ 'col': 0,
\ 'text': 'Extra space after ( in function call',
\ 'code': 'whitespace/parents',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 120,
\ 'col': 0,
\ 'text': 'At least two spaces is best between code and comments',
\ 'code': 'whitespace/comments',
\ 'type': 'W',
\ },
\ ],
\ ale#handlers#cpplint#HandleCppLintFormat(347, [
\ 'test.cpp:5: Extra space after ( in function call [whitespace/parents] [4]',
\ 'keymap_keys.hpp:120: At least two spaces is best between code and comments [whitespace/comments] [2]',
\ ])

View File

@ -0,0 +1,53 @@
Before:
runtime ale_linters/elixir/credo.vim
After:
call ale#linter#Reset()
Execute(The credo handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'bufnr': 347,
\ 'lnum': 1,
\ 'col': 24,
\ 'text': 'This code can be refactored',
\ 'type': 'W',
\ },
\ {
\ 'bufnr': 347,
\ 'lnum': 1,
\ 'col': 4,
\ 'text': 'There is no whitespace around parentheses/brackets most of the time, but here there is.',
\ 'type': 'W',
\ },
\ {
\ 'bufnr': 347,
\ 'lnum': 5,
\ 'col': 21,
\ 'text': 'TODO comment',
\ 'type': 'I',
\ },
\ {
\ 'bufnr': 347,
\ 'lnum': 26,
\ 'col': 0,
\ 'text': 'If/else blocks should not have a negated condition in `if`.',
\ 'type': 'I',
\ },
\ {
\ 'bufnr': 347,
\ 'lnum': 15,
\ 'col': 1,
\ 'text': 'Warning in the code',
\ 'type': 'W',
\ },
\ ],
\ ale_linters#elixir#credo#Handle(347, [
\ 'This line should be ignored completely',
\ 'lib/my_code/test.ex:1:24: F: This code can be refactored',
\ 'lib/filename.ex:1:4: C: There is no whitespace around parentheses/brackets most of the time, but here there is.',
\ 'lib/my_code/test.ex:5:21: D: TODO comment',
\ 'lib/phoenix/channel.ex:26: R: If/else blocks should not have a negated condition in `if`.',
\ 'lib/my_code/test.ex:15:1: W: Warning in the code',
\ ])

View File

@ -0,0 +1,28 @@
Before:
runtime ale_linters/crystal/crystal.vim
After:
call ale#linter#Reset()
Execute(The crystal handler should parse lines correctly and add the column if it can):
AssertEqual
\ [
\ {
\ 'lnum': 2,
\ 'col': 1,
\ 'text': 'unexpected token: EOF'
\ }
\ ],
\ ale_linters#crystal#crystal#Handle(255, [
\ '[{"file":"/tmp/test.cr","line":2,"column":1,"size":null,"message":"unexpected token: EOF"}]'
\ ])
Execute(The crystal handler should not fail when a missing file is required):
AssertEqual
\ [ { 'lnum':1, 'col': 1, 'text': 'while requiring "./nonexistent.cr"' } ],
\ ale_linters#crystal#crystal#Handle(255,
\ json_encode([
\ { "file":"/tmp/file.cr","line":1,"column":1,"size":0,"message":"while requiring \"./nonexistent.cr\"" },
\ { "message": "can't find file './nonexistent.cr' relative to '/tmp'" },
\ ])
\ )

View File

@ -0,0 +1,98 @@
Before:
Save g:ale_cs_csc_source
unlet! g:ale_cs_csc_source
call ale#test#SetDirectory('/testplugin/test/handler')
call ale#test#SetFilename('Test.cs')
runtime ale_linters/cs/csc.vim
After:
unlet! g:ale_cs_csc_source
call ale#test#RestoreDirectory()
call ale#linter#Reset()
Execute(The csc handler should work with the default of the buffer's directory):
AssertEqual
\ [
\ {
\ 'lnum': 12,
\ 'col' : 29,
\ 'text': '; expected',
\ 'code': 'CS1001',
\ 'type': 'E',
\ 'filename': ale#path#Simplify(g:dir . '/Test.cs'),
\ },
\ ],
\ ale_linters#cs#csc#Handle(bufnr(''), [
\ 'Test.cs(12,29): error CS1001: ; expected',
\ 'Compilation failed: 2 error(s), 1 warnings',
\ ])
Execute(The csc handler should handle cannot find symbol errors):
let g:ale_cs_csc_source = '/home/foo/project/bar'
AssertEqual
\ [
\ {
\ 'lnum': 12,
\ 'col' : 29,
\ 'text': '; expected',
\ 'code': 'CS1001',
\ 'type': 'E',
\ 'filename': ale#path#Simplify('/home/foo/project/bar/Test.cs'),
\ },
\ {
\ 'lnum': 101,
\ 'col': 0,
\ 'text': 'Unexpected processor directive (no #if for this #endif)',
\ 'code': 'CS1028',
\ 'type': 'E',
\ 'filename': ale#path#Simplify('/home/foo/project/bar/Test.cs'),
\ },
\ {
\ 'lnum': 10,
\ 'col': 12,
\ 'text': 'some warning',
\ 'code': 'CS0123',
\ 'type': 'W',
\ 'filename': ale#path#Simplify('/home/foo/project/bar/Test.cs'),
\ },
\ ],
\ ale_linters#cs#csc#Handle(bufnr(''), [
\ 'Test.cs(12,29): error CS1001: ; expected',
\ 'Test.cs(101,0): error CS1028: Unexpected processor directive (no #if for this #endif)',
\ 'Test.cs(10,12): warning CS0123: some warning',
\ 'Compilation failed: 2 error(s), 1 warnings',
\ ])
Execute(The csc handler should handle non file specific compiler errors without reporting overal status report as error):
let g:ale_cs_csc_source = '/home/foo/project/bar'
AssertEqual
\ [
\ {
\ 'lnum': -1,
\ 'col' : -1,
\ 'text': 'No source files specified.',
\ 'code': 'CS2008',
\ 'type': 'W',
\ 'filename': '<csc>',
\ },
\ {
\ 'lnum': -1,
\ 'col': -1,
\ 'text': 'Outputs without source must have the /out option specified',
\ 'code': 'CS1562',
\ 'type': 'E',
\ 'filename': '<csc>',
\ },
\ ],
\ ale_linters#cs#csc#Handle(bufnr(''), [
\ 'Microsoft (R) Visual C# Compiler version 2.8.2.62916 (2ad4aabc)',
\ 'Copyright (C) Microsoft Corporation. All rights reserved.',
\ 'warning CS2008: No source files specified.',
\ 'error CS1562: Outputs without source must have the /out option specified',
\ ])

View File

@ -0,0 +1,13 @@
Execute(The cspell handler should handle cspell output):
AssertEqual
\ [
\ {
\ 'lnum': 721,
\ 'col': 18,
\ 'type': 'W',
\ 'text': 'Unknown word (stylelint)',
\ },
\ ],
\ ale#handlers#cspell#Handle(bufnr(''),
\ '/:721:18 - Unknown word (stylelint)'
\)

View File

@ -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"}]'
\ ])

View File

@ -0,0 +1,41 @@
Before:
runtime ale_linters/cuda/nvcc.vim
After:
call ale#linter#Reset()
Execute(The cuda nvcc handler should parse errors from multiple files for NVCC 8.0):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': 'this declaration has no storage class or type specifier',
\ 'filename': has('win32')
\ ? 'C:\tmp\cudatest\test.cu'
\ : '/tmp/cudatest/test.cu',
\ },
\ {
\ 'lnum': 2,
\ 'type': 'E',
\ 'text': 'attribute "global" does not apply here',
\ 'filename': has('win32')
\ ? 'C:\tmp\cudatest\common.h'
\ : '/tmp/cudatest/common.h',
\ },
\ {
\ 'lnum': 2,
\ 'type': 'E',
\ 'text': 'expected a ";"',
\ 'filename': has('win32')
\ ? 'C:\tmp\cudatest\common.h'
\ : '/tmp/cudatest/common.h',
\ },
\ ],
\ ale_linters#cuda#nvcc#HandleNVCCFormat(0, [
\ '/tmp/cudatest/test.cu(1): error: this declaration has no storage class or type specifier',
\ '/tmp/cudatest/common.h(2): error: attribute "global" does not apply here',
\ '/tmp/cudatest/common.h(2): error: expected a ";"',
\ 'At end of source: warning: parsing restarts here after previous syntax error',
\ '3 errors detected in the compilation of "/tmp/tmpxft_00003a9f_00000000-7_test.cpp1.ii".',
\ ])

View File

@ -0,0 +1,21 @@
Before:
runtime ale_linters/cypher/cypher_lint.vim
After:
call ale#linter#Reset()
Execute(The cypher-lint handler should handle errors for the current file correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 75,
\ 'type': 'E',
\ 'text': "Invalid input ',': expected an identifier, shortestPath, allShortestPaths or '('",
\ },
\ ],
\ ale_linters#cypher#cypher_lint#Handle(bufnr(''), [
\ "shakespeare.cql:1:75: Invalid input ',': expected an identifier, shortestPath, allShortestPaths or '('",
\ "CREATE (shakespeare:Author {firstname:'William', lastname:'Shakespeare'}),,",
\ " ^",
\ ])

View File

@ -0,0 +1,36 @@
Before:
runtime ale_linters/dafny/dafny.vim
After:
call ale#linter#Reset()
Execute(The Dafny handler should parse output correctly):
AssertEqual
\ [
\ {
\ 'filename': 'File.dfy',
\ 'col': 45,
\ 'lnum': 123,
\ 'text': 'A precondition for this call might not hold.',
\ 'type': 'E'
\ },
\ {
\ 'filename': 'File.dfy',
\ 'col': 90,
\ 'lnum': 678,
\ 'text': 'This is the precondition that might not hold.',
\ 'type': 'W'
\ },
\ {
\ 'filename': 'File.dfy',
\ 'col': 45,
\ 'lnum': 123,
\ 'text': "Verification of 'Impl$$_22_Proof.__default.PutKeepsMapsFull' timed out after 2 seconds",
\ 'type': 'E'
\ },
\ ],
\ ale_linters#dafny#dafny#Handle(0, [
\ 'File.dfy(123,45): Error BP5002: A precondition for this call might not hold.',
\ 'File.dfy(678,90): Related location: This is the precondition that might not hold.',
\ "File.dfy(123,45): Verification of 'Impl$$_22_Proof.__default.PutKeepsMapsFull' timed out after 2 seconds",
\ ])

View File

@ -0,0 +1,28 @@
Before:
runtime ale_linters/dart/dart_analyze.vim
After:
call ale#linter#Reset()
Execute(Basic problems should be parsed correctly):
AssertEqual
\ [
\ {
\ 'type': 'E',
\ 'text': 'expected_token: Expected to find ''}''',
\ 'lnum': 5,
\ 'col': 1,
\ },
\ {
\ 'type': 'W',
\ 'text': 'invalid_assignment: A value of type ''String'' can''t be assigned to a variable of type ''int''',
\ 'lnum': 2,
\ 'col': 16,
\ },
\ ],
\ ale_linters#dart#dart_analyze#Handle(bufnr(''), [
\ 'Analyzing main.dart...',
\ ' error - main.dart:5:1 - Expected to find ''}'' - expected_token',
\ ' warning - main.dart:2:16 - A value of type ''String'' can''t be assigned to a variable of type ''int'' - invalid_assignment',
\ '1 error and 1 warning found.',
\ ])

View File

@ -0,0 +1,27 @@
Before:
runtime ale_linters/ruby/debride.vim
After:
call ale#linter#Reset()
Execute(The debride linter parses output correctly):
AssertEqual
\ [
\ {
\ 'lnum': 2,
\ 'text': 'Possible unused method: image_tags',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 7,
\ 'text': 'Possible unused method: not_deleted',
\ 'type': 'W',
\ }
\ ],
\ ale_linters#ruby#debride#HandleOutput(0, [
\ 'These methods MIGHT not be called:',
\ '',
\ 'Image',
\ ' image_tags app/models/image.rb:2',
\ ' not_deleted app/models/image.rb:7'
\])

View File

@ -0,0 +1,26 @@
Before:
runtime ale_linters/desktop/desktop_file_validate.vim
After:
call ale#linter#Reset()
Execute(The desktop-file-validate handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 1,
\ 'type': 'W',
\ 'text': 'key "TerminalOptions" in group "Desktop Entry" is deprecated',
\ },
\ {
\ 'lnum': 1,
\ 'col': 1,
\ 'type': 'E',
\ 'text': 'action "new-private-window" is defined, but there is no matching "Desktop Action new-private-window" group',
\ },
\ ],
\ ale_linters#desktop#desktop_file_validate#Handle(bufnr(''), [
\ 'foo.desktop: warning: key "TerminalOptions" in group "Desktop Entry" is deprecated',
\ 'foo.desktop: error: action "new-private-window" is defined, but there is no matching "Desktop Action new-private-window" group',
\ ])

View File

@ -0,0 +1,41 @@
Before:
runtime ale_linters/d/dmd.vim
call ale#test#SetDirectory('/testplugin/test/dmd')
call ale#test#SetFilename('test.d')
After:
call ale#linter#Reset()
call ale#test#RestoreDirectory()
Execute(Basic errors should be handled by dmd):
AssertEqual
\ [
\ {
\ 'filename': ale#path#Simplify(g:dir . '/test.d'),
\ 'lnum': '5',
\ 'col' : '8',
\ 'type': 'E',
\ 'text': 'module weak_reference is in file ''dstruct/weak_reference.d'' which cannot be read'
\ },
\ {
\ 'filename': ale#path#Simplify(g:dir . '/test.d'),
\ 'lnum': '20',
\ 'col' : '10',
\ 'type': 'W',
\ 'text': 'function test.thisoldfunc is deprecated'
\ },
\ {
\ 'filename': ale#path#Simplify(g:dir . '/foo.d'),
\ 'lnum': '230',
\ 'col' : '9',
\ 'type': 'W',
\ 'text': 'statement is not reachable'
\ }
\ ],
\ ale_linters#d#dmd#Handle(bufnr(''), [
\ 'test.d(5,8): Error: module weak_reference is in file ''dstruct/weak_reference.d'' which cannot be read',
\ 'import path[0] = source',
\ 'import path[1] = /usr/include/dlang/dmd',
\ ale#path#Simplify(g:dir . '/test.d') . '(20,10): Deprecation: function test.thisoldfunc is deprecated',
\ 'foo.d(230,9): Warning: statement is not reachable',
\ ])

View File

@ -0,0 +1,112 @@
Before:
runtime ale_linters/dockerfile/dockerfile_lint.vim
After:
call ale#linter#Reset()
Execute(The dockerfile_lint handler should handle broken JSON):
AssertEqual
\ [],
\ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), ["{asdf"])
Execute(The dockerfile_lint handler should handle an empty string response):
AssertEqual
\ [],
\ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), [])
Execute(The dockerfile_lint handler should handle an empty result, even if it shouldn't happen):
AssertEqual
\ [],
\ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), ["{}"])
Execute(The dockerfile_lint handler should handle a normal example):
AssertEqual
\ [
\ {
\ 'lnum': -1,
\ 'type': 'E',
\ 'text': "Required LABEL name/key 'Name' is not defined",
\ 'detail': "Required LABEL name/key 'Name' is not defined\n\nhttp://docs.projectatomic.io/container-best-practices/#_recommended_labels_for_your_project",
\ },
\ {
\ 'lnum': -1,
\ 'type': 'E',
\ 'text': "Required LABEL name/key 'Version' is not defined",
\ 'detail': "Required LABEL name/key 'Version' is not defined\n\nhttp://docs.projectatomic.io/container-best-practices/#_recommended_labels_for_your_project",
\ },
\ {
\ 'lnum': 3,
\ 'type': 'I',
\ 'text': "the MAINTAINER command is deprecated",
\ 'detail': "the MAINTAINER command is deprecated\n\nMAINTAINER is deprecated in favor of using LABEL since Docker v1.13.0\n\nhttps://github.com/docker/cli/blob/master/docs/deprecated.md#maintainer-in-dockerfile",
\ },
\ {
\ 'lnum': -1,
\ 'type': 'I',
\ 'text': "There is no 'CMD' instruction",
\ 'detail': "There is no 'CMD' instruction\n\nhttps://docs.docker.com/engine/reference/builder/#cmd",
\ },
\ ],
\ ale_linters#dockerfile#dockerfile_lint#Handle(bufnr(''), [
\ '{',
\ ' "error": {',
\ ' "count": 2,',
\ ' "data": [',
\ ' {',
\ " \"message\": \"Required LABEL name/key 'Name' is not defined\",",
\ ' "line": -1,',
\ ' "level": "error",',
\ ' "lineContent": "",',
\ ' "reference_url": [',
\ ' "http://docs.projectatomic.io/container-best-practices/#",',
\ ' "_recommended_labels_for_your_project"',
\ ' ]',
\ ' },',
\ ' {',
\ " \"message\": \"Required LABEL name/key 'Version' is not defined\",",
\ ' "line": -1,',
\ ' "level": "error",',
\ ' "lineContent": "",',
\ ' "reference_url": [',
\ ' "http://docs.projectatomic.io/container-best-practices/#",',
\ ' "_recommended_labels_for_your_project"',
\ ' ]',
\ ' }',
\ ' ]',
\ ' },',
\ ' "warn": {',
\ ' "count": 0,',
\ ' "data": []',
\ ' },',
\ ' "info": {',
\ ' "count": 2,',
\ ' "data": [',
\ ' {',
\ ' "label": "maintainer_deprecated",',
\ ' "regex": {},',
\ ' "level": "info",',
\ ' "message": "the MAINTAINER command is deprecated",',
\ ' "description": "MAINTAINER is deprecated in favor of using LABEL since Docker v1.13.0",',
\ ' "reference_url": [',
\ ' "https://github.com/docker/cli/blob/master/docs/deprecated.md",',
\ ' "#maintainer-in-dockerfile"',
\ ' ],',
\ ' "lineContent": "MAINTAINER Alexander Olofsson <ace@haxalot.com>",',
\ ' "line": 3',
\ ' },',
\ ' {',
\ ' "instruction": "CMD",',
\ ' "count": 1,',
\ ' "level": "info",',
\ " \"message\": \"There is no 'CMD' instruction\",",
\ ' "description": "None",',
\ ' "reference_url": [',
\ ' "https://docs.docker.com/engine/reference/builder/",',
\ ' "#cmd"',
\ ' ]',
\ ' }',
\ ' ]',
\ ' },',
\ ' "summary": []',
\ '}',
\ ])

View File

@ -0,0 +1,30 @@
Before:
runtime ale_linters/elixir/dogma.vim
After:
call ale#linter#Reset()
Execute(The dogma handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'bufnr': 347,
\ 'lnum': 18,
\ 'col': 5,
\ 'text': 'Some error',
\ 'type': 'E',
\ },
\ {
\ 'bufnr': 347,
\ 'lnum': 19,
\ 'col': 7,
\ 'text': 'Some warning',
\ 'type': 'W',
\ },
\ ],
\ ale_linters#elixir#dogma#Handle(347, [
\ 'This line should be ignored completely',
\ 'lib/filename.ex:18:5: C: Some error',
\ 'lib/filename.ex:19:7: R: Some warning',
\ ])

View File

@ -0,0 +1,37 @@
Before:
runtime! ale_linters/apiblueprint/drafter.vim
After:
call ale#linter#Reset()
Execute(drafter handler should handle errors output):
AssertEqual
\ [
\ {
\ 'lnum': 25,
\ 'col': 3,
\ 'text': "unable to parse response signature, expected 'response [<HTTP status code>] [(<media type>)]'",
\ 'type': "W",
\ },
\ {
\ 'lnum': 25,
\ 'col': 3,
\ 'text': "missing response HTTP status code, assuming 'Response 200'",
\ 'type': "W",
\ },
\ {
\ 'lnum': 30,
\ 'col': 7,
\ 'end_lnum': 32,
\ 'end_col': 7,
\ 'text': "message-body asset is expected to be a pre-formatted code block, separate it by a newline and indent every of its line by 12 spaces or 3 tabs",
\ 'type': "W",
\ },
\ ],
\ ale_linters#apiblueprint#drafter#HandleErrors(bufnr(''), [
\ "",
\ "OK.",
\ "warning: (3) unable to parse response signature, expected 'response [<HTTP status code>] [(<media type>)]'; line 25, column 3 - line 25, column 29",
\ "warning: (6) missing response HTTP status code, assuming 'Response 200'; line 25, column 3 - line 25, column 29",
\ "warning: (10) message-body asset is expected to be a pre-formatted code block, separate it by a newline and indent every of its line by 12 spaces or 3 tabs; line 30, column 7 - line 30, column 11; line 31, column 6 - line 31, column 7; line 32, column 6 - line 32, column 7"
\ ])

View File

@ -0,0 +1,299 @@
Before:
runtime ale_linters/elm/make.vim
After:
unlet! g:config_error_lines
call ale#linter#Reset()
" Elm 0.19
Execute(The elm-make handler should parse Elm 0.19 general problems correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': "error details\n\nstyled details"
\ }
\ ],
\ ale_linters#elm#make#Handle(347, [
\ json_encode({
\ 'type': 'error',
\ 'path': ale#util#Tempname() . '/Module.elm',
\ 'title': 'UNKNOWN IMPORT',
\ 'message': ["error details\n\n", { 'string': 'styled details' }]
\ }),
\ ])
Execute(The elm-make handler should parse Elm 0.19 compilation errors correctly):
AssertEqual
\ [
\ {
\ 'lnum': 404,
\ 'col': 1,
\ 'end_lnum': 408,
\ 'end_col': 18,
\ 'type': 'E',
\ 'text': "error details 1\n\nstyled details"
\ },
\ {
\ 'lnum': 406,
\ 'col': 5,
\ 'end_lnum': 407,
\ 'end_col': 17,
\ 'type': 'E',
\ 'text': 'error details 2',
\ },
\ {
\ 'lnum': 406,
\ 'col': 5,
\ 'end_lnum': 406,
\ 'end_col': 93,
\ 'type': 'E',
\ 'text': 'error details 3',
\ },
\ ],
\ ale_linters#elm#make#Handle(347, [
\ json_encode({
\ 'type': 'compile-errors',
\ 'errors': [
\ {
\ 'path': ale#util#Tempname() . '/Module.elm',
\ 'problems': [
\ {
\ 'title': 'TYPE MISMATCH',
\ 'message': ["error details 1\n\n", { 'string': 'styled details' }],
\ 'region': { 'start': { 'line': 404, 'column': 1 }, 'end': { 'line': 408, 'column': 18 } }
\ },
\ {
\ 'title': 'TYPE MISMATCH',
\ 'message': ['error details 2'],
\ 'region': { 'start': {'line': 406, 'column': 5}, 'end': {'line': 407, 'column': 17 } }
\ },
\ {
\ 'title': 'TYPE MISMATCH',
\ 'message': ['error details 3'],
\ 'region': { 'start': { 'line': 406, 'column': 5}, 'end': {'line': 406, 'column': 93 } }
\ }
\ ]
\ }
\ ]
\ }),
\ ])
Execute(The elm-make handler should handle errors in Elm 0.19 imported modules):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': "src/Module.elm - error details\n\nstyled details",
\ 'detail': "src/Module.elm ----------\n\nerror details\n\nstyled details"
\ },
\ {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': "Elm - error details\n\nstyled details",
\ 'detail': "Elm ----------\n\nerror details\n\nstyled details"
\ },
\ {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': "src/Module.elm:404 - error details\n\nstyled details",
\ 'detail': "src/Module.elm:404 ----------\n\nerror details\n\nstyled details"
\ },
\ ],
\ ale_linters#elm#make#Handle(347, [
\ json_encode({
\ 'type': 'error',
\ 'path': 'src/Module.elm',
\ 'title': 'UNKNOWN IMPORT',
\ 'message': ["error details\n\n", { 'string': 'styled details' }]
\ }),
\ json_encode({
\ 'type': 'error',
\ 'path': v:null,
\ 'title': 'UNKNOWN IMPORT',
\ 'message': ["error details\n\n", { 'string': 'styled details' }]
\ }),
\ json_encode({
\ 'type': 'compile-errors',
\ 'errors': [
\ {
\ 'path': 'src/Module.elm',
\ 'problems': [
\ {
\ 'title': 'TYPE MISMATCH',
\ 'message': ["error details\n\n", { 'string': 'styled details' }],
\ 'region': { 'start': { 'line': 404, 'column': 1 }, 'end': { 'line': 408, 'column': 18 } }
\ }
\ ]
\ }
\ ]
\ }),
\ ])
" Elm 0.18
Execute(The elm-make handler should parse Elm 0.18 compilation errors correctly):
AssertEqual
\ [
\ {
\ 'lnum': 33,
\ 'col': 1,
\ 'end_lnum': 33,
\ 'end_col': 19,
\ 'type': 'W',
\ 'text': 'warning overview',
\ 'detail': "warning overview\n\nwarning details",
\ },
\ {
\ 'lnum': 404,
\ 'col': 1,
\ 'end_lnum': 408,
\ 'end_col': 18,
\ 'type': 'E',
\ 'text': 'error overview 1',
\ 'detail': "error overview 1\n\nerror details 1",
\ },
\ {
\ 'lnum': 406,
\ 'col': 5,
\ 'end_lnum': 407,
\ 'end_col': 17,
\ 'type': 'E',
\ 'text': 'error overview 2',
\ 'detail': "error overview 2\n\nerror details 2",
\ },
\ {
\ 'lnum': 406,
\ 'col': 5,
\ 'end_lnum': 406,
\ 'end_col': 93,
\ 'type': 'E',
\ 'text': 'error overview 3',
\ 'detail': "error overview 3\n\nerror details 3",
\ },
\ ],
\ ale_linters#elm#make#Handle(347, [
\ json_encode([
\ {
\ 'tag': 'unused import',
\ 'overview': 'warning overview',
\ 'details': 'warning details',
\ 'region': {'start': { 'line': 33, 'column': 1 }, 'end': { 'line': 33, 'column': 19 } },
\ 'type': 'warning',
\ 'file': ale#util#Tempname() . '/Module.elm',
\ }
\ ]),
\ json_encode([
\ {
\ 'tag': 'TYPE MISMATCH',
\ 'overview': 'error overview 1',
\ 'subregion': { 'start': { 'line': 406, 'column': 5 }, 'end': { 'line': 408, 'column': 18 } },
\ 'details': 'error details 1',
\ 'region': { 'start': { 'line': 404, 'column': 1 }, 'end': { 'line': 408, 'column': 18 } },
\ 'type': 'error',
\ 'file': ale#util#Tempname() . '/Module.elm',
\ },
\ {
\ 'tag': 'TYPE MISMATCH',
\ 'overview': 'error overview 2',
\ 'subregion': { 'start': { 'line': 407, 'column': 12 }, 'end': { 'line': 407, 'column': 17 } },
\ 'details': 'error details 2',
\ 'region': { 'start': { 'line': 406, 'column': 5}, 'end': { 'line': 407, 'column': 17 } },
\ 'type':'error',
\ 'file': ale#util#Tempname() . '/Module.elm',
\ },
\ {
\ 'tag': 'TYPE MISMATCH',
\ 'overview': 'error overview 3',
\ 'subregion': { 'start': { 'line': 406, 'column': 88 }, 'end': { 'line': 406, 'column': 93 } },
\ 'details': 'error details 3',
\ 'region': { 'start': { 'line': 406, 'column': 5 }, 'end': { 'line': 406, 'column': 93 } },
\ 'type':'error',
\ 'file': ale#util#Tempname() . '/Module.elm',
\ }
\ ]),
\ ])
Execute(The elm-make handler should handle errors in Elm 0.18 imported modules):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': 'src/Module.elm:33 - error overview',
\ 'detail': "src/Module.elm:33 ----------\n\nerror overview\n\nerror details"
\ }
\ ],
\ ale_linters#elm#make#Handle(347, [
\ json_encode([
\ {
\ 'tag': 'unused import',
\ 'overview': 'warning overview',
\ 'details': 'warning details',
\ 'region': {'start': { 'line': 33, 'column': 1 }, 'end': { 'line': 33, 'column': 19 } },
\ 'type': 'warning',
\ 'file': 'src/Module.elm',
\ },
\ {
\ 'tag': 'type error',
\ 'overview': 'error overview',
\ 'details': 'error details',
\ 'region': {'start': { 'line': 33, 'column': 1 }, 'end': { 'line': 33, 'column': 19 } },
\ 'type': 'error',
\ 'file': 'src/Module.elm',
\ }
\ ]),
\ ])
" Generic
Execute(The elm-make handler should put an error on the first line if a line cannot be parsed):
AssertEqual
\ [
\ {
\ 'lnum': 404,
\ 'col': 1,
\ 'end_lnum': 408,
\ 'end_col': 18,
\ 'type': 'E',
\ 'text': "error details 1\n\nstyled details"
\ },
\ {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': 'Not JSON',
\ 'detail': "Not JSON\nAlso not JSON",
\ },
\ ],
\ ale_linters#elm#make#Handle(347, [
\ json_encode({
\ 'type': 'compile-errors',
\ 'errors': [
\ {
\ 'path': ale#util#Tempname() . '/Module.elm',
\ 'problems': [
\ {
\ 'title': 'TYPE MISMATCH',
\ 'message': ["error details 1\n\n", { 'string': 'styled details' }],
\ 'region': { 'start': { 'line': 404, 'column': 1 }, 'end': { 'line': 408, 'column': 18 } }
\ }
\ ]
\ }
\ ]
\ }),
\ 'Not JSON',
\ 'Also not JSON',
\ ])
Execute(The elm-make handler should ignore success lines):
AssertEqual
\ [],
\ ale_linters#elm#make#Handle(347, [
\ 'Successfully generated /dev/null',
\ ])

View File

@ -0,0 +1,81 @@
" Author: Adrian Zalewski <aazalewski@hotmail.com>
Before:
runtime ale_linters/handlebars/embertemplatelint.vim
After:
call ale#linter#Reset()
Execute(The ember-template-lint handler should parse lines correctly):
let input_lines = split('{
\ "/ember-project/app/templates/application.hbs": [
\ {
\ "moduleId": "app/templates/application",
\ "rule": "bare-strings",
\ "severity": 2,
\ "message": "Non-translated string used",
\ "line": 1,
\ "column": 10,
\ "source": " Bare String\n"
\ },
\ {
\ "moduleId": "app/templates/application",
\ "rule": "invalid-interactive",
\ "severity": 1,
\ "message": "Interaction added to non-interactive element",
\ "line": 3,
\ "column": 6,
\ "source": "<span {{action someAction}}></span>"
\ }
\ ]
\ }', '\n')
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 10,
\ 'text': 'bare-strings: Non-translated string used',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 3,
\ 'col': 6,
\ 'text': 'invalid-interactive: Interaction added to non-interactive element',
\ 'type': 'W',
\ },
\ ],
\ ale_linters#handlebars#embertemplatelint#Handle(347, input_lines)
Execute(The ember-template-lint handler should handle template parsing error correctly):
let input_lines = split('{
\ "/ember-project/app/templates/application.hbs": [
\ {
\ "fatal": true,
\ "moduleId": "app/templates/application",
\ "message": "Parse error on line 5 ...",
\ "line": 5,
\ "column": 3,
\ "source": "Error: Parse error on line 5 ...",
\ "severity": 2
\ }
\ ]
\ }', '\n')
AssertEqual
\ [
\ {
\ 'lnum': 5,
\ 'col': 3,
\ 'text': 'Parse error on line 5 ...',
\ 'type': 'E',
\ },
\ ],
\ ale_linters#handlebars#embertemplatelint#Handle(347, input_lines)
Execute(The ember-template-lint handler should handle no lint errors/warnings):
AssertEqual
\ [],
\ ale_linters#handlebars#embertemplatelint#Handle(347, [])
AssertEqual
\ [],
\ ale_linters#handlebars#embertemplatelint#Handle(347, ['{}'])

View File

@ -0,0 +1,70 @@
Before:
runtime ale_linters/eruby/erblint.vim
After:
unlet! g:lines
call ale#linter#Reset()
Execute(The erblint handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 3,
\ 'col': 0,
\ 'end_col': 0,
\ 'text': 'Extra blank line detected.',
\ 'code': 'ExtraNewline',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 6,
\ 'col': 0,
\ 'end_col': 0,
\ 'text': 'Remove multiple trailing newline at the end of the file.',
\ 'code': 'FinalNewline',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 4,
\ 'col': 9,
\ 'end_col': 11,
\ 'text': 'Use 1 space after `<%=` instead of 2 spaces.',
\ 'code': 'SpaceAroundErbTag',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 4,
\ 'col': 9,
\ 'end_col': 11,
\ 'text': 'Use 1 space before `%>` instead of 2 spaces.',
\ 'code': 'SpaceAroundErbTag',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 5,
\ 'col': 6,
\ 'end_col': 10,
\ 'text': 'Extra whitespace detected at end of line.',
\ 'code': 'TrailingWhitespace',
\ 'type': 'W',
\ },
\ ],
\ ale_linters#eruby#erblint#Handle(347, [
\ '{"metadata":{"erb_lint_version":"0.1.1","ruby_engine":"ruby","ruby_version":"3.0.2","ruby_patchlevel":"107","ruby_platform":"arm64-darwin20"},"files":[{"path":"demo.html.erb","offenses":[{"linter":"ExtraNewline","message":"Extra blank line detected.","location":{"start_line":3,"start_column":0,"last_line":4,"last_column":0,"length":1}},{"linter":"FinalNewline","message":"Remove multiple trailing newline at the end of the file.","location":{"start_line":6,"start_column":0,"last_line":8,"last_column":0,"length":2}},{"linter":"SpaceAroundErbTag","message":"Use 1 space after `<%=` instead of 2 spaces.","location":{"start_line":4,"start_column":9,"last_line":4,"last_column":11,"length":2}},{"linter":"SpaceAroundErbTag","message":"Use 1 space before `%>` instead of 2 spaces.","location":{"start_line":4,"start_column":9,"last_line":4,"last_column":11,"length":2}},{"linter":"TrailingWhitespace","message":"Extra whitespace detected at end of line.","location":{"start_line":5,"start_column":6,"last_line":5,"last_column":10,"length":4}}]}],"summary":{"offenses":5,"inspected_files":1,"corrected":0}}'
\ ])
Execute(The erblint handler should handle when files are checked and no offenses are found):
AssertEqual
\ [],
\ ale_linters#eruby#erblint#Handle(347, [
\ '{"metadata":{"erb_lint_version":"0.1.1","ruby_engine":"ruby","ruby_version":"3.0.2","ruby_patchlevel":"107","ruby_platform":"arm64-darwin20"},"files":[{"path":"demo.html.erb","offenses":[]}],"summary":{"offenses":0,"inspected_files":1,"corrected":0}}'
\ ])
Execute(The erblint handler should handle output without any errors):
AssertEqual
\ [],
\ ale_linters#eruby#erblint#Handle(347, ['{}'])
AssertEqual
\ [],
\ ale_linters#eruby#erblint#Handle(347, [])

View File

@ -0,0 +1,27 @@
Before:
runtime ale_linters/erlang/dialyzer.vim
After:
call ale#linter#Reset()
Execute(The dialyzer handler should handle error messages.):
AssertEqual
\[
\ {
\ 'lnum': 3,
\ 'lcol': 0,
\ 'text': 'Callback info about the provider behaviour is not available',
\ 'type': 'W'
\ }
\],
\ ale_linters#erlang#dialyzer#Handle(bufnr(''), ['erl_tidy_prv_fmt.erl:3: Callback info about the provider behaviour is not available'])
Execute(The dialyzer handler should handle empty file.):
AssertEqual
\[],
\ ale_linters#erlang#dialyzer#Handle(bufnr(''), [])
Execute(The dialyzer handler should handle empty lines.):
AssertEqual
\[],
\ ale_linters#erlang#dialyzer#Handle(bufnr(''), [''])

View File

@ -0,0 +1,40 @@
Before:
runtime ale_linters/erlang/elvis.vim
After:
call ale#linter#Reset()
Execute(Warning messages should be handled):
AssertEqual
\ [
\ {
\ 'lnum': 11,
\ 'text': "Replace the 'if' expression on line 11 with a 'case' expression or function clauses.",
\ 'type': 'W',
\ 'sub_type': 'style',
\ },
\ {
\ 'lnum': 20,
\ 'text': 'Remove the debug call to io:format/1 on line 20.',
\ 'type': 'W',
\ 'sub_type': 'style',
\ },
\ ],
\ ale_linters#erlang#elvis#Handle(bufnr(''), [
\ "src/foo.erl:11:no_if_expression:Replace the 'if' expression on line 11 with a 'case' expression or function clauses.",
\ 'src/foo.erl:20:no_debug_call:Remove the debug call to io:format/1 on line 20.',
\ ])
Execute(Line length message shouldn't contain the line itself):
AssertEqual
\ [
\ {
\ 'lnum': 24,
\ 'text': 'Line 24 is too long.',
\ 'type': 'W',
\ 'sub_type': 'style',
\ },
\ ],
\ ale_linters#erlang#elvis#Handle(bufnr(''), [
\ 'src/foo.erl:24:line_length:Line 24 is too long: io:format("Look ma, too long!"),.',
\ ])

View File

@ -0,0 +1,438 @@
Before:
Save g:ale_javascript_eslint_suppress_eslintignore
Save g:ale_javascript_eslint_suppress_missing_config
Save g:ale_warn_about_trailing_whitespace
Save g:ale_warn_about_trailing_blank_lines
let g:ale_javascript_eslint_suppress_eslintignore = 0
let g:ale_javascript_eslint_suppress_missing_config = 0
let g:ale_warn_about_trailing_whitespace = 1
let g:ale_warn_about_trailing_blank_lines = 1
unlet! b:ale_warn_about_trailing_whitespace
unlet! b:ale_warn_about_trailing_blank_lines
After:
Restore
unlet! b:ale_javascript_eslint_suppress_eslintignore
unlet! b:ale_javascript_eslint_suppress_missing_config
unlet! b:ale_warn_about_trailing_whitespace
unlet! b:ale_warn_about_trailing_blank_lines
unlet! g:config_error_lines
Execute(The eslint handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 47,
\ 'col': 14,
\ 'text': 'Missing trailing comma.',
\ 'code': 'comma-dangle',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 56,
\ 'col': 41,
\ 'text': 'Missing semicolon.',
\ 'code': 'semi',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 13,
\ 'col': 3,
\ 'text': 'Parsing error: Unexpected token',
\ 'type': 'E',
\ },
\ ],
\ ale#handlers#eslint#Handle(bufnr(''), [
\ 'This line should be ignored completely',
\ '/path/to/some-filename.js:47:14: Missing trailing comma. [Warning/comma-dangle]',
\ '/path/to/some-filename.js:56:41: Missing semicolon. [Error/semi]',
\ 'This line should be ignored completely',
\ '/path/to/some-filename.js:13:3: Parsing error: Unexpected token',
\ ])
Execute(The eslint handler should print a message about a missing configuration file):
let g:config_error_lines = [
\ '',
\ 'Oops! Something went wrong! :(',
\ '',
\ 'ESLint couldn''t find a configuration file. To set up a configuration file for this project, please run:',
\ ' eslint --init',
\ '',
\ 'ESLint looked for configuration files in /some/path/or/other and its ancestors.',
\ '',
\ 'If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://gitter.im/eslint/eslint',
\ '',
\ ]
AssertEqual
\ [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:])
Execute(The eslint handler should allow the missing config error to be suppressed):
let b:ale_javascript_eslint_suppress_missing_config = 1
let g:config_error_lines = [
\ '',
\ 'Oops! Something went wrong! :(',
\ '',
\ 'ESLint couldn''t find a configuration file. To set up a configuration file for this project, please run:',
\ ' eslint --init',
\ '',
\ 'ESLint looked for configuration files in /some/path/or/other and its ancestors.',
\ '',
\ 'If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://gitter.im/eslint/eslint',
\ '',
\ ]
AssertEqual
\ [],
\ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:])
Execute(The eslint handler should print a message for config parsing errors):
let g:config_error_lines = [
\ 'Cannot read config file: /some/path/or/other/.eslintrc.js',
\ 'Error: Unexpected token <<',
\ '/some/path/or/other/.eslintrc.js:1',
\ '(function (exports, require, module, __filename, __dirname) { <<<>>>',
\ ' ^^',
\ 'SyntaxError: Unexpected token <<',
\ ' at Object.exports.runInThisContext (vm.js:76:16)',
\ ' at Module._compile (module.js:528:28)',
\ ' at Object.Module._extensions..js (module.js:565:10)',
\ ' at Module.load (module.js:473:32)',
\ ' at tryModuleLoad (module.js:432:12)',
\ ' at Function.Module._load (module.js:424:3)',
\ ' at Module.require (module.js:483:17)',
\ ' at require (internal/module.js:20:19)',
\ ' at module.exports (/usr/local/lib/node_modules/eslint/node_modules/require-uncached/index.js:14:12)',
\ ' at loadJSConfigFile (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:160:16)',
\]
AssertEqual
\ [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:])
Execute(Suppressing missing configs shouldn't suppress parsing errors):
let b:ale_javascript_eslint_suppress_missing_config = 1
let g:config_error_lines = [
\ 'Cannot read config file: /some/path/or/other/.eslintrc.js',
\ 'Error: Unexpected token <<',
\ '/some/path/or/other/.eslintrc.js:1',
\ '(function (exports, require, module, __filename, __dirname) { <<<>>>',
\ ' ^^',
\ 'SyntaxError: Unexpected token <<',
\ ' at Object.exports.runInThisContext (vm.js:76:16)',
\ ' at Module._compile (module.js:528:28)',
\ ' at Object.Module._extensions..js (module.js:565:10)',
\ ' at Module.load (module.js:473:32)',
\ ' at tryModuleLoad (module.js:432:12)',
\ ' at Function.Module._load (module.js:424:3)',
\ ' at Module.require (module.js:483:17)',
\ ' at require (internal/module.js:20:19)',
\ ' at module.exports (/usr/local/lib/node_modules/eslint/node_modules/require-uncached/index.js:14:12)',
\ ' at loadJSConfigFile (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:160:16)',
\]
AssertEqual
\ [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:])
Execute(The eslint handler should print a message for invalid configuration settings):
let g:config_error_lines = [
\ '/home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:',
\ ' Configuration for rule "indent" is invalid:',
\ ' Value "off" is the wrong type.',
\ '',
\ 'Error: /home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:',
\ ' Configuration for rule "indent" is invalid:',
\ ' Value "off" is the wrong type.',
\ '',
\ ' at validateRuleOptions (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:115:15)',
\ ' at /usr/local/lib/node_modules/eslint/lib/config/config-validator.js:162:13',
\ ' at Array.forEach (native)',
\ ' at Object.validate (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:161:35)',
\ ' at Object.load (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:522:19)',
\ ' at loadConfig (/usr/local/lib/node_modules/eslint/lib/config.js:63:33)',
\ ' at getLocalConfig (/usr/local/lib/node_modules/eslint/lib/config.js:130:29)',
\ ' at Config.getConfig (/usr/local/lib/node_modules/eslint/lib/config.js:256:22)',
\ ' at processText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:224:33)',
\ ' at CLIEngine.executeOnText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:756:26)',
\]
AssertEqual
\ [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:])
Execute(Suppressing missing configs shouldn't suppress invalid config errors):
let b:ale_javascript_eslint_suppress_missing_config = 1
let g:config_error_lines = [
\ '/home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:',
\ ' Configuration for rule "indent" is invalid:',
\ ' Value "off" is the wrong type.',
\ '',
\ 'Error: /home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:',
\ ' Configuration for rule "indent" is invalid:',
\ ' Value "off" is the wrong type.',
\ '',
\ ' at validateRuleOptions (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:115:15)',
\ ' at /usr/local/lib/node_modules/eslint/lib/config/config-validator.js:162:13',
\ ' at Array.forEach (native)',
\ ' at Object.validate (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:161:35)',
\ ' at Object.load (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:522:19)',
\ ' at loadConfig (/usr/local/lib/node_modules/eslint/lib/config.js:63:33)',
\ ' at getLocalConfig (/usr/local/lib/node_modules/eslint/lib/config.js:130:29)',
\ ' at Config.getConfig (/usr/local/lib/node_modules/eslint/lib/config.js:256:22)',
\ ' at processText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:224:33)',
\ ' at CLIEngine.executeOnText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:756:26)',
\]
AssertEqual
\ [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:])
Execute(The eslint handler should print a message when import is not used in a module):
let g:config_error_lines = [
\ 'ImportDeclaration should appear when the mode is ES6 and in the module context.',
\ 'AssertionError: ImportDeclaration should appear when the mode is ES6 and in the module context.',
\ ' at Referencer.ImportDeclaration (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:597:9)',
\ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)',
\ ' at Referencer.Visitor.visitChildren (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:101:38)',
\ ' at Referencer.Program (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:449:14)',
\ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)',
\ ' at Object.analyze (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/index.js:138:16)',
\ ' at EventEmitter.module.exports.api.verify (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/eslint.js:887:40)',
\ ' at processText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:278:31)',
\ ' at CLIEngine.executeOnText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:734:26)',
\ ' at Object.execute (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli.js:171:42) ',
\]
AssertEqual
\ [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:])
Execute(Suppressing missing configs shouldn't suppress module import errors):
let b:ale_javascript_eslint_suppress_missing_config = 1
let g:config_error_lines = [
\ 'ImportDeclaration should appear when the mode is ES6 and in the module context.',
\ 'AssertionError: ImportDeclaration should appear when the mode is ES6 and in the module context.',
\ ' at Referencer.ImportDeclaration (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:597:9)',
\ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)',
\ ' at Referencer.Visitor.visitChildren (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:101:38)',
\ ' at Referencer.Program (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:449:14)',
\ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)',
\ ' at Object.analyze (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/index.js:138:16)',
\ ' at EventEmitter.module.exports.api.verify (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/eslint.js:887:40)',
\ ' at processText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:278:31)',
\ ' at CLIEngine.executeOnText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:734:26)',
\ ' at Object.execute (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli.js:171:42) ',
\]
AssertEqual
\ [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale#handlers#eslint#Handle(bufnr(''), g:config_error_lines[:])
Execute(The eslint handler should output end_col values where appropriate):
AssertEqual
\ [
\ {
\ 'lnum': 4,
\ 'col': 3,
\ 'end_col': 15,
\ 'text': 'Parsing error: Unexpected token ''some string''',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 70,
\ 'col': 3,
\ 'end_col': 5,
\ 'text': '''foo'' is not defined.',
\ 'code': 'no-undef',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 71,
\ 'col': 2,
\ 'end_col': 6,
\ 'text': 'Unexpected `await` inside a loop.',
\ 'code': 'no-await-in-loop',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 72,
\ 'col': 6,
\ 'end_col': 10,
\ 'text': 'Redundant use of `await` on a return value.',
\ 'code': 'no-return-await',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 73,
\ 'col': 4,
\ 'end_col': 10,
\ 'text': 'Unexpected console statement',
\ 'code': 'no-console',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 74,
\ 'col': 4,
\ 'end_col': 11,
\ 'text': 'Unexpected ''debugger'' statement.',
\ 'code': 'no-debugger',
\ 'type': 'E',
\ },
\ ],
\ ale#handlers#eslint#Handle(bufnr(''), [
\ 'app.js:4:3: Parsing error: Unexpected token ''some string'' [Error]',
\ 'app.js:70:3: ''foo'' is not defined. [Error/no-undef]',
\ 'app.js:71:2: Unexpected `await` inside a loop. [Error/no-await-in-loop]',
\ 'app.js:72:6: Redundant use of `await` on a return value. [Error/no-return-await]',
\ 'app.js:73:4: Unexpected console statement [Error/no-console]',
\ 'app.js:74:4: Unexpected ''debugger'' statement. [Error/no-debugger]',
\ ])
Execute(The eslint hint about using typescript-eslint-parser):
silent! noautocmd file foo.ts
AssertEqual
\ [
\ {
\ 'lnum': 451,
\ 'col': 2,
\ 'end_col': 2,
\ 'text': 'Parsing error (You may need configure typescript-eslint-parser): Unexpected token )',
\ 'type': 'E',
\ },
\ ],
\ ale#handlers#eslint#Handle(bufnr(''), [
\ 'foo.ts:451:2: Parsing error: Unexpected token ) [Error]',
\ ])
Execute(eslint should warn about ignored files by default):
AssertEqual
\ [{
\ 'lnum': 0,
\ 'col': 0,
\ 'type': 'W',
\ 'text': 'File ignored because of a matching ignore pattern. Use "--no-ignore" to override.'
\ }],
\ ale#handlers#eslint#Handle(bufnr(''), [
\ '/path/to/some/ignored.js:0:0: File ignored because of a matching ignore pattern. Use "--no-ignore" to override. [Warning]',
\ ])
AssertEqual
\ [{
\ 'lnum': 0,
\ 'col': 0,
\ 'type': 'W',
\ 'text': 'File ignored by default. Use "--ignore-pattern ''!node_modules/*''" to override.',
\ }],
\ ale#handlers#eslint#Handle(bufnr(''), [
\ '/path/to/some/ignored.js:0:0: File ignored by default. Use "--ignore-pattern ''!node_modules/*''" to override. [Warning]',
\ ])
Execute(eslint should not warn about ignored files when explicitly disabled):
let g:ale_javascript_eslint_suppress_eslintignore = 1
AssertEqual
\ [],
\ ale#handlers#eslint#Handle(bufnr(''), [
\ '/path/to/some/ignored.js:0:0: File ignored because of a matching ignore pattern. Use "--no-ignore" to override. [Warning]',
\ ])
AssertEqual
\ [],
\ ale#handlers#eslint#Handle(bufnr(''), [
\ '/path/to/some/ignored.js:0:0: File ignored by default. Use "--ignore-pattern ''!node_modules/*''" to override. [Warning]',
\ ])
Execute(eslint should handle react errors correctly):
AssertEqual
\ [
\ {
\ 'lnum': 59,
\ 'col': 9,
\ 'type': 'E',
\ 'text': 'Property should be placed on the same line as the component declaration',
\ 'code': 'react/jsx-first-prop-new-line',
\ },
\ ],
\ ale#handlers#eslint#Handle(bufnr(''), [
\ '/path/editor-help.jsx:59:9: Property should be placed on the same line as the component declaration [Error/react/jsx-first-prop-new-line]',
\ ])
Execute(Failing to connect to eslint_d should be handled correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.',
\ },
\ ],
\ ale#handlers#eslint#Handle(bufnr(''), [
\ 'Could not connect',
\ ])
Execute(Disabling warnings about trailing spaces should work):
silent! noautocmd file foo.ts
AssertEqual
\ [
\ {
\ 'lnum': 182,
\ 'col': 22,
\ 'code': 'no-trailing-spaces',
\ 'type': 'E',
\ 'text': 'Trailing spaces not allowed.',
\ },
\ ],
\ ale#handlers#eslint#Handle(bufnr(''), [
\ 'foo.js:182:22: Trailing spaces not allowed. [Error/no-trailing-spaces]',
\ ])
let g:ale_warn_about_trailing_whitespace = 0
AssertEqual
\ [],
\ ale#handlers#eslint#Handle(bufnr(''), [
\ 'foo.js:182:22: Trailing spaces not allowed. [Error/no-trailing-spaces]',
\ ])
let g:ale_warn_about_trailing_whitespace = 1
let b:ale_warn_about_trailing_whitespace = 0
AssertEqual
\ [],
\ ale#handlers#eslint#Handle(bufnr(''), [
\ 'foo.js:182:22: Trailing spaces not allowed. [Error/no-trailing-spaces]',
\ ])

View File

@ -0,0 +1,376 @@
Before:
Save g:ale_javascript_eslint_suppress_eslintignore
Save g:ale_javascript_eslint_suppress_missing_config
Save g:ale_warn_about_trailing_whitespace
Save g:ale_warn_about_trailing_blank_lines
let g:ale_javascript_eslint_suppress_eslintignore = 0
let g:ale_javascript_eslint_suppress_missing_config = 0
let g:ale_warn_about_trailing_whitespace = 1
let g:ale_warn_about_trailing_blank_lines = 1
unlet! b:ale_warn_about_trailing_whitespace
unlet! b:ale_warn_about_trailing_blank_lines
After:
Restore
unlet! b:ale_javascript_eslint_suppress_eslintignore
unlet! b:ale_javascript_eslint_suppress_missing_config
unlet! b:ale_warn_about_trailing_whitespace
unlet! b:ale_warn_about_trailing_blank_lines
unlet! g:config_error_lines
Execute(The eslint handler should parse json correctly):
call ale#test#SetFilename('foo.js')
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'end_lnum': 1,
\ 'col': 7,
\ 'end_col': 14,
\ 'text': '''variable'' is assigned a value but never used.',
\ 'code': 'no-unused-vars',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 5,
\ 'col': 15,
\ 'text': 'Missing semicolon.',
\ 'code': 'semi',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 7,
\ 'end_lnum': 7,
\ 'col': 7,
\ 'end_col': 14,
\ 'text': '''variable'' is already defined.',
\ 'code': 'no-redeclare',
\ 'type': 'E',
\ },
\ ],
\ ale#handlers#eslint#HandleJSON(bufnr(''), [
\ '[{"filePath":"foo.js","messages":[{"ruleId":"no-unused-vars","severity":1,"message":"''variable'' is assigned a value but never used.","line":1,"column":7,"nodeType":"Identifier","endLine":1,"endColumn":15},{"ruleId":"semi","severity":1,"message":"Missing semicolon.","line":5,"column":15,"nodeType":"ExpressionStatement","fix":{"range":[46,46],"text":";"}},{"ruleId":"no-redeclare","severity":2,"message":"''variable'' is already defined.","line":7,"column":7,"nodeType":"Identifier","endLine":7,"endColumn":15}],"errorCount":1,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":1,"source":"const variable = {\n a: 3\n};\n\nconsole.log(1)\n\nclass variable {\n}\n"}]'
\ ])
Execute(The eslint handler should suppress deprecation warnings):
call ale#test#SetFilename('foo.js')
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 9,
\ 'text': 'Parsing error: Unexpected token Controller',
\ 'type': 'E',
\ }
\ ],
\ ale#handlers#eslint#HandleJSON(bufnr(''), [
\ '[{"filePath":"foo.js","messages":[{"ruleId":null,"fatal":true,"severity":2 ,"message":"Parsing error: Unexpected token Controller","line":1,"column":9}],"errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount": 0,"source":"i:mport Controller from \"@ember/controller\";\nimport listViewControllerMixin from \"elearning/mixins/list-view-controller\";\nimport { inject as service } from \"@ember/service\";\n\nexport default Controller.extend(listViewControllerMixin(), {\n modelName: \"notification\",\n intl: service(),\n\n flatpickrLocale: computed(\"intl.locale\", function() {\n return this.intl.locale.firstObject.split(\"-\")[0];\n })\n});\n"}]', '(node:616989) [ESLINT_LEGACY_OBJECT_REST_SPREAD] DeprecationWarning: The ''parserOptions.ecmaFeatures.experimentalObjectRestSpread'' option is deprecated. Use ''parser Options.ecmaVersion'' instead. (found in "node_modules/eslint-plugin-ember/lib/config/base.js")]'
\ ])
Execute(The eslint handler should print a message about a missing configuration file):
let g:config_error_lines = [
\ '',
\ 'Oops! Something went wrong! :(',
\ '',
\ 'ESLint couldn''t find a configuration file. To set up a configuration file for this project, please run:',
\ ' eslint --init',
\ '',
\ 'ESLint looked for configuration files in /some/path/or/other and its ancestors.',
\ '',
\ 'If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://gitter.im/eslint/eslint',
\ '',
\ ]
AssertEqual
\ [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:])
Execute(The eslint handler should allow the missing config error to be suppressed):
let b:ale_javascript_eslint_suppress_missing_config = 1
let g:config_error_lines = [
\ '',
\ 'Oops! Something went wrong! :(',
\ '',
\ 'ESLint couldn''t find a configuration file. To set up a configuration file for this project, please run:',
\ ' eslint --init',
\ '',
\ 'ESLint looked for configuration files in /some/path/or/other and its ancestors.',
\ '',
\ 'If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://gitter.im/eslint/eslint',
\ '',
\ ]
AssertEqual
\ [],
\ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:])
Execute(The eslint handler should print a message for config parsing errors):
let g:config_error_lines = [
\ 'Cannot read config file: /some/path/or/other/.eslintrc.js',
\ 'Error: Unexpected token <<',
\ '/some/path/or/other/.eslintrc.js:1',
\ '(function (exports, require, module, __filename, __dirname) { <<<>>>',
\ ' ^^',
\ 'SyntaxError: Unexpected token <<',
\ ' at Object.exports.runInThisContext (vm.js:76:16)',
\ ' at Module._compile (module.js:528:28)',
\ ' at Object.Module._extensions..js (module.js:565:10)',
\ ' at Module.load (module.js:473:32)',
\ ' at tryModuleLoad (module.js:432:12)',
\ ' at Function.Module._load (module.js:424:3)',
\ ' at Module.require (module.js:483:17)',
\ ' at require (internal/module.js:20:19)',
\ ' at module.exports (/usr/local/lib/node_modules/eslint/node_modules/require-uncached/index.js:14:12)',
\ ' at loadJSConfigFile (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:160:16)',
\]
AssertEqual
\ [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:])
Execute(Suppressing missing configs shouldn't suppress parsing errors):
let b:ale_javascript_eslint_suppress_missing_config = 1
let g:config_error_lines = [
\ 'Cannot read config file: /some/path/or/other/.eslintrc.js',
\ 'Error: Unexpected token <<',
\ '/some/path/or/other/.eslintrc.js:1',
\ '(function (exports, require, module, __filename, __dirname) { <<<>>>',
\ ' ^^',
\ 'SyntaxError: Unexpected token <<',
\ ' at Object.exports.runInThisContext (vm.js:76:16)',
\ ' at Module._compile (module.js:528:28)',
\ ' at Object.Module._extensions..js (module.js:565:10)',
\ ' at Module.load (module.js:473:32)',
\ ' at tryModuleLoad (module.js:432:12)',
\ ' at Function.Module._load (module.js:424:3)',
\ ' at Module.require (module.js:483:17)',
\ ' at require (internal/module.js:20:19)',
\ ' at module.exports (/usr/local/lib/node_modules/eslint/node_modules/require-uncached/index.js:14:12)',
\ ' at loadJSConfigFile (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:160:16)',
\]
AssertEqual
\ [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:])
Execute(The eslint handler should print a message for invalid configuration settings):
let g:config_error_lines = [
\ '/home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:',
\ ' Configuration for rule "indent" is invalid:',
\ ' Value "off" is the wrong type.',
\ '',
\ 'Error: /home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:',
\ ' Configuration for rule "indent" is invalid:',
\ ' Value "off" is the wrong type.',
\ '',
\ ' at validateRuleOptions (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:115:15)',
\ ' at /usr/local/lib/node_modules/eslint/lib/config/config-validator.js:162:13',
\ ' at Array.forEach (native)',
\ ' at Object.validate (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:161:35)',
\ ' at Object.load (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:522:19)',
\ ' at loadConfig (/usr/local/lib/node_modules/eslint/lib/config.js:63:33)',
\ ' at getLocalConfig (/usr/local/lib/node_modules/eslint/lib/config.js:130:29)',
\ ' at Config.getConfig (/usr/local/lib/node_modules/eslint/lib/config.js:256:22)',
\ ' at processText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:224:33)',
\ ' at CLIEngine.executeOnText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:756:26)',
\]
AssertEqual
\ [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:])
Execute(Suppressing missing configs shouldn't suppress invalid config errors):
let b:ale_javascript_eslint_suppress_missing_config = 1
let g:config_error_lines = [
\ '/home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:',
\ ' Configuration for rule "indent" is invalid:',
\ ' Value "off" is the wrong type.',
\ '',
\ 'Error: /home/w0rp/git/wazoku/wazoku-spotlight/.eslintrc.js:',
\ ' Configuration for rule "indent" is invalid:',
\ ' Value "off" is the wrong type.',
\ '',
\ ' at validateRuleOptions (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:115:15)',
\ ' at /usr/local/lib/node_modules/eslint/lib/config/config-validator.js:162:13',
\ ' at Array.forEach (native)',
\ ' at Object.validate (/usr/local/lib/node_modules/eslint/lib/config/config-validator.js:161:35)',
\ ' at Object.load (/usr/local/lib/node_modules/eslint/lib/config/config-file.js:522:19)',
\ ' at loadConfig (/usr/local/lib/node_modules/eslint/lib/config.js:63:33)',
\ ' at getLocalConfig (/usr/local/lib/node_modules/eslint/lib/config.js:130:29)',
\ ' at Config.getConfig (/usr/local/lib/node_modules/eslint/lib/config.js:256:22)',
\ ' at processText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:224:33)',
\ ' at CLIEngine.executeOnText (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:756:26)',
\]
AssertEqual
\ [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:])
Execute(The eslint handler should print a message when import is not used in a module):
let g:config_error_lines = [
\ 'ImportDeclaration should appear when the mode is ES6 and in the module context.',
\ 'AssertionError: ImportDeclaration should appear when the mode is ES6 and in the module context.',
\ ' at Referencer.ImportDeclaration (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:597:9)',
\ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)',
\ ' at Referencer.Visitor.visitChildren (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:101:38)',
\ ' at Referencer.Program (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:449:14)',
\ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)',
\ ' at Object.analyze (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/index.js:138:16)',
\ ' at EventEmitter.module.exports.api.verify (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/eslint.js:887:40)',
\ ' at processText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:278:31)',
\ ' at CLIEngine.executeOnText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:734:26)',
\ ' at Object.execute (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli.js:171:42) ',
\]
AssertEqual
\ [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:])
Execute(Suppressing missing configs shouldn't suppress module import errors):
let b:ale_javascript_eslint_suppress_missing_config = 1
let g:config_error_lines = [
\ 'ImportDeclaration should appear when the mode is ES6 and in the module context.',
\ 'AssertionError: ImportDeclaration should appear when the mode is ES6 and in the module context.',
\ ' at Referencer.ImportDeclaration (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:597:9)',
\ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)',
\ ' at Referencer.Visitor.visitChildren (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:101:38)',
\ ' at Referencer.Program (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/referencer.js:449:14)',
\ ' at Referencer.Visitor.visit (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/esrecurse/esrecurse.js:122:34)',
\ ' at Object.analyze (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint-scope/lib/index.js:138:16)',
\ ' at EventEmitter.module.exports.api.verify (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/eslint.js:887:40)',
\ ' at processText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:278:31)',
\ ' at CLIEngine.executeOnText (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli-engine.js:734:26)',
\ ' at Object.execute (/home/w0rp/git/wazoku/wazoku-spotlight/spotlight/static/node_modules/eslint/lib/cli.js:171:42) ',
\]
AssertEqual
\ [{
\ 'lnum': 1,
\ 'text': 'eslint configuration error (type :ALEDetail for more information)',
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale#handlers#eslint#HandleJSON(bufnr(''), g:config_error_lines[:])
Execute(The eslint handler should hint about using typescript-eslint-parser):
call ale#test#SetFilename('foo.ts')
AssertEqual
\ [
\ {
\ 'lnum': 2,
\ 'col': 1,
\ 'text': 'Parsing error (You may need configure typescript-eslint-parser): The keyword ''interface'' is reserved',
\ 'type': 'E',
\ },
\ ],
\ ale#handlers#eslint#HandleJSON(bufnr(''), [
\ '[{"filePath":"foo.ts","messages":[{"ruleId":null,"fatal":true,"severity":2,"message":"Parsing error: The keyword ''interface'' is reserved","line":2,"column":1}],"errorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"\ninterface test {}\n"}]',
\ ])
Execute(eslint should warn about ignored files by default):
AssertEqual
\ [{
\ 'lnum': 0,
\ 'type': 'W',
\ 'text': 'File ignored because of a matching ignore pattern. Use "--no-ignore" to override.'
\ }],
\ ale#handlers#eslint#HandleJSON(bufnr(''), [
\ '[{"filePath":"/path/to/some/ignored/file.js","messages":[{"fatal":false,"severity":1,"message":"File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override."}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0}]',
\ ])
AssertEqual
\ [{
\ 'lnum': 0,
\ 'type': 'W',
\ 'text': 'File ignored by default. Use "--ignore-pattern ''!node_modules/*''" to override.',
\ }],
\ ale#handlers#eslint#HandleJSON(bufnr(''), [
\ '[{"filePath":"/path/to/some/ignored/file.js","messages":[{"fatal":false,"severity":1,"message":"File ignored by default. Use \"--ignore-pattern ''!node_modules/*''\" to override."}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0}]',
\ ])
Execute(eslint should not warn about ignored files when explicitly disabled):
let g:ale_javascript_eslint_suppress_eslintignore = 1
AssertEqual
\ [],
\ ale#handlers#eslint#HandleJSON(bufnr(''), [
\ '[{"filePath":"/path/to/some/ignored/file.js","messages":[{"fatal":false,"severity":1,"message":"File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override."}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0}]',
\ ])
AssertEqual
\ [],
\ ale#handlers#eslint#HandleJSON(bufnr(''), [
\ '[{"filePath":"/path/to/some/ignored/file.js","messages":[{"fatal":false,"severity":1,"message":"File ignored by default. Use \"--ignore-pattern ''!node_modules/*''\" to override."}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0}]',
\ ])
Execute(Failing to connect to eslint_d should be handled correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'text': 'Could not connect to eslint_d. Try updating eslint_d or killing it.',
\ },
\ ],
\ ale#handlers#eslint#HandleJSON(bufnr(''), [
\ 'Could not connect',
\ ])
Execute(Disabling warnings about trailing spaces should work):
call ale#test#SetFilename('foo.js')
AssertEqual
\ [
\ {
\ 'lnum': 2,
\ 'col': 16,
\ 'code': 'no-trailing-spaces',
\ 'type': 'W',
\ 'text': 'Trailing spaces not allowed.',
\ },
\ ],
\ ale#handlers#eslint#HandleJSON(bufnr(''), [
\ '[{"filePath":"foo.js","messages":[{"ruleId":"no-trailing-spaces","severity":1,"message":"Trailing spaces not allowed.","line":2,"column":16,"nodeType":"Program","fix":{"range":[16,17],"text":""}}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":1,"source":"\nconsole.log(1); \n"}]'
\ ])
let g:ale_warn_about_trailing_whitespace = 0
AssertEqual
\ [],
\ ale#handlers#eslint#HandleJSON(bufnr(''), [
\ '[{"filePath":"foo.js","messages":[{"ruleId":"no-trailing-spaces","severity":1,"message":"Trailing spaces not allowed.","line":2,"column":16,"nodeType":"Program","fix":{"range":[16,17],"text":""}}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":1,"source":"\nconsole.log(1); \n"}]'
\ ])
let g:ale_warn_about_trailing_whitespace = 1
let b:ale_warn_about_trailing_whitespace = 0
AssertEqual
\ [],
\ ale#handlers#eslint#HandleJSON(bufnr(''), [
\ '[{"filePath":"foo.js","messages":[{"ruleId":"no-trailing-spaces","severity":1,"message":"Trailing spaces not allowed.","line":2,"column":16,"nodeType":"Program","fix":{"range":[16,17],"text":""}}],"errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":1,"source":"\nconsole.log(1); \n"}]'
\ ])

View File

@ -0,0 +1,35 @@
Before:
runtime autoload/ale/handlers/fecs.vim
After:
call ale#linter#Reset()
Execute(fecs should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 20,
\ 'col': 25,
\ 'text': 'Unexpected console statement.',
\ 'code': 'no-console',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 24,
\ 'col': 36,
\ 'text': 'Missing radix parameter.',
\ 'code': 'radix',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 25,
\ 'col': 6,
\ 'text': 'Missing static property value.',
\ 'type': 'E',
\ },
\ ],
\ ale#handlers#fecs#Handle(347, [
\ 'fecs WARN → line 20, col 25: Unexpected console statement. (no-console)',
\ 'fecs ERROR → line 24, col 36: Missing radix parameter. (radix)',
\ 'fecs ERROR → line 25, col 6: Missing static property value.',
\ ])

View File

@ -0,0 +1,61 @@
Before:
runtime ale_linters/fish/fish.vim
After:
call ale#linter#Reset()
Execute(The fish handler should handle basic warnings and syntax errors):
AssertEqual
\ [
\ {
\ 'lnum': 20,
\ 'col': 23,
\ 'text': "Unsupported use of '||'. In fish, please use 'COMMAND; or COMMAND'.",
\ },
\ {
\ 'lnum': 26,
\ 'col': 7,
\ 'text': "Illegal command name '(prompt_pwd)'",
\ },
\ {
\ 'lnum': 36,
\ 'col': 1,
\ 'text': "'end' outside of a block",
\ },
\ ],
\ ale_linters#fish#fish#Handle(1, [
\ "fish_prompt.fish (line 20): Unsupported use of '||'. In fish, please use 'COMMAND; or COMMAND'.",
\ 'if set -q SSH_CLIENT || set -q SSH_TTY',
\ ' ^',
\ "fish_prompt.fish (line 26): Illegal command name '(prompt_pwd)'",
\ ' (prompt_pwd) \',
\ ' ^',
\ "fish_prompt.fish (line 36): 'end' outside of a block",
\ 'end',
\ '^',
\ 'config.fish (line 45):',
\ "abbr --add p 'cd ~/Projects'",
\ '^',
\ ])
Execute(The fish handler should handle problems where the problem before before the line with the line number):
AssertEqual
\ [
\ {
\ 'lnum': 2,
\ 'col': 23,
\ 'text': 'Unsupported use of ''||''. In fish, please use ''COMMAND; or COMMAND''.',
\ },
\ {
\ 'lnum': 5,
\ 'col': 1,
\ 'text': 'wat',
\ },
\ ],
\ ale_linters#fish#fish#Handle(bufnr(''), [
\ 'Unsupported use of ''||''. In fish, please use ''COMMAND; or COMMAND''.',
\ '/tmp/vLz620o/258/test.fish (line 2): if set -q SSH_CLIENT || set -q SSH_TTY',
\ ' ^',
\ '/tmp/vLz620o/258/test.fish (line 5): wat',
\ ' ^',
\ ])

View File

@ -0,0 +1,276 @@
Before:
Save g:ale_warn_about_trailing_blank_lines
Save g:ale_warn_about_trailing_whitespace
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
runtime ale_linters/python/flake8.vim
After:
Restore
unlet! b:ale_warn_about_trailing_blank_lines
unlet! b:ale_warn_about_trailing_whitespace
call ale#linter#Reset()
Execute(The flake8 handler should handle basic warnings and syntax errors):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 6,
\ 'vcol': 1,
\ 'type': 'E',
\ 'text': 'indentation is not a multiple of four',
\ 'code': 'E111',
\ 'sub_type': 'style',
\ },
\ {
\ 'lnum': 7,
\ 'col': 6,
\ 'vcol': 1,
\ 'type': 'W',
\ 'text': 'some warning',
\ 'code': 'W123',
\ 'sub_type': 'style',
\ },
\ {
\ 'lnum': 8,
\ 'col': 3,
\ 'vcol': 1,
\ 'type': 'E',
\ 'text': 'SyntaxError: invalid syntax',
\ 'code': 'E999',
\ },
\ ],
\ ale_linters#python#flake8#Handle(1, [
\ 'stdin:6:6: E111 indentation is not a multiple of four',
\ 'stdin:7:6: W123 some warning',
\ 'stdin:8:3: E999 SyntaxError: invalid syntax',
\ ])
Execute(The flake8 handler should set end column indexes for certain errors):
AssertEqual
\ [
\ {
\ 'lnum': 25,
\ 'col': 1,
\ 'vcol': 1,
\ 'type': 'E',
\ 'end_col': 3,
\ 'text': 'undefined name ''foo''',
\ 'code': 'F821',
\ },
\ {
\ 'lnum': 28,
\ 'col': 5,
\ 'vcol': 1,
\ 'type': 'E',
\ 'end_col': 9,
\ 'text': 'hello may be undefined, or defined from star imports: x',
\ 'code': 'F405',
\ },
\ {
\ 'lnum': 104,
\ 'col': 5,
\ 'vcol': 1,
\ 'type': 'E',
\ 'end_col': 12,
\ 'text': '''continue'' not properly in loop',
\ 'code': 'F999',
\ },
\ {
\ 'lnum': 106,
\ 'col': 5,
\ 'vcol': 1,
\ 'type': 'E',
\ 'end_col': 9,
\ 'text': '''break'' outside loop',
\ 'code': 'F999',
\ },
\ {
\ 'lnum': 109,
\ 'col': 5,
\ 'vcol': 1,
\ 'type': 'E',
\ 'end_col': 8,
\ 'text': 'local variable ''test'' is assigned to but never used',
\ 'code': 'F841',
\ },
\ ],
\ ale_linters#python#flake8#Handle(1, [
\ 'foo.py:25:1: F821 undefined name ''foo''',
\ 'foo.py:28:5: F405 hello may be undefined, or defined from star imports: x',
\ 'foo.py:104:5: F999 ''continue'' not properly in loop',
\ 'foo.py:106:5: F999 ''break'' outside loop',
\ 'foo.py:109:5: F841 local variable ''test'' is assigned to but never used',
\ ])
Execute(The flake8 handler should handle stack traces):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'text': 'ImportError: No module named parser (See :ALEDetail)',
\ 'detail': join([
\ 'Traceback (most recent call last):',
\ ' File "/usr/local/bin/flake8", line 7, in <module>',
\ ' from flake8.main.cli import main',
\ ' File "/usr/local/lib/python2.7/dist-packages/flake8/main/cli.py", line 2, in <module>',
\ ' from flake8.main import application',
\ ' File "/usr/local/lib/python2.7/dist-packages/flake8/main/application.py", line 17, in <module>',
\ ' from flake8.plugins import manager as plugin_manager',
\ ' File "/usr/local/lib/python2.7/dist-packages/flake8/plugins/manager.py", line 5, in <module>',
\ ' import pkg_resources',
\ ' File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 35, in <module>',
\ ' import email.parser',
\ 'ImportError: No module named parser',
\ ], "\n"),
\ },
\ ],
\ ale_linters#python#flake8#Handle(42, [
\ 'Traceback (most recent call last):',
\ ' File "/usr/local/bin/flake8", line 7, in <module>',
\ ' from flake8.main.cli import main',
\ ' File "/usr/local/lib/python2.7/dist-packages/flake8/main/cli.py", line 2, in <module>',
\ ' from flake8.main import application',
\ ' File "/usr/local/lib/python2.7/dist-packages/flake8/main/application.py", line 17, in <module>',
\ ' from flake8.plugins import manager as plugin_manager',
\ ' File "/usr/local/lib/python2.7/dist-packages/flake8/plugins/manager.py", line 5, in <module>',
\ ' import pkg_resources',
\ ' File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 35, in <module>',
\ ' import email.parser',
\ 'ImportError: No module named parser',
\ ])
Execute(The flake8 handler should handle names with spaces):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 6,
\ 'vcol': 1,
\ 'type': 'E',
\ 'text': 'indentation is not a multiple of four',
\ 'code': 'E111',
\ 'sub_type': 'style',
\ },
\ ],
\ ale_linters#python#flake8#Handle(42, [
\ 'C:\something\with spaces.py:6:6: E111 indentation is not a multiple of four',
\ ])
Execute(Warnings about trailing whitespace should be reported by default):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 1,
\ 'vcol': 1,
\ 'code': 'W291',
\ 'type': 'W',
\ 'sub_type': 'style',
\ 'text': 'who cares',
\ },
\ {
\ 'lnum': 6,
\ 'col': 1,
\ 'vcol': 1,
\ 'code': 'W293',
\ 'type': 'W',
\ 'sub_type': 'style',
\ 'text': 'who cares',
\ },
\ ],
\ ale_linters#python#flake8#Handle(bufnr(''), [
\ 'foo.py:6:1: W291 who cares',
\ 'foo.py:6:1: W293 who cares',
\ ])
Execute(Disabling trailing whitespace warnings should work):
let b:ale_warn_about_trailing_whitespace = 0
AssertEqual
\ [
\ ],
\ ale_linters#python#flake8#Handle(bufnr(''), [
\ 'foo.py:6:1: W291 who cares',
\ 'foo.py:6:1: W293 who cares',
\ ])
Execute(Warnings about trailing blank lines should be reported by default):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 1,
\ 'vcol': 1,
\ 'code': 'W391',
\ 'type': 'W',
\ 'sub_type': 'style',
\ 'text': 'blank line at end of file',
\ },
\ ],
\ ale_linters#python#flake8#Handle(bufnr(''), [
\ 'foo.py:6:1: W391 blank line at end of file',
\ ])
Execute(Disabling trailing blank line warnings should work):
let b:ale_warn_about_trailing_blank_lines = 0
AssertEqual
\ [
\ ],
\ ale_linters#python#flake8#Handle(bufnr(''), [
\ 'foo.py:6:1: W391 blank line at end of file',
\ ])
Execute(F401 should be a warning):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 1,
\ 'vcol': 1,
\ 'code': 'F401',
\ 'type': 'W',
\ 'text': 'module imported but unused',
\ },
\ ],
\ ale_linters#python#flake8#Handle(bufnr(''), [
\ 'foo.py:6:1: F401 module imported but unused',
\ ])
Execute(E112 should be a syntax error):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 1,
\ 'vcol': 1,
\ 'code': 'E112',
\ 'type': 'E',
\ 'text': 'expected an indented block',
\ },
\ ],
\ ale_linters#python#flake8#Handle(bufnr(''), [
\ 'foo.py:6:1: E112 expected an indented block',
\ ])
Execute(Compatibility with hacking which uses older style flake8):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 1,
\ 'vcol': 1,
\ 'code': 'H306',
\ 'type': 'W',
\ 'text': 'imports not in alphabetical order (smtplib, io)',
\ },
\ ],
\ ale_linters#python#flake8#Handle(bufnr(''), [
\ 'foo.py:6:1: H306: imports not in alphabetical order (smtplib, io)',
\ ])

View File

@ -0,0 +1,276 @@
Before:
Save g:ale_warn_about_trailing_blank_lines
Save g:ale_warn_about_trailing_whitespace
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
runtime ale_linters/python/flakehell.vim
After:
Restore
unlet! b:ale_warn_about_trailing_blank_lines
unlet! b:ale_warn_about_trailing_whitespace
call ale#linter#Reset()
Execute(The flakehell handler should handle basic warnings and syntax errors):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 6,
\ 'vcol': 1,
\ 'type': 'E',
\ 'text': 'indentation is not a multiple of four',
\ 'code': 'E111',
\ 'sub_type': 'style',
\ },
\ {
\ 'lnum': 7,
\ 'col': 6,
\ 'vcol': 1,
\ 'type': 'W',
\ 'text': 'some warning',
\ 'code': 'W123',
\ 'sub_type': 'style',
\ },
\ {
\ 'lnum': 8,
\ 'col': 3,
\ 'vcol': 1,
\ 'type': 'E',
\ 'text': 'SyntaxError: invalid syntax',
\ 'code': 'E999',
\ },
\ ],
\ ale_linters#python#flakehell#Handle(1, [
\ 'stdin:6:6: E111 indentation is not a multiple of four',
\ 'stdin:7:6: W123 some warning',
\ 'stdin:8:3: E999 SyntaxError: invalid syntax',
\ ])
Execute(The flakehell handler should set end column indexes for certain errors):
AssertEqual
\ [
\ {
\ 'lnum': 25,
\ 'col': 1,
\ 'vcol': 1,
\ 'type': 'E',
\ 'end_col': 3,
\ 'text': 'undefined name ''foo''',
\ 'code': 'F821',
\ },
\ {
\ 'lnum': 28,
\ 'col': 5,
\ 'vcol': 1,
\ 'type': 'E',
\ 'end_col': 9,
\ 'text': 'hello may be undefined, or defined from star imports: x',
\ 'code': 'F405',
\ },
\ {
\ 'lnum': 104,
\ 'col': 5,
\ 'vcol': 1,
\ 'type': 'E',
\ 'end_col': 12,
\ 'text': '''continue'' not properly in loop',
\ 'code': 'F999',
\ },
\ {
\ 'lnum': 106,
\ 'col': 5,
\ 'vcol': 1,
\ 'type': 'E',
\ 'end_col': 9,
\ 'text': '''break'' outside loop',
\ 'code': 'F999',
\ },
\ {
\ 'lnum': 109,
\ 'col': 5,
\ 'vcol': 1,
\ 'type': 'E',
\ 'end_col': 8,
\ 'text': 'local variable ''test'' is assigned to but never used',
\ 'code': 'F841',
\ },
\ ],
\ ale_linters#python#flakehell#Handle(1, [
\ 'foo.py:25:1: F821 undefined name ''foo''',
\ 'foo.py:28:5: F405 hello may be undefined, or defined from star imports: x',
\ 'foo.py:104:5: F999 ''continue'' not properly in loop',
\ 'foo.py:106:5: F999 ''break'' outside loop',
\ 'foo.py:109:5: F841 local variable ''test'' is assigned to but never used',
\ ])
Execute(The flakehell handler should handle stack traces):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'text': 'ImportError: No module named parser (See :ALEDetail)',
\ 'detail': join([
\ 'Traceback (most recent call last):',
\ ' File "/usr/local/bin/flakehell", line 7, in <module>',
\ ' from flakehell.main.cli import main',
\ ' File "/usr/local/lib/python2.7/dist-packages/flakehell/main/cli.py", line 2, in <module>',
\ ' from flakehell.main import application',
\ ' File "/usr/local/lib/python2.7/dist-packages/flakehell/main/application.py", line 17, in <module>',
\ ' from flakehell.plugins import manager as plugin_manager',
\ ' File "/usr/local/lib/python2.7/dist-packages/flakehell/plugins/manager.py", line 5, in <module>',
\ ' import pkg_resources',
\ ' File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 35, in <module>',
\ ' import email.parser',
\ 'ImportError: No module named parser',
\ ], "\n"),
\ },
\ ],
\ ale_linters#python#flakehell#Handle(42, [
\ 'Traceback (most recent call last):',
\ ' File "/usr/local/bin/flakehell", line 7, in <module>',
\ ' from flakehell.main.cli import main',
\ ' File "/usr/local/lib/python2.7/dist-packages/flakehell/main/cli.py", line 2, in <module>',
\ ' from flakehell.main import application',
\ ' File "/usr/local/lib/python2.7/dist-packages/flakehell/main/application.py", line 17, in <module>',
\ ' from flakehell.plugins import manager as plugin_manager',
\ ' File "/usr/local/lib/python2.7/dist-packages/flakehell/plugins/manager.py", line 5, in <module>',
\ ' import pkg_resources',
\ ' File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 35, in <module>',
\ ' import email.parser',
\ 'ImportError: No module named parser',
\ ])
Execute(The flakehell handler should handle names with spaces):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 6,
\ 'vcol': 1,
\ 'type': 'E',
\ 'text': 'indentation is not a multiple of four',
\ 'code': 'E111',
\ 'sub_type': 'style',
\ },
\ ],
\ ale_linters#python#flakehell#Handle(42, [
\ 'C:\something\with spaces.py:6:6: E111 indentation is not a multiple of four',
\ ])
Execute(Warnings about trailing whitespace should be reported by default):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 1,
\ 'vcol': 1,
\ 'code': 'W291',
\ 'type': 'W',
\ 'sub_type': 'style',
\ 'text': 'who cares',
\ },
\ {
\ 'lnum': 6,
\ 'col': 1,
\ 'vcol': 1,
\ 'code': 'W293',
\ 'type': 'W',
\ 'sub_type': 'style',
\ 'text': 'who cares',
\ },
\ ],
\ ale_linters#python#flakehell#Handle(bufnr(''), [
\ 'foo.py:6:1: W291 who cares',
\ 'foo.py:6:1: W293 who cares',
\ ])
Execute(Disabling trailing whitespace warnings should work):
let b:ale_warn_about_trailing_whitespace = 0
AssertEqual
\ [
\ ],
\ ale_linters#python#flakehell#Handle(bufnr(''), [
\ 'foo.py:6:1: W291 who cares',
\ 'foo.py:6:1: W293 who cares',
\ ])
Execute(Warnings about trailing blank lines should be reported by default):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 1,
\ 'vcol': 1,
\ 'code': 'W391',
\ 'type': 'W',
\ 'sub_type': 'style',
\ 'text': 'blank line at end of file',
\ },
\ ],
\ ale_linters#python#flakehell#Handle(bufnr(''), [
\ 'foo.py:6:1: W391 blank line at end of file',
\ ])
Execute(Disabling trailing blank line warnings should work):
let b:ale_warn_about_trailing_blank_lines = 0
AssertEqual
\ [
\ ],
\ ale_linters#python#flakehell#Handle(bufnr(''), [
\ 'foo.py:6:1: W391 blank line at end of file',
\ ])
Execute(F401 should be a warning):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 1,
\ 'vcol': 1,
\ 'code': 'F401',
\ 'type': 'W',
\ 'text': 'module imported but unused',
\ },
\ ],
\ ale_linters#python#flakehell#Handle(bufnr(''), [
\ 'foo.py:6:1: F401 module imported but unused',
\ ])
Execute(E112 should be a syntax error):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 1,
\ 'vcol': 1,
\ 'code': 'E112',
\ 'type': 'E',
\ 'text': 'expected an indented block',
\ },
\ ],
\ ale_linters#python#flakehell#Handle(bufnr(''), [
\ 'foo.py:6:1: E112 expected an indented block',
\ ])
Execute(Compatibility with hacking which uses older style flakehell):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 1,
\ 'vcol': 1,
\ 'code': 'H306',
\ 'type': 'W',
\ 'text': 'imports not in alphabetical order (smtplib, io)',
\ },
\ ],
\ ale_linters#python#flakehell#Handle(bufnr(''), [
\ 'foo.py:6:1: H306: imports not in alphabetical order (smtplib, io)',
\ ])

View File

@ -0,0 +1,57 @@
Before:
Save g:ale_c_flawfinder_error_severity
unlet! g:ale_c_flawfinder_error_severity
unlet! b:ale_c_flawfinder_error_severity
runtime ale_linters/c/flawfinder.vim
After:
unlet! g:ale_c_flawfinder_error_severity
Restore
Execute(The Flawfinder handler should ignore other lines of output):
AssertEqual
\ [],
\ ale#handlers#flawfinder#HandleFlawfinderFormat(347, [
\ 'foo',
\ 'bar',
\ 'baz',
\ ])
Execute(The Flawfinder handler should work):
AssertEqual
\ [
\ {
\ 'lnum': 31,
\ 'col': 4,
\ 'type': 'W',
\ 'text': "(buffer) strncpy: Easily used incorrectly",
\ },
\ ],
\ ale#handlers#flawfinder#HandleFlawfinderFormat(347, [
\ "<stdin>:31:4: [1] (buffer) strncpy:Easily used incorrectly",
\ ])
Execute(The Flawfinder error severity level should be configurable):
let b:ale_c_flawfinder_error_severity = 2
AssertEqual
\ [
\ {
\ 'lnum': 12,
\ 'col': 4,
\ 'type': 'E',
\ 'text': "(buffer) char: Statically-sized arrays can be bad",
\ },
\ {
\ 'lnum': 31,
\ 'col': 4,
\ 'type': 'W',
\ 'text': "(buffer) strncpy: Easily used incorrectly",
\ },
\ ],
\ ale#handlers#flawfinder#HandleFlawfinderFormat(bufnr(''), [
\ "<stdin>:12:4: [2] (buffer) char:Statically-sized arrays can be bad",
\ "<stdin>:31:4: [1] (buffer) strncpy:Easily used incorrectly",
\ ])

View File

@ -0,0 +1,507 @@
Before:
runtime ale_linters/javascript/flow.vim
After:
unlet! g:flow_output
unlet! g:expected
unlet! g:actual
call ale#linter#Reset()
Execute(The flow handler should throw away non-JSON lines):
AssertEqual
\ [],
\ ale_linters#javascript#flow#Handle(bufnr(''), [
\ 'Already up-to-date.',
\ '{"flowVersion":"0.50.0","errors":[],"passed":true}',
\ ])
AssertEqual
\ [],
\ ale_linters#javascript#flow#Handle(bufnr(''), [
\ 'foo',
\ 'bar',
\ 'baz',
\ '{"flowVersion":"0.50.0","errors":[],"passed":true}',
\ ])
Execute(The flow handler should process errors correctly.):
silent! noautocmd file /home/w0rp/Downloads/graphql-js/src/language/parser.js
let g:flow_output = {
\ "flowVersion": "0.39.0",
\ "errors": [
\ {
\ "kind": "infer",
\ "level": "error",
\ "message": [
\ {
\ "context": " return 1",
\ "descr": "number",
\ "type": "Blame",
\ "loc": {
\ "source": expand('%:p'),
\ "type": "SourceFile",
\ "start": {
\ "line": 417,
\ "column": 10,
\ "offset": 9503
\ },
\ "end": {
\ "line": 417,
\ "column": 10,
\ "offset": 9504
\ }
\ },
\ "path": expand('%:p'),
\ "line": 417,
\ "endline": 417,
\ "start": 10,
\ "end": 10
\ },
\ {
\ "context": v:null,
\ "descr": "This type is incompatible with the expected return type of",
\ "type": "Comment",
\ "path": "",
\ "line": 0,
\ "endline": 0,
\ "start": 1,
\ "end": 0
\ },
\ {
\ "context": "function parseArguments(lexer: Lexer<*>): Array<ArgumentNode> {",
\ "descr": "array type",
\ "type": "Blame",
\ "loc": {
\ "source": expand('%:p'),
\ "type": "SourceFile",
\ "start": {
\ "line": 416,
\ "column": 43,
\ "offset": 9472
\ },
\ "end": {
\ "line": 416,
\ "column": 61,
\ "offset": 9491
\ }
\ },
\ "path": expand('%:p'),
\ "line": 416,
\ "endline": 416,
\ "start": 43,
\ "end": 61
\ }
\ ]
\ },
\ {
\ "kind": "infer",
\ "level": "warning",
\ "message": [
\ {
\ "context": " return peek(lexer, TokenKind.PAREN_L) ?",
\ "descr": "unreachable code",
\ "type": "Blame",
\ "loc": {
\ "source": expand('%:p'),
\ "type": "SourceFile",
\ "start": {
\ "line": 419,
\ "column": 3,
\ "offset": 9508
\ },
\ "end": {
\ "line": 421,
\ "column": 7,
\ "offset": 9626
\ }
\ },
\ "path": expand('%:p'),
\ "line": 419,
\ "endline": 421,
\ "start": 3,
\ "end": 7
\ }
\ ]
\ }
\ ],
\ "passed": v:false
\}
let g:actual = ale_linters#javascript#flow#Handle(bufnr(''), [json_encode(g:flow_output)])
let g:expected = [
\ {
\ 'lnum': 417,
\ 'type': 'E',
\ 'col': 10,
\ 'text': 'number: This type is incompatible with the expected return type of array type',
\ },
\ {
\ 'lnum': 419,
\ 'type': 'W',
\ 'col': 3,
\ 'text': 'unreachable code:',
\ },
\]
AssertEqual g:expected, g:actual
Execute(The flow handler should fetch the correct location for the currently opened file, even when it's not in the first message.):
silent! noautocmd file /Users/rav/Projects/vim-ale-flow/index.js
let g:flow_output = {
\ "flowVersion": "0.44.0",
\ "errors": [{
\ "operation": {
\ "context": " <Foo foo=\"bar\"/>, document.getElementById('foo')",
\ "descr": "React element `Foo`",
\ "type": "Blame",
\ "loc": {
\ "source": expand('%:p'),
\ "type": "SourceFile",
\ "start": {
\ "line": 6,
\ "column": 3,
\ "offset": 92
\ },
\ "end": {
\ "line": 6,
\ "column": 18,
\ "offset": 108
\ }
\ },
\ "path": expand('%:p'),
\ "line": 6,
\ "endline": 6,
\ "start": 3,
\ "end": 18
\ },
\ "kind": "infer",
\ "level": "error",
\ "message": [{
\ "context": "module.exports = function(props: Props) {",
\ "descr": "property `bar`",
\ "type": "Blame",
\ "loc": {
\ "source": "/Users/rav/Projects/vim-ale-flow/foo.js",
\ "type": "SourceFile",
\ "start": {
\ "line": 9,
\ "column": 34,
\ "offset": 121
\ },
\ "end": {
\ "line": 9,
\ "column": 38,
\ "offset": 126
\ }
\ },
\ "path": "/Users/rav/Projects/vim-ale-flow/foo.js",
\ "line": 9,
\ "endline": 9,
\ "start": 34,
\ "end": 38
\ }, {
\ "context": v:null,
\ "descr": "Property not found in",
\ "type": "Comment",
\ "path": "",
\ "line": 0,
\ "endline": 0,
\ "start": 1,
\ "end": 0
\ }, {
\ "context": " <Foo foo=\"bar\"/>, document.getElementById('foo')",
\ "descr": "props of React element `Foo`",
\ "type": "Blame",
\ "loc": {
\ "source": expand('%:p'),
\ "type": "SourceFile",
\ "start": {
\ "line": 6,
\ "column": 3,
\ "offset": 92
\ },
\ "end": {
\ "line": 6,
\ "column": 18,
\ "offset": 108
\ }
\ },
\ "path": expand('%:p'),
\ "line": 6,
\ "endline": 6,
\ "start": 3,
\ "end": 18
\ }]
\ }],
\ "passed": v:false
\}
let g:actual = ale_linters#javascript#flow#Handle(bufnr(''), [json_encode(g:flow_output)])
let g:expected = [
\ {
\ 'lnum': 6,
\ 'col': 3,
\ 'type': 'E',
\ 'text': 'property `bar`: Property not found in props of React element `Foo` See also: React element `Foo`',
\ }
\]
AssertEqual g:expected, g:actual
Execute(The flow handler should handle relative paths):
silent! noautocmd file /Users/rav/Projects/vim-ale-flow/index.js
let g:flow_output = {
\ "flowVersion": "0.44.0",
\ "errors": [{
\ "operation": {
\ "context": " <Foo foo=\"bar\"/>, document.getElementById('foo')",
\ "descr": "React element `Foo`",
\ "type": "Blame",
\ "loc": {
\ "source": expand('%:p'),
\ "type": "SourceFile",
\ "start": {
\ "line": 6,
\ "column": 3,
\ "offset": 92
\ },
\ "end": {
\ "line": 6,
\ "column": 18,
\ "offset": 108
\ }
\ },
\ "path": expand('%:p'),
\ "line": 6,
\ "endline": 6,
\ "start": 3,
\ "end": 18
\ },
\ "kind": "infer",
\ "level": "error",
\ "message": [{
\ "context": "module.exports = function(props: Props) {",
\ "descr": "property `bar`",
\ "type": "Blame",
\ "loc": {
\ "source": "vim-ale-flow/foo.js",
\ "type": "SourceFile",
\ "start": {
\ "line": 9,
\ "column": 34,
\ "offset": 121
\ },
\ "end": {
\ "line": 9,
\ "column": 38,
\ "offset": 126
\ }
\ },
\ "path": "vim-ale-flow/foo.js",
\ "line": 9,
\ "endline": 9,
\ "start": 34,
\ "end": 38
\ }, {
\ "context": v:null,
\ "descr": "Property not found in",
\ "type": "Comment",
\ "path": "",
\ "line": 0,
\ "endline": 0,
\ "start": 1,
\ "end": 0
\ }, {
\ "context": " <Foo foo=\"bar\"/>, document.getElementById('foo')",
\ "descr": "props of React element `Foo`",
\ "type": "Blame",
\ "loc": {
\ "source": expand('%:p'),
\ "type": "SourceFile",
\ "start": {
\ "line": 6,
\ "column": 3,
\ "offset": 92
\ },
\ "end": {
\ "line": 6,
\ "column": 18,
\ "offset": 108
\ }
\ },
\ "path": expand('%:p'),
\ "line": 6,
\ "endline": 6,
\ "start": 3,
\ "end": 18
\ }]
\ }],
\ "passed": v:false
\}
let g:actual = ale_linters#javascript#flow#Handle(bufnr(''), [json_encode(g:flow_output)])
let g:expected = [
\ {
\ 'lnum': 6,
\ 'col': 3,
\ 'type': 'E',
\ 'text': 'property `bar`: Property not found in props of React element `Foo` See also: React element `Foo`',
\ }
\]
AssertEqual g:expected, g:actual
Execute(The flow handler should handle extra errors):
silent! noautocmd file /Users/rav/Projects/vim-ale-flow/index.js
let g:flow_output = {
\ "flowVersion": "0.54.0",
\ "errors": [{
\ "extra": [{
\ "message": [{
\ "context": v:null,
\ "descr": "Property \`setVector\` is incompatible:",
\ "type": "Blame ",
\ "path": "",
\ "line": 0,
\ "endline": 0,
\ "start": 1,
\ "end": 0
\ }],
\ "children": [{
\ "message": [{
\ "context": "setVector = \{2\}",
\ "descr": "number ",
\ "type": "Blame ",
\ "loc": {
\ "source": expand('%:p'),
\ "type": "SourceFile ",
\ "start": {
\ "line": 90,
\ "column": 30,
\ "offset": 2296
\ },
\ "end": {
\ "line": 90,
\ "column": 30,
\ "offset": 2297
\ }
\ },
\ "path": expand('%:p'),
\ "line": 90,
\ "endline": 90,
\ "start": 30,
\ "end": 30
\ }, {
\ "context": v:null,
\ "descr": "This type is incompatible with ",
\ "type": "Comment ",
\ "path": "",
\ "line": 0,
\ "endline": 0,
\ "start": 1,
\ "end": 0
\ }, {
\ "context": "setVector: VectorType => void,",
\ "descr": "function type ",
\ "type": "Blame ",
\ "loc": {
\ "source": expand('%:p'),
\ "type": "SourceFile",
\ "start": {
\ "line": 9,
\ "column": 14,
\ "offset": 252
\ },
\ "end": {
\ "line": 9,
\ "column": 31,
\ "offset": 270
\ }
\ },
\ "path": expand('%:p'),
\ "line": 9,
\ "endline": 9,
\ "start": 14,
\ "end": 31
\ }]
\ }]
\ }],
\ "kind": "infer",
\ "level": "error",
\ "suppressions": [],
\ "message": [{
\ "context": " < New ",
\ "descr": "props of React element `New`",
\ "type": "Blame",
\ "loc": {
\ "source": "vim-ale-flow/foo.js",
\ "type": "SourceFile",
\ "start": {
\ "line": 89,
\ "column": 17,
\ "offset": 2262
\ },
\ "end": {
\ "line": 94,
\ "column": 18,
\ "offset": 2488
\ }
\ },
\ "path": "",
\ "line": 89,
\ "endline": 94,
\ "start": 17,
\ "end": 18
\ }, {
\ "context": v:null,
\ "descr": "This type is incompatible with",
\ "type": "Comment",
\ "path": "",
\ "line": 0,
\ "endline": 0,
\ "start": 1,
\ "end": 0
\ }, {
\ "context": "class New extends React.Component < NewProps,NewState > {",
\ "descr": "object type",
\ "type": "Blame",
\ "loc": {
\ "source": expand('%:p'),
\ "type": "SourceFile",
\ "start": {
\ "line": 20,
\ "column": 35,
\ "offset": 489
\ },
\ "end": {
\ "line": 20,
\ "column": 42,
\ "offset": 497
\ }
\ },
\ "path": expand('%:p'),
\ "line": 20,
\ "endline": 20,
\ "start": 35,
\ "end": 42
\ }]
\ }],
\ "passed": v:false
\}
let g:actual = ale_linters#javascript#flow#Handle(bufnr(''), [json_encode(g:flow_output)])
let g:expected = [
\ {
\ 'lnum': 20,
\ 'col': 35,
\ 'type': 'E',
\ 'text': 'props of React element `New`: This type is incompatible with object type',
\ 'detail': 'props of React element `New`: This type is incompatible with object type'
\ . "\nProperty `setVector` is incompatible: number This type is incompatible with function type ",
\ }
\]
AssertEqual g:expected, g:actual

View File

@ -0,0 +1,44 @@
Before:
runtime ale_linters/chef/foodcritic.vim
After:
call ale#linter#Reset()
Execute(Basic warnings should be handled):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'code': 'CINK001',
\ 'type': 'W',
\ 'text': 'Missing CHANGELOG in markdown format',
\ 'filename': '/foo/bar/CHANGELOG.md',
\ },
\ {
\ 'lnum': 1,
\ 'code': 'FC011',
\ 'type': 'W',
\ 'text': 'Missing README in markdown format',
\ 'filename': '/foo/bar/README.md',
\ },
\ {
\ 'lnum': 1,
\ 'code': 'FC031',
\ 'type': 'W',
\ 'text': 'Cookbook without metadata.rb file',
\ 'filename': '/foo/bar/metadata.rb',
\ },
\ {
\ 'lnum': 1,
\ 'code': 'FC071',
\ 'type': 'W',
\ 'text': 'Missing LICENSE file',
\ 'filename': '/foo/bar/LICENSE',
\ },
\ ],
\ ale_linters#chef#foodcritic#Handle(bufnr(''), [
\ 'CINK001: Missing CHANGELOG in markdown format: /foo/bar/CHANGELOG.md:1',
\ 'FC011: Missing README in markdown format: /foo/bar/README.md:1',
\ 'FC031: Cookbook without metadata.rb file: /foo/bar/metadata.rb:1',
\ 'FC071: Missing LICENSE file: /foo/bar/LICENSE:1',
\ ])

View File

@ -0,0 +1,95 @@
Before:
runtime ale_linters/fortran/gcc.vim
After:
call ale#linter#Reset()
Execute(The fortran handler should parse lines from GCC 4.1.2 correctly):
AssertEqual
\ [
\ {
\ 'bufnr': 357,
\ 'lnum': 4,
\ 'col': 0,
\ 'text': "Symbol b at (1) has no IMPLICIT type",
\ 'type': 'E',
\ },
\ {
\ 'bufnr': 357,
\ 'lnum': 3,
\ 'col': 0,
\ 'text': "Symbol a at (1) has no IMPLICIT type",
\ 'type': 'E',
\ },
\ ],
\ ale_linters#fortran#gcc#Handle(357, [
\ " In file :4",
\ "",
\ "write(*,*) b",
\ " 1",
\ "Error: Symbol b at (1) has no IMPLICIT type",
\ " In file :3",
\ "",
\ "write(*,*) a",
\ " 1",
\ "Error: Symbol a at (1) has no IMPLICIT type",
\ ])
Execute(The fortran handler should parse lines from GCC 4.9.3 correctly):
AssertEqual
\ [
\ {
\ 'bufnr': 357,
\ 'lnum': 3,
\ 'col': 12,
\ 'text': "Symbol a at (1) has no IMPLICIT type",
\ 'type': 'E',
\ },
\ {
\ 'bufnr': 357,
\ 'lnum': 4,
\ 'col': 12,
\ 'text': "Symbol b at (1) has no IMPLICIT type",
\ 'type': 'E',
\ },
\ ],
\ ale_linters#fortran#gcc#Handle(357, [
\ ":3.12:",
\ "",
\ "write(*,*) a",
\ " 1",
\ "Error: Symbol a at (1) has no IMPLICIT type",
\ ":4.12:",
\ "",
\ "write(*,*) b",
\ " 1",
\ "Error: Symbol b at (1) has no IMPLICIT type",
\ ])
Execute(The fortran handler should parse lines from GCC 6.3.1 correctly):
AssertEqual
\ [
\ {
\ 'bufnr': 337,
\ 'lnum': 3,
\ 'col': 12,
\ 'text': "Symbol a at (1) has no IMPLICIT type",
\ 'type': 'E',
\ },
\ {
\ 'bufnr': 337,
\ 'lnum': 4,
\ 'col': 12,
\ 'text': "Symbol b at (1) has no IMPLICIT type",
\ 'type': 'E',
\ },
\ ],
\ ale_linters#fortran#gcc#Handle(337, [
\ "<stdin>:3:12:",
\ "",
\ "Error: Symbol a at (1) has no IMPLICIT type",
\ "<stdin>:4:12:",
\ "",
\ "Error: Symbol b at (1) has no IMPLICIT type",
\ ])

View File

@ -0,0 +1,39 @@
Before:
runtime ale_linters/awk/gawk.vim
After:
call ale#linter#Reset()
Execute(gawk syntax errors should be parsed correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 0,
\ 'text': "invalid char ''' in expression",
\ 'code': 0,
\ 'type': 'E',
\ },
\ {
\ 'lnum': 5,
\ 'col': 0,
\ 'text': 'unterminated string',
\ 'code': 0,
\ 'type': 'E',
\ },
\ {
\ 'lnum': 10,
\ 'col': 0,
\ 'text': "escape sequence `\u' treated as plain `u'",
\ 'code': 0,
\ 'type': 'W',
\ },
\ ],
\ ale#handlers#gawk#HandleGawkFormat(347, [
\ "gawk: something.awk:1: BEGIN { system('touch aaaaaaaaa') }",
\ "gawk: something.awk:1: ^ invalid char ''' in expression",
\ 'gawk: something.awk:5: { x = "aaaaaaaaaaa',
\ 'gawk: something.awk:5: ^ unterminated string',
\ "gawk: something.awk:10: warning: escape sequence `\u' treated as plain `u'",
\ ])

View File

@ -0,0 +1,316 @@
Execute(The GCC handler should ignore other lines of output):
AssertEqual
\ [],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ 'foo',
\ 'bar',
\ 'baz',
\ ])
Execute(GCC errors from included files should be parsed correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 1,
\ 'filename': 'broken.h',
\ 'type': 'E',
\ 'text': 'expected identifier or ''('' before ''{'' token',
\ },
\ {
\ 'lnum': 3,
\ 'col': 2,
\ 'text': 'Error found in header. See :ALEDetail',
\ 'detail': join([
\ 'In file included from <stdin>:3:2:',
\ 'broken.h:1:1: error: expected identifier or ''('' before ''{'' token',
\ ' {{{',
\ ' ^',
\ ], "\n"),
\ },
\ ],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ 'In file included from <stdin>:3:2:',
\ 'broken.h:1:1: error: expected identifier or ''('' before ''{'' token',
\ ' {{{',
\ ' ^',
\ 'compilation terminated.',
\ ])
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 1,
\ 'filename': 'b.h',
\ 'type': 'E',
\ 'text': 'expected identifier or ''('' before ''{'' token',
\ },
\ {
\ 'lnum': 5,
\ 'text': 'Error found in header. See :ALEDetail',
\ 'detail': join([
\ 'In file included from a.h:1:0,',
\ ' from <stdin>:5:',
\ 'b.h:1:1: error: expected identifier or ''('' before ''{'' token',
\ ' {{{',
\ ' ^',
\ ], "\n"),
\ },
\ ],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ 'In file included from a.h:1:0,',
\ ' from <stdin>:5:',
\ 'b.h:1:1: error: expected identifier or ''('' before ''{'' token',
\ ' {{{',
\ ' ^',
\ 'compilation terminated.',
\ ])
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 1,
\ 'filename': 'b.h',
\ 'type': 'E',
\ 'text': 'unknown type name ''bad_type''',
\ },
\ {
\ 'lnum': 2,
\ 'col': 1,
\ 'filename': 'b.h',
\ 'type': 'E',
\ 'text': 'unknown type name ''other_bad_type''',
\ },
\ {
\ 'lnum': 3,
\ 'text': 'Error found in header. See :ALEDetail',
\ 'detail': join([
\ 'In file included from a.h:1:0,',
\ ' from <stdin>:3:',
\ 'b.h:1:1: error: unknown type name bad_type',
\ ' bad_type x;',
\ ' ^',
\ 'b.h:2:1: error: unknown type name other_bad_type',
\ ' other_bad_type y;',
\ ' ^',
\ ], "\n"),
\ },
\ ],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ 'In file included from a.h:1:0,',
\ ' from <stdin>:3:',
\ 'b.h:1:1: error: unknown type name bad_type',
\ ' bad_type x;',
\ ' ^',
\ 'b.h:2:1: error: unknown type name other_bad_type',
\ ' other_bad_type y;',
\ ' ^',
\ 'compilation terminated.',
\ ])
Execute(The GCC handler shouldn't complain about #pragma once for headers):
silent file! test.h
AssertEqual
\ [],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ '<stdin>:1:1: warning: #pragma once in main file [enabled by default]',
\ ])
silent file! test.hpp
AssertEqual
\ [],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ '<stdin>:1:1: warning: #pragma once in main file [enabled by default]',
\ ])
Execute(The GCC handler should handle syntax errors):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 12,
\ 'type': 'E',
\ 'text': 'invalid suffix "p" on integer constant'
\ },
\ {
\ 'lnum': 17,
\ 'col': 5,
\ 'type': 'E',
\ 'text': 'invalid suffix "n" on integer constant'
\ },
\ {
\ 'lnum': 4,
\ 'type': 'E',
\ 'text': 'variable or field ''foo'' declared void'
\ },
\ {
\ 'lnum': 4,
\ 'type': 'E',
\ 'text': '''cat'' was not declared in this scope'
\ },
\ {
\ 'lnum': 12,
\ 'type': 'E',
\ 'text': 'expected '';'' before ''o'''
\ },
\ ],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ '<stdin>:6:12: error: invalid suffix "p" on integer constant',
\ '<stdin>:17:5: error: invalid suffix "n" on integer constant',
\ '<stdin>:4: error: variable or field ''foo'' declared void',
\ '<stdin>:4: error: ''cat'' was not declared in this scope',
\ '<stdin>:12: error: expected `;'' before ''o''',
\ ])
Execute(The GCC handler should handle notes with no previous message):
AssertEqual
\ [],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ '<stdin>:1:1: note: x',
\ '<stdin>:1:1: note: x',
\ ])
Execute(The GCC handler should attach notes to previous messages):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 12,
\ 'type': 'E',
\ 'text': 'Some error',
\ 'detail': "Some error\n<stdin>:1:1: note: x",
\ },
\ ],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ '-:6:12: error: Some error',
\ '<stdin>:1:1: note: x',
\ ])
Execute(The GCC handler should interpret - as being the current file):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 12,
\ 'type': 'E',
\ 'text': 'Some error',
\ },
\ ],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ '-:6:12: error: Some error',
\ ])
Execute(The GCC handler should handle fatal error messages due to missing files):
AssertEqual
\ [
\ {
\ 'lnum': 3,
\ 'col': 12,
\ 'type': 'E',
\ 'text': 'foo.h: No such file or directory'
\ },
\ ],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ '<stdin>:3:12: fatal error: foo.h: No such file or directory',
\ ])
Execute(The GCC handler should handle errors for inlined header functions):
AssertEqual
\ [
\ {
\ 'lnum': 50,
\ 'col': 4,
\ 'filename': '/usr/include/bits/fcntl2.h',
\ 'type': 'E',
\ 'text': 'call to ''__open_missing_mode'' declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments',
\ },
\ {
\ 'lnum': 44,
\ 'col': 5,
\ 'filename': '/usr/include/bits/fcntl2.h',
\ 'type': 'E',
\ 'text': 'call to ''__open_too_many_args'' declared with attribute error: open can be called either with 2 or 3 arguments, not more',
\ },
\ {
\ 'lnum': 7,
\ 'col': 10,
\ 'type': 'E',
\ 'text': 'call to ''__open_missing_mode'' declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments',
\ },
\ {
\ 'lnum': 13,
\ 'col': 11,
\ 'type': 'E',
\ 'text': 'call to ''__open_too_many_args'' declared with attribute error: open can be called either with 2 or 3 arguments, not more',
\ },
\ {
\ 'lnum': 1,
\ 'text': 'Error found in header. See :ALEDetail',
\ 'detail': join([
\ 'In file included from /usr/include/fcntl.h:328,',
\ ' from <stdin>:1:',
\ 'In function open,',
\ ' inlined from main at <stdin>:7:10:',
\ '/usr/include/bits/fcntl2.h:50:4: error: call to __open_missing_mode declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments',
\ ' __open_missing_mode ();',
\ ' ^~~~~~~~~~~~~~~~~~~~~~',
\ 'In function open,',
\ ' inlined from main at <stdin>:13:11:',
\ '/usr/include/bits/fcntl2.h:44:5: error: call to __open_too_many_args declared with attribute error: open can be called either with 2 or 3 arguments, not more',
\ ' __open_too_many_args ();',
\ ], "\n")
\ },
\],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ 'In file included from /usr/include/fcntl.h:328,',
\ ' from <stdin>:1:',
\ 'In function open,',
\ ' inlined from main at <stdin>:7:10:',
\ '/usr/include/bits/fcntl2.h:50:4: error: call to __open_missing_mode declared with attribute error: open with O_CREAT or O_TMPFILE in second argument needs 3 arguments',
\ ' __open_missing_mode ();',
\ ' ^~~~~~~~~~~~~~~~~~~~~~',
\ 'In function open,',
\ ' inlined from main at <stdin>:13:11:',
\ '/usr/include/bits/fcntl2.h:44:5: error: call to __open_too_many_args declared with attribute error: open can be called either with 2 or 3 arguments, not more',
\ ' __open_too_many_args ();',
\ ' ^~~~~~~~~~~~~~~~~~~~~~~',
\ ])
Execute(The GCC handler should handle macro expansion errors in current file):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 19,
\ 'type': 'E',
\ 'text': 'error message',
\ 'detail': "error message\n<stdin>:1:19: note: in expansion of macro 'TEST'",
\ },
\ ],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ '<command-line>: error: error message',
\ '<stdin>:1:19: note: in expansion of macro TEST',
\ ' 1 | std::string str = TEST;',
\ ' | ^~~~',
\ ])
Execute(The GCC handler should handle macro expansion errors in other files):
AssertEqual
\ [
\ {
\ 'lnum': 0,
\ 'type': 'E',
\ 'text': 'Error found in macro expansion. See :ALEDetail',
\ 'detail': "error message\ninc.h:1:19: note: in expansion of macro 'TEST'",
\ },
\ ],
\ ale#handlers#gcc#HandleGCCFormatWithIncludes(347, [
\ '<command-line>: error: error message',
\ 'inc.h:1:19: note: in expansion of macro TEST',
\ ' 1 | std::string str = TEST;',
\ ' | ^~~~',
\ ])

View File

@ -0,0 +1,177 @@
Execute(The ghc handler should handle hdevtools output):
call ale#test#SetFilename('foo.hs')
AssertEqual
\ [
\ {
\ 'lnum': 147,
\ 'type': 'W',
\ 'col': 62,
\ 'text': '• Couldnt match type a -> T.Text with T.Text Expected type: [T.Text]',
\ 'detail': join([
\ '• Couldnt match type a -> T.Text with T.Text',
\ ' Expected type: [T.Text]',
\ ], "\n"),
\ },
\ ],
\ ale#handlers#haskell#HandleGHCFormat(bufnr(''), [
\ 'foo.hs:147:62: warning:',
\ '• Couldnt match type a -> T.Text with T.Text',
\ ' Expected type: [T.Text]',
\ ])
Execute(The ghc handler should handle ghc 8 output):
call ale#test#SetFilename('src/Appoint/Lib.hs')
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'type': 'E',
\ 'col': 1,
\ 'text': 'Failed to load interface for GitHub.Data Use -v to see a list of the files searched for.',
\ 'detail': join([
\ ' Failed to load interface for GitHub.Data',
\ ' Use -v to see a list of the files searched for.',
\ ], "\n"),
\ },
\ {
\ 'lnum': 7,
\ 'type': 'W',
\ 'col': 1,
\ 'text': 'Failed to load interface for GitHub.Endpoints.PullRequests Use -v to see a list of the files searched for.',
\ 'detail': join([
\ ' Failed to load interface for GitHub.Endpoints.PullRequests',
\ ' Use -v to see a list of the files searched for.',
\ ], "\n"),
\ },
\ ],
\ ale#handlers#haskell#HandleGHCFormat(bufnr(''), [
\ '',
\ ale#path#Simplify('src/Appoint/Lib.hs') . ':6:1: error:',
\ ' Failed to load interface for GitHub.Data',
\ ' Use -v to see a list of the files searched for.',
\ '',
\ ale#path#Simplify('src/Appoint/Lib.hs') . ':7:1: warning:',
\ ' Failed to load interface for GitHub.Endpoints.PullRequests',
\ ' Use -v to see a list of the files searched for.',
\ ])
Execute(The ghc handler should handle ghc 7 output):
call ale#test#SetFilename('src/Main.hs')
AssertEqual
\ [
\ {
\ 'lnum': 168,
\ 'type': 'E',
\ 'col': 1,
\ 'text': 'parse error (possibly incorrect indentation or mismatched brackets)',
\ 'detail': join([
\ ' parse error (possibly incorrect indentation or mismatched brackets)',
\ ], "\n"),
\ },
\ {
\ 'lnum': 84,
\ 'col': 1,
\ 'type': 'W',
\ 'text': 'Top-level binding with no type signature: myLayout :: Choose Tall (Choose (Mirror Tall) Full) a',
\ 'detail': join([
\ ' Top-level binding with no type signature:',
\ ' myLayout :: Choose Tall (Choose (Mirror Tall) Full) a',
\ ], "\n"),
\ },
\ {
\ 'lnum': 94,
\ 'col': 5,
\ 'type': 'E',
\ 'text': 'Some other error',
\ 'detail': join([
\ ' Some other error',
\ ], "\n"),
\ },
\ ],
\ ale#handlers#haskell#HandleGHCFormat(bufnr(''), [
\ ale#path#Simplify('src/Main.hs') . ':168:1:',
\ ' parse error (possibly incorrect indentation or mismatched brackets)',
\ ale#path#Simplify('src/Main.hs') . ':84:1:Warning:',
\ ' Top-level binding with no type signature:',
\ ' myLayout :: Choose Tall (Choose (Mirror Tall) Full) a',
\ ale#path#Simplify('src/Main.hs') . ':94:5:Error:',
\ ' Some other error',
\ ])
Execute(The ghc handler should handle stack 1.5.1 output):
call ale#test#SetFilename('src/Main.hs')
AssertEqual
\ [
\ {
\ 'lnum': 160,
\ 'col': 14,
\ 'type': 'E',
\ 'text': '• Expecting one fewer arguments to Exp Expected kind k0 -> *, but Exp has kind * • In the type Exp a | 160 | pattern F :: Exp a | ^^^^^',
\ 'detail': join([
\ ' • Expecting one fewer arguments to Exp',
\ ' Expected kind k0 -> *, but Exp has kind *',
\ ' • In the type Exp a',
\ ' |',
\ ' 160 | pattern F :: Exp a',
\ ' | ^^^^^',
\ ], "\n"),
\ },
\ ],
\ ale#handlers#haskell#HandleGHCFormat(bufnr(''), [
\ ' ' . ale#path#Simplify('src/Main.hs') . ':160:14: error:',
\ ' • Expecting one fewer arguments to Exp',
\ ' Expected kind k0 -> *, but Exp has kind *',
\ ' • In the type Exp a',
\ ' |',
\ ' 160 | pattern F :: Exp a',
\ ' | ^^^^^',
\ ])
Execute(The ghc handler should handle ghc panic):
let g:detail = [
\ '[15 of 15] Compiling SizedTypes.List',
\ 'ghc: panic! (the ''impossible'' happened)',
\ ' (GHC version 8.10.3:',
\ ' src/SizedTypes/List.hs:(46,19)-(50,0) Specified type does not refine Haskell type for `SizedTypes.List.out` (Plugged Init types new)',
\ ' The Liquid type',
\ ' .',
\ ' GHC.Types.Int -> (SizedTypes.List.List a) -> (_, (SizedTypes.List.List a))',
\ ' .',
\ ' is inconsistent with the Haskell type',
\ ' .',
\ ' forall p a ->',
\ 'p -> SizedTypes.List.List a -> (a, SizedTypes.List.List a)',
\ ' .',
\ ' defined at src/SizedTypes/List.hs:52:1-3',
\ ' .',
\ ' Specifically, the Liquid component',
\ ' .',
\ ' {VV##0 : GHC.Types.Int | VV##0 >= 0}',
\ ' .',
\ ' is inconsistent with the Haskell component',
\ ' .',
\ ' p',
\ ' .',
\ ' ',
\ ' HINT: Use the hole ''_'' instead of the mismatched component (in the Liquid specification)',
\ '',
\ 'Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug',
\ '',
\ ''
\ ]
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 1,
\ 'type': 'E',
\ 'text': 'ghc panic!',
\ 'detail': join(g:detail[1:-3], "\n"),
\ },
\ ],
\ ale#handlers#haskell#HandleGHCFormat(bufnr(''), g:detail)
unlet g:detail

View File

@ -0,0 +1,37 @@
Execute(HandleGhcFormat should handle ghc-mod problems):
call ale#test#SetFilename('check2.hs')
AssertEqual
\ [
\ {
\ 'lnum': 2,
\ 'col': 1,
\ 'type': 'E',
\ 'text': 'Failed to load interface for MissingUse -v to see a list of the files searched for.',
\ },
\ {
\ 'lnum': 2,
\ 'col': 1,
\ 'type': 'E',
\ 'text': 'Suggestion: Use camelCaseFound: my_variable = ...Why not: myVariable = ...',
\ },
\ {
\ 'lnum': 6,
\ 'col': 1,
\ 'type': 'W',
\ 'text': 'Eta reduceFound: myFunc x = succ xWhy not: myFunc = succ',
\ },
\ {
\ 'lnum': 28,
\ 'col': 28,
\ 'type': 'W',
\ 'text': 'Defaulting the following constraints to type Integer (Num a0) arising from the literal 3 at check2.hs:28:28 (Eq a0) arising from a use of lookup at check2.hs:28:21-28 • In the first argument of lookup, namely 3 In the expression: lookup 3 In the second argument of fmap, namely (lookup 3 $ zip [1, 2, 3] [4, 5, 6])'''
\ },
\ ],
\ ale#handlers#haskell#HandleGHCFormat(bufnr(''), [
\ 'check2.hs:2:1:Failed to load interface for MissingUse -v to see a list of the files searched for.',
\ 'check2.hs:2:1: Suggestion: Use camelCaseFound: my_variable = ...Why not: myVariable = ...',
\ 'check2.hs:6:1: Warning: Eta reduceFound: myFunc x = succ xWhy not: myFunc = succ',
\ 'xxx.hs:6:1: Warning: Eta reduceFound: myFunc x = succ xWhy not: myFunc = succ',
\ printf("check2.hs:28:28: Warning: Defaulting the following constraints to type Integer (Num a0) arising from the literal 3 at %s/check2.hs:28:28 (Eq a0) arising from a use of lookup at %s/check2.hs:28:21-28 • In the first argument of lookup, namely 3 In the expression: lookup 3 In the second argument of fmap, namely (lookup 3 $ zip [1, 2, 3] [4, 5, 6])'", tempname(), tempname()),
\ ])

View File

@ -0,0 +1,26 @@
Before:
runtime ale_linters/vhdl/ghdl.vim
After:
call ale#linter#Reset()
Execute(The ghdl handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 41,
\ 'col' : 5,
\ 'type': 'E',
\ 'text': "error: 'begin' is expected instead of 'if'"
\ },
\ {
\ 'lnum': 12,
\ 'col' : 8,
\ 'type': 'E',
\ 'text': ' no declaration for "i0"'
\ },
\ ],
\ ale_linters#vhdl#ghdl#Handle(bufnr(''), [
\ "dff_en.vhd:41:5:error: 'begin' is expected instead of 'if'",
\ '/path/to/file.vhdl:12:8: no declaration for "i0"',
\ ])

View File

@ -0,0 +1,89 @@
Before:
Save g:ale_warn_about_trailing_whitespace
let g:ale_warn_about_trailing_whitespace = 1
runtime ale_linters/gitcommit/gitlint.vim
After:
Restore
unlet! b:ale_warn_about_trailing_whitespace
call ale#linter#Reset()
Execute(The gitlint handler should handle basic warnings and syntax errors):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'type': 'E',
\ 'text': 'Body message is missing',
\ 'code': 'B6',
\ },
\ {
\ 'lnum': 2,
\ 'type': 'E',
\ 'text': 'Second line is not empty: "to send to upstream"',
\ 'code': 'B4',
\ },
\ {
\ 'lnum': 3,
\ 'type': 'E',
\ 'text': 'Body message is too short (19<20): "to send to upstream"',
\ 'code': 'B5',
\ },
\ {
\ 'lnum': 8,
\ 'type': 'E',
\ 'text': 'Title exceeds max length (92>72): "some very long commit subject line where the author can''t wait to explain what he just fixed"',
\ 'code': 'T1',
\ },
\ ],
\ ale_linters#gitcommit#gitlint#Handle(1, [
\ '1: B6 Body message is missing',
\ '2: B4 Second line is not empty: "to send to upstream"',
\ '3: B5 Body message is too short (19<20): "to send to upstream"',
\ '8: T1 Title exceeds max length (92>72): "some very long commit subject line where the author can''t wait to explain what he just fixed"'
\ ])
Execute(Disabling trailing whitespace warnings should work):
AssertEqual
\ [
\ {
\ 'lnum': 8,
\ 'type': 'E',
\ 'text': 'Trailing whitespace',
\ 'code': 'T2',
\ },
\ ],
\ ale_linters#gitcommit#gitlint#Handle(bufnr(''), [
\ '8: T2 Trailing whitespace',
\])
AssertEqual
\ [
\ {
\ 'lnum': 8,
\ 'type': 'E',
\ 'text': 'Trailing whitespace',
\ 'code': 'B2',
\ },
\ ],
\ ale_linters#gitcommit#gitlint#Handle(bufnr(''), [
\ '8: B2 Trailing whitespace',
\])
let b:ale_warn_about_trailing_whitespace = 0
AssertEqual
\ [],
\ ale_linters#gitcommit#gitlint#Handle(bufnr(''), [
\ '8: T2 Trailing whitespace',
\ ])
AssertEqual
\ [],
\ ale_linters#gitcommit#gitlint#Handle(bufnr(''), [
\ '8: B2 Trailing whitespace',
\ ])

View File

@ -0,0 +1,24 @@
Before:
runtime ale_linters/glsl/glslang.vim
Execute(The glsl glslang handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 4,
\ 'col': 0,
\ 'type': 'E',
\ 'text': '''gl_ModelViewProjectionMatrix'' : undeclared identifier',
\ },
\ {
\ 'lnum': 121,
\ 'col': 0,
\ 'type': 'W',
\ 'text': '''switch'' : last case/default label not followed by statements',
\ },
\ ],
\ ale_linters#glsl#glslang#Handle(bufnr(''), [
\ 'ERROR: 0:4: ''gl_ModelViewProjectionMatrix'' : undeclared identifier',
\ 'WARNING: 0:121: ''switch'' : last case/default label not followed by statements',
\ 'ERROR: 2 compilation errors. No code generated.',
\ ])

View File

@ -0,0 +1,38 @@
Execute(The golang handler should return the correct filenames):
AssertEqual
\ [
\ {
\ 'lnum': 27,
\ 'col': 0,
\ 'text': 'some error',
\ 'type': 'E',
\ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'),
\ },
\ {
\ 'lnum': 27,
\ 'col': 5,
\ 'text': 'some error with a column',
\ 'type': 'E',
\ 'filename': ale#path#Simplify(expand('%:p:h') . '/other.go'),
\ },
\ {
\ 'lnum': 18,
\ 'col': 0,
\ 'text': 'random error',
\ 'type': 'E',
\ 'filename': ale#path#Simplify(expand('%:p:h') . '/go1.14.go'),
\ },
\ {
\ 'lnum': 36,
\ 'col': 2,
\ 'text': 'another random error',
\ 'type': 'E',
\ 'filename': ale#path#Simplify(expand('%:p:h') . '/anothergo1.14.go'),
\ },
\ ],
\ ale#handlers#go#Handler(bufnr(''), [
\ 'test.go:27: some error',
\ 'other.go:27:5: some error with a column',
\ 'vet: go1.14.go:18:0: random error',
\ 'vet: anothergo1.14.go:36:2: another random error',
\ ])

View File

@ -0,0 +1,45 @@
Before:
runtime ale_linters/go/gobuild.vim
After:
call ale#linter#Reset()
Execute (The gobuild handler should handle names with spaces):
" We can't test Windows paths with the path resovling on Linux, but we can
" test the regex.
AssertEqual
\ [
\ [
\ 'C:\something\file with spaces.go',
\ '27',
\ '',
\ 'missing argument for Printf("%s"): format reads arg 2, have only 1 args',
\ ],
\ [
\ 'C:\something\file with spaces.go',
\ '5',
\ '2',
\ 'expected declaration, found ''STRING'' "log"',
\ ],
\ ],
\ map(ale_linters#go#gobuild#GetMatches([
\ 'C:\something\file with spaces.go:27: missing argument for Printf("%s"): format reads arg 2, have only 1 args',
\ 'C:\something\file with spaces.go:5:2: expected declaration, found ''STRING'' "log"',
\ ]), 'v:val[1:4]')
Execute (The gobuild handler should handle relative paths correctly):
call ale#test#SetFilename('app/test.go')
AssertEqual
\ [
\ {
\ 'lnum': 27,
\ 'col': 0,
\ 'text': 'missing argument for Printf("%s"): format reads arg 2, have only 1 args',
\ 'type': 'E',
\ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'),
\ },
\ ],
\ ale_linters#go#gobuild#Handler(bufnr(''), [
\ 'test.go:27: missing argument for Printf("%s"): format reads arg 2, have only 1 args',
\ ])

View File

@ -0,0 +1,84 @@
Before:
runtime ale_linters/go/golangci_lint.vim
After:
call ale#linter#Reset()
Execute (The golangci-lint handler should handle names with spaces):
" We can't test Windows paths with the path resovling on Linux, but we can
" test the regex.
AssertEqual
\ [
\ [
\ 'C:\something\file with spaces.go',
\ '12',
\ '3',
\ 'expected ''package'', found ''IDENT'' gibberish',
\ 'staticcheck',
\ ],
\ [
\ 'C:\something\file with spaces.go',
\ '37',
\ '5',
\ 'expected ''package'', found ''IDENT'' gibberish',
\ 'golint',
\ ],
\ ],
\ map(ale_linters#go#golangci_lint#GetMatches([
\ 'C:\something\file with spaces.go:12:3: expected ''package'', found ''IDENT'' gibberish (staticcheck)',
\ 'C:\something\file with spaces.go:37:5: expected ''package'', found ''IDENT'' gibberish (golint)',
\ ]), 'v:val[1:5]')
Execute (The golangci-lint handler should handle paths correctly):
call ale#test#SetFilename('app/test.go')
let file = ale#path#GetAbsPath(expand('%:p:h'), 'test.go')
AssertEqual
\ [
\ {
\ 'lnum': 12,
\ 'col': 3,
\ 'text': 'expected ''package'', found ''IDENT'' gibberish (staticcheck)',
\ 'type': 'W',
\ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'),
\ },
\ {
\ 'lnum': 37,
\ 'col': 5,
\ 'text': 'expected ''package'', found ''IDENT'' gibberish (golint)',
\ 'type': 'W',
\ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'),
\ },
\ ],
\ ale_linters#go#golangci_lint#Handler(bufnr(''), [
\ file . ':12:3: expected ''package'', found ''IDENT'' gibberish (staticcheck)',
\ file . ':37:5: expected ''package'', found ''IDENT'' gibberish (golint)',
\ ])
Execute (The golangci-lint handler should handle only typecheck lines as errors):
call ale#test#SetFilename('app/main.go')
let file = ale#path#GetAbsPath(expand('%:p:h'), 'test.go')
AssertEqual
\ [
\ {
\ 'lnum': 30,
\ 'col': 5,
\ 'text': 'variable ''err'' is not used (typecheck)',
\ 'type': 'E',
\ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'),
\ },
\ {
\ 'lnum': 505,
\ 'col': 75,
\ 'text': 'Magic number: 404, in <argument> detected (gomnd)',
\ 'type': 'W',
\ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'),
\ }
\ ],
\ ale_linters#go#golangci_lint#Handler(bufnr(''), [
\ file . ':30:5: variable ''err'' is not used (typecheck)',
\ file . ':505:75: Magic number: 404, in <argument> detected (gomnd)',
\ ])

View File

@ -0,0 +1,57 @@
Before:
runtime ale_linters/go/gometalinter.vim
After:
call ale#linter#Reset()
Execute (The gometalinter handler should handle names with spaces):
" We can't test Windows paths with the path resovling on Linux, but we can
" test the regex.
AssertEqual
\ [
\ [
\ 'C:\something\file with spaces.go',
\ '12',
\ '3',
\ 'warning',
\ 'expected ''package'', found ''IDENT'' gibberish (staticcheck)',
\ ],
\ [
\ 'C:\something\file with spaces.go',
\ '37',
\ '5',
\ 'error',
\ 'expected ''package'', found ''IDENT'' gibberish (golint)',
\ ],
\ ],
\ map(ale_linters#go#gometalinter#GetMatches([
\ 'C:\something\file with spaces.go:12:3:warning: expected ''package'', found ''IDENT'' gibberish (staticcheck)',
\ 'C:\something\file with spaces.go:37:5:error: expected ''package'', found ''IDENT'' gibberish (golint)',
\ ]), 'v:val[1:5]')
Execute (The gometalinter handler should handle paths correctly):
call ale#test#SetFilename('app/test.go')
let file = ale#path#GetAbsPath(expand('%:p:h'), 'test.go')
AssertEqual
\ [
\ {
\ 'lnum': 12,
\ 'col': 3,
\ 'text': 'expected ''package'', found ''IDENT'' gibberish (staticcheck)',
\ 'type': 'W',
\ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'),
\ },
\ {
\ 'lnum': 37,
\ 'col': 5,
\ 'text': 'expected ''package'', found ''IDENT'' gibberish (golint)',
\ 'type': 'E',
\ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.go'),
\ },
\ ],
\ ale_linters#go#gometalinter#Handler(bufnr(''), [
\ file . ':12:3:warning: expected ''package'', found ''IDENT'' gibberish (staticcheck)',
\ file . ':37:5:error: expected ''package'', found ''IDENT'' gibberish (golint)',
\ ])

View File

@ -0,0 +1,59 @@
Before:
runtime ale_linters/dockerfile/hadolint.vim
After:
call ale#linter#Reset()
Execute(The hadolint handler should handle an empty string response):
AssertEqual
\ [],
\ ale_linters#dockerfile#hadolint#Handle(bufnr(''), [])
Execute(The hadolint handler should handle a normal example):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 0,
\ 'type': 'W',
\ 'code': 'DL3006',
\ 'text': "DL3006: Always tag the version of an image explicitly",
\ 'detail': "DL3006 ( https://github.com/hadolint/hadolint/wiki/DL3006 )\n\nAlways tag the version of an image explicitly",
\ },
\ {
\ 'lnum': 4,
\ 'col': 0,
\ 'type': 'W',
\ 'code': 'DL3033',
\ 'text': "DL3033: Specify version with `yum install -y <package>-<version>`.",
\ 'detail': "DL3033 ( https://github.com/hadolint/hadolint/wiki/DL3033 )\n\nSpecify version with `yum install -y <package>-<version>`.",
\ },
\ {
\ 'lnum': 12,
\ 'col': 0,
\ 'type': 'W',
\ 'code': 'SC2039',
\ 'text': "SC2039: In POSIX sh, brace expansion is undefined.",
\ 'detail': "SC2039 ( https://github.com/koalaman/shellcheck/wiki/SC2039 )\n\nIn POSIX sh, brace expansion is undefined.",
\ },
\ ],
\ ale_linters#dockerfile#hadolint#Handle(bufnr(''), [
\ '-:1 DL3006 warning: Always tag the version of an image explicitly',
\ '-:4 DL3033 warning: Specify version with `yum install -y <package>-<version>`.',
\ '-:12 SC2039 warning: In POSIX sh, brace expansion is undefined.',
\ ])
Execute(The hadolint handler should handle parsing errors):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 1,
\ 'type': 'E',
\ 'text': "unexpected 'b' expecting '#', ADD, ARG, CMD, COPY, ENTRYPOINT, ENV, EXPOSE, FROM, HEALTHCHECK, LABEL, MAINTAINER, ONBUILD, RUN, SHELL, STOPSIGNAL, USER, VOLUME, WORKDIR, or end of input",
\ 'detail': "hadolint could not parse the file because of a syntax error.",
\ },
\ ],
\ ale_linters#dockerfile#hadolint#Handle(bufnr(''), [
\ '/dev/stdin:1:1 unexpected ''b'' expecting ''#'', ADD, ARG, CMD, COPY, ENTRYPOINT, ENV, EXPOSE, FROM, HEALTHCHECK, LABEL, MAINTAINER, ONBUILD, RUN, SHELL, STOPSIGNAL, USER, VOLUME, WORKDIR, or end of input',
\ ])

View File

@ -0,0 +1,7 @@
Before:
runtime ale/handlers/haskell_stack.vim
Execute(Escape stack should correctly identify a stack exec command):
AssertEqual
\ ale#Escape('stack') . ' exec ' . ale#Escape('hlint') . ' --',
\ ale#handlers#haskell_stack#EscapeExecutable('stack', 'hlint')

View File

@ -0,0 +1,80 @@
Before:
runtime! ale_linters/haskell/hlint.vim
After:
call ale#linter#Reset()
Execute(The hlint handler should parse items correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 4,
\ 'end_lnum': 3,
\ 'end_col': 2,
\ 'text': 'Error: Do something. Found: [Char] Why not: String',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 2,
\ 'col': 4,
\ 'end_lnum': 7,
\ 'end_col': 2,
\ 'text': 'Warning: Do something. Found: [Char] Why not: String',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 73,
\ 'col': 25,
\ 'end_lnum': 73,
\ 'end_col': 31,
\ 'text': 'Suggestion: Use String. Found: [Char] Why not: String',
\ 'type': 'I',
\ },
\ ],
\ ale_linters#haskell#hlint#Handle(bufnr(''), [json_encode([
\ {
\ 'module': 'Main',
\ 'decl': 'foo',
\ 'severity': 'Error',
\ 'hint': 'Do something',
\ 'file': '-',
\ 'startLine': 1,
\ 'startColumn': 4,
\ 'endLine': 3,
\ 'endColumn': 2,
\ 'from': '[Char]',
\ 'to': 'String',
\ },
\ {
\ 'module': 'Main',
\ 'decl': 'foo',
\ 'severity': 'Warning',
\ 'hint': 'Do something',
\ 'file': '-',
\ 'startLine': 2,
\ 'startColumn': 4,
\ 'endLine': 7,
\ 'endColumn': 2,
\ 'from': '[Char]',
\ 'to': 'String',
\ },
\ {
\ 'module': 'Main',
\ 'decl': 'myFocusedBorderColor',
\ 'severity': 'Suggestion',
\ 'hint': 'Use String',
\ 'file': '-',
\ 'startLine': 73,
\ 'startColumn': 25,
\ 'endLine': 73,
\ 'endColumn': 31,
\ 'from': '[Char]',
\ 'to': 'String',
\ },
\ ])])
Execute(The hlint handler should handle empty output):
AssertEqual
\ [],
\ ale_linters#haskell#hlint#Handle(bufnr(''), [])

View File

@ -0,0 +1,49 @@
Before:
runtime! ale_linters/openapi/ibm_validator.vim
After:
call ale#linter#Reset()
Execute(Problems should be parsed correctly for openapi-ibm-validator):
AssertEqual
\ [
\ {
\ 'lnum': 54,
\ 'col': 0,
\ 'type': 'E',
\ 'text': 'Items with a description must have content in it.',
\ },
\ {
\ 'lnum': 24,
\ 'col': 0,
\ 'type': 'W',
\ 'text': 'Operations must have a non-empty `operationId`.',
\ },
\ {
\ 'lnum': 40,
\ 'col': 0,
\ 'type': 'W',
\ 'text': 'operationIds must follow case convention: lower_snake_case',
\ },
\ ],
\ ale_linters#openapi#ibm_validator#Handle(bufnr(''), [
\ '',
\ '[Warning] No .validaterc file found. The validator will run in default mode.',
\ 'To configure the validator, create a .validaterc file.',
\ '',
\ 'errors',
\ '',
\ ' Message : Items with a description must have content in it.',
\ ' Path : paths./settings.patch.description',
\ ' Line : 54',
\ '',
\ 'warnings',
\ '',
\ ' Message : Operations must have a non-empty `operationId`.',
\ ' Path : paths./stats.get.operationId',
\ ' Line : 24',
\ '',
\ ' Message : operationIds must follow case convention: lower_snake_case',
\ ' Path : paths./settings.get.operationId',
\ ' Line : 40'
\ ])

View File

@ -0,0 +1,66 @@
Before:
Save $TMPDIR
" Set TMPDIR so the temporary file checks work.
let $TMPDIR = '/tmp'
runtime ale_linters/idris/idris.vim
After:
Restore
call ale#linter#Reset()
Execute(The idris handler should parse messages that reference a single column):
if has('win32')
call ale#test#SetFilename($TEMP . '\foo.idr')
else
call ale#test#SetFilename('/tmp/foo.idr')
endif
AssertEqual
\ [
\ {
\ 'lnum': 4,
\ 'col': 5,
\ 'type': 'E',
\ 'text': 'When checking right hand side of main with expected type IO () When checking an application of function Prelude.Monad.>>=: Type mismatch between IO () (Type of putStrLn _) and _ -> _ (Is putStrLn _ applied to too many arguments?) Specifically: Type mismatch between IO and \uv => _ -> uv'
\ }
\ ],
\ ale_linters#idris#idris#Handle(bufnr(''), [
\ expand('%:p') . ':4:5:',
\ 'When checking right hand side of main with expected type',
\ ' IO ()',
\ '',
\ 'When checking an application of function Prelude.Monad.>>=:',
\ ' Type mismatch between',
\ ' IO () (Type of putStrLn _)',
\ ' and',
\ ' _ -> _ (Is putStrLn _ applied to too many arguments?)',
\ '',
\ ' Specifically:',
\ ' Type mismatch between',
\ ' IO',
\ ' and',
\ ' \uv => _ -> uv',
\ ])
Execute(The idris handler should parse messages that reference a column range):
call ale#test#SetFilename('/tmp/foo.idr')
AssertEqual
\ [
\ {
\ 'lnum': 11,
\ 'col': 11,
\ 'type': 'E',
\ 'text': 'When checking right hand side of Main.case block in main at /tmp/foo.idr:10:10 with expected type IO () Last statement in do block must be an expression'
\ }
\ ],
\ ale_linters#idris#idris#Handle(bufnr(''), [
\ expand('%:p') . ':11:11-13:',
\ 'When checking right hand side of Main.case block in main at /tmp/foo.idr:10:10 with expected type',
\ ' IO ()',
\ '',
\ 'Last statement in do block must be an expression',
\ ])

View File

@ -0,0 +1,54 @@
Before:
runtime ale_linters/inko/inko.vim
After:
call ale#linter#Reset()
Execute(The inko handler should parse errors correctly):
AssertEqual
\ [
\ {
\ 'filename': ale#path#Simplify('/tmp/foo.inko'),
\ 'lnum': 4,
\ 'col': 5,
\ 'text': 'this is an error',
\ 'type': 'E',
\ }
\ ],
\ ale#handlers#inko#Handle(bufnr(''), [
\ '[',
\ ' {',
\ ' "file": "/tmp/foo.inko",',
\ ' "line": 4,',
\ ' "column": 5,',
\ ' "message": "this is an error",',
\ ' "level": "error"',
\ ' }',
\ ']'
\ ])
Execute(The inko handler should parse warnings correctly):
AssertEqual
\ [
\ {
\ 'filename': ale#path#Simplify('/tmp/foo.inko'),
\ 'lnum': 4,
\ 'col': 5,
\ 'text': 'this is a warning',
\ 'type': 'W',
\ }
\ ],
\ ale#handlers#inko#Handle(bufnr(''), [
\ '[',
\ ' {',
\ ' "file": "/tmp/foo.inko",',
\ ' "line": 4,',
\ ' "column": 5,',
\ ' "message": "this is a warning",',
\ ' "level": "warning"',
\ ' }',
\ ']'
\ ])
Execute(The inko handler should handle empty output):
AssertEqual [], ale#handlers#inko#Handle(bufnr(''), [])

View File

@ -0,0 +1,90 @@
Before:
runtime ale_linters/ispc/ispc.vim
After:
call ale#linter#Reset()
Execute(The ispc handler should parse input correctly):
AssertEqual
\ [
\ {
\ 'bufnr': 0,
\ 'lnum': 33,
\ 'col': 14,
\ 'type': 'E',
\ 'text': 'syntax error, unexpected ''int'', expecting '','' or '';''.',
\ },
\ {
\ 'bufnr': 0,
\ 'lnum': 36,
\ 'col': 5,
\ 'type': 'E',
\ 'text': 'syntax error, unexpected ''for''.',
\ },
\ {
\ 'bufnr': 0,
\ 'lnum': 51,
\ 'col': 9,
\ 'type': 'E',
\ 'text': '''foobar.h'' file not found',
\ },
\ {
\ 'bufnr': 0,
\ 'lnum': 79,
\ 'col': 52,
\ 'type': 'W',
\ 'text': 'Modulus operator with varying types is very inefficient.',
\ },
\ {
\ 'bufnr': 0,
\ 'lnum': 85,
\ 'col': 13,
\ 'type': 'W',
\ 'text': 'Undefined behavior: all program instances are writing to the same location!',
\ },
\ {
\ 'bufnr': 0,
\ 'lnum': 93,
\ 'col': 19,
\ 'type': 'W',
\ 'text': 'Gather required to load value.',
\ },
\ {
\ 'bufnr': 0,
\ 'lnum': 93,
\ 'col': 9,
\ 'type': 'W',
\ 'text': 'Scatter required to store value.',
\ },
\ ],
\ ale_linters#ispc#ispc#Handle(0, [
\ 'Warning: No output file or header file name specified. Program will be compiled and warnings/errors will be issued, but no output will be generated. ',
\ 'Warning: No --target specified on command-line. Using default system target "avx2-i32x8".',
\ 'mandelbrot.ispc:33:14: Error: syntax error, unexpected ''int'', expecting '','' or '';''.',
\ 'static iline int mandel(float c_re, float c_im, int count) {',
\ ' ^^^',
\ '',
\ 'mandelbrot.ispc:36:5: Error: syntax error, unexpected ''for''.',
\ ' for (i = 0; i < count; ++i) {',
\ ' ^^^',
\ '',
\ 'mandelbrot.ispc:51:9: fatal error: ''foobar.h'' file not found',
\ '#include<foobar.h>',
\ ' ^~~~~~~~~~',
\ 'mandelbrot.ispc:79:52: Performance Warning: Modulus operator with varying types is very inefficient.',
\ ' double x = x0 + i * (dx + epsilon*(k%2)*delta);',
\ ' ^^^',
\ '',
\ 'mandelbrot.ispc:85:13: Warning: Undefined behavior: all program instances are writing to the same location!',
\ ' output[index] = (NNN) / sample_size;',
\ ' ^^^^^^^^^^^^^',
\ '',
\ 'mandelbrot.ispc:93:19: Performance Warning: Gather required to load value.',
\ ' A[i*8] *= A[i*8];',
\ ' ^^^^^^',
\ '',
\ 'mandelbrot.ispc:93:9: Performance Warning: Scatter required to store value.',
\ ' A[i*8] *= A[i*8];',
\ ' ^^^^^^',
\ '',
\ ])

View File

@ -0,0 +1,97 @@
Before:
runtime ale_linters/java/javac.vim
call ale#test#SetDirectory('/testplugin/test')
call ale#test#SetFilename('dummy.java')
After:
call ale#test#RestoreDirectory()
call ale#linter#Reset()
Execute(The javac handler should handle cannot find symbol errors):
AssertEqual
\ [
\ {
\ 'filename': ale#path#Simplify('/tmp/vLPr4Q5/33/foo.java'),
\ 'lnum': 1,
\ 'text': 'error: some error',
\ 'type': 'E',
\ },
\ {
\ 'filename': ale#path#Simplify('/tmp/vLPr4Q5/33/foo.java'),
\ 'lnum': 2,
\ 'col': 5,
\ 'text': 'error: cannot find symbol: BadName',
\ 'type': 'E',
\ },
\ {
\ 'filename': ale#path#Simplify('/tmp/vLPr4Q5/33/foo.java'),
\ 'lnum': 34,
\ 'col': 5,
\ 'text': 'error: cannot find symbol: BadName2',
\ 'type': 'E',
\ },
\ {
\ 'filename': ale#path#Simplify('/tmp/vLPr4Q5/33/foo.java'),
\ 'lnum': 37,
\ 'text': 'warning: some warning',
\ 'type': 'W',
\ },
\ {
\ 'filename': ale#path#Simplify('/tmp/vLPr4Q5/33/foo.java'),
\ 'lnum': 42,
\ 'col': 11,
\ 'text': 'error: cannot find symbol: bar()',
\ 'type': 'E',
\ },
\ {
\ 'filename': ale#path#Simplify('/tmp/vLPr4Q5/33/foo.java'),
\ 'lnum': 58,
\ 'col': 19,
\ 'text': 'error: incompatible types: Bar cannot be converted to Foo',
\ 'type': 'E',
\ },
\ ],
\ ale_linters#java#javac#Handle(bufnr(''), [
\ '/tmp/vLPr4Q5/33/foo.java:1: error: some error',
\ '/tmp/vLPr4Q5/33/foo.java:2: error: cannot find symbol',
\ ' BadName foo() {',
\ ' ^',
\ ' symbol: class BadName',
\ ' location: class Bar',
\ '/tmp/vLPr4Q5/33/foo.java:34: error: cannot find symbol',
\ ' BadName2 foo() {',
\ ' ^',
\ ' symbol: class BadName2',
\ ' location: class Bar',
\ '/tmp/vLPr4Q5/33/foo.java:37: warning: some warning',
\ '/tmp/vLPr4Q5/33/foo.java:42: error: cannot find symbol',
\ ' this.bar();',
\ ' ^',
\ ' symbol: method bar()',
\ '/tmp/vLPr4Q5/33/foo.java:58: error: incompatible types: Bar cannot be converted to Foo',
\ ' this.setFoo(bar);',
\ ' ^',
\ '6 errors',
\ ])
Execute(The javac handler should resolve files from different directories):
AssertEqual
\ [
\ {
\ 'filename': ale#path#Simplify(g:dir . '/Foo.java'),
\ 'lnum': 1,
\ 'text': 'error: some error',
\ 'type': 'E',
\ },
\ {
\ 'filename': ale#path#Simplify(g:dir . '/Bar.java'),
\ 'lnum': 1,
\ 'text': 'error: some error',
\ 'type': 'E',
\ },
\ ],
\ ale_linters#java#javac#Handle(bufnr(''), [
\ './Foo.java:1: error: some error',
\ './Bar.java:1: error: some error',
\ ])

View File

@ -0,0 +1,39 @@
Before:
runtime ale_linters/javascript/jscs.vim
After:
call ale#linter#Reset()
Execute(jscs should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 7,
\ 'text': 'Variable declarations should use `let` or `const` not `var`',
\ 'code': 'disallowVar',
\ },
\ {
\ 'lnum': 3,
\ 'col': 21,
\ 'text': 'Illegal trailing whitespace',
\ 'code': 'disallowTrailingWhitespace',
\ },
\ {
\ 'lnum': 5,
\ 'col': 9,
\ 'text': 'Variable `hello` is not used',
\ 'code': 'disallowUnusedVariables',
\ },
\ {
\ 'lnum': 2,
\ 'col': 1,
\ 'text': 'Expected indentation of 1 characters',
\ },
\ ],
\ ale_linters#javascript#jscs#Handle(347, [
\ 'foobar.js: line 1, col 7, disallowVar: Variable declarations should use `let` or `const` not `var`',
\ 'foobar.js: line 3, col 21, disallowTrailingWhitespace: Illegal trailing whitespace',
\ 'foobar.js: line 5, col 9, disallowUnusedVariables: Variable `hello` is not used',
\ 'foobar.js: line 2, col 1, Expected indentation of 1 characters',
\ ])

View File

@ -0,0 +1,21 @@
Before:
Save g:ale_kotlin_ktlint_rulesets
let g:ale_kotlin_ktlint_rulesets = []
After:
Restore
Execute(The ktlint handler method GetRulesets should properly parse custom rulesets):
let g:ale_kotlin_ktlint_rulesets = ['/path/to/custom/ruleset.jar', '/path/to/other/ruleset.jar']
AssertEqual
\ '--ruleset /path/to/custom/ruleset.jar --ruleset /path/to/other/ruleset.jar',
\ ale#handlers#ktlint#GetRulesets(bufnr(''))
Execute(The ktlint handler method GetRulesets should return an empty string when no rulesets have been configured):
let g:ale_kotlin_ktlint_rulesets = []
AssertEqual
\ '',
\ ale#handlers#ktlint#GetRulesets(bufnr(''))

View File

@ -0,0 +1,34 @@
Before:
runtime ale_linters/tex/lacheck.vim
call ale#test#SetDirectory('/testplugin/test/handler')
After:
call ale#linter#Reset()
call ale#test#RestoreDirectory()
Execute(The lacheck handler should parse lines correctly):
call ale#test#SetFilename('../test-files/tex/sample1.tex')
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'type': 'W',
\ 'text': 'perhaps you should insert a `~'' before "\ref"'
\ }
\ ],
\ ale_linters#tex#lacheck#Handle(bufnr(''), [
\ "** sample1:",
\ "\"sample1.tex\", line 1: perhaps you should insert a `~' before \"\\ref\""
\ ])
Execute(The lacheck handler should ignore errors from input files):
call ale#test#SetFilename('ale_test.tex')
AssertEqual
\ [
\ ],
\ ale_linters#tex#lacheck#Handle(255, [
\ "** ale_input:",
\ "\"ale_input.tex\", line 1: perhaps you should insert a `~' before \"\\ref\""
\ ])

View File

@ -0,0 +1,62 @@
Before:
runtime! ale_linters/text/languagetool.vim
After:
call ale#linter#Reset()
Execute(languagetool handler should report 3 errors):
AssertEqual
\ [
\ {
\ 'lnum': 3,
\ 'col': 19,
\ 'end_col': 20,
\ 'text': 'This sentence does not start with an uppercase letter',
\ 'type': 'W',
\ 'code': 'UPPERCASE_SENTENCE_START',
\ },
\ {
\ 'lnum': 3,
\ 'col': 36,
\ 'end_col': 42,
\ 'text': "Did you mean 'to see'?",
\ 'type': 'W',
\ 'code': 'TOO_TO[1]',
\ },
\ {
\ 'lnum': 3,
\ 'col': 44,
\ 'end_col': 45,
\ 'text': "Use 'a' instead of 'an' if the following word doesn't start with a vowel sound, e.g. 'a sentence', 'a university'",
\ 'type': 'W',
\ 'code': 'EN_A_VS_AN',
\ }
\ ],
\ ale#handlers#languagetool#HandleOutput(bufnr(''), [
\ '1.) Line 3, column 19, Rule ID: UPPERCASE_SENTENCE_START',
\ 'Message: This sentence does not start with an uppercase letter',
\ 'Suggestion: Or',
\ '...red phrases for details on potential errors. or use this text too see an few of of the probl...',
\ ' ^^ ',
\ '',
\ '2.) Line 3, column 36, Rule ID: TOO_TO[1]',
\ "Message: Did you mean 'to see'?",
\ 'Suggestion: to see',
\ '...etails on potential errors. or use this text too see an few of of the problems that LanguageTool ...',
\ ' ^^^^^^^ ',
\ '',
\ '3.) Line 3, column 44, Rule ID: EN_A_VS_AN',
\ "Message: Use 'a' instead of 'an' if the following word doesn't start with a vowel sound, e.g. 'a sentence', 'a university'",
\ 'Suggestion: a',
\ '...n potential errors. or use this text too see an few of of the problems that LanguageTool can...',
\ ' ^^ ',
\ 'Time: 2629ms for 8 sentences (3.0 sentences/sec)'
\ ])
Execute(languagetool handler should report no errors on empty input):
AssertEqual
\ [],
\ ale#handlers#languagetool#HandleOutput(bufnr(''), [
\ '',
\ 'Time: 2629ms for 8 sentences (3.0 sentences/sec)'
\ ])

View File

@ -0,0 +1,69 @@
Before:
call ale#test#SetDirectory('/testplugin/test/handler')
call ale#test#SetFilename('testfile.less')
runtime ale_linters/less/lessc.vim
After:
call ale#test#RestoreDirectory()
call ale#linter#Reset()
Execute(The lessc handler should handle errors for the current file correctly):
AssertEqual
\ [
\ {
\ 'lnum': 2,
\ 'col': 1,
\ 'type': 'E',
\ 'text': 'Unrecognised input. Possibly missing something',
\ },
\ ],
\ ale_linters#less#lessc#Handle(bufnr(''), [
\ 'ParseError: Unrecognised input. Possibly missing something in - on line 2, column 1:',
\ '1 vwewww',
\ '2 ',
\])
Execute(The lessc handler should handle errors for other files in the same directory correctly):
AssertEqual
\ [
\ {
\ 'lnum': 2,
\ 'col': 1,
\ 'type': 'E',
\ 'text': 'Unrecognised input. Possibly missing something',
\ 'filename': ale#path#Simplify(g:dir . '/imported.less')
\ },
\ {
\ 'lnum': 2,
\ 'col': 1,
\ 'type': 'E',
\ 'text': 'Unrecognised input. Possibly missing something',
\ 'filename': ale#path#Simplify(g:dir . '/imported.less')
\ },
\ ],
\ ale_linters#less#lessc#Handle(bufnr(''), [
\ 'ParseError: Unrecognised input. Possibly missing something in imported.less on line 2, column 1:',
\ '1 vwewww',
\ '2 ',
\ 'ParseError: Unrecognised input. Possibly missing something in ./imported.less on line 2, column 1:',
\ '1 vwewww',
\ '2 ',
\])
Execute(The lessc handler should handle errors for files in directories above correctly):
AssertEqual
\ [
\ {
\ 'lnum': 2,
\ 'col': 1,
\ 'type': 'E',
\ 'text': 'Unrecognised input. Possibly missing something',
\ 'filename': ale#path#Simplify(g:dir . '/../imported2.less')
\ },
\ ],
\ ale_linters#less#lessc#Handle(bufnr(''), [
\ 'ParseError: Unrecognised input. Possibly missing something in ../imported2.less on line 2, column 1:',
\ '1 vwewww',
\ '2 ',
\])

View File

@ -0,0 +1,58 @@
Before:
runtime! ale_linters/llvm/llc.vim
After:
call ale#linter#Reset()
Execute(llc handler should parse errors output for STDIN):
AssertEqual
\ [
\ {
\ 'lnum': 10,
\ 'col': 7,
\ 'text': "error: value doesn't match function result type 'i32'",
\ 'type': 'E',
\ },
\ {
\ 'lnum': 10,
\ 'col': 13,
\ 'text': "error: use of undefined value '@foo'",
\ 'type': 'E',
\ },
\ ],
\ ale_linters#llvm#llc#HandleErrors(bufnr(''), [
\ "llc: <stdin>:10:7: error: value doesn't match function result type 'i32'",
\ 'ret i64 0',
\ ' ^',
\ '',
\ "llc: <stdin>:10:13: error: use of undefined value '@foo'",
\ 'call void @foo(i64 %0)',
\ ' ^',
\ ])
Execute(llc handler should parse errors output for some file):
call ale#test#SetFilename('test.ll')
AssertEqual
\ [
\ {
\ 'lnum': 10,
\ 'col': 7,
\ 'text': "error: value doesn't match function result type 'i32'",
\ 'type': 'E',
\ },
\ {
\ 'lnum': 10,
\ 'col': 13,
\ 'text': "error: use of undefined value '@foo'",
\ 'type': 'E',
\ },
\ ],
\ ale_linters#llvm#llc#HandleErrors(bufnr(''), [
\ "llc: /path/to/test.ll:10:7: error: value doesn't match function result type 'i32'",
\ 'ret i64 0',
\ ' ^',
\ '',
\ "llc: /path/to/test.ll:10:13: error: use of undefined value '@foo'",
\ 'call void @foo(i64 %0)',
\ ' ^',
\ ])

View File

@ -0,0 +1,38 @@
Before:
runtime ale_linters/lua/selene.vim
After:
Restore
call ale#linter#Reset()
Execute(The selene handler for Lua should parse input correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'end_lnum': 2,
\ 'col': 1,
\ 'end_col': 3,
\ 'text': 'empty if block',
\ 'code': 'empty_if',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 1,
\ 'end_lnum': 1,
\ 'col': 4,
\ 'end_col': 11,
\ 'text': 'comparing things to nan directly is not allowed',
\ 'code': 'compare_nan',
\ 'type': 'E',
\ 'detail': "comparing things to nan directly is not allowed\n\ntry: `x ~= x` instead"
\ },
\ ],
\ ale_linters#lua#selene#Handle(0, [
\ '{"severity":"Warning","code":"empty_if","message":"empty if block","primary_label":{"span":{"start":0,"start_line":0,"start_column":0,"end":20,"end_line":1,"end_column":3},"message":""},"notes":[],"secondary_labels":[]}',
\ '{"severity":"Error","code":"compare_nan","message":"comparing things to nan directly is not allowed","primary_label":{"span":{"start":3,"start_line":0,"start_column":3,"end":11,"end_line":0,"end_column":11},"message":""},"notes":["try: `x ~= x` instead"],"secondary_labels":[]}',
\ 'Results:',
\ '1 errors',
\ '1 warnings',
\ '0 parse errors',
\ ])

View File

@ -0,0 +1,36 @@
Before:
Save g:ale_warn_about_trailing_whitespace
let g:ale_warn_about_trailing_whitespace = 1
runtime ale_linters/lua/luac.vim
After:
Restore
call ale#linter#Reset()
Execute(The luac handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'text': 'line contains trailing whitespace',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 3,
\ 'text': 'unexpected symbol near ''-''',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 5,
\ 'text': '''='' expected near '')''',
\ 'type': 'E',
\ },
\ ],
\ ale_linters#lua#luac#Handle(347, [
\ 'luac /file/path/here.lua:1: line contains trailing whitespace',
\ 'luac /file/path/here.lua:3: unexpected symbol near ''-''',
\ 'luac /file/path/here.lua:5: ''='' expected near '')''',
\ ])

View File

@ -0,0 +1,62 @@
Before:
Save g:ale_warn_about_trailing_whitespace
let g:ale_warn_about_trailing_whitespace = 1
runtime ale_linters/lua/luacheck.vim
After:
Restore
call ale#linter#Reset()
Execute(The luacheck handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'col': 8,
\ 'text': 'line contains trailing whitespace',
\ 'code': 'W612',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 3,
\ 'col': 5,
\ 'text': 'unused loop variable ''k''',
\ 'code': 'W213',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 3,
\ 'col': 19,
\ 'text': 'accessing undefined variable ''x''',
\ 'code': 'W113',
\ 'type': 'W',
\ },
\ ],
\ ale_linters#lua#luacheck#Handle(347, [
\ ' /file/path/here.lua:1:8: (W612) line contains trailing whitespace',
\ ' /file/path/here.lua:3:5: (W213) unused loop variable ''k''',
\ ' /file/path/here.lua:3:19: (W113) accessing undefined variable ''x''',
\ ])
Execute(The luacheck handler should respect the warn_about_trailing_whitespace option):
let g:ale_warn_about_trailing_whitespace = 0
AssertEqual
\ [
\ {
\ 'lnum': 5,
\ 'col': 43,
\ 'text': 'unused argument ''g''',
\ 'code': 'W212',
\ 'type': 'W',
\ }
\ ],
\ ale_linters#lua#luacheck#Handle(347, [
\ '/file/path/here.lua:15:97: (W614) trailing whitespace in a comment',
\ '/file/path/here.lua:16:60: (W612) line contains trailing whitespace',
\ '/file/path/here.lua:17:1: (W611) line contains only whitespace',
\ '/file/path/here.lua:27:57: (W613) trailing whitespace in a string',
\ '/file/path/here.lua:5:43: (W212) unused argument ''g''',
\ ])

View File

@ -0,0 +1,91 @@
Before:
runtime ale_linters/markdown/markdownlint.vim
After:
call ale#linter#Reset()
Execute(The Markdownlint handler should parse pre v0.19.0 output with single digit line correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'code': 'MD013/line-length',
\ 'text': 'Line length [Expected: 80; Actual: 114]',
\ 'type': 'W'
\ }
\ ],
\ ale#handlers#markdownlint#Handle(0, [
\ 'README.md: 1: MD013/line-length Line length [Expected: 80; Actual: 114]'
\ ])
Execute(The Markdownlint handler should parse pre v0.19.0 output with multi digit line correctly):
AssertEqual
\ [
\ {
\ 'lnum': 100,
\ 'code': 'MD013/line-length',
\ 'text': 'Line length [Expected: 80; Actual: 114]',
\ 'type': 'W'
\ }
\ ],
\ ale#handlers#markdownlint#Handle(0, [
\ 'README.md: 100: MD013/line-length Line length [Expected: 80; Actual: 114]'
\ ])
Execute(The Markdownlint handler should parse post v0.19.0 output with single digit line correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'code': 'MD013/line-length',
\ 'text': 'Line length [Expected: 80; Actual: 114]',
\ 'type': 'W'
\ }
\ ],
\ ale#handlers#markdownlint#Handle(0, [
\ 'README.md:1 MD013/line-length Line length [Expected: 80; Actual: 114]'
\ ])
Execute(The Markdownlint handler should parse post v0.19.0 output with multi digit line correctly):
AssertEqual
\ [
\ {
\ 'lnum': 100,
\ 'code': 'MD013/line-length',
\ 'text': 'Line length [Expected: 80; Actual: 114]',
\ 'type': 'W'
\ }
\ ],
\ ale#handlers#markdownlint#Handle(0, [
\ 'README.md:100 MD013/line-length Line length [Expected: 80; Actual: 114]'
\ ])
Execute(The Markdownlint handler should parse post v0.22.0 output with column correctly):
AssertEqual
\ [
\ {
\ 'lnum': 10,
\ 'col': 20,
\ 'code': 'MD013/line-length',
\ 'text': 'Line length [Expected: 80; Actual: 114]',
\ 'type': 'W'
\ }
\ ],
\ ale#handlers#markdownlint#Handle(0, [
\ 'README.md:10:20 MD013/line-length Line length [Expected: 80; Actual: 114]'
\ ])
Execute(The Markdownlint handler should parse output with multiple slashes in rule name correctly):
AssertEqual
\ [
\ {
\ 'lnum': 10,
\ 'code': 'MD022/blanks-around-headings/blanks-around-headers',
\ 'text': 'Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Above] [Context: "### something"]',
\ 'type': 'W'
\ }
\ ],
\ ale#handlers#markdownlint#Handle(0, [
\ 'README.md:10 MD022/blanks-around-headings/blanks-around-headers Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Above] [Context: "### something"]'
\ ])

View File

@ -0,0 +1,37 @@
Before:
runtime ale_linters/cs/mcs.vim
After:
call ale#linter#Reset()
Execute(The mcs handler should handle cannot find symbol errors):
AssertEqual
\ [
\ {
\ 'lnum': 12,
\ 'col' : 29,
\ 'text': '; expected',
\ 'code': 'CS1001',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 101,
\ 'col': 0,
\ 'text': 'Unexpected processor directive (no #if for this #endif)',
\ 'code': 'CS1028',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 10,
\ 'col': 12,
\ 'text': 'some warning',
\ 'code': 'CS0123',
\ 'type': 'W',
\ },
\ ],
\ ale_linters#cs#mcs#Handle(347, [
\ 'Tests.cs(12,29): error CS1001: ; expected',
\ 'Tests.cs(101,0): error CS1028: Unexpected processor directive (no #if for this #endif)',
\ 'Tests.cs(10,12): warning CS0123: some warning',
\ 'Compilation failed: 2 error(s), 1 warnings',
\ ])

View File

@ -0,0 +1,88 @@
Before:
Save g:ale_cs_mcsc_source
unlet! g:ale_cs_mcsc_source
call ale#test#SetDirectory('/testplugin/test/handler')
call ale#test#SetFilename('Test.cs')
runtime ale_linters/cs/mcsc.vim
After:
unlet! g:ale_cs_mcsc_source
call ale#test#RestoreDirectory()
call ale#linter#Reset()
Execute(The mcs handler should work with the default of the buffer's directory):
AssertEqual
\ [
\ {
\ 'lnum': 12,
\ 'col' : 29,
\ 'text': '; expected',
\ 'code': 'CS1001',
\ 'type': 'E',
\ 'filename': ale#path#Simplify(g:dir . '/Test.cs'),
\ },
\ ],
\ ale_linters#cs#mcsc#Handle(bufnr(''), [
\ 'Test.cs(12,29): error CS1001: ; expected',
\ 'Compilation failed: 2 error(s), 1 warnings',
\ ])
Execute(The mcs handler should handle cannot find symbol errors):
let g:ale_cs_mcsc_source = '/home/foo/project/bar'
AssertEqual
\ [
\ {
\ 'lnum': 12,
\ 'col' : 29,
\ 'text': '; expected',
\ 'code': 'CS1001',
\ 'type': 'E',
\ 'filename': ale#path#Simplify('/home/foo/project/bar/Test.cs'),
\ },
\ {
\ 'lnum': 101,
\ 'col': 0,
\ 'text': 'Unexpected processor directive (no #if for this #endif)',
\ 'code': 'CS1028',
\ 'type': 'E',
\ 'filename': ale#path#Simplify('/home/foo/project/bar/Test.cs'),
\ },
\ {
\ 'lnum': 10,
\ 'col': 12,
\ 'text': 'some warning',
\ 'code': 'CS0123',
\ 'type': 'W',
\ 'filename': ale#path#Simplify('/home/foo/project/bar/Test.cs'),
\ },
\ ],
\ ale_linters#cs#mcsc#Handle(bufnr(''), [
\ 'Test.cs(12,29): error CS1001: ; expected',
\ 'Test.cs(101,0): error CS1028: Unexpected processor directive (no #if for this #endif)',
\ 'Test.cs(10,12): warning CS0123: some warning',
\ 'Compilation failed: 2 error(s), 1 warnings',
\ ])
Execute(The mcsc handler should handle non file specific compiler errors without reporting overal status report as error):
let g:ale_cs_mcsc_source = '/home/foo/project/bar'
AssertEqual
\ [
\ {
\ 'lnum': -1,
\ 'col' : -1,
\ 'text': 'No files to compile were specified',
\ 'code': 'CS2008',
\ 'type': 'E',
\ 'filename': '<mcs>',
\ },
\ ],
\ ale_linters#cs#mcsc#Handle(bufnr(''), [
\ 'error CS2008: No files to compile were specified',
\ 'Compilation failed: 1 error(s), 0 warnings',
\ ])

View File

@ -0,0 +1,25 @@
Before:
runtime ale_linters/markdown/mdl.vim
After:
call ale#linter#Reset()
Execute(The mdl handler should parse output correctly):
AssertEqual
\ [
\ {
\ 'lnum': 1,
\ 'code': 'MD002/first-header-h1',
\ 'text': 'First header should be a top level header',
\ 'type': 'W'
\ },
\ {
\ 'lnum': 18,
\ 'code': 'MD033/no-inline-html',
\ 'text': 'Inline HTML',
\ 'type': 'W'
\ }
\ ],
\ ale_linters#markdown#mdl#Handle(0, [
\ '[{"filename":"README.md","line":1,"rule":"MD002","aliases":["first-header-h1"],"description":"First header should be a top level header"},{"filename":"README.md","line":18,"rule":"MD033","aliases":["no-inline-html"],"description":"Inline HTML"}]'
\ ])

View File

@ -0,0 +1,58 @@
Before:
runtime ale_linters/mercury/mmc.vim
After:
call ale#linter#Reset()
Execute(The mmc handler should handle syntax errors):
AssertEqual
\ [
\ {
\ 'lnum': 3,
\ 'type': 'E',
\ 'text': "Syntax error at token ',': operator precedence error."
\ }
\ ],
\ ale_linters#mercury#mmc#Handle(1, [
\ "file_name.m:003: Syntax error at token ',': operator precedence error."
\ ])
Execute(The mmc handler should handle warnings):
AssertEqual
\ [
\ {
\ 'lnum': 10,
\ 'type': 'W',
\ 'text': 'Warning: reference to uninitialized state variable !.X.'
\ },
\ {
\ 'lnum': 12,
\ 'type': 'W',
\ 'text': 'warning: determinism declaration could be tighter.'
\ }
\ ],
\ ale_linters#mercury#mmc#Handle(1, [
\ 'file_name.m:010: Warning: reference to uninitialized state variable !.X.',
\ "file_name.m:012: In `some_predicate':",
\ 'file_name.m:012: warning: determinism declaration could be tighter.'
\ ])
Execute(The mmc handler should handle semantic errors):
AssertEqual
\ [
\ {
\ 'lnum': 7,
\ 'type': 'E',
\ 'text': "error: undefined type `bar'/0."
\ },
\ {
\ 'lnum': 15,
\ 'type': 'E',
\ 'text': "Error: circular equivalence type `file_name.foo'/0."
\ }
\ ],
\ ale_linters#mercury#mmc#Handle(1, [
\ "file_name.m:007: In clause for predicate `foldit'/4:",
\ "file_name.m:007: error: undefined type `bar'/0.",
\ "file_name.m:015: Error: circular equivalence type `file_name.foo'/0."
\ ])

View File

@ -0,0 +1,21 @@
Before:
runtime ale_linters/elixir/mix.vim
After:
call ale#linter#Reset()
Execute(The mix handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'bufnr': 347,
\ 'lnum': 87,
\ 'col': 0,
\ 'text': 'undefined function update_in/4',
\ 'type': 'E',
\ },
\ ],
\ ale_linters#elixir#mix#Handle(347, [
\ '** (CompileError) apps/sim/lib/sim/server.ex:87: undefined function update_in/4'
\ ])

View File

@ -0,0 +1,24 @@
Before:
runtime ale_linters/po/msgfmt.vim
After:
call ale#linter#Reset()
Execute(Duplicate messages should be made easier to navigate):
AssertEqual
\ [
\ {'lnum': 14, 'col': 0, 'type': 'W', 'text': 'some other thing'},
\ {'lnum': 1746, 'col': 0, 'type': 'W', 'text': 'duplicate of message at line 262'},
\ {'lnum': 262, 'col': 0, 'type': 'W', 'text': 'first location of duplicate of message at line 1746'},
\ {'lnum': 666, 'col': 0, 'type': 'W', 'text': 'duplicate message definition...'},
\ {'lnum': 888, 'col': 0, 'type': 'W', 'text': 'some other thing'},
\ {'lnum': 999, 'col': 0, 'type': 'W', 'text': '...this is the location of the first definition'},
\ ],
\ ale_linters#po#msgfmt#Handle(bufnr(''), [
\ '/tmp/v6GMUFf/16/foo.po:14: some other thing',
\ '/tmp/v6GMUFf/16/foo.po:1746: duplicate message definition...',
\ '/tmp/v6GMUFf/16/foo.po:262: ...this is the location of the first definition',
\ '/tmp/v6GMUFf/16/foo.po:666: duplicate message definition...',
\ '/tmp/v6GMUFf/16/foo.po:888: some other thing',
\ '/tmp/v6GMUFf/16/foo.po:999: ...this is the location of the first definition',
\ ])

View File

@ -0,0 +1,141 @@
Before:
Save g:ale_python_mypy_ignore_invalid_syntax
Save g:ale_python_mypy_show_notes
unlet! g:ale_python_mypy_show_notes
unlet! g:ale_python_mypy_ignore_invalid_syntax
runtime ale_linters/python/mypy.vim
call ale#test#SetDirectory('/testplugin/test/handler')
After:
Restore
call ale#test#RestoreDirectory()
call ale#linter#Reset()
Execute(The mypy handler should parse lines correctly):
call ale#test#SetFilename('__init__.py')
let g:ale_python_mypy_show_notes = 0
AssertEqual
\ [
\ {
\ 'lnum': 768,
\ 'col': 38,
\ 'filename': ale#path#Simplify(g:dir . '/baz.py'),
\ 'type': 'E',
\ 'text': 'Cannot determine type of ''SOME_SYMBOL''',
\ },
\ {
\ 'lnum': 821,
\ 'col': 38,
\ 'filename': ale#path#Simplify(g:dir . '/baz.py'),
\ 'type': 'E',
\ 'text': 'Cannot determine type of ''SOME_SYMBOL''',
\ },
\ {
\ 'lnum': 38,
\ 'col': 44,
\ 'filename': ale#path#Simplify(g:dir . '/other.py'),
\ 'type': 'E',
\ 'text': 'Cannot determine type of ''ANOTHER_SYMBOL''',
\ },
\ {
\ 'lnum': 15,
\ 'col': 3,
\ 'filename': ale#path#Simplify(g:dir . '/__init__.py'),
\ 'type': 'E',
\ 'text': 'Argument 1 to "somefunc" has incompatible type "int"; expected "str"'
\ },
\ {
\ 'lnum': 72,
\ 'col': 1,
\ 'filename': ale#path#Simplify(g:dir . '/__init__.py'),
\ 'type': 'W',
\ 'text': 'Some warning',
\ },
\ ],
\ ale_linters#python#mypy#Handle(bufnr(''), [
\ 'baz.py: note: In class "SomeClass":',
\ 'baz.py:768:38: error: Cannot determine type of ''SOME_SYMBOL''',
\ 'baz.py: note: In class "AnotherClass":',
\ 'baz.py:821:38: error: Cannot determine type of ''SOME_SYMBOL''',
\ '__init__.py:92: note: In module imported here:',
\ 'other.py: note: In class "YetAnotherClass":',
\ 'other.py:38:44: error: Cannot determine type of ''ANOTHER_SYMBOL''',
\ '__init__.py: note: At top level:',
\ '__init__.py:15:3: error: Argument 1 to "somefunc" has incompatible type "int"; expected "str"',
\ 'another_module/bar.py:14: note: In module imported here,',
\ 'another_module/__init__.py:16: note: ... from here,',
\ '__init__.py:72:1: warning: Some warning',
\ ])
Execute(The mypy handler should show notes if enabled):
call ale#test#SetFilename('__init__.py')
AssertEqual
\ [
\ {
\ 'lnum': 72,
\ 'col': 1,
\ 'filename': ale#path#Simplify(g:dir . '/__init__.py'),
\ 'type': 'I',
\ 'text': 'A note',
\ },
\ ],
\ ale_linters#python#mypy#Handle(bufnr(''), [
\ '__init__.py:72:1: note: A note',
\ ])
let g:ale_python_mypy_show_notes = 0
AssertEqual
\ [],
\ ale_linters#python#mypy#Handle(bufnr(''), [
\ '__init__.py:72:1: note: A note',
\ ])
Execute(The mypy handler should handle Windows names with spaces):
" This test works on Unix, where this is seen as a single filename
silent file C:\\something\\with\ spaces.py
AssertEqual
\ [
\ {
\ 'lnum': 4,
\ 'col': 0,
\ 'filename': ale#path#Simplify('C:\something\with spaces.py'),
\ 'type': 'E',
\ 'text': 'No library stub file for module ''django.db''',
\ },
\ ],
\ ale_linters#python#mypy#Handle(bufnr(''), [
\ 'C:\something\with spaces.py:4: error: No library stub file for module ''django.db''',
\ ])
Execute(The mypy syntax errors shouldn't be ignored by default):
AssertEqual
\ [
\ {
\ 'lnum': 4,
\ 'col': 0,
\ 'filename': ale#path#Simplify(g:dir . '/foo.py'),
\ 'type': 'E',
\ 'text': 'invalid syntax',
\ },
\ ],
\ ale_linters#python#mypy#Handle(bufnr(''), [
\ 'foo.py:4: error: invalid syntax',
\ ])
Execute(The mypy syntax errors should be ignored when the option is on):
let g:ale_python_mypy_ignore_invalid_syntax = 1
AssertEqual
\ [],
\ ale_linters#python#mypy#Handle(bufnr(''), [
\ 'foo.py:4: error: invalid syntax',
\ ])

View File

@ -0,0 +1,23 @@
Before:
runtime ale_linters/wgsl/naga.vim
After:
call ale#linter#Reset()
Execute(Error handler should parse error message and position from input):
let example_output = [
\ "error: expected global item ('struct', 'let', 'var', 'type', ';', 'fn') or the end of the file, found '['",
\ " ┌─ wgsl:5:1",
\ " │",
\ "5 │ [[group(1), binding(0)]]",
\ " │ ^ expected global item ('struct', 'let', 'var', 'type', ';', 'fn') or the end of the file",
\ "Could not parse WGSL",
\ ]
let actual = ale#handlers#naga#Handle(0, example_output)
let expected = [{
\ "text": "expected global item ('struct', 'let', 'var', 'type', ';', 'fn') or the end of the file, found '['",
\ "lnum": 5,
\ "col": 1,
\ "type": "E",
\ }]
AssertEqual actual, expected

View File

@ -0,0 +1,174 @@
Before:
runtime ale_linters/tcl/nagelfar.vim
After:
call ale#linter#Reset()
Execute(The nagelfar handler should parse lines correctly):
AssertEqual
\ [
\ {
\ 'lnum': 5,
\ 'type': 'W',
\ 'text': 'Found constant "bepa" which is also a variable.'
\ },
\ {
\ 'lnum': 7,
\ 'type': 'E',
\ 'text': 'Unknown variable "cep"'
\ },
\ {
\ 'lnum': 7,
\ 'type': 'W',
\ 'text': 'Unknown command "se"'
\ },
\ {
\ 'lnum': 8,
\ 'type': 'E',
\ 'text': 'Unknown variable "epa"'
\ },
\ {
\ 'lnum': 10,
\ 'type': 'E',
\ 'text': 'Unknown variable "depa"'
\ },
\ {
\ 'lnum': 10,
\ 'type': 'W',
\ 'text': 'Suspicious variable name "$depa"'
\ },
\ {
\ 'lnum': 11,
\ 'type': 'W',
\ 'text': 'Suspicious variable name "$cepa"'
\ },
\ {
\ 'lnum': 13,
\ 'type': 'E',
\ 'text': 'Wrong number of arguments (3) to "set"'
\ },
\ {
\ 'lnum': 13,
\ 'type': 'W',
\ 'text': 'Found constant "bepa" which is also a variable.'
\ },
\ {
\ 'lnum': 13,
\ 'type': 'W',
\ 'text': 'Found constant "cepa" which is also a variable.'
\ },
\ {
\ 'lnum': 18,
\ 'type': 'E',
\ 'text': 'Badly formed if statement'
\ },
\ {
\ 'lnum': 24,
\ 'type': 'E',
\ 'text': 'Unknown subcommand "gurka" to "info"'
\ },
\ {
\ 'lnum': 31,
\ 'type': 'W',
\ 'text': 'Switch pattern starting with #. This could be a bad comment.'
\ },
\ {
\ 'lnum': 31,
\ 'type': 'W',
\ 'text': 'Unknown command "This"'
\ },
\ {
\ 'lnum': 31,
\ 'type': 'W',
\ 'text': 'Unknown command "bad"'
\ },
\ {
\ 'lnum': 34,
\ 'type': 'W',
\ 'text': 'Unknown command "miffo"'
\ },
\ {
\ 'lnum': 55,
\ 'type': 'W',
\ 'text': 'Suspicious variable name "$bepa"'
\ },
\ {
\ 'lnum': 56,
\ 'type': 'W',
\ 'text': 'Suspicious variable name "$apa"'
\ },
\ {
\ 'lnum': 61,
\ 'type': 'E',
\ 'text': 'Could not complete statement.'
\ },
\ {
\ 'lnum': 67,
\ 'type': 'E',
\ 'text': 'Could not complete statement.'
\ },
\ {
\ 'lnum': 70,
\ 'type': 'E',
\ 'text': 'Wrong number of arguments (4) to "proc"'
\ },
\ {
\ 'lnum': 72,
\ 'type': 'E',
\ 'text': 'Wrong number of arguments (1) to "if"'
\ },
\ {
\ 'lnum': 75,
\ 'type': 'E',
\ 'text': 'Unbalanced close brace found'
\ },
\ {
\ 'lnum': 82,
\ 'type': 'E',
\ 'text': 'Unbalanced close brace found'
\ },
\ {
\ 'lnum': 88,
\ 'type': 'E',
\ 'text': 'Could not complete statement.'
\ },
\ {
\ 'lnum': 90,
\ 'type': 'E',
\ 'text': 'Wrong number of arguments (1) to "if"'
\ },
\ {
\ 'lnum': 93,
\ 'type': 'W',
\ 'text': 'Close brace not aligned with line 90 (4 0)'
\ },
\ ],
\ ale_linters#tcl#nagelfar#Handle(bufnr(''), [
\ 'Line 5: W Found constant "bepa" which is also a variable.',
\ 'Line 7: E Unknown variable "cep"',
\ 'Line 7: W Unknown command "se"',
\ 'Line 8: E Unknown variable "epa"',
\ 'Line 10: E Unknown variable "depa"',
\ 'Line 10: N Suspicious variable name "$depa"',
\ 'Line 11: N Suspicious variable name "$cepa"',
\ 'Line 13: E Wrong number of arguments (3) to "set"',
\ 'Line 13: W Found constant "bepa" which is also a variable.',
\ 'Line 13: W Found constant "cepa" which is also a variable.',
\ 'Line 18: E Badly formed if statement',
\ 'Line 24: E Unknown subcommand "gurka" to "info"',
\ 'Line 31: W Switch pattern starting with #. This could be a bad comment.',
\ 'Line 31: W Unknown command "This"',
\ 'Line 31: W Unknown command "bad"',
\ 'Line 34: W Unknown command "miffo"',
\ 'Line 55: N Suspicious variable name "$bepa"',
\ 'Line 56: N Suspicious variable name "$apa"',
\ 'Line 61: E Could not complete statement.',
\ 'Line 67: E Could not complete statement.',
\ 'Line 70: E Wrong number of arguments (4) to "proc"',
\ 'Line 72: E Wrong number of arguments (1) to "if"',
\ 'Line 75: E Unbalanced close brace found',
\ 'Line 82: E Unbalanced close brace found',
\ 'Line 88: E Could not complete statement.',
\ 'Line 90: E Wrong number of arguments (1) to "if"',
\ 'Line 93: N Close brace not aligned with line 90 (4 0)',
\ ])

View File

@ -0,0 +1,30 @@
Before:
runtime ale_linters/nasm/nasm.vim
After:
call ale#linter#Reset()
Execute(The nasm handler should parse GCC style output from nasm correctly):
AssertEqual
\ [
\ {
\ 'lnum': 2,
\ 'text': "label alone on a line without a colon might be in error",
\ 'type': 'W',
\ },
\ {
\ 'lnum': 4,
\ 'text': "invalid combination of opcode and operands",
\ 'type': 'E',
\ },
\ {
\ 'lnum': 7,
\ 'text': "unable to open include file `bar.asm'",
\ 'type': 'E',
\ },
\ ],
\ ale_linters#nasm#nasm#Handle(bufnr(''), [
\ "tmp.asm:2: warning: label alone on a line without a colon might be in error",
\ "tmp.asm:4: error: invalid combination of opcode and operands",
\ "tmp.asm:7: fatal: unable to open include file `bar.asm'"
\ ])

View File

@ -0,0 +1,80 @@
Before:
runtime ale_linters/nim/nimcheck.vim
After:
call ale#linter#Reset()
Execute(Parsing nim errors should work):
silent file foobar.nim
AssertEqual
\ [
\ {
\ 'lnum': 8,
\ 'col': 8,
\ 'text': 'use {.base.} for base methods; baseless methods are deprecated',
\ 'code': 'UseBase',
\ 'type': 'W',
\ },
\ {
\ 'lnum': 12,
\ 'col': 2,
\ 'text': 'identifier expected, but found ''a.barfoo''',
\ 'type': 'E',
\ 'end_col': 9,
\ },
\ {
\ 'lnum': 2,
\ 'col': 5,
\ 'text': '''NotUsed'' is declared but not used',
\ 'code': 'XDeclaredButNotUsed',
\ 'type': 'W',
\ 'end_col': 11,
\ },
\ {
\ 'lnum': 12,
\ 'col': 2,
\ 'text': 'with : character',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 1,
\ 'col': 8,
\ 'text': 'imported and not used: ''strutils''',
\ 'code': 'UnusedImport',
\ 'type': 'W',
\ 'end_col': 15,
\ },
\ {
\ 'lnum': 12,
\ 'col': 9,
\ 'text': 'undeclared identifier: ''total''',
\ 'type': 'E',
\ 'end_col': 13,
\ },
\ {
\ 'lnum': 14,
\ 'col': 1,
\ 'text': '''sum'' cannot be assigned to',
\ 'type': 'E',
\ 'end_col': 3,
\ },
\ {
\ 'lnum': 15,
\ 'col': 1,
\ 'text': 'redefinition of ''getName''; previous declaration here: /nested/folder/foobar.nim(14, 6)',
\ 'type': 'E',
\ 'end_col': 7,
\ },
\ ],
\ ale_linters#nim#nimcheck#Handle(bufnr(''), [
\ 'Line with wrong( format)',
\ 'foobar.nim(8, 8) Warning: use {.base.} for base methods; baseless methods are deprecated [UseBase]',
\ 'foobar.nim(12, 2) Error: identifier expected, but found ''a.barfoo''',
\ '/nested/folder/foobar.nim(2, 5) Hint: ''NotUsed'' is declared but not used [XDeclaredButNotUsed]',
\ 'foobar.nim(12, 2) Error: with : character',
\ 'foobar.nim(1, 8) Warning: imported and not used: ''strutils'' [UnusedImport]',
\ 'foobar.nim(12, 9) Error: undeclared identifier: ''total''',
\ 'foobar.nim(14, 1) Error: ''sum'' cannot be assigned to',
\ 'foobar.nim(15, 1) Error: redefinition of ''getName''; previous declaration here: /nested/folder/foobar.nim(14, 6)',
\ ])

View File

@ -0,0 +1,91 @@
Before:
runtime ale_linters/nix/nix.vim
After:
call ale#linter#Reset()
Execute(The nix handler should parse nix-instantiate error messages correctly):
AssertEqual
\ [
\ {
\ 'lnum': 6,
\ 'col': 3,
\ 'type': 'E',
\ 'text': "syntax error, unexpected ']', expecting ';'",
\ },
\ {
\ 'lnum': 3,
\ 'col': 5,
\ 'type': 'E',
\ 'text': "undefined variable 'foo'",
\ },
\
\ ],
\ ale_linters#nix#nix#Handle(bufnr(''), [
\ "@nix {\"line\":6,\"column\":3,\"raw_msg\":\"syntax error, unexpected ']', expecting ';'\"}",
\ "@nix {\"line\":3,\"column\":5,\"raw_msg\":\"undefined variable 'foo'\"}",
\ "@nix {\"unrelated\":\"message\"}"
\ ])
Execute(The nix handler should parse message from old nix-instantiate correctly):
AssertEqual
\ [
\ {
\ 'lnum': 23,
\ 'col': 14,
\ 'text': 'error: syntax error, unexpected IN',
\ 'type': 'E',
\ },
\ {
\ 'lnum': 3,
\ 'col': 12,
\ 'text': 'error: syntax error, unexpected ''='', expecting '';''',
\ 'type': 'E',
\ },
\
\ ],
\ ale_linters#nix#nix#Handle(47, [
\ 'This line should be ignored',
\ 'error: syntax error, unexpected IN, at /path/to/filename.nix:23:14',
\ 'error: syntax error, unexpected ''='', expecting '';'', at /path/to/filename.nix:3:12',
\ ])
Execute(The nix command should not add 'log-format' option for nix version 2.3):
AssertEqual
\ 'nix-instantiate --parse -',
\ ale_linters#nix#nix#Command('', ['nix-instantiate (Nix) 2.3.0'], '')
Execute(The nix command should add 'log-format' option for nix version 2.4):
AssertEqual
\ 'nix-instantiate --log-format internal-json --parse -',
\ ale_linters#nix#nix#Command('', ['nix-instantiate (Nix) 2.4.1'], '')
Execute(The nix command should add 'log-format' option for nix version 2.5):
AssertEqual
\ 'nix-instantiate --log-format internal-json --parse -',
\ ale_linters#nix#nix#Command('', ['nix-instantiate (Nix) 2.5.0pre20211206_d1aaa7e'], '')
Execute(The nix command should add 'log-format' option for nix version 2.6):
AssertEqual
\ 'nix-instantiate --log-format internal-json --parse -',
\ ale_linters#nix#nix#Command('', ['nix-instantiate (Nix) 2.6.0pre20211206_ignored'], '')
Execute(The nix command should add 'log-format' option for nix version 2.7):
AssertEqual
\ 'nix-instantiate --log-format internal-json --parse -',
\ ale_linters#nix#nix#Command('', ['nix-instantiate (Nix) 2.7.0pre20211206_ignored'], '')
Execute(The nix command should add 'log-format' option for nix version 2.8):
AssertEqual
\ 'nix-instantiate --log-format internal-json --parse -',
\ ale_linters#nix#nix#Command('', ['nix-instantiate (Nix) 2.8.0pre20211206_ignored'], '')
Execute(The nix command should add 'log-format' option for nix version 2.9):
AssertEqual
\ 'nix-instantiate --log-format internal-json --parse -',
\ ale_linters#nix#nix#Command('', ['nix-instantiate (Nix) 2.9.0pre20211206_ignored'], '')
Execute(The nix command should add 'log-format' option for nix version 3.0):
AssertEqual
\ 'nix-instantiate --log-format internal-json --parse -',
\ ale_linters#nix#nix#Command('', ['nix-instantiate (Nix) 3.0.0pre20211206_ignored'], '')

View File

@ -0,0 +1,277 @@
Before:
call ale#test#SetDirectory('/testplugin/test/handler')
runtime ale_linters/perl6/perl6.vim
After:
call ale#test#RestoreDirectory()
call ale#linter#Reset()
Execute(The Perl6 linter should handle empty output):
call ale#test#SetFilename('bar.pl6')
AssertEqual [], ale_linters#perl6#perl6#Handle(bufnr(''), [])
Execute(The Perl6 linter should complain about undeclared variables):
call ale#test#SetFilename('bar.pl6')
AssertEqual
\ [
\ {
\ 'lnum': '6',
\ 'text': 'Variable ''$tes'' is not declared. Did you mean any of these? $res $test ',
\ 'type': 'E',
\ 'col': '',
\ 'end_lnum': '',
\ 'code': 'X::Undeclared',
\ }
\ ],
\ ale_linters#perl6#perl6#Handle(bufnr(''), [
\ '{
\ "X::Undeclared" : {
\ "highexpect" : [ ],
\ "is-compile-time" : 1,
\ "modules" : [ ],
\ "column" : null,
\ "pos" : 18,
\ "symbol" : "$tes",
\ "filename" : "bar.pl6",
\ "what" : "Variable",
\ "pre" : "my $test = 0; say ",
\ "post" : "$tes",
\ "suggestions" : [
\ "$res",
\ "$test"
\ ],
\ "line" : 6,
\ "message" : "Variable ''$tes'' is not declared. Did you mean any of these?\n $res\n $test\n"
\ }
\ }'
\ ])
Execute(The Perl6 linter should complain about Comp::AdHoc errors):
call ale#test#SetFilename('bar.pl6')
AssertEqual
\ [
\ {
\ 'lnum': '3',
\ 'type': 'E',
\ 'text': 'is repr(...) trait needs a parameter',
\ 'col': '',
\ 'end_lnum': '',
\ 'code': 'X::Comp::AdHoc',
\ }
\ ],
\ ale_linters#perl6#perl6#Handle(bufnr(''), [
\ '{
\ "X::Comp::AdHoc" : {
\ "pre" : "class test is repr",
\ "message" : "is repr(...) trait needs a parameter",
\ "line" : 3,
\ "post" : " {}",
\ "is-compile-time" : true,
\ "pos" : 19,
\ "highexpect" : [ ],
\ "payload" : "is repr(...) trait needs a parameter",
\ "filename" : "bar.pl6",
\ "column" : null,
\ "modules" : [ ]
\ }
\ }'
\])
Execute(The Perl6 linter should be able to extract a line number from an error message):
call ale#test#SetFilename('bar.pl6')
AssertEqual
\ [
\ {
\ 'lnum': '3',
\ 'text': 'Could not find Module::Does::not::exist at line 3 in: /usr/share/perl6/site /usr/share/perl6/vendor /usr/share/perl6 CompUnit::Repository::AbsolutePath<94023691448416> CompUnit::Repository::NQP<94023670532736> CompUnit::Repository::Perl5<94023670532776>',
\ 'col': '',
\ 'type': 'E',
\ 'end_lnum': '',
\ 'code': 'X::CompUnit::UnsatisfiedDependency',
\ }
\ ],
\ ale_linters#perl6#perl6#Handle(bufnr(''), [
\ '{
\ "X::CompUnit::UnsatisfiedDependency" : {
\ "message" : "Could not find Module::Does::not::exist at line 3 in:\n /usr/share/perl6/site\n /usr/share/perl6/vendor\n /usr/share/perl6\n CompUnit::Repository::AbsolutePath<94023691448416>\n CompUnit::Repository::NQP<94023670532736>\n CompUnit::Repository::Perl5<94023670532776>",
\ "specification" : "Module::Does::not::exist"
\ }
\ }'
\ ])
Execute(The Perl6 linter should be able to differentiate between warnings and errors):
call ale#test#SetFilename('bar.pl6')
AssertEqual
\ [
\ {
\ 'lnum': '1',
\ 'col': '',
\ 'code': 'X::Syntax::Regex::Unterminated',
\ 'end_lnum': '',
\ 'type': 'E',
\ 'text': 'Regex not terminated.',
\ },
\ {
\ 'lnum': '1',
\ 'col': '',
\ 'code': 'X::Comp::AdHoc',
\ 'end_lnum': '',
\ 'type': 'W',
\ 'text': 'Space is not significant here; please use quotes or :s (:sigspace) modifier (or, to suppress this warning, omit the space, or otherwise change the spacing)',
\ }
\ ],
\ ale_linters#perl6#perl6#Handle(bufnr(''), [
\ '{
\ "X::Comp::Group" : {
\ "message" : "Regex not terminated.\nUnable to parse regex; couldn''t find final ''/''\nSpace is not significant here; please use quotes or :s (:sigspace) modifier (or, to suppress this warning, omit the space, or otherwise change the spacing)",
\ "panic" : "Unable to parse regex; couldn''t find final ''/''",
\ "sorrows" : [
\ {
\ "X::Syntax::Regex::Unterminated" : {
\ "highexpect" : [
\ "infix stopper"
\ ],
\ "pos" : 6,
\ "is-compile-time" : 1,
\ "modules" : [ ],
\ "post" : "<EOL>",
\ "message" : "Regex not terminated.",
\ "line" : 1,
\ "filename" : "bar.pl6",
\ "column" : null,
\ "pre" : "/win 3"
\ }
\ }
\ ],
\ "worries" : [
\ {
\ "X::Comp::AdHoc" : {
\ "filename" : "bar.pl6",
\ "line" : 1,
\ "column" : null,
\ "pre" : "/win",
\ "highexpect" : [ ],
\ "payload" : "Space is not significant here; please use quotes or :s (:sigspace) modifier (or, to suppress this warning, omit the space, or otherwise change the spacing)",
\ "post" : " 3",
\ "message" : "Space is not significant here; please use quotes or :s (:sigspace) modifier (or, to suppress this warning, omit the space, or otherwise change the spacing)",
\ "modules" : [ ],
\ "is-compile-time" : true,
\ "pos" : 4
\ }
\ }
\ ]
\ }
\ }'
\])
Execute(The Perl6 linter should gracefully handle non-JSON messages):
call ale#test#SetFilename('bar.pl6')
AssertEqual
\ [
\ {
\ 'lnum': '1',
\ 'text': 'Received output in the default Perl6 error format. See :ALEDetail for details',
\ 'type': 'W',
\ 'detail': join([
\ 'Potential difficulties:',
\ ' Redeclaration of symbol ''$_''',
\ ' at /home/travis/perl6-error-fail/insanity-test.pl6:1',
\ ' ------> sub foo($_) {.say}; my $_<HERE> = 1; .&foo;',
\ ' Space is not significant here; please use quotes or :s (:sigspace) modifier (or, to suppress this warning, omit the space, or otherwise change the spacing)',
\ ' at /home/travis/perl6-error-fail/insanity-test.pl6:4',
\ ' ------> /win<HERE> 3/',
\ 'Syntax OK',], "\n")
\ }
\ ],
\ ale_linters#perl6#perl6#Handle(bufnr(''), [
\ 'Potential difficulties:',
\ ' Redeclaration of symbol ''$_''',
\ ' at /home/travis/perl6-error-fail/insanity-test.pl6:1',
\ ' ------> sub foo($_) {.say}; my $_<HERE> = 1; .&foo;',
\ ' Space is not significant here; please use quotes or :s (:sigspace) modifier (or, to suppress this warning, omit the space, or otherwise change the spacing)',
\ ' at /home/travis/perl6-error-fail/insanity-test.pl6:4',
\ ' ------> /win<HERE> 3/',
\ 'Syntax OK'
\ ])
Execute(The Perl6 linter should gracefully handle messages without a line number):
call ale#test#SetFilename('bar.pl6')
AssertEqual
\ [
\ {
\ 'lnum': '1',
\ 'end_lnum': '',
\ 'text': 'Cannot find method ''has_compile_time_value'' on object of type NQPMu',
\ 'type': 'E',
\ 'col' : '',
\ 'code': 'X::AdHoc',
\ }
\ ],
\ ale_linters#perl6#perl6#Handle(bufnr(''), [
\ '{',
\ '"X::AdHoc" : {',
\ '"message" : "Cannot find method ''has_compile_time_value'' on object of type NQPMu",',
\ '"payload" : "Cannot find method ''has_compile_time_value'' on object of type NQPMu"',
\ '}',
\ '}',
\ ])
Execute(The Perl6 linter should not include errors from a known separate file):
call ale#test#SetFilename('bar.pl6')
AssertEqual
\ [],
\ ale_linters#perl6#perl6#Handle(bufnr(''), [
\ '{
\ "X::Undeclared" : {
\ "highexpect" : [ ],
\ "is-compile-time" : 1,
\ "modules" : [ ],
\ "column" : null,
\ "pos" : 18,
\ "symbol" : "$tes",
\ "filename" : "foo.pl6",
\ "what" : "Variable",
\ "pre" : "my $test = 0; say ",
\ "post" : "$tes",
\ "suggestions" : [
\ "$res",
\ "$test"
\ ],
\ "line" : 6,
\ "message" : "Variable ''$tes'' is not declared. Did you mean any of these?\n $res\n $test\n"
\ }
\ }'
\ ])
Execute(The Perl6 linter should not ignore errors without a filename):
call ale#test#SetFilename('bar.pl6')
AssertEqual
\ [
\ {
\ 'lnum': '3',
\ 'end_lnum': '',
\ 'text': 'Cannot find method ''has_compile_time_value'' on object of type NQPMu',
\ 'type': 'E',
\ 'col' : '',
\ 'code': 'X::AdHoc',
\ }
\ ],
\ ale_linters#perl6#perl6#Handle(bufnr(''), [
\ '{',
\ '"X::AdHoc" : {',
\ '"line" : 3,',
\ '"message" : "Cannot find method ''has_compile_time_value'' on object of type NQPMu",',
\ '"payload" : "Cannot find method ''has_compile_time_value'' on object of type NQPMu"',
\ '}',
\ '}',
\ ])

Some files were not shown because too many files have changed in this diff Show More