Upgrade to golangci-lint v2 (#1008)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
// Package assert provides assertion functions for unit testing.
|
||||
package assert
|
||||
|
||||
import (
|
||||
@@ -9,66 +10,67 @@ import (
|
||||
)
|
||||
|
||||
// True asserts that an expression is true.
|
||||
func True(t testing.TB, ok bool, msgAndArgs ...any) {
|
||||
func True(tb testing.TB, ok bool, msgAndArgs ...any) {
|
||||
tb.Helper()
|
||||
if ok {
|
||||
return
|
||||
}
|
||||
t.Helper()
|
||||
t.Fatal(formatMsgAndArgs("Expected expression to be true", msgAndArgs...))
|
||||
tb.Fatal(formatMsgAndArgs("Expected expression to be true", msgAndArgs...))
|
||||
}
|
||||
|
||||
// False asserts that an expression is false.
|
||||
func False(t testing.TB, ok bool, msgAndArgs ...any) {
|
||||
func False(tb testing.TB, ok bool, msgAndArgs ...any) {
|
||||
tb.Helper()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
t.Helper()
|
||||
t.Fatal(formatMsgAndArgs("Expected expression to be false", msgAndArgs...))
|
||||
tb.Fatal(formatMsgAndArgs("Expected expression to be false", msgAndArgs...))
|
||||
}
|
||||
|
||||
// Equal asserts that "expected" and "actual" are equal.
|
||||
func Equal[T any](t testing.TB, expected, actual T, msgAndArgs ...any) {
|
||||
func Equal[T any](tb testing.TB, expected, actual T, msgAndArgs ...any) {
|
||||
tb.Helper()
|
||||
if objectsAreEqual(expected, actual) {
|
||||
return
|
||||
}
|
||||
t.Helper()
|
||||
msg := formatMsgAndArgs("Expected values to be equal:", msgAndArgs...)
|
||||
t.Fatalf("%s\n%s", msg, diff(expected, actual))
|
||||
tb.Fatalf("%s\n%s", msg, diff(expected, actual))
|
||||
}
|
||||
|
||||
// Error asserts that an error is not nil.
|
||||
func Error(t testing.TB, err error, msgAndArgs ...any) {
|
||||
func Error(tb testing.TB, err error, msgAndArgs ...any) {
|
||||
tb.Helper()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
t.Helper()
|
||||
t.Fatal(formatMsgAndArgs("Expected an error", msgAndArgs...))
|
||||
tb.Fatal(formatMsgAndArgs("Expected an error", msgAndArgs...))
|
||||
}
|
||||
|
||||
// NoError asserts that an error is nil.
|
||||
func NoError(t testing.TB, err error, msgAndArgs ...any) {
|
||||
func NoError(tb testing.TB, err error, msgAndArgs ...any) {
|
||||
tb.Helper()
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
t.Helper()
|
||||
msg := formatMsgAndArgs("Unexpected error:", msgAndArgs...)
|
||||
t.Fatalf("%s\n%+v", msg, err)
|
||||
tb.Fatalf("%s\n%+v", msg, err)
|
||||
}
|
||||
|
||||
// Panics asserts that the given function panics.
|
||||
func Panics(t testing.TB, fn func(), msgAndArgs ...any) {
|
||||
t.Helper()
|
||||
func Panics(tb testing.TB, fn func(), msgAndArgs ...any) {
|
||||
tb.Helper()
|
||||
defer func() {
|
||||
if recover() == nil {
|
||||
msg := formatMsgAndArgs("Expected function to panic", msgAndArgs...)
|
||||
t.Fatal(msg)
|
||||
tb.Fatal(msg)
|
||||
}
|
||||
}()
|
||||
fn()
|
||||
}
|
||||
|
||||
// Zero asserts that a value is its zero value.
|
||||
func Zero[T any](t testing.TB, value T, msgAndArgs ...any) {
|
||||
func Zero[T any](tb testing.TB, value T, msgAndArgs ...any) {
|
||||
tb.Helper()
|
||||
var zero T
|
||||
if objectsAreEqual(value, zero) {
|
||||
return
|
||||
@@ -77,22 +79,26 @@ func Zero[T any](t testing.TB, value T, msgAndArgs ...any) {
|
||||
if (val.Kind() == reflect.Slice || val.Kind() == reflect.Map || val.Kind() == reflect.Array) && val.Len() == 0 {
|
||||
return
|
||||
}
|
||||
t.Helper()
|
||||
msg := formatMsgAndArgs("Expected zero value but got:", msgAndArgs...)
|
||||
t.Fatalf("%s\n%v", msg, value)
|
||||
tb.Fatalf("%s\n%v", msg, value)
|
||||
}
|
||||
|
||||
func NotZero[T any](t testing.TB, value T, msgAndArgs ...any) {
|
||||
func NotZero[T any](tb testing.TB, value T, msgAndArgs ...any) {
|
||||
tb.Helper()
|
||||
var zero T
|
||||
if !objectsAreEqual(value, zero) {
|
||||
val := reflect.ValueOf(value)
|
||||
if !((val.Kind() == reflect.Slice || val.Kind() == reflect.Map || val.Kind() == reflect.Array) && val.Len() == 0) {
|
||||
switch val.Kind() {
|
||||
case reflect.Slice, reflect.Map, reflect.Array:
|
||||
if val.Len() > 0 {
|
||||
return
|
||||
}
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Helper()
|
||||
msg := formatMsgAndArgs("Unexpected zero value:", msgAndArgs...)
|
||||
t.Fatalf("%s\n%v", msg, value)
|
||||
tb.Fatalf("%s\n%v", msg, value)
|
||||
}
|
||||
|
||||
func formatMsgAndArgs(msg string, args ...any) string {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package assert
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
@@ -12,135 +13,167 @@ type Data struct {
|
||||
|
||||
func TestBadMessage(t *testing.T) {
|
||||
invalidMessage := func() { True(t, false, 1234) }
|
||||
assertOk(t, "Non-fmt message value", func(t testing.TB) {
|
||||
Panics(t, invalidMessage)
|
||||
assertOk(t, "Non-fmt message value", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Panics(tb, invalidMessage)
|
||||
})
|
||||
assertFail(t, "Non-fmt message value", func(t testing.TB) {
|
||||
True(t, false, "example %s", "message")
|
||||
assertFail(t, "Non-fmt message value", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
True(tb, false, "example %s", "message")
|
||||
})
|
||||
}
|
||||
|
||||
func TestTrue(t *testing.T) {
|
||||
assertOk(t, "Succeed", func(t testing.TB) {
|
||||
True(t, 1 > 0)
|
||||
assertOk(t, "Succeed", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
True(tb, 1 > 0)
|
||||
})
|
||||
assertFail(t, "Fail", func(t testing.TB) {
|
||||
True(t, 1 < 0)
|
||||
assertFail(t, "Fail", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
True(tb, 1 < 0)
|
||||
})
|
||||
}
|
||||
|
||||
func TestFalse(t *testing.T) {
|
||||
assertOk(t, "Succeed", func(t testing.TB) {
|
||||
False(t, 1 < 0)
|
||||
assertOk(t, "Succeed", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
False(tb, 1 < 0)
|
||||
})
|
||||
assertFail(t, "Fail", func(t testing.TB) {
|
||||
False(t, 1 > 0)
|
||||
assertFail(t, "Fail", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
False(tb, 1 > 0)
|
||||
})
|
||||
}
|
||||
|
||||
func TestEqual(t *testing.T) {
|
||||
assertOk(t, "Nil", func(t testing.TB) {
|
||||
Equal(t, interface{}(nil), interface{}(nil))
|
||||
assertOk(t, "Nil", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Equal(tb, interface{}(nil), interface{}(nil))
|
||||
})
|
||||
assertOk(t, "Identical structs", func(t testing.TB) {
|
||||
Equal(t, Data{"expected", 1234}, Data{"expected", 1234})
|
||||
assertOk(t, "Identical structs", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Equal(tb, Data{"expected", 1234}, Data{"expected", 1234})
|
||||
})
|
||||
assertFail(t, "Different structs", func(t testing.TB) {
|
||||
Equal(t, Data{"expected", 1234}, Data{"actual", 1234})
|
||||
assertFail(t, "Different structs", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Equal(tb, Data{"expected", 1234}, Data{"actual", 1234})
|
||||
})
|
||||
assertOk(t, "Identical numbers", func(t testing.TB) {
|
||||
Equal(t, 1234, 1234)
|
||||
assertOk(t, "Identical numbers", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Equal(tb, 1234, 1234)
|
||||
})
|
||||
assertFail(t, "Identical numbers", func(t testing.TB) {
|
||||
Equal(t, 1234, 1324)
|
||||
assertFail(t, "Identical numbers", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Equal(tb, 1234, 1324)
|
||||
})
|
||||
assertOk(t, "Zero-length byte arrays", func(t testing.TB) {
|
||||
Equal(t, []byte(nil), []byte(""))
|
||||
assertOk(t, "Zero-length byte arrays", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Equal(tb, []byte(nil), []byte(""))
|
||||
})
|
||||
assertOk(t, "Identical byte arrays", func(t testing.TB) {
|
||||
Equal(t, []byte{1, 2, 3, 4}, []byte{1, 2, 3, 4})
|
||||
assertOk(t, "Identical byte arrays", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Equal(tb, []byte{1, 2, 3, 4}, []byte{1, 2, 3, 4})
|
||||
})
|
||||
assertFail(t, "Different byte arrays", func(t testing.TB) {
|
||||
Equal(t, []byte{1, 2, 3, 4}, []byte{1, 3, 2, 4})
|
||||
assertFail(t, "Different byte arrays", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Equal(tb, []byte{1, 2, 3, 4}, []byte{1, 3, 2, 4})
|
||||
})
|
||||
assertOk(t, "Identical strings", func(t testing.TB) {
|
||||
Equal(t, "example", "example")
|
||||
assertOk(t, "Identical strings", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Equal(tb, "example", "example")
|
||||
})
|
||||
assertFail(t, "Identical strings", func(t testing.TB) {
|
||||
Equal(t, "example", "elpmaxe")
|
||||
assertFail(t, "Identical strings", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Equal(tb, "example", "elpmaxe")
|
||||
})
|
||||
}
|
||||
|
||||
func TestError(t *testing.T) {
|
||||
assertOk(t, "Error", func(t testing.TB) {
|
||||
Error(t, fmt.Errorf("example"))
|
||||
assertOk(t, "Error", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Error(tb, errors.New("example"))
|
||||
})
|
||||
assertFail(t, "Nil", func(t testing.TB) {
|
||||
Error(t, nil)
|
||||
assertFail(t, "Nil", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Error(tb, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNoError(t *testing.T) {
|
||||
assertFail(t, "Error", func(t testing.TB) {
|
||||
NoError(t, fmt.Errorf("example"))
|
||||
assertFail(t, "Error", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
NoError(tb, errors.New("example"))
|
||||
})
|
||||
assertOk(t, "Nil", func(t testing.TB) {
|
||||
NoError(t, nil)
|
||||
assertOk(t, "Nil", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
NoError(tb, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPanics(t *testing.T) {
|
||||
willPanic := func() { panic("example") }
|
||||
wontPanic := func() {}
|
||||
assertOk(t, "Will panic", func(t testing.TB) {
|
||||
Panics(t, willPanic)
|
||||
assertOk(t, "Will panic", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Panics(tb, willPanic)
|
||||
})
|
||||
assertFail(t, "Won't panic", func(t testing.TB) {
|
||||
Panics(t, wontPanic)
|
||||
assertFail(t, "Won't panic", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Panics(tb, wontPanic)
|
||||
})
|
||||
}
|
||||
|
||||
func TestZero(t *testing.T) {
|
||||
assertOk(t, "Empty struct", func(t testing.TB) {
|
||||
Zero(t, Data{})
|
||||
assertOk(t, "Empty struct", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Zero(tb, Data{})
|
||||
})
|
||||
assertFail(t, "Non-empty struct", func(t testing.TB) {
|
||||
Zero(t, Data{Label: "example"})
|
||||
assertFail(t, "Non-empty struct", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
Zero(tb, Data{Label: "example"})
|
||||
})
|
||||
assertOk(t, "Nil slice", func(t testing.TB) {
|
||||
assertOk(t, "Nil slice", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
var slice []int
|
||||
Zero(t, slice)
|
||||
Zero(tb, slice)
|
||||
})
|
||||
assertFail(t, "Non-empty slice", func(t testing.TB) {
|
||||
assertFail(t, "Non-empty slice", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
slice := []int{1, 2, 3, 4}
|
||||
Zero(t, slice)
|
||||
Zero(tb, slice)
|
||||
})
|
||||
assertOk(t, "Zero-length slice", func(t testing.TB) {
|
||||
assertOk(t, "Zero-length slice", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
slice := []int{}
|
||||
Zero(t, slice)
|
||||
Zero(tb, slice)
|
||||
})
|
||||
}
|
||||
|
||||
func TestNotZero(t *testing.T) {
|
||||
assertFail(t, "Empty struct", func(t testing.TB) {
|
||||
assertFail(t, "Empty struct", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
zero := Data{}
|
||||
NotZero(t, zero)
|
||||
NotZero(tb, zero)
|
||||
})
|
||||
assertOk(t, "Non-empty struct", func(t testing.TB) {
|
||||
assertOk(t, "Non-empty struct", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
notZero := Data{Label: "example"}
|
||||
NotZero(t, notZero)
|
||||
NotZero(tb, notZero)
|
||||
})
|
||||
assertFail(t, "Nil slice", func(t testing.TB) {
|
||||
assertFail(t, "Nil slice", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
var slice []int
|
||||
NotZero(t, slice)
|
||||
NotZero(tb, slice)
|
||||
})
|
||||
assertFail(t, "Zero-length slice", func(t testing.TB) {
|
||||
assertFail(t, "Zero-length slice", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
slice := []int{}
|
||||
NotZero(t, slice)
|
||||
NotZero(tb, slice)
|
||||
})
|
||||
assertOk(t, "Non-empty slice", func(t testing.TB) {
|
||||
assertOk(t, "Non-empty slice", func(tb testing.TB) {
|
||||
tb.Helper()
|
||||
slice := []int{1, 2, 3, 4}
|
||||
NotZero(t, slice)
|
||||
NotZero(tb, slice)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -157,7 +190,7 @@ func (t *testCase) Fatalf(message string, args ...interface{}) {
|
||||
t.failed = fmt.Sprintf(message, args...)
|
||||
}
|
||||
|
||||
func assertFail(t *testing.T, name string, fn func(t testing.TB)) {
|
||||
func assertFail(t *testing.T, name string, fn func(testing.TB)) {
|
||||
t.Helper()
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Helper()
|
||||
@@ -171,7 +204,7 @@ func assertFail(t *testing.T, name string, fn func(t testing.TB)) {
|
||||
})
|
||||
}
|
||||
|
||||
func assertOk(t *testing.T, name string, fn func(t testing.TB)) {
|
||||
func assertOk(t *testing.T, name string, fn func(testing.TB)) {
|
||||
t.Helper()
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Helper()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package characters
|
||||
|
||||
var invalidAsciiTable = [256]bool{
|
||||
var invalidASCIITable = [256]bool{
|
||||
0x00: true,
|
||||
0x01: true,
|
||||
0x02: true,
|
||||
@@ -37,6 +37,6 @@ var invalidAsciiTable = [256]bool{
|
||||
0x7F: true,
|
||||
}
|
||||
|
||||
func InvalidAscii(b byte) bool {
|
||||
return invalidAsciiTable[b]
|
||||
func InvalidASCII(b byte) bool {
|
||||
return invalidASCIITable[b]
|
||||
}
|
||||
|
||||
+22
-46
@@ -1,20 +1,12 @@
|
||||
// Package characters provides functions for working with string encodings.
|
||||
package characters
|
||||
|
||||
import (
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type utf8Err struct {
|
||||
Index int
|
||||
Size int
|
||||
}
|
||||
|
||||
func (u utf8Err) Zero() bool {
|
||||
return u.Size == 0
|
||||
}
|
||||
|
||||
// Verified that a given string is only made of valid UTF-8 characters allowed
|
||||
// by the TOML spec:
|
||||
// Utf8TomlValidAlreadyEscaped verifies that a given string is only made of
|
||||
// valid UTF-8 characters allowed by the TOML spec:
|
||||
//
|
||||
// Any Unicode character may be used except those that must be escaped:
|
||||
// quotation mark, backslash, and the control characters other than tab (U+0000
|
||||
@@ -23,8 +15,8 @@ func (u utf8Err) Zero() bool {
|
||||
// It is a copy of the Go 1.17 utf8.Valid implementation, tweaked to exit early
|
||||
// when a character is not allowed.
|
||||
//
|
||||
// The returned utf8Err is Zero() if the string is valid, or contains the byte
|
||||
// index and size of the invalid character.
|
||||
// The returned slice is empty if the string is valid, or contains the bytes
|
||||
// of the invalid character.
|
||||
//
|
||||
// quotation mark => already checked
|
||||
// backslash => already checked
|
||||
@@ -32,9 +24,8 @@ func (u utf8Err) Zero() bool {
|
||||
// 0x9 => tab, ok
|
||||
// 0xA - 0x1F => invalid
|
||||
// 0x7F => invalid
|
||||
func Utf8TomlValidAlreadyEscaped(p []byte) (err utf8Err) {
|
||||
func Utf8TomlValidAlreadyEscaped(p []byte) []byte {
|
||||
// Fast path. Check for and skip 8 bytes of ASCII characters per iteration.
|
||||
offset := 0
|
||||
for len(p) >= 8 {
|
||||
// Combining two 32 bit loads allows the same code to be used
|
||||
// for 32 and 64 bit platforms.
|
||||
@@ -48,24 +39,19 @@ func Utf8TomlValidAlreadyEscaped(p []byte) (err utf8Err) {
|
||||
}
|
||||
|
||||
for i, b := range p[:8] {
|
||||
if InvalidAscii(b) {
|
||||
err.Index = offset + i
|
||||
err.Size = 1
|
||||
return
|
||||
if InvalidASCII(b) {
|
||||
return p[i : i+1]
|
||||
}
|
||||
}
|
||||
|
||||
p = p[8:]
|
||||
offset += 8
|
||||
}
|
||||
n := len(p)
|
||||
for i := 0; i < n; {
|
||||
pi := p[i]
|
||||
if pi < utf8.RuneSelf {
|
||||
if InvalidAscii(pi) {
|
||||
err.Index = offset + i
|
||||
err.Size = 1
|
||||
return
|
||||
if InvalidASCII(pi) {
|
||||
return p[i : i+1]
|
||||
}
|
||||
i++
|
||||
continue
|
||||
@@ -73,44 +59,34 @@ func Utf8TomlValidAlreadyEscaped(p []byte) (err utf8Err) {
|
||||
x := first[pi]
|
||||
if x == xx {
|
||||
// Illegal starter byte.
|
||||
err.Index = offset + i
|
||||
err.Size = 1
|
||||
return
|
||||
return p[i : i+1]
|
||||
}
|
||||
size := int(x & 7)
|
||||
if i+size > n {
|
||||
// Short or invalid.
|
||||
err.Index = offset + i
|
||||
err.Size = n - i
|
||||
return
|
||||
return p[i:n]
|
||||
}
|
||||
accept := acceptRanges[x>>4]
|
||||
if c := p[i+1]; c < accept.lo || accept.hi < c {
|
||||
err.Index = offset + i
|
||||
err.Size = 2
|
||||
return
|
||||
} else if size == 2 {
|
||||
return p[i : i+2]
|
||||
} else if size == 2 { //revive:disable:empty-block
|
||||
} else if c := p[i+2]; c < locb || hicb < c {
|
||||
err.Index = offset + i
|
||||
err.Size = 3
|
||||
return
|
||||
} else if size == 3 {
|
||||
return p[i : i+3]
|
||||
} else if size == 3 { //revive:disable:empty-block
|
||||
} else if c := p[i+3]; c < locb || hicb < c {
|
||||
err.Index = offset + i
|
||||
err.Size = 4
|
||||
return
|
||||
return p[i : i+4]
|
||||
}
|
||||
i += size
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// Return the size of the next rune if valid, 0 otherwise.
|
||||
// Utf8ValidNext returns the size of the next rune if valid, 0 otherwise.
|
||||
func Utf8ValidNext(p []byte) int {
|
||||
c := p[0]
|
||||
|
||||
if c < utf8.RuneSelf {
|
||||
if InvalidAscii(c) {
|
||||
if InvalidASCII(c) {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
@@ -129,10 +105,10 @@ func Utf8ValidNext(p []byte) int {
|
||||
accept := acceptRanges[x>>4]
|
||||
if c := p[1]; c < accept.lo || accept.hi < c {
|
||||
return 0
|
||||
} else if size == 2 {
|
||||
} else if size == 2 { //nolint:revive
|
||||
} else if c := p[2]; c < locb || hicb < c {
|
||||
return 0
|
||||
} else if size == 3 {
|
||||
} else if size == 3 { //nolint:revive
|
||||
} else if c := p[3]; c < locb || hicb < c {
|
||||
return 0
|
||||
}
|
||||
|
||||
+8
-8
@@ -1,3 +1,4 @@
|
||||
// Package cli provides common functions for command-line programs.
|
||||
package cli
|
||||
|
||||
import (
|
||||
@@ -27,17 +28,16 @@ func (p *Program) Execute() {
|
||||
os.Exit(p.main(flag.Args(), os.Stdin, os.Stdout, os.Stderr))
|
||||
}
|
||||
|
||||
func (p *Program) main(files []string, input io.Reader, output, error io.Writer) int {
|
||||
func (p *Program) main(files []string, input io.Reader, output, stderr io.Writer) int {
|
||||
err := p.run(files, input, output)
|
||||
if err != nil {
|
||||
|
||||
var derr *toml.DecodeError
|
||||
if errors.As(err, &derr) {
|
||||
fmt.Fprintln(error, derr.String())
|
||||
_, _ = fmt.Fprintln(stderr, derr.String())
|
||||
row, col := derr.Position()
|
||||
fmt.Fprintln(error, "error occurred at row", row, "column", col)
|
||||
_, _ = fmt.Fprintln(stderr, "error occurred at row", row, "column", col)
|
||||
} else {
|
||||
fmt.Fprintln(error, err.Error())
|
||||
_, _ = fmt.Fprintln(stderr, err.Error())
|
||||
}
|
||||
|
||||
return -1
|
||||
@@ -54,7 +54,7 @@ func (p *Program) run(files []string, input io.Reader, output io.Writer) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
defer func() { _ = f.Close() }()
|
||||
input = f
|
||||
}
|
||||
return p.Fn(input, output)
|
||||
@@ -71,7 +71,7 @@ func (p *Program) runAllFilesInPlace(files []string) error {
|
||||
}
|
||||
|
||||
func (p *Program) runFileInPlace(path string) error {
|
||||
in, err := os.ReadFile(path)
|
||||
in, err := os.ReadFile(path) // #nosec G304
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -83,5 +83,5 @@ func (p *Program) runFileInPlace(path string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.WriteFile(path, out.Bytes(), 0600)
|
||||
return os.WriteFile(path, out.Bytes(), 0o600)
|
||||
}
|
||||
|
||||
+16
-20
@@ -2,7 +2,7 @@ package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
@@ -23,7 +23,7 @@ func TestProcessMainStdin(t *testing.T) {
|
||||
stderr := new(bytes.Buffer)
|
||||
input := strings.NewReader("this is the input")
|
||||
|
||||
exit := processMain([]string{}, input, stdout, stderr, func(r io.Reader, w io.Writer) error {
|
||||
exit := processMain([]string{}, input, stdout, stderr, func(io.Reader, io.Writer) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -37,8 +37,8 @@ func TestProcessMainStdinErr(t *testing.T) {
|
||||
stderr := new(bytes.Buffer)
|
||||
input := strings.NewReader("this is the input")
|
||||
|
||||
exit := processMain([]string{}, input, stdout, stderr, func(r io.Reader, w io.Writer) error {
|
||||
return fmt.Errorf("something bad")
|
||||
exit := processMain([]string{}, input, stdout, stderr, func(io.Reader, io.Writer) error {
|
||||
return errors.New("something bad")
|
||||
})
|
||||
|
||||
assert.Equal(t, -1, exit)
|
||||
@@ -51,7 +51,7 @@ func TestProcessMainStdinDecodeErr(t *testing.T) {
|
||||
stderr := new(bytes.Buffer)
|
||||
input := strings.NewReader("this is the input")
|
||||
|
||||
exit := processMain([]string{}, input, stdout, stderr, func(r io.Reader, w io.Writer) error {
|
||||
exit := processMain([]string{}, input, stdout, stderr, func(io.Reader, io.Writer) error {
|
||||
var v interface{}
|
||||
return toml.Unmarshal([]byte(`qwe = 001`), &v)
|
||||
})
|
||||
@@ -62,16 +62,16 @@ func TestProcessMainStdinDecodeErr(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestProcessMainFileExists(t *testing.T) {
|
||||
tmpfile, err := os.CreateTemp("", "example")
|
||||
tmpfile, err := os.CreateTemp(t.TempDir(), "example")
|
||||
assert.NoError(t, err)
|
||||
defer os.Remove(tmpfile.Name())
|
||||
_, err = tmpfile.Write([]byte(`some data`))
|
||||
_, err = tmpfile.WriteString(`some data`)
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, tmpfile.Close())
|
||||
|
||||
stdout := new(bytes.Buffer)
|
||||
stderr := new(bytes.Buffer)
|
||||
|
||||
exit := processMain([]string{tmpfile.Name()}, nil, stdout, stderr, func(r io.Reader, w io.Writer) error {
|
||||
exit := processMain([]string{tmpfile.Name()}, nil, stdout, stderr, func(io.Reader, io.Writer) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -84,7 +84,7 @@ func TestProcessMainFileDoesNotExist(t *testing.T) {
|
||||
stdout := new(bytes.Buffer)
|
||||
stderr := new(bytes.Buffer)
|
||||
|
||||
exit := processMain([]string{"/lets/hope/this/does/not/exist"}, nil, stdout, stderr, func(r io.Reader, w io.Writer) error {
|
||||
exit := processMain([]string{"/lets/hope/this/does/not/exist"}, nil, stdout, stderr, func(io.Reader, io.Writer) error {
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -94,16 +94,14 @@ func TestProcessMainFileDoesNotExist(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestProcessMainFilesInPlace(t *testing.T) {
|
||||
dir, err := os.MkdirTemp("", "")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(dir)
|
||||
dir := t.TempDir()
|
||||
|
||||
path1 := path.Join(dir, "file1")
|
||||
path2 := path.Join(dir, "file2")
|
||||
|
||||
err = os.WriteFile(path1, []byte("content 1"), 0600)
|
||||
err := os.WriteFile(path1, []byte("content 1"), 0o600)
|
||||
assert.NoError(t, err)
|
||||
err = os.WriteFile(path2, []byte("content 2"), 0600)
|
||||
err = os.WriteFile(path2, []byte("content 2"), 0o600)
|
||||
assert.NoError(t, err)
|
||||
|
||||
p := Program{
|
||||
@@ -136,17 +134,15 @@ func TestProcessMainFilesInPlaceErrRead(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestProcessMainFilesInPlaceFailFn(t *testing.T) {
|
||||
dir, err := os.MkdirTemp("", "")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(dir)
|
||||
dir := t.TempDir()
|
||||
|
||||
path1 := path.Join(dir, "file1")
|
||||
|
||||
err = os.WriteFile(path1, []byte("content 1"), 0600)
|
||||
err := os.WriteFile(path1, []byte("content 1"), 0o600)
|
||||
assert.NoError(t, err)
|
||||
|
||||
p := Program{
|
||||
Fn: func(io.Reader, io.Writer) error { return fmt.Errorf("oh no") },
|
||||
Fn: func(io.Reader, io.Writer) error { return errors.New("oh no") },
|
||||
Inplace: true,
|
||||
}
|
||||
|
||||
|
||||
+20
-21
@@ -1,21 +1,21 @@
|
||||
// Package danger provides optimized unsafe functions.
|
||||
package danger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const maxInt = uintptr(int(^uint(0) >> 1))
|
||||
|
||||
func SubsliceOffset(data []byte, subslice []byte) int {
|
||||
datap := (*reflect.SliceHeader)(unsafe.Pointer(&data))
|
||||
hlp := (*reflect.SliceHeader)(unsafe.Pointer(&subslice))
|
||||
datap := uintptr(unsafe.Pointer(unsafe.SliceData(data))) // #nosec G103
|
||||
hlp := uintptr(unsafe.Pointer(unsafe.SliceData(subslice))) // #nosec G103
|
||||
|
||||
if hlp.Data < datap.Data {
|
||||
panic(fmt.Errorf("subslice address (%d) is before data address (%d)", hlp.Data, datap.Data))
|
||||
if hlp < datap {
|
||||
panic(fmt.Errorf("subslice address (%d) is before data address (%d)", hlp, datap))
|
||||
}
|
||||
offset := hlp.Data - datap.Data
|
||||
offset := hlp - datap
|
||||
|
||||
if offset > maxInt {
|
||||
panic(fmt.Errorf("slice offset larger than int (%d)", offset))
|
||||
@@ -23,12 +23,12 @@ func SubsliceOffset(data []byte, subslice []byte) int {
|
||||
|
||||
intoffset := int(offset)
|
||||
|
||||
if intoffset > datap.Len {
|
||||
panic(fmt.Errorf("slice offset (%d) is farther than data length (%d)", intoffset, datap.Len))
|
||||
if intoffset > len(data) {
|
||||
panic(fmt.Errorf("slice offset (%d) is farther than data length (%d)", intoffset, len(data)))
|
||||
}
|
||||
|
||||
if intoffset+hlp.Len > datap.Len {
|
||||
panic(fmt.Errorf("slice ends (%d+%d) is farther than data length (%d)", intoffset, hlp.Len, datap.Len))
|
||||
if intoffset+len(subslice) > len(data) {
|
||||
panic(fmt.Errorf("slice ends (%d+%d) is farther than data length (%d)", intoffset, len(subslice), len(data)))
|
||||
}
|
||||
|
||||
return intoffset
|
||||
@@ -38,28 +38,27 @@ func BytesRange(start []byte, end []byte) []byte {
|
||||
if start == nil || end == nil {
|
||||
panic("cannot call BytesRange with nil")
|
||||
}
|
||||
startp := (*reflect.SliceHeader)(unsafe.Pointer(&start))
|
||||
endp := (*reflect.SliceHeader)(unsafe.Pointer(&end))
|
||||
|
||||
if startp.Data > endp.Data {
|
||||
panic(fmt.Errorf("start pointer address (%d) is after end pointer address (%d)", startp.Data, endp.Data))
|
||||
startp := uintptr(unsafe.Pointer(unsafe.SliceData(start))) // #nosec G103
|
||||
endp := uintptr(unsafe.Pointer(unsafe.SliceData(end))) // #nosec G103
|
||||
|
||||
if startp > endp {
|
||||
panic(fmt.Errorf("start pointer address (%d) is after end pointer address (%d)", startp, endp))
|
||||
}
|
||||
|
||||
l := startp.Len
|
||||
endLen := int(endp.Data-startp.Data) + endp.Len
|
||||
l := len(start)
|
||||
endLen := int(endp-startp) + len(end)
|
||||
if endLen > l {
|
||||
l = endLen
|
||||
}
|
||||
|
||||
if l > startp.Cap {
|
||||
panic(fmt.Errorf("range length is larger than capacity"))
|
||||
if l > cap(start) {
|
||||
panic("range length is larger than capacity")
|
||||
}
|
||||
|
||||
return start[:l]
|
||||
}
|
||||
|
||||
func Stride(ptr unsafe.Pointer, size uintptr, offset int) unsafe.Pointer {
|
||||
// TODO: replace with unsafe.Add when Go 1.17 is released
|
||||
// https://github.com/golang/go/issues/40481
|
||||
return unsafe.Pointer(uintptr(ptr) + uintptr(int(size)*offset))
|
||||
return unsafe.Add(ptr, size*uintptr(offset))
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// typeID is used as key in encoder and decoder caches to enable using
|
||||
// TypeID is used as key in encoder and decoder caches to enable using
|
||||
// the optimize runtime.mapaccess2_fast64 function instead of the more
|
||||
// expensive lookup if we were to use reflect.Type as map key.
|
||||
//
|
||||
@@ -19,5 +19,5 @@ func MakeTypeID(t reflect.Type) TypeID {
|
||||
// reflect.Type has the fields:
|
||||
// typ unsafe.Pointer
|
||||
// ptr unsafe.Pointer
|
||||
return TypeID((*[2]unsafe.Pointer)(unsafe.Pointer(&t))[1])
|
||||
return TypeID((*[2]unsafe.Pointer)(unsafe.Pointer(&t))[1]) // #nosec G103
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package imported_tests
|
||||
package imported_tests //revive:disable:var-naming
|
||||
|
||||
// Those tests have been imported from v1, but adjust to match the new
|
||||
// defaults of v2.
|
||||
@@ -21,12 +21,12 @@ func TestDocMarshal(t *testing.T) {
|
||||
Subdocs testDocSubs `toml:"subdoc"`
|
||||
Basics testDocBasics `toml:"basic"`
|
||||
SubDocList []testSubDoc `toml:"subdoclist"`
|
||||
err int `toml:"shouldntBeHere"`
|
||||
err int `toml:"shouldntBeHere"` //nolint:unused
|
||||
unexported int `toml:"shouldntBeHere"`
|
||||
Unexported2 int `toml:"-"`
|
||||
}
|
||||
|
||||
var docData = testDoc{
|
||||
docData := testDoc{
|
||||
Title: "TOML Marshal Testing",
|
||||
unexported: 0,
|
||||
Unexported2: 0,
|
||||
@@ -128,8 +128,7 @@ String2 = 'Two'
|
||||
String2 = 'Three'
|
||||
`
|
||||
|
||||
assert.Equal(t, string(expected), string(result))
|
||||
|
||||
assert.Equal(t, expected, string(result))
|
||||
}
|
||||
|
||||
func TestEmptyMarshal(t *testing.T) {
|
||||
@@ -164,7 +163,7 @@ stringlist = []
|
||||
[map]
|
||||
`
|
||||
|
||||
assert.Equal(t, string(expected), string(result))
|
||||
assert.Equal(t, expected, string(result))
|
||||
}
|
||||
|
||||
type textMarshaler struct {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package imported_tests
|
||||
package imported_tests //revive:disable:var-naming
|
||||
|
||||
// Those tests were imported directly from go-toml v1
|
||||
// https://raw.githubusercontent.com/pelletier/go-toml/a2e52561804c6cd9392ebf0048ca64fe4af67a43/marshal_test.go
|
||||
@@ -149,9 +149,6 @@ type quotedKeyMarshalTestStruct struct {
|
||||
SubList []basicMarshalTestSubStruct `toml:"W.sublist-𝟘"`
|
||||
}
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
var quotedKeyMarshalTestData = quotedKeyMarshalTestStruct{
|
||||
String: "Hello",
|
||||
Float: 3.5,
|
||||
@@ -161,7 +158,7 @@ var quotedKeyMarshalTestData = quotedKeyMarshalTestStruct{
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var quotedKeyMarshalTestToml = []byte(`"Yfloat-𝟘" = 3.5
|
||||
"Z.string-àéù" = "Hello"
|
||||
|
||||
@@ -183,11 +180,12 @@ type testDoc struct {
|
||||
Subdocs testDocSubs `toml:"subdoc"`
|
||||
Basics testDocBasics `toml:"basic"`
|
||||
SubDocList []testSubDoc `toml:"subdoclist"`
|
||||
err int `toml:"shouldntBeHere"` // nolint:structcheck,unused
|
||||
err int `toml:"shouldntBeHere"` //nolint:unused
|
||||
unexported int `toml:"shouldntBeHere"`
|
||||
Unexported2 int `toml:"-"`
|
||||
}
|
||||
|
||||
//nolint:unused
|
||||
type testMapDoc struct {
|
||||
Title string `toml:"title"`
|
||||
BasicMap map[string]string `toml:"basic_map"`
|
||||
@@ -274,7 +272,7 @@ var docData = testDoc{
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var mapTestDoc = testMapDoc{
|
||||
Title: "TOML Marshal Testing",
|
||||
BasicMap: map[string]string{
|
||||
@@ -543,31 +541,35 @@ func TestNestedUnmarshal(t *testing.T) {
|
||||
assert.Equal(t, nestedTestData, result)
|
||||
}
|
||||
|
||||
//nolint:unused
|
||||
type customMarshalerParent struct {
|
||||
Self customMarshaler `toml:"me"`
|
||||
Friends []customMarshaler `toml:"friends"`
|
||||
}
|
||||
|
||||
//nolint:unused
|
||||
type customMarshaler struct {
|
||||
FirstName string
|
||||
LastName string
|
||||
}
|
||||
|
||||
//nolint:unused
|
||||
func (c customMarshaler) MarshalTOML() ([]byte, error) {
|
||||
fullName := fmt.Sprintf("%s %s", c.FirstName, c.LastName)
|
||||
return []byte(fullName), nil
|
||||
}
|
||||
|
||||
//nolint:unused
|
||||
var customMarshalerData = customMarshaler{FirstName: "Sally", LastName: "Fields"}
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var customMarshalerToml = []byte(`Sally Fields`)
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var nestedCustomMarshalerData = customMarshalerParent{
|
||||
Self: customMarshaler{FirstName: "Maiku", LastName: "Suteda"},
|
||||
Friends: []customMarshaler{customMarshalerData},
|
||||
@@ -575,7 +577,7 @@ var nestedCustomMarshalerData = customMarshalerParent{
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var nestedCustomMarshalerToml = []byte(`friends = ["Sally Fields"]
|
||||
me = "Maiku Suteda"
|
||||
`)
|
||||
@@ -590,7 +592,7 @@ func (x *IntOrString) MarshalTOML() ([]byte, error) {
|
||||
s := *(*string)(x)
|
||||
_, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return []byte(fmt.Sprintf(`"%s"`, s)), nil
|
||||
return []byte(fmt.Sprintf(`"%s"`, s)), nil //nolint:nilerr
|
||||
}
|
||||
return []byte(s), nil
|
||||
}
|
||||
@@ -662,7 +664,7 @@ func (m *textPointerMarshaler) MarshalText() ([]byte, error) {
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var commentTestToml = []byte(`
|
||||
# it's a comment on type
|
||||
[postgres]
|
||||
@@ -687,6 +689,7 @@ var commentTestToml = []byte(`
|
||||
My = "Baar"
|
||||
`)
|
||||
|
||||
//nolint:unused
|
||||
type mapsTestStruct struct {
|
||||
Simple map[string]string
|
||||
Paths map[string]string
|
||||
@@ -700,7 +703,7 @@ type mapsTestStruct struct {
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var mapsTestData = mapsTestStruct{
|
||||
Simple: map[string]string{
|
||||
"one plus one": "two",
|
||||
@@ -724,7 +727,7 @@ var mapsTestData = mapsTestStruct{
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var mapsTestToml = []byte(`
|
||||
[Other]
|
||||
"testing" = 3.9999
|
||||
@@ -747,7 +750,7 @@ var mapsTestToml = []byte(`
|
||||
|
||||
// TODO: Remove nolint once type is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused
|
||||
//nolint:unused
|
||||
type structArrayNoTag struct {
|
||||
A struct {
|
||||
B []int64
|
||||
@@ -757,7 +760,7 @@ type structArrayNoTag struct {
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var customTagTestToml = []byte(`
|
||||
[postgres]
|
||||
password = "bvalue"
|
||||
@@ -772,7 +775,7 @@ var customTagTestToml = []byte(`
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var customCommentTagTestToml = []byte(`
|
||||
# db connection
|
||||
[postgres]
|
||||
@@ -786,7 +789,7 @@ var customCommentTagTestToml = []byte(`
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var customCommentedTagTestToml = []byte(`
|
||||
[postgres]
|
||||
# password = "bvalue"
|
||||
@@ -841,7 +844,7 @@ func TestUnmarshalTabInStringAndQuotedKey(t *testing.T) {
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var customMultilineTagTestToml = []byte(`int_slice = [
|
||||
1,
|
||||
2,
|
||||
@@ -851,7 +854,7 @@ var customMultilineTagTestToml = []byte(`int_slice = [
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var testDocBasicToml = []byte(`
|
||||
[document]
|
||||
bool_val = true
|
||||
@@ -862,16 +865,12 @@ var testDocBasicToml = []byte(`
|
||||
uint_val = 5001
|
||||
`)
|
||||
|
||||
// TODO: Remove nolint once type is used by a test
|
||||
//
|
||||
//nolint:deadcode
|
||||
//nolint:unused
|
||||
type testDocCustomTag struct {
|
||||
Doc testDocBasicsCustomTag `file:"document"`
|
||||
}
|
||||
|
||||
// TODO: Remove nolint once type is used by a test
|
||||
//
|
||||
//nolint:deadcode
|
||||
//nolint:unused
|
||||
type testDocBasicsCustomTag struct {
|
||||
Bool bool `file:"bool_val"`
|
||||
Date time.Time `file:"date_val"`
|
||||
@@ -882,9 +881,7 @@ type testDocBasicsCustomTag struct {
|
||||
unexported int `file:"shouldntBeHere"`
|
||||
}
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,varcheck
|
||||
//nolint:unused
|
||||
var testDocCustomTagData = testDocCustomTag{
|
||||
Doc: testDocBasicsCustomTag{
|
||||
Bool: true,
|
||||
@@ -987,13 +984,13 @@ func TestUnmarshalInvalidPointerKind(t *testing.T) {
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused
|
||||
//nolint:unused
|
||||
type testDuration struct {
|
||||
Nanosec time.Duration `toml:"nanosec"`
|
||||
Microsec1 time.Duration `toml:"microsec1"`
|
||||
Microsec2 *time.Duration `toml:"microsec2"`
|
||||
Millisec time.Duration `toml:"millisec"`
|
||||
Sec time.Duration `toml:"sec"`
|
||||
Sec time.Duration `toml:"sec"` //nolint:staticcheck
|
||||
Min time.Duration `toml:"min"`
|
||||
Hour time.Duration `toml:"hour"`
|
||||
Mixed time.Duration `toml:"mixed"`
|
||||
@@ -1002,7 +999,7 @@ type testDuration struct {
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var testDurationToml = []byte(`
|
||||
nanosec = "1ns"
|
||||
microsec1 = "1us"
|
||||
@@ -1017,7 +1014,7 @@ a_string = "15s"
|
||||
|
||||
// TODO: Remove nolint once var is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused,varcheck
|
||||
//nolint:unused
|
||||
var testDurationToml2 = []byte(`a_string = "15s"
|
||||
hour = "1h0m0s"
|
||||
microsec1 = "1µs"
|
||||
@@ -1031,15 +1028,14 @@ sec = "1s"
|
||||
|
||||
// TODO: Remove nolint once type is used by a test
|
||||
//
|
||||
//nolint:deadcode,unused
|
||||
//nolint:unused
|
||||
type testBadDuration struct {
|
||||
Val time.Duration `toml:"val"`
|
||||
}
|
||||
|
||||
// TODO: add back camelCase test
|
||||
var testCamelCaseKeyToml = []byte(`fooBar = 10`) //nolint:unused
|
||||
var testCamelCaseKeyToml = []byte(`fooBar = 10`)
|
||||
|
||||
//nolint:unused
|
||||
func TestUnmarshalCamelCaseKey(t *testing.T) {
|
||||
t.Skipf("don't know if it is a good idea to automatically convert like that yet")
|
||||
var x struct {
|
||||
@@ -1058,7 +1054,7 @@ func TestUnmarshalCamelCaseKey(t *testing.T) {
|
||||
|
||||
func TestUnmarshalNegativeUint(t *testing.T) {
|
||||
t.Skipf("not sure if we this should always error")
|
||||
type check struct{ U uint } // nolint:unused
|
||||
type check struct{ U uint }
|
||||
err := toml.Unmarshal([]byte("U = -1"), &check{})
|
||||
assert.Error(t, err)
|
||||
}
|
||||
@@ -1535,7 +1531,7 @@ func TestUnmarshalLocalDateTime(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, example := range examples {
|
||||
doc := fmt.Sprintf(`date = %s`, example.in)
|
||||
doc := "date = " + example.in
|
||||
|
||||
t.Run(fmt.Sprintf("ToLocalDateTime_%d_%s", i, example.name), func(t *testing.T) {
|
||||
type dateStruct struct {
|
||||
@@ -1621,7 +1617,7 @@ func TestUnmarshalLocalTime(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, example := range examples {
|
||||
doc := fmt.Sprintf(`Time = %s`, example.in)
|
||||
doc := "Time = " + example.in
|
||||
|
||||
t.Run(fmt.Sprintf("ToLocalTime_%d_%s", i, example.name), func(t *testing.T) {
|
||||
type dateStruct struct {
|
||||
@@ -1906,19 +1902,12 @@ func TestUnmarshalMixedTypeSlice(t *testing.T) {
|
||||
ArrayField []interface{}
|
||||
}
|
||||
|
||||
//doc := []byte(`ArrayField = [3.14,100,true,"hello world",{Field = "inner1"},[{Field = "inner2"},{Field = "inner3"}]]
|
||||
//`)
|
||||
|
||||
doc := []byte(`ArrayField = [{Field = "inner1"},[{Field = "inner2"},{Field = "inner3"}]]
|
||||
`)
|
||||
|
||||
actual := TestStruct{}
|
||||
expected := TestStruct{
|
||||
ArrayField: []interface{}{
|
||||
//3.14,
|
||||
//int64(100),
|
||||
//true,
|
||||
//"hello world",
|
||||
map[string]interface{}{
|
||||
"Field": "inner1",
|
||||
},
|
||||
@@ -2004,7 +1993,8 @@ func TestDecoderStrict(t *testing.T) {
|
||||
"Expected a *toml.StrictMissingError, got: %v", reflect.TypeOf(err),
|
||||
)
|
||||
|
||||
se := err.(*toml.StrictMissingError)
|
||||
var se *toml.StrictMissingError
|
||||
assert.True(t, errors.As(err, &se))
|
||||
|
||||
keys := []toml.Key{}
|
||||
|
||||
@@ -2026,6 +2016,7 @@ func TestDecoderStrict(t *testing.T) {
|
||||
|
||||
var m map[string]interface{}
|
||||
err = decoder(input).Decode(&m)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestDecoderStrictValid(t *testing.T) {
|
||||
@@ -2062,19 +2053,6 @@ func (d *docUnmarshalTOML) UnmarshalTOML(i interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestDecoderStrictCustomUnmarshal(t *testing.T) {
|
||||
t.Skip()
|
||||
//input := `key = "ok"`
|
||||
//var doc docUnmarshalTOML
|
||||
//err := NewDecoder(bytes.NewReader([]byte(input))).Strict(true).Decode(&doc)
|
||||
//if err != nil {
|
||||
// t.Fatal("unexpected error:", err)
|
||||
//}
|
||||
//if doc.Decoded.Key != "ok" {
|
||||
// t.Errorf("Bad unmarshal: expected ok, got %v", doc.Decoded.Key)
|
||||
//}
|
||||
}
|
||||
|
||||
type parent struct {
|
||||
Doc docUnmarshalTOML
|
||||
DocPointer *docUnmarshalTOML
|
||||
@@ -2278,7 +2256,7 @@ type Custom struct {
|
||||
v string
|
||||
}
|
||||
|
||||
func (c *Custom) UnmarshalTOML(v interface{}) error {
|
||||
func (c *Custom) UnmarshalTOML(interface{}) error {
|
||||
c.v = "called"
|
||||
return nil
|
||||
}
|
||||
@@ -2303,14 +2281,14 @@ type durationString struct {
|
||||
time.Duration
|
||||
}
|
||||
|
||||
func (d *durationString) UnmarshalTOML(v interface{}) error {
|
||||
func (d *durationString) UnmarshalTOML(interface{}) error {
|
||||
d.Duration = 10 * time.Second
|
||||
return nil
|
||||
}
|
||||
|
||||
type config437Error struct{}
|
||||
|
||||
func (e *config437Error) UnmarshalTOML(v interface{}) error {
|
||||
func (e *config437Error) UnmarshalTOML(interface{}) error {
|
||||
return errors.New("expected")
|
||||
}
|
||||
|
||||
|
||||
@@ -3,17 +3,18 @@ package testsuite
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
)
|
||||
|
||||
// addTag adds JSON tags to a data structure as expected by toml-test.
|
||||
func addTag(key string, tomlData interface{}) interface{} {
|
||||
func addTag(tomlData interface{}) interface{} {
|
||||
// Switch on the data type.
|
||||
switch orig := tomlData.(type) {
|
||||
default:
|
||||
//return map[string]interface{}{}
|
||||
// return map[string]interface{}{}
|
||||
panic(fmt.Sprintf("Unknown type: %T", tomlData))
|
||||
|
||||
// A table: we don't need to add any tags, just recurse for every table
|
||||
@@ -21,7 +22,7 @@ func addTag(key string, tomlData interface{}) interface{} {
|
||||
case map[string]interface{}:
|
||||
typed := make(map[string]interface{}, len(orig))
|
||||
for k, v := range orig {
|
||||
typed[k] = addTag(k, v)
|
||||
typed[k] = addTag(v)
|
||||
}
|
||||
return typed
|
||||
|
||||
@@ -30,13 +31,13 @@ func addTag(key string, tomlData interface{}) interface{} {
|
||||
case []map[string]interface{}:
|
||||
typed := make([]map[string]interface{}, len(orig))
|
||||
for i, v := range orig {
|
||||
typed[i] = addTag("", v).(map[string]interface{})
|
||||
typed[i] = addTag(v).(map[string]interface{})
|
||||
}
|
||||
return typed
|
||||
case []interface{}:
|
||||
typed := make([]interface{}, len(orig))
|
||||
for i, v := range orig {
|
||||
typed[i] = addTag("", v)
|
||||
typed[i] = addTag(v)
|
||||
}
|
||||
return typed
|
||||
|
||||
@@ -52,11 +53,11 @@ func addTag(key string, tomlData interface{}) interface{} {
|
||||
|
||||
// Tag primitive values: bool, string, int, and float64.
|
||||
case bool:
|
||||
return tag("bool", fmt.Sprintf("%v", orig))
|
||||
return tag("bool", strconv.FormatBool(orig))
|
||||
case string:
|
||||
return tag("string", orig)
|
||||
case int64:
|
||||
return tag("integer", fmt.Sprintf("%d", orig))
|
||||
return tag("integer", strconv.FormatInt(orig, 10))
|
||||
case float64:
|
||||
// Special case for nan since NaN == NaN is false.
|
||||
if math.IsNaN(orig) {
|
||||
|
||||
+10
-10
@@ -9,6 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func CmpJSON(t *testing.T, key string, want, have interface{}) {
|
||||
t.Helper()
|
||||
switch w := want.(type) {
|
||||
case map[string]interface{}:
|
||||
cmpJSONMaps(t, key, w, have)
|
||||
@@ -22,6 +23,7 @@ func CmpJSON(t *testing.T, key string, want, have interface{}) {
|
||||
}
|
||||
|
||||
func cmpJSONMaps(t *testing.T, key string, want map[string]interface{}, have interface{}) {
|
||||
t.Helper()
|
||||
haveMap, ok := have.(map[string]interface{})
|
||||
if !ok {
|
||||
mismatch(t, key, "table", want, haveMap)
|
||||
@@ -61,6 +63,7 @@ func cmpJSONMaps(t *testing.T, key string, want map[string]interface{}, have int
|
||||
}
|
||||
|
||||
func cmpJSONArrays(t *testing.T, key string, want, have interface{}) {
|
||||
t.Helper()
|
||||
wantSlice, ok := want.([]interface{})
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("'value' should be a JSON array when 'type=array', but it is a %T", want))
|
||||
@@ -83,6 +86,7 @@ func cmpJSONArrays(t *testing.T, key string, want, have interface{}) {
|
||||
}
|
||||
|
||||
func cmpJSONValues(t *testing.T, key string, want, have map[string]interface{}) {
|
||||
t.Helper()
|
||||
wantType, ok := want["type"].(string)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("'type' should be a string, but it is a %T", want["type"]))
|
||||
@@ -126,6 +130,7 @@ func cmpJSONValues(t *testing.T, key string, want, have map[string]interface{})
|
||||
}
|
||||
|
||||
func cmpAsStrings(t *testing.T, key string, want, have string) {
|
||||
t.Helper()
|
||||
if want != have {
|
||||
t.Fatalf("Values for key '%s' don't match:\n"+
|
||||
" Expected: %s\n"+
|
||||
@@ -135,6 +140,7 @@ func cmpAsStrings(t *testing.T, key string, want, have string) {
|
||||
}
|
||||
|
||||
func cmpFloats(t *testing.T, key string, want, have string) {
|
||||
t.Helper()
|
||||
// Special case for NaN, since NaN != NaN.
|
||||
if strings.HasSuffix(want, "nan") || strings.HasSuffix(have, "nan") {
|
||||
if want != have {
|
||||
@@ -177,6 +183,7 @@ var layouts = map[string]string{
|
||||
}
|
||||
|
||||
func cmpAsDatetimes(t *testing.T, key string, kind, want, have string) {
|
||||
t.Helper()
|
||||
layout, ok := layouts[kind]
|
||||
if !ok {
|
||||
panic("should never happen")
|
||||
@@ -200,15 +207,6 @@ func cmpAsDatetimes(t *testing.T, key string, kind, want, have string) {
|
||||
}
|
||||
}
|
||||
|
||||
func cmpAsDatetimesLocal(t *testing.T, key string, want, have string) {
|
||||
if datetimeRepl.Replace(want) != datetimeRepl.Replace(have) {
|
||||
t.Fatalf("Values for key '%s' don't match:\n"+
|
||||
" Expected: %v\n"+
|
||||
" Your encoder: %v",
|
||||
key, want, have)
|
||||
}
|
||||
}
|
||||
|
||||
func kjoin(old, key string) string {
|
||||
if len(old) == 0 {
|
||||
return key
|
||||
@@ -230,6 +228,7 @@ func isValue(m map[string]interface{}) bool {
|
||||
}
|
||||
|
||||
func mismatch(t *testing.T, key string, wantType string, want, have interface{}) {
|
||||
t.Helper()
|
||||
t.Fatalf("Key '%s' is not an %s but %[4]T:\n"+
|
||||
" Expected: %#[3]v\n"+
|
||||
" Your encoder: %#[4]v",
|
||||
@@ -237,8 +236,9 @@ func mismatch(t *testing.T, key string, wantType string, want, have interface{})
|
||||
}
|
||||
|
||||
func valMismatch(t *testing.T, key string, wantType, haveType string, want, have interface{}) {
|
||||
t.Helper()
|
||||
t.Fatalf("Key '%s' is not an %s but %s:\n"+
|
||||
" Expected: %#[3]v\n"+
|
||||
" Your encoder: %#[4]v",
|
||||
key, wantType, want, have)
|
||||
key, wantType, haveType, want, have)
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
package testsuite
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
)
|
||||
|
||||
type parser struct{}
|
||||
|
||||
func (p parser) Decode(input string) (output string, outputIsError bool, retErr error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
switch rr := r.(type) {
|
||||
case error:
|
||||
retErr = rr
|
||||
default:
|
||||
retErr = fmt.Errorf("%s", rr)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
var v interface{}
|
||||
|
||||
if err := toml.Unmarshal([]byte(input), &v); err != nil {
|
||||
return err.Error(), true, nil
|
||||
}
|
||||
|
||||
j, err := json.MarshalIndent(addTag("", v), "", " ")
|
||||
if err != nil {
|
||||
return "", false, retErr
|
||||
}
|
||||
|
||||
return string(j), false, retErr
|
||||
}
|
||||
|
||||
func (p parser) Encode(input string) (output string, outputIsError bool, retErr error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
switch rr := r.(type) {
|
||||
case error:
|
||||
retErr = rr
|
||||
default:
|
||||
retErr = fmt.Errorf("%s", rr)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
var tmp interface{}
|
||||
err := json.Unmarshal([]byte(input), &tmp)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
|
||||
rm, err := rmTag(tmp)
|
||||
if err != nil {
|
||||
return err.Error(), true, retErr
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
err = toml.NewEncoder(buf).Encode(rm)
|
||||
if err != nil {
|
||||
return err.Error(), true, retErr
|
||||
}
|
||||
|
||||
return buf.String(), false, retErr
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
// Remove JSON tags to a data structure as returned by toml-test.
|
||||
func rmTag(typedJson interface{}) (interface{}, error) {
|
||||
func rmTag(typedJSON interface{}) (interface{}, error) {
|
||||
// Check if key is in the table m.
|
||||
in := func(key string, m map[string]interface{}) bool {
|
||||
_, ok := m[key]
|
||||
@@ -17,8 +17,7 @@ func rmTag(typedJson interface{}) (interface{}, error) {
|
||||
}
|
||||
|
||||
// Switch on the data type.
|
||||
switch v := typedJson.(type) {
|
||||
|
||||
switch v := typedJSON.(type) {
|
||||
// Object: this can either be a TOML table or a primitive with tags.
|
||||
case map[string]interface{}:
|
||||
// This value represents a primitive: remove the tags and return just
|
||||
@@ -56,7 +55,7 @@ func rmTag(typedJson interface{}) (interface{}, error) {
|
||||
}
|
||||
|
||||
// The top level must be an object or array.
|
||||
return nil, fmt.Errorf("unrecognized JSON format '%T'", typedJson)
|
||||
return nil, fmt.Errorf("unrecognized JSON format '%T'", typedJSON)
|
||||
}
|
||||
|
||||
// Return a primitive: read the "type" and convert the "value" to that.
|
||||
@@ -79,7 +78,7 @@ func untag(typed map[string]interface{}) (interface{}, error) {
|
||||
}
|
||||
return f, nil
|
||||
|
||||
//toml.LocalDate{Year:2020, Month:12, Day:12}
|
||||
// toml.LocalDate{Year:2020, Month:12, Day:12}
|
||||
case "datetime":
|
||||
return time.Parse("2006-01-02T15:04:05.999999999Z07:00", v)
|
||||
case "datetime-local":
|
||||
@@ -115,15 +114,3 @@ func untag(typed map[string]interface{}) (interface{}, error) {
|
||||
|
||||
return nil, fmt.Errorf("untag: unrecognized tag type %q", t)
|
||||
}
|
||||
|
||||
func parseTime(v, format string, local bool) (t time.Time, err error) {
|
||||
if local {
|
||||
t, err = time.ParseInLocation(format, v, time.Local)
|
||||
} else {
|
||||
t, err = time.Parse(format, v)
|
||||
}
|
||||
if err != nil {
|
||||
return time.Time{}, fmt.Errorf("Could not parse %q as a datetime: %w", v, err)
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ func Unmarshal(data []byte, v interface{}) error {
|
||||
// ValueToTaggedJSON takes a data structure and returns the tagged JSON
|
||||
// representation.
|
||||
func ValueToTaggedJSON(doc interface{}) ([]byte, error) {
|
||||
return json.MarshalIndent(addTag("", doc), "", " ")
|
||||
return json.MarshalIndent(addTag(doc), "", " ")
|
||||
}
|
||||
|
||||
// DecodeStdin is a helper function for the toml-test binary interface. TOML input
|
||||
@@ -37,13 +37,13 @@ func DecodeStdin() error {
|
||||
var decoded map[string]interface{}
|
||||
|
||||
if err := toml.NewDecoder(os.Stdin).Decode(&decoded); err != nil {
|
||||
return fmt.Errorf("Error decoding TOML: %s", err)
|
||||
return fmt.Errorf("error decoding TOML: %w", err)
|
||||
}
|
||||
|
||||
j := json.NewEncoder(os.Stdout)
|
||||
j.SetIndent("", " ")
|
||||
if err := j.Encode(addTag("", decoded)); err != nil {
|
||||
return fmt.Errorf("Error encoding JSON: %s", err)
|
||||
if err := j.Encode(addTag(decoded)); err != nil {
|
||||
return fmt.Errorf("error encoding JSON: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -36,7 +36,7 @@ func (t *KeyTracker) Pop(node *unstable.Node) {
|
||||
}
|
||||
}
|
||||
|
||||
// Key returns the current key
|
||||
// Key returns the current key.
|
||||
func (t *KeyTracker) Key() []string {
|
||||
k := make([]string, len(t.k))
|
||||
copy(k, t.k)
|
||||
|
||||
@@ -288,11 +288,12 @@ func (s *SeenTracker) checkKeyValue(node *unstable.Node) (bool, error) {
|
||||
idx = s.create(parentIdx, k, tableKind, false, true)
|
||||
} else {
|
||||
entry := s.entries[idx]
|
||||
if it.IsLast() {
|
||||
switch {
|
||||
case it.IsLast():
|
||||
return false, fmt.Errorf("toml: key %s is already defined", string(k))
|
||||
} else if entry.kind != tableKind {
|
||||
case entry.kind != tableKind:
|
||||
return false, fmt.Errorf("toml: expected %s to be a table, not a %s", string(k), entry.kind)
|
||||
} else if entry.explicit {
|
||||
case entry.explicit:
|
||||
return false, fmt.Errorf("toml: cannot redefine table %s that has already been explicitly defined", string(k))
|
||||
}
|
||||
}
|
||||
@@ -309,16 +310,16 @@ func (s *SeenTracker) checkKeyValue(node *unstable.Node) (bool, error) {
|
||||
return s.checkInlineTable(value)
|
||||
case unstable.Array:
|
||||
return s.checkArray(value)
|
||||
default:
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (s *SeenTracker) checkArray(node *unstable.Node) (first bool, err error) {
|
||||
it := node.Children()
|
||||
for it.Next() {
|
||||
n := it.Node()
|
||||
switch n.Kind {
|
||||
switch n.Kind { //nolint:exhaustive
|
||||
case unstable.InlineTable:
|
||||
first, err = s.checkInlineTable(n)
|
||||
if err != nil {
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
// Package tracker provides functions for keeping track of AST nodes.
|
||||
package tracker
|
||||
|
||||
Reference in New Issue
Block a user