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