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,
  \     }
  \   },
  \ ])])
