1 package toml
2
3 import (
4 "bytes"
5 "errors"
6 "fmt"
7 "strings"
8 "testing"
9
10 "github.com/pelletier/go-toml/v2/unstable"
11 "github.com/stretchr/testify/assert"
12 )
13
14
15 func TestDecodeError(t *testing.T) {
16
17 examples := []struct {
18 desc string
19 doc [3]string
20 msg string
21 expected string
22 }{
23 {
24 desc: "no context",
25 doc: [3]string{"", "morning", ""},
26 msg: "this is wrong",
27 expected: `
28 1| morning
29 | ~~~~~~~ this is wrong`,
30 },
31 {
32 desc: "one line",
33 doc: [3]string{"good ", "morning", " everyone"},
34 msg: "this is wrong",
35 expected: `
36 1| good morning everyone
37 | ~~~~~~~ this is wrong`,
38 },
39 {
40 desc: "exactly 3 lines",
41 doc: [3]string{`line1
42 line2
43 line3
44 before `, "highlighted", ` after
45 post line 1
46 post line 2
47 post line 3`},
48 msg: "this is wrong",
49 expected: `
50 1| line1
51 2| line2
52 3| line3
53 4| before highlighted after
54 | ~~~~~~~~~~~ this is wrong
55 5| post line 1
56 6| post line 2
57 7| post line 3`,
58 },
59 {
60 desc: "more than 3 lines",
61 doc: [3]string{`should not be seen1
62 should not be seen2
63 line1
64 line2
65 line3
66 before `, "highlighted", ` after
67 post line 1
68 post line 2
69 post line 3
70 should not be seen3
71 should not be seen4`},
72 msg: "this is wrong",
73 expected: `
74 3| line1
75 4| line2
76 5| line3
77 6| before highlighted after
78 | ~~~~~~~~~~~ this is wrong
79 7| post line 1
80 8| post line 2
81 9| post line 3`,
82 },
83 {
84 desc: "more than 10 total lines",
85 doc: [3]string{`should not be seen 0
86 should not be seen1
87 should not be seen2
88 should not be seen3
89 line1
90 line2
91 line3
92 before `, "highlighted", ` after
93 post line 1
94 post line 2
95 post line 3
96 should not be seen3
97 should not be seen4`},
98 msg: "this is wrong",
99 expected: `
100 5| line1
101 6| line2
102 7| line3
103 8| before highlighted after
104 | ~~~~~~~~~~~ this is wrong
105 9| post line 1
106 10| post line 2
107 11| post line 3`,
108 },
109 {
110 desc: "last line of more than 10",
111 doc: [3]string{`should not be seen
112 should not be seen
113 should not be seen
114 should not be seen
115 should not be seen
116 should not be seen
117 should not be seen
118 line1
119 line2
120 line3
121 before `, "highlighted", ``},
122 msg: "this is wrong",
123 expected: `
124 8| line1
125 9| line2
126 10| line3
127 11| before highlighted
128 | ~~~~~~~~~~~ this is wrong
129 `,
130 },
131 {
132 desc: "handle empty lines in the before/after blocks",
133 doc: [3]string{
134 `line1
135
136 line 2
137 before `, "highlighted", ` after
138 line 3
139
140 line 4
141 line 5`,
142 },
143 expected: `1| line1
144 2|
145 3| line 2
146 4| before highlighted after
147 | ~~~~~~~~~~~
148 5| line 3
149 6|
150 7| line 4`,
151 },
152 {
153 desc: "handle remainder of the error line when there is only one line",
154 doc: [3]string{`P=`, `[`, `#`},
155 msg: "array is incomplete",
156 expected: `1| P=[#
157 | ~ array is incomplete`,
158 },
159 }
160
161 for _, e := range examples {
162 e := e
163 t.Run(e.desc, func(t *testing.T) {
164
165 b := bytes.Buffer{}
166 b.Write([]byte(e.doc[0]))
167 start := b.Len()
168 b.Write([]byte(e.doc[1]))
169 end := b.Len()
170 b.Write([]byte(e.doc[2]))
171 doc := b.Bytes()
172 hl := doc[start:end]
173
174 err := wrapDecodeError(doc, &unstable.ParserError{
175 Highlight: hl,
176 Message: e.msg,
177 })
178
179 var derr *DecodeError
180 if !errors.As(err, &derr) {
181 t.Errorf("error not in expected format")
182
183 return
184 }
185
186 assert.Equal(t, strings.Trim(e.expected, "\n"), derr.String())
187 })
188 }
189 }
190
191 func TestDecodeError_Accessors(t *testing.T) {
192
193 e := DecodeError{
194 message: "foo",
195 line: 1,
196 column: 2,
197 key: []string{"one", "two"},
198 human: "bar",
199 }
200 assert.Equal(t, "toml: foo", e.Error())
201 r, c := e.Position()
202 assert.Equal(t, 1, r)
203 assert.Equal(t, 2, c)
204 assert.Equal(t, Key{"one", "two"}, e.Key())
205 assert.Equal(t, "bar", e.String())
206 }
207
208 func ExampleDecodeError() {
209 doc := `name = 123__456`
210
211 s := map[string]interface{}{}
212 err := Unmarshal([]byte(doc), &s)
213
214 fmt.Println(err)
215
216 var derr *DecodeError
217 if errors.As(err, &derr) {
218 fmt.Println(derr.String())
219 row, col := derr.Position()
220 fmt.Println("error occurred at row", row, "column", col)
221 }
222
223
224
225
226
227 }
228
View as plain text