shad-go/gitfame/test/integration/gitfame_test.go

193 lines
4 KiB
Go
Raw Normal View History

2021-02-28 17:35:21 +00:00
package integration
import (
2021-03-01 14:10:47 +00:00
"bytes"
2021-02-28 17:35:21 +00:00
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
2021-03-01 12:46:46 +00:00
"sort"
"strconv"
2021-02-28 17:35:21 +00:00
"testing"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v2"
"gitlab.com/slon/shad-go/tools/testtool"
)
const importPath = "gitlab.com/slon/shad-go/gitfame/cmd/gitfame"
var binCache testtool.BinCache
func TestMain(m *testing.M) {
os.Exit(func() int {
var teardown testtool.CloseFunc
binCache, teardown = testtool.NewBinCache()
defer teardown()
return m.Run()
}())
}
func TestGitFame(t *testing.T) {
binary, err := binCache.GetBinary(importPath)
require.NoError(t, err)
bundlesDir := path.Join("./testdata", "bundles")
2021-02-28 22:46:24 +00:00
testsDir := path.Join("./testdata", "tests")
2021-03-01 12:46:46 +00:00
testDirs := ListTestDirs(t, testsDir)
2021-02-28 17:35:21 +00:00
2021-03-01 12:46:46 +00:00
for _, dir := range testDirs {
tc := ReadTestCase(t, filepath.Join(testsDir, dir))
2021-02-28 17:35:21 +00:00
2021-03-01 12:46:46 +00:00
t.Run(dir+"/"+tc.Name, func(t *testing.T) {
2021-02-28 17:35:21 +00:00
dir, err := ioutil.TempDir("", "gitfame-")
require.NoError(t, err)
defer func() { _ = os.RemoveAll(dir) }()
args := []string{"--repository", dir}
args = append(args, tc.Args...)
Unbundle(t, filepath.Join(bundlesDir, tc.Bundle), dir)
2021-03-02 22:48:23 +00:00
headRef := GetHEADRef(t, dir)
2021-02-28 17:35:21 +00:00
cmd := exec.Command(binary, args...)
2022-05-19 14:55:19 +00:00
cmd.Stderr = os.Stderr
2021-02-28 17:35:21 +00:00
output, err := cmd.Output()
2021-02-28 22:46:24 +00:00
if !tc.Error {
require.NoError(t, err)
2021-03-01 14:10:47 +00:00
CompareResults(t, tc.Expected, output, tc.Format)
2021-02-28 22:46:24 +00:00
} else {
require.Error(t, err)
_, ok := err.(*exec.ExitError)
require.True(t, ok)
}
2021-03-03 15:44:16 +00:00
newHEADRef := GetHEADRef(t, dir)
require.Equal(t, headRef, newHEADRef)
2021-02-28 17:35:21 +00:00
})
}
}
2021-03-01 12:46:46 +00:00
func ListTestDirs(t *testing.T, path string) []string {
t.Helper()
files, err := ioutil.ReadDir(path)
require.NoError(t, err)
var names []string
for _, f := range files {
if !f.IsDir() {
continue
}
names = append(names, f.Name())
}
toInt := func(name string) int {
i, err := strconv.Atoi(name)
require.NoError(t, err)
return i
}
sort.Slice(names, func(i, j int) bool {
return toInt(names[i]) < toInt(names[j])
})
return names
}
2021-02-28 17:35:21 +00:00
type TestCase struct {
*TestDescription
Expected []byte
}
func ReadTestCase(t *testing.T, path string) *TestCase {
t.Helper()
desc := ReadTestDescription(t, path)
expected, err := ioutil.ReadFile(filepath.Join(path, "expected.out"))
require.NoError(t, err)
return &TestCase{TestDescription: desc, Expected: expected}
}
type TestDescription struct {
Name string `yaml:"name"`
Args []string `yaml:"args"`
Bundle string `yaml:"bundle"`
2021-02-28 22:46:24 +00:00
Error bool `yaml:"error"`
2021-03-01 14:10:47 +00:00
Format string `yaml:"format,omitempty"`
2021-02-28 17:35:21 +00:00
}
func ReadTestDescription(t *testing.T, path string) *TestDescription {
t.Helper()
data, err := ioutil.ReadFile(filepath.Join(path, "description.yaml"))
require.NoError(t, err)
var desc TestDescription
require.NoError(t, yaml.Unmarshal(data, &desc))
return &desc
}
func Unbundle(t *testing.T, src, dst string) {
t.Helper()
cmd := exec.Command("git", "clone", src, dst)
require.NoError(t, cmd.Run())
}
2021-03-01 14:10:47 +00:00
func CompareResults(t *testing.T, expected, actual []byte, format string) {
t.Helper()
switch format {
case "json":
if len(expected) == 0 {
require.Empty(t, string(actual))
} else {
require.JSONEq(t, string(expected), string(actual))
}
case "json-lines":
if len(expected) == 0 {
require.Empty(t, string(actual))
} else {
CompareJSONLines(t, expected, actual)
}
default:
require.Equal(t, string(expected), string(actual))
}
}
func CompareJSONLines(t *testing.T, expected, actual []byte) {
t.Helper()
expectedLines := ParseJSONLines(expected)
actualLines := ParseJSONLines(actual)
require.Equal(t, len(expectedLines), len(actualLines))
for i, l := range expectedLines {
require.JSONEq(t, string(l), string(actualLines[i]))
}
}
func ParseJSONLines(data []byte) [][]byte {
return bytes.Split(bytes.TrimSpace(data), []byte("\n"))
}
2021-03-02 22:48:23 +00:00
func GetHEADRef(t *testing.T, path string) string {
t.Helper()
2021-03-03 15:44:16 +00:00
cmd := exec.Command("git", "rev-parse", "HEAD")
2021-03-02 22:48:23 +00:00
cmd.Dir = path
out, err := cmd.Output()
require.NoError(t, err)
return string(out)
}