whatcanGOwrong
This commit is contained in:
@@ -0,0 +1,245 @@
|
||||
//go:build go1.16
|
||||
// +build go1.16
|
||||
|
||||
package toml_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"math"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
tomltest "github.com/BurntSushi/toml/internal/toml-test"
|
||||
)
|
||||
|
||||
func TestErrorPosition(t *testing.T) {
|
||||
// Note: take care to use leading spaces (not tabs).
|
||||
tests := []struct {
|
||||
test, err string
|
||||
}{
|
||||
{"array/missing-separator.toml", `
|
||||
toml: error: expected a comma (',') or array terminator (']'), but got '2'
|
||||
|
||||
At line 1, column 13:
|
||||
|
||||
1 | wrong = [ 1 2 3 ]
|
||||
^`},
|
||||
|
||||
{"array/no-close-2.toml", `
|
||||
toml: error: expected a comma (',') or array terminator (']'), but got end of file
|
||||
|
||||
At line 1, column 10:
|
||||
|
||||
1 | x = [42 #
|
||||
^`},
|
||||
|
||||
{"array/tables-2.toml", `
|
||||
toml: error: Key 'fruit.variety' has already been defined.
|
||||
|
||||
At line 9, column 3-8:
|
||||
|
||||
7 |
|
||||
8 | # This table conflicts with the previous table
|
||||
9 | [fruit.variety]
|
||||
^^^^^`},
|
||||
{"datetime/trailing-t.toml", `
|
||||
toml: error: Invalid TOML Datetime: "2006-01-30T".
|
||||
|
||||
At line 2, column 4-15:
|
||||
|
||||
1 | # Date cannot end with trailing T
|
||||
2 | d = 2006-01-30T
|
||||
^^^^^^^^^^^`},
|
||||
}
|
||||
|
||||
fsys := tomltest.EmbeddedTests()
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.test, func(t *testing.T) {
|
||||
input, err := fs.ReadFile(fsys, "invalid/"+tt.test)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var x interface{}
|
||||
_, err = toml.Decode(string(input), &x)
|
||||
if err == nil {
|
||||
t.Fatal("err is nil")
|
||||
}
|
||||
|
||||
var pErr toml.ParseError
|
||||
if !errors.As(err, &pErr) {
|
||||
t.Errorf("err is not a ParseError: %T %[1]v", err)
|
||||
}
|
||||
|
||||
tt.err = tt.err[1:] + "\n" // Remove first newline, and add trailing.
|
||||
want := pErr.ErrorWithUsage()
|
||||
|
||||
if !strings.Contains(want, tt.err) {
|
||||
t.Fatalf("\nwant:\n%s\nhave:\n%s", tt.err, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseError(t *testing.T) {
|
||||
tests := []struct {
|
||||
in interface{}
|
||||
toml, err string
|
||||
}{
|
||||
{
|
||||
&struct{ Int int8 }{},
|
||||
"Int = 200",
|
||||
`| toml: error: 200 is out of range for int8
|
||||
|
|
||||
| At line 1, column 6-9:
|
||||
|
|
||||
| 1 | Int = 200
|
||||
| ^^^
|
||||
| Error help:
|
||||
|
|
||||
| This number is too large; this may be an error in the TOML, but it can also be a
|
||||
| bug in the program that uses too small of an integer.
|
||||
|
|
||||
| The maximum and minimum values are:
|
||||
|
|
||||
| size │ lowest │ highest
|
||||
| ───────┼────────────────┼──────────
|
||||
| int8 │ -128 │ 127
|
||||
| int16 │ -32,768 │ 32,767
|
||||
| int32 │ -2,147,483,648 │ 2,147,483,647
|
||||
| int64 │ -9.2 × 10¹⁷ │ 9.2 × 10¹⁷
|
||||
| uint8 │ 0 │ 255
|
||||
| uint16 │ 0 │ 65535
|
||||
| uint32 │ 0 │ 4294967295
|
||||
| uint64 │ 0 │ 1.8 × 10¹⁸
|
||||
|
|
||||
| int refers to int32 on 32-bit systems and int64 on 64-bit systems.
|
||||
`,
|
||||
},
|
||||
{
|
||||
&struct{ Int int }{},
|
||||
fmt.Sprintf("Int = %d", uint64(math.MaxInt64+1)),
|
||||
`| toml: error: 9223372036854775808 is out of range for int64
|
||||
|
|
||||
| At line 1, column 6-25:
|
||||
|
|
||||
| 1 | Int = 9223372036854775808
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
| Error help:
|
||||
|
|
||||
| This number is too large; this may be an error in the TOML, but it can also be a
|
||||
| bug in the program that uses too small of an integer.
|
||||
|
|
||||
| The maximum and minimum values are:
|
||||
|
|
||||
| size │ lowest │ highest
|
||||
| ───────┼────────────────┼──────────
|
||||
| int8 │ -128 │ 127
|
||||
| int16 │ -32,768 │ 32,767
|
||||
| int32 │ -2,147,483,648 │ 2,147,483,647
|
||||
| int64 │ -9.2 × 10¹⁷ │ 9.2 × 10¹⁷
|
||||
| uint8 │ 0 │ 255
|
||||
| uint16 │ 0 │ 65535
|
||||
| uint32 │ 0 │ 4294967295
|
||||
| uint64 │ 0 │ 1.8 × 10¹⁸
|
||||
|
|
||||
| int refers to int32 on 32-bit systems and int64 on 64-bit systems.
|
||||
`,
|
||||
},
|
||||
{
|
||||
&struct{ Float float32 }{},
|
||||
"Float = 1.1e99",
|
||||
`
|
||||
| toml: error: 1.1e+99 is out of range for float32
|
||||
|
|
||||
| At line 1, column 8-14:
|
||||
|
|
||||
| 1 | Float = 1.1e99
|
||||
| ^^^^^^
|
||||
| Error help:
|
||||
|
|
||||
| This number is too large; this may be an error in the TOML, but it can also be a
|
||||
| bug in the program that uses too small of an integer.
|
||||
|
|
||||
| The maximum and minimum values are:
|
||||
|
|
||||
| size │ lowest │ highest
|
||||
| ───────┼────────────────┼──────────
|
||||
| int8 │ -128 │ 127
|
||||
| int16 │ -32,768 │ 32,767
|
||||
| int32 │ -2,147,483,648 │ 2,147,483,647
|
||||
| int64 │ -9.2 × 10¹⁷ │ 9.2 × 10¹⁷
|
||||
| uint8 │ 0 │ 255
|
||||
| uint16 │ 0 │ 65535
|
||||
| uint32 │ 0 │ 4294967295
|
||||
| uint64 │ 0 │ 1.8 × 10¹⁸
|
||||
|
|
||||
| int refers to int32 on 32-bit systems and int64 on 64-bit systems.
|
||||
`,
|
||||
},
|
||||
|
||||
{
|
||||
&struct{ D time.Duration }{},
|
||||
`D = "99 bottles"`,
|
||||
`
|
||||
| toml: error: invalid duration: "99 bottles"
|
||||
|
|
||||
| At line 1, column 5-15:
|
||||
|
|
||||
| 1 | D = "99 bottles"
|
||||
| ^^^^^^^^^^
|
||||
| Error help:
|
||||
|
|
||||
| A duration must be as "number<unit>", without any spaces. Valid units are:
|
||||
|
|
||||
| ns nanoseconds (billionth of a second)
|
||||
| us, µs microseconds (millionth of a second)
|
||||
| ms milliseconds (thousands of a second)
|
||||
| s seconds
|
||||
| m minutes
|
||||
| h hours
|
||||
|
|
||||
| You can combine multiple units; for example "5m10s" for 5 minutes and 10
|
||||
| seconds.
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
prep := func(s string) string {
|
||||
lines := strings.Split(strings.TrimSpace(s), "\n")
|
||||
for i := range lines {
|
||||
if j := strings.IndexByte(lines[i], '|'); j >= 0 {
|
||||
lines[i] = lines[i][j+1:]
|
||||
lines[i] = strings.Replace(lines[i], " ", "", 1)
|
||||
}
|
||||
}
|
||||
return strings.Join(lines, "\n") + "\n"
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run("", func(t *testing.T) {
|
||||
_, err := toml.Decode(tt.toml, tt.in)
|
||||
if err == nil {
|
||||
t.Fatalf("err is nil; decoded: %#v", tt.in)
|
||||
}
|
||||
|
||||
var pErr toml.ParseError
|
||||
if !errors.As(err, &pErr) {
|
||||
t.Fatalf("err is not a ParseError: %#v", err)
|
||||
}
|
||||
|
||||
tt.err = prep(tt.err)
|
||||
have := pErr.ErrorWithUsage()
|
||||
|
||||
// have = strings.ReplaceAll(have, " ", "·")
|
||||
// tt.err = strings.ReplaceAll(tt.err, " ", "·")
|
||||
if have != tt.err {
|
||||
t.Fatalf("\nwant:\n%s\nhave:\n%s", tt.err, have)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user