2024-01-02 15:12:47 +03:00
|
|
|
package cli
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"testing"
|
|
|
|
|
2024-05-26 19:35:50 +03:00
|
|
|
"github.com/charmbracelet/log"
|
|
|
|
|
2024-05-01 21:03:26 +03:00
|
|
|
"git.numtide.com/numtide/treefmt/stats"
|
|
|
|
|
2024-02-15 12:20:01 +03:00
|
|
|
"git.numtide.com/numtide/treefmt/test"
|
|
|
|
|
2024-01-02 15:12:47 +03:00
|
|
|
"github.com/alecthomas/kong"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func newKong(t *testing.T, cli interface{}, options ...kong.Option) *kong.Kong {
|
|
|
|
t.Helper()
|
|
|
|
options = append([]kong.Option{
|
|
|
|
kong.Name("test"),
|
|
|
|
kong.Exit(func(int) {
|
|
|
|
t.Helper()
|
|
|
|
t.Fatalf("unexpected exit()")
|
|
|
|
}),
|
|
|
|
}, options...)
|
|
|
|
parser, err := kong.New(cli, options...)
|
|
|
|
require.NoError(t, err)
|
|
|
|
return parser
|
|
|
|
}
|
|
|
|
|
|
|
|
func cmd(t *testing.T, args ...string) ([]byte, error) {
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
// create a new kong context
|
2024-06-06 21:16:34 +03:00
|
|
|
p := newKong(t, New(), NewOptions()...)
|
2024-01-02 15:12:47 +03:00
|
|
|
ctx, err := p.Parse(args)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
tempDir := t.TempDir()
|
2024-06-04 20:23:04 +03:00
|
|
|
tempOut := test.TempFile(t, tempDir, "combined_output", nil)
|
2024-01-02 15:12:47 +03:00
|
|
|
|
|
|
|
// capture standard outputs before swapping them
|
|
|
|
stdout := os.Stdout
|
|
|
|
stderr := os.Stderr
|
|
|
|
|
|
|
|
// swap them temporarily
|
|
|
|
os.Stdout = tempOut
|
|
|
|
os.Stderr = tempOut
|
|
|
|
|
2024-05-26 19:35:50 +03:00
|
|
|
log.SetOutput(tempOut)
|
|
|
|
|
2024-01-02 15:12:47 +03:00
|
|
|
// run the command
|
|
|
|
if err = ctx.Run(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// reset and read the temporary output
|
|
|
|
if _, err = tempOut.Seek(0, 0); err != nil {
|
2024-05-02 13:40:49 +03:00
|
|
|
return nil, fmt.Errorf("failed to reset temp output for reading: %w", err)
|
2024-01-02 15:12:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
out, err := io.ReadAll(tempOut)
|
|
|
|
if err != nil {
|
2024-05-02 13:40:49 +03:00
|
|
|
return nil, fmt.Errorf("failed to read temp output: %w", err)
|
2024-01-02 15:12:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// swap outputs back
|
|
|
|
os.Stdout = stdout
|
|
|
|
os.Stderr = stderr
|
2024-05-26 19:35:50 +03:00
|
|
|
log.SetOutput(stderr)
|
2024-01-02 15:12:47 +03:00
|
|
|
|
|
|
|
return out, nil
|
|
|
|
}
|
2024-05-01 13:15:39 +03:00
|
|
|
|
2024-05-01 21:03:26 +03:00
|
|
|
func assertStats(t *testing.T, as *require.Assertions, traversed int32, emitted int32, matched int32, formatted int32) {
|
2024-05-01 13:15:39 +03:00
|
|
|
t.Helper()
|
2024-05-10 13:26:10 +03:00
|
|
|
as.Equal(traversed, stats.Value(stats.Traversed), "stats.traversed")
|
|
|
|
as.Equal(emitted, stats.Value(stats.Emitted), "stats.emitted")
|
|
|
|
as.Equal(matched, stats.Value(stats.Matched), "stats.matched")
|
|
|
|
as.Equal(formatted, stats.Value(stats.Formatted), "stats.formatted")
|
2024-05-01 13:15:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func assertFormatted(t *testing.T, as *require.Assertions, output []byte, count int) {
|
|
|
|
t.Helper()
|
2024-07-04 12:11:51 +03:00
|
|
|
as.Contains(string(output), fmt.Sprintf("(%d changed)", count))
|
2024-05-01 13:15:39 +03:00
|
|
|
}
|