blob: f8c136ca39f45ddce5758af5546edb5a13d8873a [file] [log] [blame]
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package golden_test
import (
"io"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
)
func TestGoldens(t *testing.T) {
_, fn, _, _ := runtime.Caller(0)
dir := filepath.Dir(fn)
gitDir, err := showTopLevel(dir)
if err != nil {
t.Fatalf("Could not find root git dir: %v", err)
}
des, err := os.ReadDir(dir)
if err != nil {
t.Fatalf("Could not read goldens/ directory: %v", err)
}
var tcs []string
for _, de := range des {
if n, ok := strings.CutSuffix(de.Name(), ".in"); ok {
tcs = append(tcs, n)
}
}
if len(tcs) == 0 {
t.Fatalf("Did not find any golden files.")
}
needsRegen := make(chan string, len(tcs))
t.Run("group", func(t *testing.T) {
for _, tc := range tcs {
tc := tc
t.Run(tc, func(t *testing.T) {
t.Parallel()
inFile := filepath.Join(dir, tc+".in")
in, err := os.Open(inFile)
if err != nil {
t.Fatalf("Could not open .in file: %v", err)
}
out, err := os.Open(filepath.Join(dir, tc+".out"))
if err != nil {
t.Fatalf("Could not open .out file: %v", err)
}
want, err := io.ReadAll(out)
if err != nil {
t.Fatalf("Could not read .out file: %v", err)
}
cmd := exec.Command("go", "run", gitDir, "--id=keep-sorted-test", "-")
cmd.Stdin = in
stdout, err := cmd.StdoutPipe()
if err != nil {
t.Fatalf("Could not create stdout pipe: %v", err)
}
stderr, err := cmd.StderrPipe()
if err != nil {
t.Fatalf("Could not create stderr pipe: %v", err)
}
if err := cmd.Start(); err != nil {
t.Errorf("could not start keep-sorted: %v", err)
}
if stderr, err := io.ReadAll(stderr); err != nil {
t.Errorf("could not read keep-sorted stderr: %v", err)
} else if len(stderr) != 0 {
t.Errorf("keep-sorted stderr: %s", string(stderr))
}
if got, err := io.ReadAll(stdout); err != nil {
t.Errorf("could not read keep-sorted stdout: %v", err)
} else if diff := cmp.Diff(strings.Split(string(want), "\n"), strings.Split(string(got), "\n")); diff != "" {
t.Errorf("keep-sorted stdout diff (-want +got):\n%s", diff)
needsRegen <- inFile
}
if err := cmd.Wait(); err != nil {
t.Errorf("keep-sorted failed: %v", err)
}
})
}
})
close(needsRegen)
var files []string
for f := range needsRegen {
files = append(files, f)
}
if len(files) != 0 {
t.Logf("Run the following to fix: %s %s", filepath.Join(gitDir, "goldens/generate-goldens.sh"), strings.Join(files, " "))
}
}
func showTopLevel(dir string) (string, error) {
b, err := exec.Command("git", "-C", dir, "rev-parse", "--show-toplevel").Output()
return strings.TrimSpace(string(b)), err
}