Skip to content

Commit 6f5a7bd

Browse files
committed
Add -script, -skip-must-fail
For the benefit running in CI via https://github.com/toml-lang/setup-toml-test
1 parent 953b272 commit 6f5a7bd

File tree

5 files changed

+238
-176
lines changed

5 files changed

+238
-176
lines changed

README.md

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -38,41 +38,15 @@ that directory by setting `GOBIN`; for example to use the current directory:
3838

3939
[release page]: https://github.com/toml-lang/toml-test/releases
4040

41-
### Installation in CI
42-
There are two options:
43-
44-
1. Build from source as per the above; this is typically more than fast enough,
45-
but requires Go to be installed. For example in GitHub actions:
46-
47-
steps:
48-
- {uses: actions/setup-go@v4, with: {go-version: '1.24'}}
49-
- run: 'go install github.com/toml-lang/toml-test/cmd/toml-test@latest'
50-
# ~/go/bin should already be in $PATH on GitHub actions.
51-
52-
2. Alternatively, you can download a release binary. These are statically linked
53-
and should run anywhere. For example in GitHub actions:
54-
55-
steps:
56-
- name: 'install toml-test'
57-
run: |
58-
version=v1.6.0
59-
platform=linux-amd64
60-
curl -sL https://github.com/toml-lang/toml-test/releases/download/$version/toml-test-$version-$platform.gz |
61-
gzip -d >toml-test
62-
chmod a+x toml-test
63-
64-
Many implementations don't pass all the tests, because they are "known bugs" or
65-
by choice (especially for "invalid" tests as some are a tad pedantic). You can
66-
use `-skip` to skip some tests; for example with a small shell script:
67-
68-
#!/usr/bin/env bash
69-
skip=(
70-
-skip 'invalid/foo'
71-
-skip 'invalid/bar'
72-
)
73-
toml-test -toml=1.0 ${skip[@]} my-parser-cmd
74-
75-
Use `toml-test my-parser-cmd -print-skip` to generate a script for all failures.
41+
Running in CI
42+
-------------
43+
The [setup-toml-test] action can be used in GitHub. See the README for more
44+
details.
45+
46+
For other CI systems: the action essentially just downloads a release binary.
47+
See index.js. Should be easy enough to reproduce elsewhere.
48+
49+
[setup-toml-test]: https://github.com/toml-lang/setup-toml-test
7650

7751
Usage
7852
-----

cmd/toml-test/main.go

