OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / pelletier / go-toml / parser_test.go
1 package toml
2
3 import (
4         "fmt"
5         "reflect"
6         "testing"
7         "time"
8
9         "github.com/davecgh/go-spew/spew"
10 )
11
12 func assertSubTree(t *testing.T, path []string, tree *Tree, err error, ref map[string]interface{}) {
13         if err != nil {
14                 t.Error("Non-nil error:", err.Error())
15                 return
16         }
17         for k, v := range ref {
18                 nextPath := append(path, k)
19                 t.Log("asserting path", nextPath)
20                 // NOTE: directly access key instead of resolve by path
21                 // NOTE: see TestSpecialKV
22                 switch node := tree.GetPath([]string{k}).(type) {
23                 case []*Tree:
24                         t.Log("\tcomparing key", nextPath, "by array iteration")
25                         for idx, item := range node {
26                                 assertSubTree(t, nextPath, item, err, v.([]map[string]interface{})[idx])
27                         }
28                 case *Tree:
29                         t.Log("\tcomparing key", nextPath, "by subtree assestion")
30                         assertSubTree(t, nextPath, node, err, v.(map[string]interface{}))
31                 default:
32                         t.Log("\tcomparing key", nextPath, "by string representation because it's of type", reflect.TypeOf(node))
33                         if fmt.Sprintf("%v", node) != fmt.Sprintf("%v", v) {
34                                 t.Errorf("was expecting %v at %v but got %v", v, k, node)
35                         }
36                 }
37         }
38 }
39
40 func assertTree(t *testing.T, tree *Tree, err error, ref map[string]interface{}) {
41         t.Log("Asserting tree:\n", spew.Sdump(tree))
42         assertSubTree(t, []string{}, tree, err, ref)
43         t.Log("Finished tree assertion.")
44 }
45
46 func TestCreateSubTree(t *testing.T) {
47         tree := newTree()
48         tree.createSubTree([]string{"a", "b", "c"}, Position{})
49         tree.Set("a.b.c", "", false, 42)
50         if tree.Get("a.b.c") != 42 {
51                 t.Fail()
52         }
53 }
54
55 func TestSimpleKV(t *testing.T) {
56         tree, err := Load("a = 42")
57         assertTree(t, tree, err, map[string]interface{}{
58                 "a": int64(42),
59         })
60
61         tree, _ = Load("a = 42\nb = 21")
62         assertTree(t, tree, err, map[string]interface{}{
63                 "a": int64(42),
64                 "b": int64(21),
65         })
66 }
67
68 func TestNumberInKey(t *testing.T) {
69         tree, err := Load("hello2 = 42")
70         assertTree(t, tree, err, map[string]interface{}{
71                 "hello2": int64(42),
72         })
73 }
74
75 func TestSimpleNumbers(t *testing.T) {
76         tree, err := Load("a = +42\nb = -21\nc = +4.2\nd = -2.1")
77         assertTree(t, tree, err, map[string]interface{}{
78                 "a": int64(42),
79                 "b": int64(-21),
80                 "c": float64(4.2),
81                 "d": float64(-2.1),
82         })
83 }
84
85 func TestNumbersWithUnderscores(t *testing.T) {
86         tree, err := Load("a = 1_000")
87         assertTree(t, tree, err, map[string]interface{}{
88                 "a": int64(1000),
89         })
90
91         tree, err = Load("a = 5_349_221")
92         assertTree(t, tree, err, map[string]interface{}{
93                 "a": int64(5349221),
94         })
95
96         tree, err = Load("a = 1_2_3_4_5")
97         assertTree(t, tree, err, map[string]interface{}{
98                 "a": int64(12345),
99         })
100
101         tree, err = Load("flt8 = 9_224_617.445_991_228_313")
102         assertTree(t, tree, err, map[string]interface{}{
103                 "flt8": float64(9224617.445991228313),
104         })
105
106         tree, err = Load("flt9 = 1e1_00")
107         assertTree(t, tree, err, map[string]interface{}{
108                 "flt9": float64(1e100),
109         })
110 }
111
112 func TestFloatsWithExponents(t *testing.T) {
113         tree, err := Load("a = 5e+22\nb = 5E+22\nc = -5e+22\nd = -5e-22\ne = 6.626e-34")
114         assertTree(t, tree, err, map[string]interface{}{
115                 "a": float64(5e+22),
116                 "b": float64(5E+22),
117                 "c": float64(-5e+22),
118                 "d": float64(-5e-22),
119                 "e": float64(6.626e-34),
120         })
121 }
122
123 func TestSimpleDate(t *testing.T) {
124         tree, err := Load("a = 1979-05-27T07:32:00Z")
125         assertTree(t, tree, err, map[string]interface{}{
126                 "a": time.Date(1979, time.May, 27, 7, 32, 0, 0, time.UTC),
127         })
128 }
129
130 func TestDateOffset(t *testing.T) {
131         tree, err := Load("a = 1979-05-27T00:32:00-07:00")
132         assertTree(t, tree, err, map[string]interface{}{
133                 "a": time.Date(1979, time.May, 27, 0, 32, 0, 0, time.FixedZone("", -7*60*60)),
134         })
135 }
136
137 func TestDateNano(t *testing.T) {
138         tree, err := Load("a = 1979-05-27T00:32:00.999999999-07:00")
139         assertTree(t, tree, err, map[string]interface{}{
140                 "a": time.Date(1979, time.May, 27, 0, 32, 0, 999999999, time.FixedZone("", -7*60*60)),
141         })
142 }
143
144 func TestSimpleString(t *testing.T) {
145         tree, err := Load("a = \"hello world\"")
146         assertTree(t, tree, err, map[string]interface{}{
147                 "a": "hello world",
148         })
149 }
150
151 func TestSpaceKey(t *testing.T) {
152         tree, err := Load("\"a b\" = \"hello world\"")
153         assertTree(t, tree, err, map[string]interface{}{
154                 "a b": "hello world",
155         })
156 }
157
158 func TestStringEscapables(t *testing.T) {
159         tree, err := Load("a = \"a \\n b\"")
160         assertTree(t, tree, err, map[string]interface{}{
161                 "a": "a \n b",
162         })
163
164         tree, err = Load("a = \"a \\t b\"")
165         assertTree(t, tree, err, map[string]interface{}{
166                 "a": "a \t b",
167         })
168
169         tree, err = Load("a = \"a \\r b\"")
170         assertTree(t, tree, err, map[string]interface{}{
171                 "a": "a \r b",
172         })
173
174         tree, err = Load("a = \"a \\\\ b\"")
175         assertTree(t, tree, err, map[string]interface{}{
176                 "a": "a \\ b",
177         })
178 }
179
180 func TestEmptyQuotedString(t *testing.T) {
181         tree, err := Load(`[""]
182 "" = 1`)
183         assertTree(t, tree, err, map[string]interface{}{
184                 "": map[string]interface{}{
185                         "": int64(1),
186                 },
187         })
188 }
189
190 func TestBools(t *testing.T) {
191         tree, err := Load("a = true\nb = false")
192         assertTree(t, tree, err, map[string]interface{}{
193                 "a": true,
194                 "b": false,
195         })
196 }
197
198 func TestNestedKeys(t *testing.T) {
199         tree, err := Load("[a.b.c]\nd = 42")
200         assertTree(t, tree, err, map[string]interface{}{
201                 "a": map[string]interface{}{
202                         "b": map[string]interface{}{
203                                 "c": map[string]interface{}{
204                                         "d": int64(42),
205                                 },
206                         },
207                 },
208         })
209 }
210
211 func TestNestedQuotedUnicodeKeys(t *testing.T) {
212         tree, err := Load("[ j . \"Êž\" . l ]\nd = 42")
213         assertTree(t, tree, err, map[string]interface{}{
214                 "j": map[string]interface{}{
215                         "Êž": map[string]interface{}{
216                                 "l": map[string]interface{}{
217                                         "d": int64(42),
218                                 },
219                         },
220                 },
221         })
222
223         tree, err = Load("[ g . h . i ]\nd = 42")
224         assertTree(t, tree, err, map[string]interface{}{
225                 "g": map[string]interface{}{
226                         "h": map[string]interface{}{
227                                 "i": map[string]interface{}{
228                                         "d": int64(42),
229                                 },
230                         },
231                 },
232         })
233
234         tree, err = Load("[ d.e.f ]\nk = 42")
235         assertTree(t, tree, err, map[string]interface{}{
236                 "d": map[string]interface{}{
237                         "e": map[string]interface{}{
238                                 "f": map[string]interface{}{
239                                         "k": int64(42),
240                                 },
241                         },
242                 },
243         })
244 }
245
246 func TestArrayOne(t *testing.T) {
247         tree, err := Load("a = [1]")
248         assertTree(t, tree, err, map[string]interface{}{
249                 "a": []int64{int64(1)},
250         })
251 }
252
253 func TestArrayZero(t *testing.T) {
254         tree, err := Load("a = []")
255         assertTree(t, tree, err, map[string]interface{}{
256                 "a": []interface{}{},
257         })
258 }
259
260 func TestArraySimple(t *testing.T) {
261         tree, err := Load("a = [42, 21, 10]")
262         assertTree(t, tree, err, map[string]interface{}{
263                 "a": []int64{int64(42), int64(21), int64(10)},
264         })
265
266         tree, _ = Load("a = [42, 21, 10,]")
267         assertTree(t, tree, err, map[string]interface{}{
268                 "a": []int64{int64(42), int64(21), int64(10)},
269         })
270 }
271
272 func TestArrayMultiline(t *testing.T) {
273         tree, err := Load("a = [42,\n21, 10,]")
274         assertTree(t, tree, err, map[string]interface{}{
275                 "a": []int64{int64(42), int64(21), int64(10)},
276         })
277 }
278
279 func TestArrayNested(t *testing.T) {
280         tree, err := Load("a = [[42, 21], [10]]")
281         assertTree(t, tree, err, map[string]interface{}{
282                 "a": [][]int64{{int64(42), int64(21)}, {int64(10)}},
283         })
284 }
285
286 func TestNestedArrayComment(t *testing.T) {
287         tree, err := Load(`
288 someArray = [
289 # does not work
290 ["entry1"]
291 ]`)
292         assertTree(t, tree, err, map[string]interface{}{
293                 "someArray": [][]string{{"entry1"}},
294         })
295 }
296
297 func TestNestedEmptyArrays(t *testing.T) {
298         tree, err := Load("a = [[[]]]")
299         assertTree(t, tree, err, map[string]interface{}{
300                 "a": [][][]interface{}{{{}}},
301         })
302 }
303
304 func TestArrayMixedTypes(t *testing.T) {
305         _, err := Load("a = [42, 16.0]")
306         if err.Error() != "(1, 10): mixed types in array" {
307                 t.Error("Bad error message:", err.Error())
308         }
309
310         _, err = Load("a = [42, \"hello\"]")
311         if err.Error() != "(1, 11): mixed types in array" {
312                 t.Error("Bad error message:", err.Error())
313         }
314 }
315
316 func TestArrayNestedStrings(t *testing.T) {
317         tree, err := Load("data = [ [\"gamma\", \"delta\"], [\"Foo\"] ]")
318         assertTree(t, tree, err, map[string]interface{}{
319                 "data": [][]string{{"gamma", "delta"}, {"Foo"}},
320         })
321 }
322
323 func TestParseUnknownRvalue(t *testing.T) {
324         _, err := Load("a = !bssss")
325         if err == nil {
326                 t.Error("Expecting a parse error")
327         }
328
329         _, err = Load("a = /b")
330         if err == nil {
331                 t.Error("Expecting a parse error")
332         }
333 }
334
335 func TestMissingValue(t *testing.T) {
336         _, err := Load("a = ")
337         if err.Error() != "(1, 5): expecting a value" {
338                 t.Error("Bad error message:", err.Error())
339         }
340 }
341
342 func TestUnterminatedArray(t *testing.T) {
343         _, err := Load("a = [1,")
344         if err.Error() != "(1, 8): unterminated array" {
345                 t.Error("Bad error message:", err.Error())
346         }
347
348         _, err = Load("a = [1")
349         if err.Error() != "(1, 7): unterminated array" {
350                 t.Error("Bad error message:", err.Error())
351         }
352
353         _, err = Load("a = [1 2")
354         if err.Error() != "(1, 8): missing comma" {
355                 t.Error("Bad error message:", err.Error())
356         }
357 }
358
359 func TestNewlinesInArrays(t *testing.T) {
360         tree, err := Load("a = [1,\n2,\n3]")
361         assertTree(t, tree, err, map[string]interface{}{
362                 "a": []int64{int64(1), int64(2), int64(3)},
363         })
364 }
365
366 func TestArrayWithExtraComma(t *testing.T) {
367         tree, err := Load("a = [1,\n2,\n3,\n]")
368         assertTree(t, tree, err, map[string]interface{}{
369                 "a": []int64{int64(1), int64(2), int64(3)},
370         })
371 }
372
373 func TestArrayWithExtraCommaComment(t *testing.T) {
374         tree, err := Load("a = [1, # wow\n2, # such items\n3, # so array\n]")
375         assertTree(t, tree, err, map[string]interface{}{
376                 "a": []int64{int64(1), int64(2), int64(3)},
377         })
378 }
379
380 func TestSimpleInlineGroup(t *testing.T) {
381         tree, err := Load("key = {a = 42}")
382         assertTree(t, tree, err, map[string]interface{}{
383                 "key": map[string]interface{}{
384                         "a": int64(42),
385                 },
386         })
387 }
388
389 func TestDoubleInlineGroup(t *testing.T) {
390         tree, err := Load("key = {a = 42, b = \"foo\"}")
391         assertTree(t, tree, err, map[string]interface{}{
392                 "key": map[string]interface{}{
393                         "a": int64(42),
394                         "b": "foo",
395                 },
396         })
397 }
398
399 func TestExampleInlineGroup(t *testing.T) {
400         tree, err := Load(`name = { first = "Tom", last = "Preston-Werner" }
401 point = { x = 1, y = 2 }`)
402         assertTree(t, tree, err, map[string]interface{}{
403                 "name": map[string]interface{}{
404                         "first": "Tom",
405                         "last":  "Preston-Werner",
406                 },
407                 "point": map[string]interface{}{
408                         "x": int64(1),
409                         "y": int64(2),
410                 },
411         })
412 }
413
414 func TestExampleInlineGroupInArray(t *testing.T) {
415         tree, err := Load(`points = [{ x = 1, y = 2 }]`)
416         assertTree(t, tree, err, map[string]interface{}{
417                 "points": []map[string]interface{}{
418                         {
419                                 "x": int64(1),
420                                 "y": int64(2),
421                         },
422                 },
423         })
424 }
425
426 func TestInlineTableUnterminated(t *testing.T) {
427         _, err := Load("foo = {")
428         if err.Error() != "(1, 8): unterminated inline table" {
429                 t.Error("Bad error message:", err.Error())
430         }
431 }
432
433 func TestInlineTableCommaExpected(t *testing.T) {
434         _, err := Load("foo = {hello = 53 test = foo}")
435         if err.Error() != "(1, 19): comma expected between fields in inline table" {
436                 t.Error("Bad error message:", err.Error())
437         }
438 }
439
440 func TestInlineTableCommaStart(t *testing.T) {
441         _, err := Load("foo = {, hello = 53}")
442         if err.Error() != "(1, 8): inline table cannot start with a comma" {
443                 t.Error("Bad error message:", err.Error())
444         }
445 }
446
447 func TestInlineTableDoubleComma(t *testing.T) {
448         _, err := Load("foo = {hello = 53,, foo = 17}")
449         if err.Error() != "(1, 19): need field between two commas in inline table" {
450                 t.Error("Bad error message:", err.Error())
451         }
452 }
453
454 func TestDuplicateGroups(t *testing.T) {
455         _, err := Load("[foo]\na=2\n[foo]b=3")
456         if err.Error() != "(3, 2): duplicated tables" {
457                 t.Error("Bad error message:", err.Error())
458         }
459 }
460
461 func TestDuplicateKeys(t *testing.T) {
462         _, err := Load("foo = 2\nfoo = 3")
463         if err.Error() != "(2, 1): The following key was defined twice: foo" {
464                 t.Error("Bad error message:", err.Error())
465         }
466 }
467
468 func TestEmptyIntermediateTable(t *testing.T) {
469         _, err := Load("[foo..bar]")
470         if err.Error() != "(1, 2): invalid table array key: empty table key" {
471                 t.Error("Bad error message:", err.Error())
472         }
473 }
474
475 func TestImplicitDeclarationBefore(t *testing.T) {
476         tree, err := Load("[a.b.c]\nanswer = 42\n[a]\nbetter = 43")
477         assertTree(t, tree, err, map[string]interface{}{
478                 "a": map[string]interface{}{
479                         "b": map[string]interface{}{
480                                 "c": map[string]interface{}{
481                                         "answer": int64(42),
482                                 },
483                         },
484                         "better": int64(43),
485                 },
486         })
487 }
488
489 func TestFloatsWithoutLeadingZeros(t *testing.T) {
490         _, err := Load("a = .42")
491         if err.Error() != "(1, 5): cannot start float with a dot" {
492                 t.Error("Bad error message:", err.Error())
493         }
494
495         _, err = Load("a = -.42")
496         if err.Error() != "(1, 5): cannot start float with a dot" {
497                 t.Error("Bad error message:", err.Error())
498         }
499 }
500
501 func TestMissingFile(t *testing.T) {
502         _, err := LoadFile("foo.toml")
503         if err.Error() != "open foo.toml: no such file or directory" &&
504                 err.Error() != "open foo.toml: The system cannot find the file specified." {
505                 t.Error("Bad error message:", err.Error())
506         }
507 }
508
509 func TestParseFile(t *testing.T) {
510         tree, err := LoadFile("example.toml")
511
512         assertTree(t, tree, err, map[string]interface{}{
513                 "title": "TOML Example",
514                 "owner": map[string]interface{}{
515                         "name":         "Tom Preston-Werner",
516                         "organization": "GitHub",
517                         "bio":          "GitHub Cofounder & CEO\nLikes tater tots and beer.",
518                         "dob":          time.Date(1979, time.May, 27, 7, 32, 0, 0, time.UTC),
519                 },
520                 "database": map[string]interface{}{
521                         "server":         "192.168.1.1",
522                         "ports":          []int64{8001, 8001, 8002},
523                         "connection_max": 5000,
524                         "enabled":        true,
525                 },
526                 "servers": map[string]interface{}{
527                         "alpha": map[string]interface{}{
528                                 "ip": "10.0.0.1",
529                                 "dc": "eqdc10",
530                         },
531                         "beta": map[string]interface{}{
532                                 "ip": "10.0.0.2",
533                                 "dc": "eqdc10",
534                         },
535                 },
536                 "clients": map[string]interface{}{
537                         "data": []interface{}{
538                                 []string{"gamma", "delta"},
539                                 []int64{1, 2},
540                         },
541                 },
542         })
543 }
544
545 func TestParseFileCRLF(t *testing.T) {
546         tree, err := LoadFile("example-crlf.toml")
547
548         assertTree(t, tree, err, map[string]interface{}{
549                 "title": "TOML Example",
550                 "owner": map[string]interface{}{
551                         "name":         "Tom Preston-Werner",
552                         "organization": "GitHub",
553                         "bio":          "GitHub Cofounder & CEO\nLikes tater tots and beer.",
554                         "dob":          time.Date(1979, time.May, 27, 7, 32, 0, 0, time.UTC),
555                 },
556                 "database": map[string]interface{}{
557                         "server":         "192.168.1.1",
558                         "ports":          []int64{8001, 8001, 8002},
559                         "connection_max": 5000,
560                         "enabled":        true,
561                 },
562                 "servers": map[string]interface{}{
563                         "alpha": map[string]interface{}{
564                                 "ip": "10.0.0.1",
565                                 "dc": "eqdc10",
566                         },
567                         "beta": map[string]interface{}{
568                                 "ip": "10.0.0.2",
569                                 "dc": "eqdc10",
570                         },
571                 },
572                 "clients": map[string]interface{}{
573                         "data": []interface{}{
574                                 []string{"gamma", "delta"},
575                                 []int64{1, 2},
576                         },
577                 },
578         })
579 }
580
581 func TestParseKeyGroupArray(t *testing.T) {
582         tree, err := Load("[[foo.bar]] a = 42\n[[foo.bar]] a = 69")
583         assertTree(t, tree, err, map[string]interface{}{
584                 "foo": map[string]interface{}{
585                         "bar": []map[string]interface{}{
586                                 {"a": int64(42)},
587                                 {"a": int64(69)},
588                         },
589                 },
590         })
591 }
592
593 func TestParseKeyGroupArrayUnfinished(t *testing.T) {
594         _, err := Load("[[foo.bar]\na = 42")
595         if err.Error() != "(1, 10): was expecting token [[, but got unclosed table array key instead" {
596                 t.Error("Bad error message:", err.Error())
597         }
598
599         _, err = Load("[[foo.[bar]\na = 42")
600         if err.Error() != "(1, 3): unexpected token table array key cannot contain ']', was expecting a table array key" {
601                 t.Error("Bad error message:", err.Error())
602         }
603 }
604
605 func TestParseKeyGroupArrayQueryExample(t *testing.T) {
606         tree, err := Load(`
607       [[book]]
608       title = "The Stand"
609       author = "Stephen King"
610       [[book]]
611       title = "For Whom the Bell Tolls"
612       author = "Ernest Hemmingway"
613       [[book]]
614       title = "Neuromancer"
615       author = "William Gibson"
616     `)
617
618         assertTree(t, tree, err, map[string]interface{}{
619                 "book": []map[string]interface{}{
620                         {"title": "The Stand", "author": "Stephen King"},
621                         {"title": "For Whom the Bell Tolls", "author": "Ernest Hemmingway"},
622                         {"title": "Neuromancer", "author": "William Gibson"},
623                 },
624         })
625 }
626
627 func TestParseKeyGroupArraySpec(t *testing.T) {
628         tree, err := Load("[[fruit]]\n name=\"apple\"\n [fruit.physical]\n color=\"red\"\n shape=\"round\"\n [[fruit]]\n name=\"banana\"")
629         assertTree(t, tree, err, map[string]interface{}{
630                 "fruit": []map[string]interface{}{
631                         {"name": "apple", "physical": map[string]interface{}{"color": "red", "shape": "round"}},
632                         {"name": "banana"},
633                 },
634         })
635 }
636
637 func TestTomlValueStringRepresentation(t *testing.T) {
638         for idx, item := range []struct {
639                 Value  interface{}
640                 Expect string
641         }{
642                 {int64(12345), "12345"},
643                 {uint64(50), "50"},
644                 {float64(123.45), "123.45"},
645                 {bool(true), "true"},
646                 {"hello world", "\"hello world\""},
647                 {"\b\t\n\f\r\"\\", "\"\\b\\t\\n\\f\\r\\\"\\\\\""},
648                 {"\x05", "\"\\u0005\""},
649                 {time.Date(1979, time.May, 27, 7, 32, 0, 0, time.UTC),
650                         "1979-05-27T07:32:00Z"},
651                 {[]interface{}{"gamma", "delta"},
652                         "[\"gamma\",\"delta\"]"},
653                 {nil, ""},
654         } {
655                 result, err := tomlValueStringRepresentation(item.Value)
656                 if err != nil {
657                         t.Errorf("Test %d - unexpected error: %s", idx, err)
658                 }
659                 if result != item.Expect {
660                         t.Errorf("Test %d - got '%s', expected '%s'", idx, result, item.Expect)
661                 }
662         }
663 }
664
665 func TestToStringMapStringString(t *testing.T) {
666         tree, err := TreeFromMap(map[string]interface{}{"m": map[string]interface{}{"v": "abc"}})
667         if err != nil {
668                 t.Fatalf("unexpected error: %s", err)
669         }
670         want := "\n[m]\n  v = \"abc\"\n"
671         got := tree.String()
672
673         if got != want {
674                 t.Errorf("want:\n%q\ngot:\n%q", want, got)
675         }
676 }
677
678 func assertPosition(t *testing.T, text string, ref map[string]Position) {
679         tree, err := Load(text)
680         if err != nil {
681                 t.Errorf("Error loading document text: `%v`", text)
682                 t.Errorf("Error: %v", err)
683         }
684         for path, pos := range ref {
685                 testPos := tree.GetPosition(path)
686                 if testPos.Invalid() {
687                         t.Errorf("Failed to query tree path or path has invalid position: %s", path)
688                 } else if pos != testPos {
689                         t.Errorf("Expected position %v, got %v instead", pos, testPos)
690                 }
691         }
692 }
693
694 func TestDocumentPositions(t *testing.T) {
695         assertPosition(t,
696                 "[foo]\nbar=42\nbaz=69",
697                 map[string]Position{
698                         "":        {1, 1},
699                         "foo":     {1, 1},
700                         "foo.bar": {2, 1},
701                         "foo.baz": {3, 1},
702                 })
703 }
704
705 func TestDocumentPositionsWithSpaces(t *testing.T) {
706         assertPosition(t,
707                 "  [foo]\n  bar=42\n  baz=69",
708                 map[string]Position{
709                         "":        {1, 1},
710                         "foo":     {1, 3},
711                         "foo.bar": {2, 3},
712                         "foo.baz": {3, 3},
713                 })
714 }
715
716 func TestDocumentPositionsWithGroupArray(t *testing.T) {
717         assertPosition(t,
718                 "[[foo]]\nbar=42\nbaz=69",
719                 map[string]Position{
720                         "":        {1, 1},
721                         "foo":     {1, 1},
722                         "foo.bar": {2, 1},
723                         "foo.baz": {3, 1},
724                 })
725 }
726
727 func TestNestedTreePosition(t *testing.T) {
728         assertPosition(t,
729                 "[foo.bar]\na=42\nb=69",
730                 map[string]Position{
731                         "":          {1, 1},
732                         "foo":       {1, 1},
733                         "foo.bar":   {1, 1},
734                         "foo.bar.a": {2, 1},
735                         "foo.bar.b": {3, 1},
736                 })
737 }
738
739 func TestInvalidGroupArray(t *testing.T) {
740         _, err := Load("[table#key]\nanswer = 42")
741         if err == nil {
742                 t.Error("Should error")
743         }
744
745         _, err = Load("[foo.[bar]\na = 42")
746         if err.Error() != "(1, 2): unexpected token table key cannot contain ']', was expecting a table key" {
747                 t.Error("Bad error message:", err.Error())
748         }
749 }
750
751 func TestDoubleEqual(t *testing.T) {
752         _, err := Load("foo= = 2")
753         if err.Error() != "(1, 6): cannot have multiple equals for the same key" {
754                 t.Error("Bad error message:", err.Error())
755         }
756 }
757
758 func TestGroupArrayReassign(t *testing.T) {
759         _, err := Load("[hello]\n[[hello]]")
760         if err.Error() != "(2, 3): key \"hello\" is already assigned and not of type table array" {
761                 t.Error("Bad error message:", err.Error())
762         }
763 }
764
765 func TestInvalidFloatParsing(t *testing.T) {
766         _, err := Load("a=1e_2")
767         if err.Error() != "(1, 3): invalid use of _ in number" {
768                 t.Error("Bad error message:", err.Error())
769         }
770
771         _, err = Load("a=1e2_")
772         if err.Error() != "(1, 3): invalid use of _ in number" {
773                 t.Error("Bad error message:", err.Error())
774         }
775
776         _, err = Load("a=1__2")
777         if err.Error() != "(1, 3): invalid use of _ in number" {
778                 t.Error("Bad error message:", err.Error())
779         }
780
781         _, err = Load("a=_1_2")
782         if err.Error() != "(1, 3): cannot start number with underscore" {
783                 t.Error("Bad error message:", err.Error())
784         }
785 }