+Before:
+ Save g:ale_typescript_tslint_ignore_empty_files
+
+ unlet! g:ale_typescript_tslint_ignore_empty_files
+ unlet! b:ale_typescript_tslint_ignore_empty_files
+
+ runtime ale_linters/typescript/tslint.vim
+
+ call ale#test#SetDirectory('/testplugin/test/handler')
+
+After:
+ Restore
+
+ unlet! b:ale_typescript_tslint_ignore_empty_files
+ unlet! b:relative_to_root
+ unlet! b:tempname_suffix
+ unlet! b:relative_tempname
+
+ call ale#test#RestoreDirectory()
+ call ale#linter#Reset()
+
+Execute(The tslint handler should parse lines correctly):
+ call ale#test#SetFilename('app/test.ts')
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 1,
+ \ 'col': 15,
+ \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.ts'),
+ \ 'end_lnum': 1,
+ \ 'type': 'E',
+ \ 'end_col': 15,
+ \ 'text': 'Missing semicolon',
+ \ 'code': 'semicolon',
+ \ },
+ \ {
+ \ 'lnum': 2,
+ \ 'col': 8,
+ \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.ts'),
+ \ 'end_lnum': 3,
+ \ 'type': 'W',
+ \ 'end_col': 12,
+ \ 'text': 'Something else',
+ \ },
+ \ {
+ \ 'lnum': 2,
+ \ 'col': 8,
+ \ 'filename': ale#path#Simplify(expand('%:p:h') . '/something-else.ts'),
+ \ 'end_lnum': 3,
+ \ 'type': 'W',
+ \ 'end_col': 12,
+ \ 'text': 'Something else',
+ \ 'code': 'something',
+ \ },
+ \ {
+ \ 'lnum': 31,
+ \ 'col': 9,
+ \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.ts'),
+ \ 'end_lnum': 31,
+ \ 'type': 'E',
+ \ 'end_col': 20,
+ \ 'text': 'Calls to console.log are not allowed.',
+ \ 'code': 'no-console',
+ \ },
+ \ ] ,
+ \ ale_linters#typescript#tslint#Handle(bufnr(''), [json_encode([
+ \ {
+ \ 'endPosition': {
+ \ 'character': 14,
+ \ 'line': 0,
+ \ 'position': 1000
+ \ },
+ \ 'failure': 'Missing semicolon',
+ \ 'fix': {
+ \ 'innerLength': 0,
+ \ 'innerStart': 14,
+ \ 'innerText': ';'
+ \ },
+ \ 'name': 'test.ts',
+ \ 'ruleName': 'semicolon',
+ \ 'ruleSeverity': 'ERROR',
+ \ 'startPosition': {
+ \ 'character': 14,
+ \ 'line': 0,
+ \ 'position': 1000
+ \ }
+ \ },
+ \ {
+ \ 'endPosition': {
+ \ 'character': 11,
+ \ 'line': 2,
+ \ 'position': 1000
+ \ },
+ \ 'failure': 'Something else',
+ \ 'fix': {
+ \ 'innerLength': 0,
+ \ 'innerStart': 14,
+ \ 'innerText': ';'
+ \ },
+ \ 'name': 'test.ts',
+ \ 'ruleSeverity': 'WARNING',
+ \ 'startPosition': {
+ \ 'character': 7,
+ \ 'line': 1,
+ \ 'position': 1000
+ \ }
+ \ },
+ \ {
+ \ 'endPosition': {
+ \ 'character': 11,
+ \ 'line': 2,
+ \ 'position': 22
+ \ },
+ \ 'failure': 'Something else',
+ \ 'fix': {
+ \ 'innerLength': 0,
+ \ 'innerStart': 14,
+ \ 'innerText': ';'
+ \ },
+ \ 'name': 'something-else.ts',
+ \ 'ruleName': 'something',
+ \ 'ruleSeverity': 'WARNING',
+ \ 'startPosition': {
+ \ 'character': 7,
+ \ 'line': 1,
+ \ 'position': 14
+ \ }
+ \ },
+ \ {
+ \ "endPosition": {
+ \ "character": 19,
+ \ "line": 30,
+ \ "position": 14590
+ \ },
+ \ "failure": "Calls to console.log are not allowed.",
+ \ 'name': 'test.ts',
+ \ "ruleName": "no-console",
+ \ "startPosition": {
+ \ "character": 8,
+ \ "line": 30,
+ \ "position": 14579
+ \ }
+ \ },
+ \])])
+
+Execute(The tslint handler should handle empty output):
+ AssertEqual
+ \ [],
+ \ ale_linters#typescript#tslint#Handle(bufnr(''), [])
+
+Execute(The tslint handler report errors for empty files by default):
+ call ale#test#SetFilename('app/test.ts')
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 2,
+ \ 'col': 1,
+ \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.ts'),
+ \ 'end_lnum': 2,
+ \ 'type': 'E',
+ \ 'end_col': 1,
+ \ 'text': 'Consecutive blank lines are forbidden',
+ \ 'code': 'no-consecutive-blank-lines',
+ \ },
+ \ ],
+ \ ale_linters#typescript#tslint#Handle(bufnr(''), [json_encode([{
+ \ 'endPosition': {
+ \ 'character': 0,
+ \ 'line': 1,
+ \ 'position': 1
+ \ },
+ \ 'failure': 'Consecutive blank lines are forbidden',
+ \ 'fix': [{
+ \ 'innerStart': 0,
+ \ 'innerLength': 1,
+ \ 'innerText': ''
+ \ }],
+ \ 'name': 'test.ts',
+ \ 'ruleName': 'no-consecutive-blank-lines',
+ \ 'ruleSeverity': 'ERROR',
+ \ 'startPosition': {
+ \ 'character': 0,
+ \ 'line': 1,
+ \ 'position': 1
+ \ }
+ \ }])])
+
+Execute(The tslint handler should not report errors for empty files when the ignore option is on):
+ let b:ale_typescript_tslint_ignore_empty_files = 1
+ call ale#test#SetFilename('app/test.ts')
+
+ AssertEqual
+ \ [
+ \ ],
+ \ ale_linters#typescript#tslint#Handle(bufnr(''), [json_encode([{
+ \ 'endPosition': {
+ \ 'character': 0,
+ \ 'line': 1,
+ \ 'position': 1
+ \ },
+ \ 'failure': 'Consecutive blank lines are forbidden',
+ \ 'fix': [{
+ \ 'innerStart': 0,
+ \ 'innerLength': 1,
+ \ 'innerText': ''
+ \ }],
+ \ 'name': 'test.ts',
+ \ 'ruleName': 'no-consecutive-blank-lines',
+ \ 'ruleSeverity': 'ERROR',
+ \ 'startPosition': {
+ \ 'character': 0,
+ \ 'line': 1,
+ \ 'position': 1
+ \ }
+ \ }])])
+
+Given typescript(A file with extra blank lines):
+ const x = 3
+
+
+ const y = 4
+
+Execute(The tslint handler should report errors when the ignore option is on, but the file is not empty):
+ let b:ale_typescript_tslint_ignore_empty_files = 1
+ call ale#test#SetFilename('app/test.ts')
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 2,
+ \ 'col': 1,
+ \ 'filename': ale#path#Simplify(expand('%:p:h') . '/test.ts'),
+ \ 'end_lnum': 2,
+ \ 'type': 'E',
+ \ 'end_col': 1,
+ \ 'text': 'Consecutive blank lines are forbidden',
+ \ 'code': 'no-consecutive-blank-lines',
+ \ },
+ \ ],
+ \ ale_linters#typescript#tslint#Handle(bufnr(''), [json_encode([{
+ \ 'endPosition': {
+ \ 'character': 0,
+ \ 'line': 1,
+ \ 'position': 1
+ \ },
+ \ 'failure': 'Consecutive blank lines are forbidden',
+ \ 'fix': [{
+ \ 'innerStart': 0,
+ \ 'innerLength': 1,
+ \ 'innerText': ''
+ \ }],
+ \ 'name': 'test.ts',
+ \ 'ruleName': 'no-consecutive-blank-lines',
+ \ 'ruleSeverity': 'ERROR',
+ \ 'startPosition': {
+ \ 'character': 0,
+ \ 'line': 1,
+ \ 'position': 1
+ \ }
+ \ }])])
+
+Execute(The tslint handler should not report no-implicit-dependencies errors):
+ call ale#test#SetFilename('app/test.ts')
+
+ AssertEqual
+ \ [
+ \ ],
+ \ ale_linters#typescript#tslint#Handle(bufnr(''), [json_encode([{
+ \ 'endPosition': {
+ \ 'character': 0,
+ \ 'line': 1,
+ \ 'position': 1
+ \ },
+ \ 'failure': 'this is ignored',
+ \ 'name': 'test.ts',
+ \ 'ruleName': 'no-implicit-dependencies',
+ \ 'ruleSeverity': 'ERROR',
+ \ 'startPosition': {
+ \ 'character': 0,
+ \ 'line': 1,
+ \ 'position': 1
+ \ },
+ \ }])])
+
+Execute(The tslint handler should set filename keys for temporary files):
+ " The temporary filename below is hacked into being a relative path so we can
+ " test that we resolve the temporary filename first.
+ let b:relative_to_root = substitute(expand('%:p'), '\v[^/\\]*([/\\])[^/\\]*', '../', 'g')
+ let b:tempname_suffix = substitute(tempname(), '^\v([A-Z]:)?[/\\]', '', '')
+ let b:relative_tempname = substitute(b:relative_to_root . b:tempname_suffix, '\\', '/', 'g')
+
+ AssertEqual
+ \ [
+ \ {'lnum': 47, 'col': 1, 'code': 'curly', 'end_lnum': 47, 'type': 'E', 'end_col': 26, 'text': 'if statements must be braced'},
+ \ ],
+ \ ale_linters#typescript#tslint#Handle(bufnr(''), [json_encode([
+ \ {
+ \ 'endPosition': {
+ \ 'character':25,
+ \ 'line':46,
+ \ 'position':1383,
+ \ },
+ \ 'failure': 'if statements must be braced',
+ \ 'name': b:relative_tempname,
+ \ 'ruleName': 'curly',
+ \ 'ruleSeverity':'ERROR',
+ \ 'startPosition': {
+ \ 'character':0,
+ \ 'line':46,
+ \ 'position':1358,
+ \ }
+ \ },
+ \ ])])