blob: 923c53aa9bbb1081a1ad3359bb63a7828f175a61 [file] [log] [blame]
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package benchfmt
import (
"errors"
"io/fs"
"os"
"strings"
"testing"
)
func TestFiles(t *testing.T) {
// Switch to testdata/files directory.
oldDir, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
defer os.Chdir(oldDir)
if err := os.Chdir("testdata/files"); err != nil {
t.Fatal(err)
}
check := func(f *Files, want ...string) {
t.Helper()
for f.Scan() {
switch res := f.Result(); res := res.(type) {
default:
t.Fatalf("unexpected result type %T", res)
case *SyntaxError:
t.Fatalf("unexpected Result error %s", res)
return
case *Result:
if len(want) == 0 {
t.Errorf("got result, want end of stream")
return
}
got := res.GetConfig(".file") + " " + string(res.Name.Full())
if got != want[0] {
t.Errorf("got %q, want %q", got, want[0])
}
want = want[1:]
}
}
err := f.Err()
noent := errors.Is(err, fs.ErrNotExist)
wantNoent := len(want) == 1 && strings.HasPrefix(want[0], "ErrNotExist")
if wantNoent {
want = want[1:]
}
if err != nil && !noent {
t.Errorf("got unexpected error %s", err)
} else if noent && !wantNoent {
t.Errorf("got %s, want success", err)
} else if !noent && wantNoent {
t.Errorf("got success, want ErrNotExist")
}
if len(want) != 0 {
t.Errorf("got end of stream, want %v", want)
}
}
// Basic tests.
check(
&Files{Paths: []string{"a", "b"}},
"a X", "a Y", "b Z",
)
check(
&Files{Paths: []string{"a", "b", "c", "d"}},
"a X", "a Y", "b Z", "ErrNotExist",
)
// Ambiguous paths.
check(
&Files{Paths: []string{"a", "b", "a"}},
"a#0 X", "a#0 Y", "b Z", "a#1 X", "a#1 Y",
)
// AllowStdin.
check(
&Files{Paths: []string{"-"}},
"ErrNotExist",
)
fakeStdin("BenchmarkIn 1 1 ns/op\n", func() {
check(
&Files{
Paths: []string{"-"},
AllowStdin: true,
},
"- In",
)
})
// Labels.
check(
&Files{
Paths: []string{"a", "b"},
AllowLabels: true,
},
"a X", "a Y", "b Z",
)
check(
&Files{
Paths: []string{"foo=a", "b"},
AllowLabels: true,
},
"foo X", "foo Y", "b Z",
)
fakeStdin("BenchmarkIn 1 1 ns/op\n", func() {
check(
&Files{
Paths: []string{"foo=-"},
AllowStdin: true,
AllowLabels: true,
},
"foo In",
)
})
// Ambiguous labels don't get disambiguated.
check(
&Files{
Paths: []string{"foo=a", "foo=a"},
AllowLabels: true,
},
"foo X", "foo Y", "foo X", "foo Y",
)
}
func fakeStdin(content string, cb func()) {
r, w, err := os.Pipe()
if err != nil {
panic(err)
}
go func() {
defer w.Close()
w.WriteString(content)
}()
defer r.Close()
defer func(orig *os.File) { os.Stdin = orig }(os.Stdin)
os.Stdin = r
cb()
}