lint/cmd/qa/cmd_php_test.go

153 lines
3.8 KiB
Go

package qa
import (
"io"
"os"
"path/filepath"
"testing"
"forge.lthn.ai/core/cli/pkg/cli"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPHPStanJSONOutput_DoesNotAppendSuccessBanner(t *testing.T) {
dir := t.TempDir()
writeTestFile(t, filepath.Join(dir, "composer.json"), "{}")
writeExecutable(t, filepath.Join(dir, "vendor", "bin", "phpstan"), "#!/bin/sh\nprintf '%s\\n' '{\"tool\":\"phpstan\",\"status\":\"ok\"}'\n")
restoreWorkingDir(t, dir)
resetPHPStanFlags(t)
parent := &cli.Command{Use: "qa"}
addPHPStanCommand(parent)
command := findSubcommand(t, parent, "stan")
require.NoError(t, command.Flags().Set("json", "true"))
output := captureStdout(t, func() {
require.NoError(t, command.RunE(command, nil))
})
assert.Equal(t, "{\"tool\":\"phpstan\",\"status\":\"ok\"}\n", output)
assert.NotContains(t, output, "Static analysis passed")
assert.NotContains(t, output, "PHP Static Analysis")
}
func TestPHPPsalmJSONOutput_DoesNotAppendSuccessBanner(t *testing.T) {
dir := t.TempDir()
writeTestFile(t, filepath.Join(dir, "composer.json"), "{}")
writeExecutable(t, filepath.Join(dir, "vendor", "bin", "psalm"), "#!/bin/sh\nprintf '%s\\n' '{\"tool\":\"psalm\",\"status\":\"ok\"}'\n")
restoreWorkingDir(t, dir)
resetPHPPsalmFlags(t)
parent := &cli.Command{Use: "qa"}
addPHPPsalmCommand(parent)
command := findSubcommand(t, parent, "psalm")
require.NoError(t, command.Flags().Set("json", "true"))
output := captureStdout(t, func() {
require.NoError(t, command.RunE(command, nil))
})
assert.Equal(t, "{\"tool\":\"psalm\",\"status\":\"ok\"}\n", output)
assert.NotContains(t, output, "Psalm analysis passed")
assert.NotContains(t, output, "PHP Psalm Analysis")
}
func writeTestFile(t *testing.T, path string, content string) {
t.Helper()
require.NoError(t, os.MkdirAll(filepath.Dir(path), 0o755))
require.NoError(t, os.WriteFile(path, []byte(content), 0o644))
}
func writeExecutable(t *testing.T, path string, content string) {
t.Helper()
require.NoError(t, os.MkdirAll(filepath.Dir(path), 0o755))
require.NoError(t, os.WriteFile(path, []byte(content), 0o755))
}
func restoreWorkingDir(t *testing.T, dir string) {
t.Helper()
wd, err := os.Getwd()
require.NoError(t, err)
require.NoError(t, os.Chdir(dir))
t.Cleanup(func() {
require.NoError(t, os.Chdir(wd))
})
}
func resetPHPStanFlags(t *testing.T) {
t.Helper()
oldLevel := phpStanLevel
oldMemory := phpStanMemory
oldJSON := phpStanJSON
oldSARIF := phpStanSARIF
phpStanLevel = 0
phpStanMemory = ""
phpStanJSON = false
phpStanSARIF = false
t.Cleanup(func() {
phpStanLevel = oldLevel
phpStanMemory = oldMemory
phpStanJSON = oldJSON
phpStanSARIF = oldSARIF
})
}
func resetPHPPsalmFlags(t *testing.T) {
t.Helper()
oldLevel := phpPsalmLevel
oldFix := phpPsalmFix
oldBaseline := phpPsalmBaseline
oldShowInfo := phpPsalmShowInfo
oldJSON := phpPsalmJSON
oldSARIF := phpPsalmSARIF
phpPsalmLevel = 0
phpPsalmFix = false
phpPsalmBaseline = false
phpPsalmShowInfo = false
phpPsalmJSON = false
phpPsalmSARIF = false
t.Cleanup(func() {
phpPsalmLevel = oldLevel
phpPsalmFix = oldFix
phpPsalmBaseline = oldBaseline
phpPsalmShowInfo = oldShowInfo
phpPsalmJSON = oldJSON
phpPsalmSARIF = oldSARIF
})
}
func findSubcommand(t *testing.T, parent *cli.Command, name string) *cli.Command {
t.Helper()
for _, command := range parent.Commands() {
if command.Name() == name {
return command
}
}
t.Fatalf("subcommand %q not found", name)
return nil
}
func captureStdout(t *testing.T, fn func()) string {
t.Helper()
oldStdout := os.Stdout
reader, writer, err := os.Pipe()
require.NoError(t, err)
os.Stdout = writer
defer func() {
os.Stdout = oldStdout
}()
defer func() {
require.NoError(t, reader.Close())
}()
fn()
require.NoError(t, writer.Close())
output, err := io.ReadAll(reader)
require.NoError(t, err)
return string(output)
}