Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f5cc8c49eb | |||
| 89d7b412d8 | |||
| 88a8aecdd4 | |||
| 9804fc57e0 |
@@ -2,11 +2,14 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/pelletier/go-toml/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConvertFn func(r io.Reader, w io.Writer) error
|
type ConvertFn func(r io.Reader, w io.Writer) error
|
||||||
@@ -28,7 +31,16 @@ func (p *Program) Execute() {
|
|||||||
func (p *Program) main(files []string, input io.Reader, output, error io.Writer) int {
|
func (p *Program) main(files []string, input io.Reader, output, error io.Writer) int {
|
||||||
err := p.run(files, input, output)
|
err := p.run(files, input, output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
|
var derr *toml.DecodeError
|
||||||
|
if errors.As(err, &derr) {
|
||||||
|
fmt.Fprintln(error, derr.String())
|
||||||
|
row, col := derr.Position()
|
||||||
|
fmt.Fprintln(error, "error occurred at row", row, "column", col)
|
||||||
|
} else {
|
||||||
fmt.Fprintln(error, err.Error())
|
fmt.Fprintln(error, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pelletier/go-toml/v2"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@@ -47,6 +48,21 @@ func TestProcessMainStdinErr(t *testing.T) {
|
|||||||
assert.NotEmpty(t, stderr.String())
|
assert.NotEmpty(t, stderr.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestProcessMainStdinDecodeErr(t *testing.T) {
|
||||||
|
stdout := new(bytes.Buffer)
|
||||||
|
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 {
|
||||||
|
var v interface{}
|
||||||
|
return toml.Unmarshal([]byte(`qwe = 001`), &v)
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t, -1, exit)
|
||||||
|
assert.Empty(t, stdout.String())
|
||||||
|
assert.Contains(t, stderr.String(), "error occurred at")
|
||||||
|
}
|
||||||
|
|
||||||
func TestProcessMainFileExists(t *testing.T) {
|
func TestProcessMainFileExists(t *testing.T) {
|
||||||
tmpfile, err := ioutil.TempFile("", "example")
|
tmpfile, err := ioutil.TempFile("", "example")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ type entry struct {
|
|||||||
name []byte
|
name []byte
|
||||||
kind keyKind
|
kind keyKind
|
||||||
explicit bool
|
explicit bool
|
||||||
|
kv bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the index of the child of parentIdx with key k. Returns -1 if
|
// Find the index of the child of parentIdx with key k. Returns -1 if
|
||||||
@@ -111,7 +112,7 @@ func (s *SeenTracker) clear(idx int) {
|
|||||||
s.entries[idx].child = -1
|
s.entries[idx].child = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SeenTracker) create(parentIdx int, name []byte, kind keyKind, explicit bool) int {
|
func (s *SeenTracker) create(parentIdx int, name []byte, kind keyKind, explicit bool, kv bool) int {
|
||||||
e := entry{
|
e := entry{
|
||||||
child: -1,
|
child: -1,
|
||||||
next: s.entries[parentIdx].child,
|
next: s.entries[parentIdx].child,
|
||||||
@@ -119,6 +120,7 @@ func (s *SeenTracker) create(parentIdx int, name []byte, kind keyKind, explicit
|
|||||||
name: name,
|
name: name,
|
||||||
kind: kind,
|
kind: kind,
|
||||||
explicit: explicit,
|
explicit: explicit,
|
||||||
|
kv: kv,
|
||||||
}
|
}
|
||||||
var idx int
|
var idx int
|
||||||
if s.entries[0].next >= 0 {
|
if s.entries[0].next >= 0 {
|
||||||
@@ -137,7 +139,10 @@ func (s *SeenTracker) create(parentIdx int, name []byte, kind keyKind, explicit
|
|||||||
|
|
||||||
func (s *SeenTracker) setExplicitFlag(parentIdx int) {
|
func (s *SeenTracker) setExplicitFlag(parentIdx int) {
|
||||||
for i := s.entries[parentIdx].child; i >= 0; i = s.entries[i].next {
|
for i := s.entries[parentIdx].child; i >= 0; i = s.entries[i].next {
|
||||||
|
if s.entries[i].kv {
|
||||||
s.entries[i].explicit = true
|
s.entries[i].explicit = true
|
||||||
|
s.entries[i].kv = false
|
||||||
|
}
|
||||||
s.setExplicitFlag(i)
|
s.setExplicitFlag(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,7 +188,7 @@ func (s *SeenTracker) checkTable(node *ast.Node) error {
|
|||||||
idx := s.find(parentIdx, k)
|
idx := s.find(parentIdx, k)
|
||||||
|
|
||||||
if idx < 0 {
|
if idx < 0 {
|
||||||
idx = s.create(parentIdx, k, tableKind, false)
|
idx = s.create(parentIdx, k, tableKind, false, false)
|
||||||
} else {
|
} else {
|
||||||
entry := s.entries[idx]
|
entry := s.entries[idx]
|
||||||
if entry.kind == valueKind {
|
if entry.kind == valueKind {
|
||||||
@@ -206,7 +211,7 @@ func (s *SeenTracker) checkTable(node *ast.Node) error {
|
|||||||
}
|
}
|
||||||
s.entries[idx].explicit = true
|
s.entries[idx].explicit = true
|
||||||
} else {
|
} else {
|
||||||
idx = s.create(parentIdx, k, tableKind, true)
|
idx = s.create(parentIdx, k, tableKind, true, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.currentIdx = idx
|
s.currentIdx = idx
|
||||||
@@ -233,7 +238,7 @@ func (s *SeenTracker) checkArrayTable(node *ast.Node) error {
|
|||||||
idx := s.find(parentIdx, k)
|
idx := s.find(parentIdx, k)
|
||||||
|
|
||||||
if idx < 0 {
|
if idx < 0 {
|
||||||
idx = s.create(parentIdx, k, tableKind, false)
|
idx = s.create(parentIdx, k, tableKind, false, false)
|
||||||
} else {
|
} else {
|
||||||
entry := s.entries[idx]
|
entry := s.entries[idx]
|
||||||
if entry.kind == valueKind {
|
if entry.kind == valueKind {
|
||||||
@@ -254,7 +259,7 @@ func (s *SeenTracker) checkArrayTable(node *ast.Node) error {
|
|||||||
}
|
}
|
||||||
s.clear(idx)
|
s.clear(idx)
|
||||||
} else {
|
} else {
|
||||||
idx = s.create(parentIdx, k, arrayTableKind, true)
|
idx = s.create(parentIdx, k, arrayTableKind, true, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.currentIdx = idx
|
s.currentIdx = idx
|
||||||
@@ -272,7 +277,7 @@ func (s *SeenTracker) checkKeyValue(node *ast.Node) error {
|
|||||||
idx := s.find(parentIdx, k)
|
idx := s.find(parentIdx, k)
|
||||||
|
|
||||||
if idx < 0 {
|
if idx < 0 {
|
||||||
idx = s.create(parentIdx, k, tableKind, false)
|
idx = s.create(parentIdx, k, tableKind, false, true)
|
||||||
} else {
|
} else {
|
||||||
entry := s.entries[idx]
|
entry := s.entries[idx]
|
||||||
if it.IsLast() {
|
if it.IsLast() {
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package tracker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestEntrySize(t *testing.T) {
|
||||||
|
// Validate no regression on the size of entry{}. This is a critical bit for
|
||||||
|
// performance of unmarshaling documents. Should only be increased with care
|
||||||
|
// and a very good reason.
|
||||||
|
require.LessOrEqual(t, 48, int(unsafe.Sizeof(entry{})))
|
||||||
|
}
|
||||||
@@ -617,6 +617,8 @@ func (p *parser) parseMultilineBasicString(b []byte) ([]byte, []byte, []byte, er
|
|||||||
builder.WriteByte('\r')
|
builder.WriteByte('\r')
|
||||||
case 't':
|
case 't':
|
||||||
builder.WriteByte('\t')
|
builder.WriteByte('\t')
|
||||||
|
case 'e':
|
||||||
|
builder.WriteByte(0x1B)
|
||||||
case 'u':
|
case 'u':
|
||||||
x, err := hexToRune(atmost(token[i+1:], 4), 4)
|
x, err := hexToRune(atmost(token[i+1:], 4), 4)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -774,6 +776,8 @@ func (p *parser) parseBasicString(b []byte) ([]byte, []byte, []byte, error) {
|
|||||||
builder.WriteByte('\r')
|
builder.WriteByte('\r')
|
||||||
case 't':
|
case 't':
|
||||||
builder.WriteByte('\t')
|
builder.WriteByte('\t')
|
||||||
|
case 'e':
|
||||||
|
builder.WriteByte(0x1B)
|
||||||
case 'u':
|
case 'u':
|
||||||
x, err := hexToRune(token[i+1:len(token)-1], 4)
|
x, err := hexToRune(token[i+1:len(token)-1], 4)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+90
-8
@@ -1,4 +1,4 @@
|
|||||||
// Generated by tomltestgen for toml-test ref master on 2021-12-31T17:10:15-05:00
|
// Generated by tomltestgen for toml-test ref master on 2022-04-07T20:09:42-04:00
|
||||||
package toml_test
|
package toml_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -55,11 +55,51 @@ func TestTOMLTest_Invalid_Array_TextInArray(t *testing.T) {
|
|||||||
testgenInvalid(t, input)
|
testgenInvalid(t, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_Bool_AlmostFalseWithExtra(t *testing.T) {
|
||||||
|
input := "a = falsify\n"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_Bool_AlmostFalse(t *testing.T) {
|
||||||
|
input := "a = fals\n"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_Bool_AlmostTrueWithExtra(t *testing.T) {
|
||||||
|
input := "a = truthy\n"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_Bool_AlmostTrue(t *testing.T) {
|
||||||
|
input := "a = tru\n"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_Bool_JustF(t *testing.T) {
|
||||||
|
input := "a = f\n"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_Bool_JustT(t *testing.T) {
|
||||||
|
input := "a = t\n"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
func TestTOMLTest_Invalid_Bool_MixedCase(t *testing.T) {
|
func TestTOMLTest_Invalid_Bool_MixedCase(t *testing.T) {
|
||||||
input := "valid = False\n"
|
input := "valid = False\n"
|
||||||
testgenInvalid(t, input)
|
testgenInvalid(t, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_Bool_StartingSameFalse(t *testing.T) {
|
||||||
|
input := "a = falsey\n"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_Bool_StartingSameTrue(t *testing.T) {
|
||||||
|
input := "a = truer\n"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
func TestTOMLTest_Invalid_Bool_WrongCaseFalse(t *testing.T) {
|
func TestTOMLTest_Invalid_Bool_WrongCaseFalse(t *testing.T) {
|
||||||
input := "b = FALSE\n"
|
input := "b = FALSE\n"
|
||||||
testgenInvalid(t, input)
|
testgenInvalid(t, input)
|
||||||
@@ -70,11 +110,26 @@ func TestTOMLTest_Invalid_Bool_WrongCaseTrue(t *testing.T) {
|
|||||||
testgenInvalid(t, input)
|
testgenInvalid(t, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_Control_BareCr(t *testing.T) {
|
||||||
|
input := "# The following line contains a single carriage return control character\r\n\r"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_Control_BareFormfeed(t *testing.T) {
|
||||||
|
input := "bare-formfeed = \f\n"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
func TestTOMLTest_Invalid_Control_BareNull(t *testing.T) {
|
func TestTOMLTest_Invalid_Control_BareNull(t *testing.T) {
|
||||||
input := "bare-null = \"some value\" \x00\n"
|
input := "bare-null = \"some value\" \x00\n"
|
||||||
testgenInvalid(t, input)
|
testgenInvalid(t, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_Control_BareVerticalTab(t *testing.T) {
|
||||||
|
input := "bare-vertical-tab = \v\n"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
func TestTOMLTest_Invalid_Control_CommentCr(t *testing.T) {
|
func TestTOMLTest_Invalid_Control_CommentCr(t *testing.T) {
|
||||||
input := "comment-cr = \"Carriage return in comment\" # \ra=1\n"
|
input := "comment-cr = \"Carriage return in comment\" # \ra=1\n"
|
||||||
testgenInvalid(t, input)
|
testgenInvalid(t, input)
|
||||||
@@ -445,6 +500,11 @@ func TestTOMLTest_Invalid_Float_UsBeforePoint(t *testing.T) {
|
|||||||
testgenInvalid(t, input)
|
testgenInvalid(t, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_InlineTable_Add(t *testing.T) {
|
||||||
|
input := "a={}\n# Inline tables are immutable and can't be extended\n[a.b]\n"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
func TestTOMLTest_Invalid_InlineTable_DoubleComma(t *testing.T) {
|
func TestTOMLTest_Invalid_InlineTable_DoubleComma(t *testing.T) {
|
||||||
input := "t = {x=3,,y=4}\n"
|
input := "t = {x=3,,y=4}\n"
|
||||||
testgenInvalid(t, input)
|
testgenInvalid(t, input)
|
||||||
@@ -525,6 +585,21 @@ func TestTOMLTest_Invalid_Integer_DoubleUs(t *testing.T) {
|
|||||||
testgenInvalid(t, input)
|
testgenInvalid(t, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_Integer_IncompleteBin(t *testing.T) {
|
||||||
|
input := "incomplete-bin = 0b\n"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_Integer_IncompleteHex(t *testing.T) {
|
||||||
|
input := "incomplete-hex = 0x\n"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Invalid_Integer_IncompleteOct(t *testing.T) {
|
||||||
|
input := "incomplete-oct = 0o\n"
|
||||||
|
testgenInvalid(t, input)
|
||||||
|
}
|
||||||
|
|
||||||
func TestTOMLTest_Invalid_Integer_InvalidBin(t *testing.T) {
|
func TestTOMLTest_Invalid_Integer_InvalidBin(t *testing.T) {
|
||||||
input := "invalid-bin = 0b0012\n"
|
input := "invalid-bin = 0b0012\n"
|
||||||
testgenInvalid(t, input)
|
testgenInvalid(t, input)
|
||||||
@@ -910,11 +985,6 @@ func TestTOMLTest_Invalid_String_MultilineQuotes1(t *testing.T) {
|
|||||||
testgenInvalid(t, input)
|
testgenInvalid(t, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTOMLTest_Invalid_String_MultilineQuotes2(t *testing.T) {
|
|
||||||
input := "a = \"\"\"6 quotes: \"\"\"\"\"\"\n"
|
|
||||||
testgenInvalid(t, input)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTOMLTest_Invalid_String_NoClose(t *testing.T) {
|
func TestTOMLTest_Invalid_String_NoClose(t *testing.T) {
|
||||||
input := "no-ending-quote = \"One time, at band camp\n"
|
input := "no-ending-quote = \"One time, at band camp\n"
|
||||||
testgenInvalid(t, input)
|
testgenInvalid(t, input)
|
||||||
@@ -1471,6 +1541,12 @@ func TestTOMLTest_Valid_String_Empty(t *testing.T) {
|
|||||||
testgenValid(t, input, jsonRef)
|
testgenValid(t, input, jsonRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Valid_String_EscapeEsc(t *testing.T) {
|
||||||
|
input := "esc = \"\\e There is no escape! \\e\"\n"
|
||||||
|
jsonRef := "{\n \"esc\": {\n \"type\": \"string\",\n \"value\": \"\\u001b There is no escape! \\u001b\"\n }\n}\n"
|
||||||
|
testgenValid(t, input, jsonRef)
|
||||||
|
}
|
||||||
|
|
||||||
func TestTOMLTest_Valid_String_EscapeTricky(t *testing.T) {
|
func TestTOMLTest_Valid_String_EscapeTricky(t *testing.T) {
|
||||||
input := "end_esc = \"String does not end here\\\" but ends here\\\\\"\nlit_end_esc = 'String ends here\\'\n\nmultiline_unicode = \"\"\"\n\\u00a0\"\"\"\n\nmultiline_not_unicode = \"\"\"\n\\\\u0041\"\"\"\n\nmultiline_end_esc = \"\"\"When will it end? \\\"\"\"...\"\"\\\" should be here\\\"\"\"\"\n\nlit_multiline_not_unicode = '''\n\\u007f'''\n\nlit_multiline_end = '''There is no escape\\'''\n"
|
input := "end_esc = \"String does not end here\\\" but ends here\\\\\"\nlit_end_esc = 'String ends here\\'\n\nmultiline_unicode = \"\"\"\n\\u00a0\"\"\"\n\nmultiline_not_unicode = \"\"\"\n\\\\u0041\"\"\"\n\nmultiline_end_esc = \"\"\"When will it end? \\\"\"\"...\"\"\\\" should be here\\\"\"\"\"\n\nlit_multiline_not_unicode = '''\n\\u007f'''\n\nlit_multiline_end = '''There is no escape\\'''\n"
|
||||||
jsonRef := "{\n \"end_esc\": {\n \"type\": \"string\",\n \"value\": \"String does not end here\\\" but ends here\\\\\"\n },\n \"lit_end_esc\": {\n \"type\": \"string\",\n \"value\": \"String ends here\\\\\"\n },\n \"lit_multiline_end\": {\n \"type\": \"string\",\n \"value\": \"There is no escape\\\\\"\n },\n \"lit_multiline_not_unicode\": {\n \"type\": \"string\",\n \"value\": \"\\\\u007f\"\n },\n \"multiline_end_esc\": {\n \"type\": \"string\",\n \"value\": \"When will it end? \\\"\\\"\\\"...\\\"\\\"\\\" should be here\\\"\"\n },\n \"multiline_not_unicode\": {\n \"type\": \"string\",\n \"value\": \"\\\\u0041\"\n },\n \"multiline_unicode\": {\n \"type\": \"string\",\n \"value\": \"\u00a0\"\n }\n}\n"
|
jsonRef := "{\n \"end_esc\": {\n \"type\": \"string\",\n \"value\": \"String does not end here\\\" but ends here\\\\\"\n },\n \"lit_end_esc\": {\n \"type\": \"string\",\n \"value\": \"String ends here\\\\\"\n },\n \"lit_multiline_end\": {\n \"type\": \"string\",\n \"value\": \"There is no escape\\\\\"\n },\n \"lit_multiline_not_unicode\": {\n \"type\": \"string\",\n \"value\": \"\\\\u007f\"\n },\n \"multiline_end_esc\": {\n \"type\": \"string\",\n \"value\": \"When will it end? \\\"\\\"\\\"...\\\"\\\"\\\" should be here\\\"\"\n },\n \"multiline_not_unicode\": {\n \"type\": \"string\",\n \"value\": \"\\\\u0041\"\n },\n \"multiline_unicode\": {\n \"type\": \"string\",\n \"value\": \"\u00a0\"\n }\n}\n"
|
||||||
@@ -1489,9 +1565,15 @@ func TestTOMLTest_Valid_String_Escapes(t *testing.T) {
|
|||||||
testgenValid(t, input, jsonRef)
|
testgenValid(t, input, jsonRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTOMLTest_Valid_String_MultilineEscapedCrlf(t *testing.T) {
|
||||||
|
input := "# The following line should be an unescaped backslash followed by a Windows\r\n# newline sequence (\"\\r\\n\")\r\n0=\"\"\"\\\r\n\"\"\"\r\n"
|
||||||
|
jsonRef := "{\n \"0\": {\n \"type\": \"string\",\n \"value\": \"\"\n }\n}\n"
|
||||||
|
testgenValid(t, input, jsonRef)
|
||||||
|
}
|
||||||
|
|
||||||
func TestTOMLTest_Valid_String_MultilineQuotes(t *testing.T) {
|
func TestTOMLTest_Valid_String_MultilineQuotes(t *testing.T) {
|
||||||
input := "# Make sure that quotes inside multiline strings are allowed, including right\n# after the opening '''/\"\"\" and before the closing '''/\"\"\"\n\nlit_one = ''''one quote''''\nlit_two = '''''two quotes'''''\nlit_one_space = ''' 'one quote' '''\nlit_two_space = ''' ''two quotes'' '''\n\none = \"\"\"\"one quote\"\"\"\"\ntwo = \"\"\"\"\"two quotes\"\"\"\"\"\none_space = \"\"\" \"one quote\" \"\"\"\ntwo_space = \"\"\" \"\"two quotes\"\" \"\"\"\n\nmismatch1 = \"\"\"aaa'''bbb\"\"\"\nmismatch2 = '''aaa\"\"\"bbb'''\n"
|
input := "# Make sure that quotes inside multiline strings are allowed, including right\n# after the opening '''/\"\"\" and before the closing '''/\"\"\"\n\nlit_one = ''''one quote''''\nlit_two = '''''two quotes'''''\nlit_one_space = ''' 'one quote' '''\nlit_two_space = ''' ''two quotes'' '''\n\none = \"\"\"\"one quote\"\"\"\"\ntwo = \"\"\"\"\"two quotes\"\"\"\"\"\none_space = \"\"\" \"one quote\" \"\"\"\ntwo_space = \"\"\" \"\"two quotes\"\" \"\"\"\n\nmismatch1 = \"\"\"aaa'''bbb\"\"\"\nmismatch2 = '''aaa\"\"\"bbb'''\n\n# Three opening \"\"\", then one escaped \", then two \"\" (allowed), and then three\n# closing \"\"\"\nescaped = \"\"\"lol\\\"\"\"\"\"\"\n"
|
||||||
jsonRef := "{\n \"lit_one\": {\n \"type\": \"string\",\n \"value\": \"'one quote'\"\n },\n \"lit_one_space\": {\n \"type\": \"string\",\n \"value\": \" 'one quote' \"\n },\n \"lit_two\": {\n \"type\": \"string\",\n \"value\": \"''two quotes''\"\n },\n \"lit_two_space\": {\n \"type\": \"string\",\n \"value\": \" ''two quotes'' \"\n },\n \"mismatch1\": {\n \"type\": \"string\",\n \"value\": \"aaa'''bbb\"\n },\n \"mismatch2\": {\n \"type\": \"string\",\n \"value\": \"aaa\\\"\\\"\\\"bbb\"\n },\n \"one\": {\n \"type\": \"string\",\n \"value\": \"\\\"one quote\\\"\"\n },\n \"one_space\": {\n \"type\": \"string\",\n \"value\": \" \\\"one quote\\\" \"\n },\n \"two\": {\n \"type\": \"string\",\n \"value\": \"\\\"\\\"two quotes\\\"\\\"\"\n },\n \"two_space\": {\n \"type\": \"string\",\n \"value\": \" \\\"\\\"two quotes\\\"\\\" \"\n }\n}\n"
|
jsonRef := "{\n \"escaped\": {\n \"type\": \"string\",\n \"value\": \"lol\\\"\\\"\\\"\"\n },\n \"lit_one\": {\n \"type\": \"string\",\n \"value\": \"'one quote'\"\n },\n \"lit_one_space\": {\n \"type\": \"string\",\n \"value\": \" 'one quote' \"\n },\n \"lit_two\": {\n \"type\": \"string\",\n \"value\": \"''two quotes''\"\n },\n \"lit_two_space\": {\n \"type\": \"string\",\n \"value\": \" ''two quotes'' \"\n },\n \"mismatch1\": {\n \"type\": \"string\",\n \"value\": \"aaa'''bbb\"\n },\n \"mismatch2\": {\n \"type\": \"string\",\n \"value\": \"aaa\\\"\\\"\\\"bbb\"\n },\n \"one\": {\n \"type\": \"string\",\n \"value\": \"\\\"one quote\\\"\"\n },\n \"one_space\": {\n \"type\": \"string\",\n \"value\": \" \\\"one quote\\\" \"\n },\n \"two\": {\n \"type\": \"string\",\n \"value\": \"\\\"\\\"two quotes\\\"\\\"\"\n },\n \"two_space\": {\n \"type\": \"string\",\n \"value\": \" \\\"\\\"two quotes\\\"\\\" \"\n }\n}\n"
|
||||||
testgenValid(t, input, jsonRef)
|
testgenValid(t, input, jsonRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -611,7 +611,7 @@ func (d *decoder) tryTextUnmarshaler(node *ast.Node, v reflect.Value) (bool, err
|
|||||||
if v.CanAddr() && v.Addr().Type().Implements(textUnmarshalerType) {
|
if v.CanAddr() && v.Addr().Type().Implements(textUnmarshalerType) {
|
||||||
err := v.Addr().Interface().(encoding.TextUnmarshaler).UnmarshalText(node.Data)
|
err := v.Addr().Interface().(encoding.TextUnmarshaler).UnmarshalText(node.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, newDecodeError(d.p.Raw(node.Raw), "error calling UnmarshalText: %w", err)
|
return false, newDecodeError(d.p.Raw(node.Raw), "%w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
|
|||||||
@@ -545,6 +545,35 @@ func TestUnmarshal(t *testing.T) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "issue 739 - table redefinition",
|
||||||
|
input: `
|
||||||
|
[foo.bar.baz]
|
||||||
|
wibble = 'wobble'
|
||||||
|
|
||||||
|
[foo]
|
||||||
|
|
||||||
|
[foo.bar]
|
||||||
|
huey = 'dewey'
|
||||||
|
`,
|
||||||
|
gen: func() test {
|
||||||
|
m := map[string]interface{}{}
|
||||||
|
|
||||||
|
return test{
|
||||||
|
target: &m,
|
||||||
|
expected: &map[string]interface{}{
|
||||||
|
`foo`: map[string]interface{}{
|
||||||
|
"bar": map[string]interface{}{
|
||||||
|
"huey": "dewey",
|
||||||
|
"baz": map[string]interface{}{
|
||||||
|
"wibble": "wobble",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
desc: "multiline basic string",
|
desc: "multiline basic string",
|
||||||
input: `A = """\
|
input: `A = """\
|
||||||
|
|||||||
Reference in New Issue
Block a user