Lines changed: 64 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"bytes"
5+
_ "embed"
56
"encoding/json"
67
"fmt"
78
"io"
@@ -12,6 +13,7 @@ import (
1213
"sort"
1314
"strconv"
1415
"strings"
16+
"text/template"
1517
"time"
1618

1719
"github.com/BurntSushi/toml"
@@ -22,33 +24,42 @@ import (
2224

2325
var hlErr = zli.Color256(224).Bg() | zli.Color256(0) | zli.Bold
2426

27+
//go:embed script.gotxt
28+
var script []byte
29+
30+
var scriptTemplate = template.Must(template.New("").Option("missingkey=error").Parse(string(script)))
31+
2532
func parseFlags() (tomltest.Runner, []string, int, string, bool, bool, bool) {
2633
f := zli.NewFlags(os.Args)
2734
var (
28-
help = f.Bool(false, "help", "h")
29-
versionFlag = f.IntCounter(0, "version", "V")
30-
tomlVersion = f.String(tomltest.DefaultVersion, "toml")
31-
encoder = f.Bool(false, "encoder")
32-
testDir = f.String("", "testdir")
33-
showAll = f.IntCounter(0, "v")
34-
color = f.String("always", "color")
35-
skip = f.StringList(nil, "skip")
36-
run = f.StringList(nil, "run")
37-
listFiles = f.Bool(false, "list-files")
38-
cat = f.Int(0, "cat")
39-
copyFiles = f.Bool(false, "copy")
40-
parallel = f.Int(runtime.NumCPU(), "parallel")
41-
printSkip = f.Bool(false, "print-skip")
42-
intAsFloat = f.Bool(false, "int-as-float")
43-
errors = f.String("", "errors")
44-
timeout = f.String("1s", "timeout")
45-
noNumber = f.Bool(false, "no-number", "no_number")
35+
help = f.Bool(false, "help", "h")
36+
versionFlag = f.IntCounter(0, "version", "V")
37+
tomlVersion = f.String(tomltest.DefaultVersion, "toml")
38+
encoder = f.Bool(false, "encoder")
39+
testDir = f.String("", "testdir")
40+
showAll = f.IntCounter(0, "v")
41+
color = f.String("always", "color")
42+
skip = f.StringList(nil, "skip")
43+
run = f.StringList(nil, "run")
44+
listFiles = f.Bool(false, "list-files")
45+
cat = f.Int(0, "cat")
46+
copyFiles = f.Bool(false, "copy")
47+
parallel = f.Int(runtime.NumCPU(), "parallel")
48+
script = f.Bool(false, "script", "print-skip") // -print-skip is the old name
49+
intAsFloat = f.Bool(false, "int-as-float")
50+
errors = f.String("", "errors")
51+
timeout = f.String("1s", "timeout")
52+
noNumber = f.Bool(false, "no-number", "no_number")
53+
skipMustError = f.Bool(false, "skip-error")
4654
)
4755
zli.F(f.Parse())
4856
if help.Bool() {
4957
fmt.Printf(usage, filepath.Base(os.Args[0]))
5058
zli.Exit(0)
5159
}
60+
if script.Bool() && encoder.Bool() {
61+
zli.Fatalf("cannot use -script and -encoder; generate a script without -encoder and fill in the encoder binary")
62+
}
5263
if tomlVersion.String() == "latest" {
5364
*tomlVersion.Pointer() = tomltest.DefaultVersion
5465
}
@@ -85,16 +96,17 @@ func parseFlags() (tomltest.Runner, []string, int, string, bool, bool, bool) {
8596
}
8697

8798
r := tomltest.Runner{
88-
Encoder: encoder.Bool(),
89-
RunTests: run.StringsSplit(","),
90-
SkipTests: skip.StringsSplit(","),
91-
Version: tomlVersion.String(),
92-
Parallel: parallel.Int(),
93-
Files: fsys,
94-
Parser: tomltest.NewCommandParser(fsys, f.Args),
95-
Timeout: dur,
96-
IntAsFloat: intAsFloat.Bool(),
97-
Errors: errs,
99+
Encoder: encoder.Bool(),
100+
RunTests: run.StringsSplit(","),
101+
SkipTests: skip.StringsSplit(","),
102+
Version: tomlVersion.String(),
103+
Parallel: parallel.Int(),
104+
Files: fsys,
105+
Parser: tomltest.NewCommandParser(fsys, f.Args),
106+
Timeout: dur,
107+
IntAsFloat: intAsFloat.Bool(),
108+
SkipMustError: skipMustError.Bool(),
109+
Errors: errs,
98110
}
99111
if intAsFloat.Bool() {
100112
r.SkipTests = append(r.SkipTests, "valid/integer/long")
@@ -132,7 +144,7 @@ func parseFlags() (tomltest.Runner, []string, int, string, bool, bool, bool) {
132144
}
133145
}
134146

135-
return r, f.Args, showAll.Int(), testDir.String(), listFiles.Bool(), printSkip.Bool(), noNumber.Bool()
147+
return r, f.Args, showAll.Int(), testDir.String(), listFiles.Bool(), script.Bool(), noNumber.Bool()
136148
}
137149

138150
func getFS(testDir string, set bool) fs.FS {
@@ -181,7 +193,7 @@ func getList(r tomltest.Runner) []string {
181193
}
182194

183195
func main() {
184-
runner, cmd, showAll, testDir, listFiles, printSkip, noNumber := parseFlags()
196+
runner, cmd, showAll, testDir, listFiles, script, noNumber := parseFlags()
185197

186198
if listFiles {
187199
l := getList(runner)
@@ -194,6 +206,28 @@ func main() {
194206
tests, err := runner.Run()
195207
zli.F(err)
196208

209+
//if script && (tests.FailedValid > 0 || tests.FailedInvalid > 0) {
210+
if script {
211+
var failedValid, failedInvalid []string
212+
for _, f := range tests.Tests {
213+
if f.Failed() {
214+
if f.Type() == tomltest.TypeValid {
215+
failedValid = append(failedValid, f.Path)
216+
} else {
217+
failedInvalid = append(failedInvalid, f.Path)
218+
}
219+
}
220+
}
221+
err := scriptTemplate.Execute(os.Stdout, struct {
222+
Decoder string
223+
TOML string
224+
FailedValid []string
225+
FailedInvalid []string
226+
}{strings.Join(cmd, " "), runner.Version, failedValid, failedInvalid})
227+
zli.F(err)
228+
return
229+
}
230+
197231
for _, t := range tests.Tests {
198232
if t.Failed() || showAll > 1 {
199233
fmt.Print(detailed(runner, t, noNumber))
@@ -213,21 +247,6 @@ func main() {
213247
fmt.Printf(", %2d skipped", tests.Skipped)
214248
}
215249

216-
if printSkip && (tests.FailedValid > 0 || tests.FailedInvalid > 0) {
217-
fmt.Print("\n\n #!/usr/bin/env bash\n # Also compatible with zsh.\n skip=(\n")
218-
for _, f := range tests.Tests {
219-
if f.Failed() {
220-
fmt.Printf(" -skip '%s'\n", f.Path)
221-
}
222-
}
223-
fmt.Println(" )")
224-
fmt.Printf(" toml-test -toml=%s ${skip[@]} %s", runner.Version, strings.Join(cmd, " "))
225-
if runner.Encoder {
226-
fmt.Print(" -encoder")
227-
}
228-
fmt.Println()
229-
}
230-
231250
fmt.Println()
232251
if runner.Encoder {
233252
fmt.Printf("encoder tests: %3d passed, %2d failed\n", tests.PassedValid, tests.FailedValid)

cmd/toml-test/script.gotxt

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env bash
2+
# Also compatible with zsh, but not POSIX sh.
3+
#
4+
# Run the toml-test compliance tests: https://github.com/toml-lang/toml-test
5+
6+
decoder="{{.Decoder}}"
7+
8+
# Leave empty to not test encoder tests.
9+
encoder=
10+
11+
# Version of the TOML specification to test.
12+
toml={{.TOML}}
13+
14+
# Skip known failures.
15+
skip=(
16+
{{- if .FailedValid}}
17+
# Failing "valid" tests
18+
{{range $t := .FailedValid}}{{"\t"}}-skip '{{$t}}'
19+
{{$t}}{{end}}{{end}}
20+
{{- if .FailedInvalid}}
21+
# Failing "invalid" tests
22+
{{range $t := .FailedInvalid}}{{"\t"}}-skip '{{$t}}'
23+
{{end}}{{end -}}
24+
)
25+
26+
# Find toml-test
27+
tt=
28+
if [[ -x "./toml-test" ]]; then
29+
tt="./toml-test"
30+
elif command -v "toml-test" >/dev/null; then
31+
tt="toml-test"
32+
elif [[ -n "$(go env GOBIN)" ]] && [[ -x "$(go env GOBIN)/toml-test" ]]; then
33+
tt="$(go env GOPATH)/toml-test"
34+
elif [[ -n "$(go env GOPATH)" ]] && [[ -x "$(go env GOPATH)/bin/toml-test" ]]; then
35+
tt="$(go env GOPATH)/bin/toml-test"
36+
elif [[ -x "$HOME/go/bin/toml-test" ]]; then
37+
tt="$HOME/go/bin/toml-test"
38+
fi
39+
if ! command -v "$tt" >/dev/null; then
40+
echo >&2 'toml-test not in current dir, $PATH, $GOBIN, $GOPATH/bin, or $HOME/go/bin; install with:'
41+
echo >&2 ' % go install github.com/toml-lang/toml-test/cmd/toml-test@latest'
42+
echo >&2
43+
echo >&2 'Or download a binary from:'
44+
echo >&2 ' https://github.com/toml-lang/toml-test/releases'
45+
exit 1
46+
fi
47+
48+
fail=0
49+
"$tt" -toml="$toml" -skip-must-error ${skip[@]} -- "$decoder" "$@" || fail=1
50+
if [[ -n "$encoder" ]]; then
51+
"$tt" -toml="$toml" -skip-must-error ${skip[@]} -encoder -- "$encoder" "$@" || fail=1
52+
fi
53+
exit $fail

0 commit comments

Comments
 (0)