Before:
  call ale#assert#SetUpLinterTest('php', 'phpstan')

  let g:old_dir = g:dir

  " Create a temporary directory and work within it, otherwise these tests
  " cannot be run in parallel.
  let g:parent_dir = tempname()
  let g:dir = ale#path#Simplify(g:parent_dir . '/src')

  call mkdir(g:parent_dir, '', 0750)
  call mkdir(g:dir, '', 0750)

  silent! execute 'cd ' . fnameescape(g:dir)
  silent! noautocmd execute 'file ' . fnameescape(ale#path#Simplify(g:dir . '/test.php'))

  call delete('./phpstan.neon')

  GivenCommandOutput ['0.10.2']

After:
  silent! execute 'cd ' . fnameescape(g:old_dir)
  call delete(g:dir, 'rf')
  let g:dir = g:old_dir
  unlet! g:old_dir
  call ale#assert#TearDownLinterTest()

Execute(The local phpstan executable should be used):
  call mkdir('vendor/bin', 'p', 0750)
  call writefile([''], 'vendor/bin/phpstan')
  call ale#test#SetFilename('phpstan-test-files/foo/test.php')

  let g:executable = ale#path#Simplify(g:dir . '/vendor/bin/phpstan')

  AssertLinter g:executable,
  \ ale#Escape(g:executable) . ' analyze --no-progress --errorFormat json -l ' . ale#Escape('4') . ' %s'
  AssertLinterCwd v:null

Execute(use_global should override local executable detection):
  let g:ale_php_phpstan_use_global = 1

  call mkdir('vendor/bin', 'p', 0750)
  call writefile([''], 'vendor/bin/phpstan')
  call ale#test#SetFilename('phpstan-test-files/foo/test.php')

  AssertLinter 'phpstan',
  \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json -l ' . ale#Escape('4') . ' %s'

Execute(Custom executables should be used for the executable and command):
  let g:ale_php_phpstan_executable = 'phpstan_test'

  AssertLinter 'phpstan_test',
  \ ale#Escape('phpstan_test') . ' analyze --no-progress --errorFormat json -l ' . ale#Escape('4') . ' %s'

Execute(project with level set to 3):
  call ale#test#SetFilename('phpstan-test-files/foo/test.php')
  let g:ale_php_phpstan_level = 3

  AssertLinter 'phpstan',
  \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json -l ' . ale#Escape('3') . ' %s'

Execute(project with level set to 0):
  call ale#test#SetFilename('phpstan-test-files/foo/test.php')
  let g:ale_php_phpstan_level = 0

  AssertLinter 'phpstan',
  \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json -l ' . ale#Escape('0') . ' %s'

Execute(Custom phpstan configuration file):
  let g:ale_php_phpstan_configuration = 'phpstan_config'

  AssertLinter 'phpstan',
  \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json -c ' . ale#Escape('phpstan_config') . ' -l ' . ale#Escape('4') . ' %s'

Execute(Choose the right format for error format param):
  GivenCommandOutput ['0.10.3']

  AssertLinter 'phpstan', [
  \ ale#Escape('phpstan') . ' --version',
  \ ale#Escape('phpstan') . ' analyze --no-progress --error-format json -l ' . ale#Escape('4') . ' %s'
  \ ]

Execute(Configuration file exists in current directory):
  call writefile(['parameters:', '  level: 7'], './phpstan.neon')
  let g:ale_php_phpstan_level = ''
  let g:ale_php_phpstan_configuration = ''

  AssertLinter 'phpstan', [
  \ ale#Escape('phpstan') . ' --version',
  \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json %s'
  \ ]
  AssertLinterCwd g:dir

Execute(Configuration dist file exists in current directory):
  call writefile(['parameters:', '  level: 7'], './phpstan.neon.dist')
  let g:ale_php_phpstan_level = ''
  let g:ale_php_phpstan_configuration = ''

  AssertLinter 'phpstan', [
  \ ale#Escape('phpstan') . ' --version',
  \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json %s'
  \ ]
  AssertLinterCwd g:dir

Execute(Configuration alternative dist file exists in current directory):
  call writefile(['parameters:', '  level: 7'], './phpstan.dist.neon')
  let g:ale_php_phpstan_level = ''
  let g:ale_php_phpstan_configuration = ''

  AssertLinter 'phpstan', [
  \ ale#Escape('phpstan') . ' --version',
  \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json %s'
  \ ]
  AssertLinterCwd g:dir

Execute(Configuration file exists in current directory, but force phpstan level):
  call writefile(['parameters:', '  level: 7'], './phpstan.neon')
  let g:ale_php_phpstan_configuration = ''
  let g:ale_php_phpstan_level = '7'

  AssertLinter 'phpstan', [
  \ ale#Escape('phpstan') . ' --version',
  \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json -l ' . ale#Escape('7') . ' %s'
  \ ]

Execute(Configuration file exists in current directory, but force phpstan configuration):
  call writefile(['parameters:', '  level: 7'], './phpstan.neon')
  let g:ale_php_phpstan_level = ''
  let g:ale_php_phpstan_configuration = 'phpstan.custom.neon'

  AssertLinter 'phpstan', [
  \ ale#Escape('phpstan') . ' --version',
  \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json -c ' . ale#Escape('phpstan.custom.neon') . ' %s'
  \ ]

Execute(Autoload parameter is added to the command):
  let g:ale_php_phpstan_autoload = 'autoload.php'

  AssertLinter 'phpstan',
  \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json -a ' . ale#Escape('autoload.php') . ' -l ' . ale#Escape('4') . ' %s'

Execute(Memory limit parameter is added to the command):
  let g:ale_php_phpstan_memory_limit = '500M'

  AssertLinter 'phpstan',
  \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json -l ' . ale#Escape('4') . ' --memory-limit=' . ale#Escape('500M') . ' %s'

Execute(Directory is changed to that of the configuration file):
  call writefile([], '../phpstan.neon')

  AssertLinterCwd g:parent_dir
  AssertLinter 'phpstan',
  \ ale#Escape('phpstan') . ' analyze --no-progress --errorFormat json %s'
