...

Source file src/github.com/pelletier/go-toml/parser_test.go

Documentation: github.com/pelletier/go-toml

     1  package toml
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"reflect"
     7  	"testing"
     8  	"time"
     9  )
    10  
    11  func assertSubTree(t *testing.T, path []string, tree *Tree, err error, ref map[string]interface{}) {
    12  	if err != nil {
    13  		t.Error("Non-nil error:", err.Error())
    14  		return
    15  	}
    16  	for k, v := range ref {
    17  		nextPath := append(path, k)
    18  		t.Log("asserting path", nextPath)
    19  		// NOTE: directly access key instead of resolve by path
    20  		// NOTE: see TestSpecialKV
    21  		switch node := tree.GetPath([]string{k}).(type) {
    22  		case []*Tree:
    23  			t.Log("\tcomparing key", nextPath, "by array iteration")
    24  			for idx, item := range node {
    25  				assertSubTree(t, nextPath, item, err, v.([]map[string]interface{})[idx])
    26  			}
    27  		case *Tree:
    28  			t.Log("\tcomparing key", nextPath, "by subtree assestion")
    29  			assertSubTree(t, nextPath, node, err, v.(map[string]interface{}))
    30  		default:
    31  			t.Log("\tcomparing key", nextPath, "by string representation because it's of type", reflect.TypeOf(node))
    32  			if fmt.Sprintf("%v", node) != fmt.Sprintf("%v", v) {
    33  				t.Errorf("was expecting %v at %v but got %v", v, k, node)
    34  			}
    35  		}
    36  	}
    37  }
    38  
    39  func assertTree(t *testing.T, tree *Tree, err error, ref map[string]interface{}) {
    40  	t.Logf("Asserting tree:\n (%T)(%p)(%+v)", tree, tree, tree)
    41  	assertSubTree(t, []string{}, tree, err, ref)
    42  	t.Log("Finished tree assertion.")
    43  }
    44  
    45  func TestCreateSubTree(t *testing.T) {
    46  	tree := newTree()
    47  	tree.createSubTree([]string{"a", "b", "c"}, Position{})
    48  	tree.Set("a.b.c", 42)
    49  	if tree.Get("a.b.c") != 42 {
    50  		t.Fail()
    51  	}
    52  }
    53  
    54  func TestSimpleKV(t *testing.T) {
    55  	tree, err := Load("a = 42")
    56  	assertTree(t, tree, err, map[string]interface{}{
    57  		"a": int64(42),
    58  	})
    59  
    60  	tree, _ = Load("a = 42\nb = 21")
    61  	assertTree(t, tree, err, map[string]interface{}{
    62  		"a": int64(42),
    63  		"b": int64(21),
    64  	})
    65  }
    66  
    67  func TestNumberInKey(t *testing.T) {
    68  	tree, err := Load("hello2 = 42")
    69  	assertTree(t, tree, err, map[string]interface{}{
    70  		"hello2": int64(42),
    71  	})
    72  }
    73  
    74  func TestIncorrectKeyExtraSquareBracket(t *testing.T) {
    75  	_, err := Load(`[a]b]
    76  zyx = 42`)
    77  	if err == nil {
    78  		t.Error("Error should have been returned.")
    79  	}
    80  	if err.Error() != "(1, 4): parsing error: keys cannot contain ] character" {
    81  		t.Error("Bad error message:", err.Error())
    82  	}
    83  }
    84  
    85  func TestSimpleNumbers(t *testing.T) {
    86  	tree, err := Load("a = +42\nb = -21\nc = +4.2\nd = -2.1")
    87  	assertTree(t, tree, err, map[string]interface{}{
    88  		"a": int64(42),
    89  		"b": int64(-21),
    90  		"c": float64(4.2),
    91  		"d": float64(-2.1),
    92  	})
    93  }
    94  
    95  func TestSpecialFloats(t *testing.T) {
    96  	tree, err := Load(`
    97  normalinf = inf
    98  plusinf = +inf
    99  minusinf = -inf
   100  normalnan = nan
   101  plusnan = +nan
   102  minusnan = -nan
   103  `)
   104  	assertTree(t, tree, err, map[string]interface{}{
   105  		"normalinf": math.Inf(1),
   106  		"plusinf":   math.Inf(1),
   107  		"minusinf":  math.Inf(-1),
   108  		"normalnan": math.NaN(),
   109  		"plusnan":   math.NaN(),
   110  		"minusnan":  math.NaN(),
   111  	})
   112  }
   113  
   114  func TestHexIntegers(t *testing.T) {
   115  	tree, err := Load(`a = 0xDEADBEEF`)
   116  	assertTree(t, tree, err, map[string]interface{}{"a": int64(3735928559)})
   117  
   118  	tree, err = Load(`a = 0xdeadbeef`)
   119  	assertTree(t, tree, err, map[string]interface{}{"a": int64(3735928559)})
   120  
   121  	tree, err = Load(`a = 0xdead_beef`)
   122  	assertTree(t, tree, err, map[string]interface{}{"a": int64(3735928559)})
   123  
   124  	_, err = Load(`a = 0x_1`)
   125  	if err.Error() != "(1, 5): invalid use of _ in hex number" {
   126  		t.Error("Bad error message:", err.Error())
   127  	}
   128  }
   129  
   130  func TestOctIntegers(t *testing.T) {
   131  	tree, err := Load(`a = 0o01234567`)
   132  	assertTree(t, tree, err, map[string]interface{}{"a": int64(342391)})
   133  
   134  	tree, err = Load(`a = 0o755`)
   135  	assertTree(t, tree, err, map[string]interface{}{"a": int64(493)})
   136  
   137  	_, err = Load(`a = 0o_1`)
   138  	if err.Error() != "(1, 5): invalid use of _ in number" {
   139  		t.Error("Bad error message:", err.Error())
   140  	}
   141  }
   142  
   143  func TestBinIntegers(t *testing.T) {
   144  	tree, err := Load(`a = 0b11010110`)
   145  	assertTree(t, tree, err, map[string]interface{}{"a": int64(214)})
   146  
   147  	_, err = Load(`a = 0b_1`)
   148  	if err.Error() != "(1, 5): invalid use of _ in number" {
   149  		t.Error("Bad error message:", err.Error())
   150  	}
   151  }
   152  
   153  func TestBadIntegerBase(t *testing.T) {
   154  	_, err := Load(`a = 0k1`)
   155  	if err.Error() != "(1, 5): unknown number base: k. possible options are x (hex) o (octal) b (binary)" {
   156  		t.Error("Error should have been returned.")
   157  	}
   158  }
   159  
   160  func TestIntegerNoDigit(t *testing.T) {
   161  	_, err := Load(`a = 0b`)
   162  	if err.Error() != "(1, 5): number needs at least one digit" {
   163  		t.Error("Bad error message:", err.Error())
   164  	}
   165  }
   166  
   167  func TestNumbersWithUnderscores(t *testing.T) {
   168  	tree, err := Load("a = 1_000")
   169  	assertTree(t, tree, err, map[string]interface{}{
   170  		"a": int64(1000),
   171  	})
   172  
   173  	tree, err = Load("a = 5_349_221")
   174  	assertTree(t, tree, err, map[string]interface{}{
   175  		"a": int64(5349221),
   176  	})
   177  
   178  	tree, err = Load("a = 1_2_3_4_5")
   179  	assertTree(t, tree, err, map[string]interface{}{
   180  		"a": int64(12345),
   181  	})
   182  
   183  	tree, err = Load("flt8 = 9_224_617.445_991_228_313")
   184  	assertTree(t, tree, err, map[string]interface{}{
   185  		"flt8": float64(9224617.445991228313),
   186  	})
   187  
   188  	tree, err = Load("flt9 = 1e1_00")
   189  	assertTree(t, tree, err, map[string]interface{}{
   190  		"flt9": float64(1e100),
   191  	})
   192  }
   193  
   194  func TestFloatsWithExponents(t *testing.T) {
   195  	tree, err := Load("a = 5e+22\nb = 5E+22\nc = -5e+22\nd = -5e-22\ne = 6.626e-34")
   196  	assertTree(t, tree, err, map[string]interface{}{
   197  		"a": float64(5e+22),
   198  		"b": float64(5e+22),
   199  		"c": float64(-5e+22),
   200  		"d": float64(-5e-22),
   201  		"e": float64(6.626e-34),
   202  	})
   203  }
   204  
   205  func TestSimpleDate(t *testing.T) {
   206  	tree, err := Load("a = 1979-05-27T07:32:00Z")
   207  	assertTree(t, tree, err, map[string]interface{}{
   208  		"a": time.Date(1979, time.May, 27, 7, 32, 0, 0, time.UTC),
   209  	})
   210  }
   211  
   212  func TestDateOffset(t *testing.T) {
   213  	tree, err := Load("a = 1979-05-27T00:32:00-07:00")
   214  	assertTree(t, tree, err, map[string]interface{}{
   215  		"a": time.Date(1979, time.May, 27, 0, 32, 0, 0, time.FixedZone("", -7*60*60)),
   216  	})
   217  }
   218  
   219  func TestDateNano(t *testing.T) {
   220  	tree, err := Load("a = 1979-05-27T00:32:00.999999999-07:00")
   221  	assertTree(t, tree, err, map[string]interface{}{
   222  		"a": time.Date(1979, time.May, 27, 0, 32, 0, 999999999, time.FixedZone("", -7*60*60)),
   223  	})
   224  }
   225  
   226  func TestLocalDateTime(t *testing.T) {
   227  	tree, err := Load("a = 1979-05-27T07:32:00")
   228  	assertTree(t, tree, err, map[string]interface{}{
   229  		"a": LocalDateTime{
   230  			Date: LocalDate{
   231  				Year:  1979,
   232  				Month: 5,
   233  				Day:   27,
   234  			},
   235  			Time: LocalTime{
   236  				Hour:       7,
   237  				Minute:     32,
   238  				Second:     0,
   239  				Nanosecond: 0,
   240  			},
   241  		},
   242  	})
   243  }
   244  
   245  func TestLocalDateTimeNano(t *testing.T) {
   246  	tree, err := Load("a = 1979-05-27T07:32:00.999999")
   247  	assertTree(t, tree, err, map[string]interface{}{
   248  		"a": LocalDateTime{
   249  			Date: LocalDate{
   250  				Year:  1979,
   251  				Month: 5,
   252  				Day:   27,
   253  			},
   254  			Time: LocalTime{
   255  				Hour:       7,
   256  				Minute:     32,
   257  				Second:     0,
   258  				Nanosecond: 999999000,
   259  			},
   260  		},
   261  	})
   262  }
   263  
   264  func TestLocalDate(t *testing.T) {
   265  	tree, err := Load("a = 1979-05-27")
   266  	assertTree(t, tree, err, map[string]interface{}{
   267  		"a": LocalDate{
   268  			Year:  1979,
   269  			Month: 5,
   270  			Day:   27,
   271  		},
   272  	})
   273  }
   274  
   275  func TestLocalDateError(t *testing.T) {
   276  	_, err := Load("a = 2020-09-31")
   277  	if err == nil {
   278  		t.Fatalf("should error")
   279  	}
   280  }
   281  
   282  func TestLocalTimeError(t *testing.T) {
   283  	_, err := Load("a = 07:99:00")
   284  	if err == nil {
   285  		t.Fatalf("should error")
   286  	}
   287  }
   288  
   289  func TestLocalDateTimeError(t *testing.T) {
   290  	_, err := Load("a = 2020-09-31T07:99:00")
   291  	if err == nil {
   292  		t.Fatalf("should error")
   293  	}
   294  }
   295  
   296  func TestDateTimeOffsetError(t *testing.T) {
   297  	_, err := Load("a = 2020-09-31T07:99:00Z")
   298  	if err == nil {
   299  		t.Fatalf("should error")
   300  	}
   301  }
   302  
   303  func TestLocalTime(t *testing.T) {
   304  	tree, err := Load("a = 07:32:00")
   305  	assertTree(t, tree, err, map[string]interface{}{
   306  		"a": LocalTime{
   307  			Hour:       7,
   308  			Minute:     32,
   309  			Second:     0,
   310  			Nanosecond: 0,
   311  		},
   312  	})
   313  }
   314  
   315  func TestLocalTimeNano(t *testing.T) {
   316  	tree, err := Load("a = 00:32:00.999999")
   317  	assertTree(t, tree, err, map[string]interface{}{
   318  		"a": LocalTime{
   319  			Hour:       0,
   320  			Minute:     32,
   321  			Second:     0,
   322  			Nanosecond: 999999000,
   323  		},
   324  	})
   325  }
   326  
   327  func TestSimpleString(t *testing.T) {
   328  	tree, err := Load("a = \"hello world\"")
   329  	assertTree(t, tree, err, map[string]interface{}{
   330  		"a": "hello world",
   331  	})
   332  }
   333  
   334  func TestSpaceKey(t *testing.T) {
   335  	tree, err := Load("\"a b\" = \"hello world\"")
   336  	assertTree(t, tree, err, map[string]interface{}{
   337  		"a b": "hello world",
   338  	})
   339  }
   340  
   341  func TestDoubleQuotedKey(t *testing.T) {
   342  	tree, err := Load(`
   343  	"key"        = "a"
   344  	"\t"         = "b"
   345  	"\U0001F914" = "c"
   346  	"\u2764"     = "d"
   347  	`)
   348  	assertTree(t, tree, err, map[string]interface{}{
   349  		"key":        "a",
   350  		"\t":         "b",
   351  		"\U0001F914": "c",
   352  		"\u2764":     "d",
   353  	})
   354  }
   355  
   356  func TestSingleQuotedKey(t *testing.T) {
   357  	tree, err := Load(`
   358  	'key'        = "a"
   359  	'\t'         = "b"
   360  	'\U0001F914' = "c"
   361  	'\u2764'     = "d"
   362  	`)
   363  	assertTree(t, tree, err, map[string]interface{}{
   364  		`key`:        "a",
   365  		`\t`:         "b",
   366  		`\U0001F914`: "c",
   367  		`\u2764`:     "d",
   368  	})
   369  }
   370  
   371  func TestStringEscapables(t *testing.T) {
   372  	tree, err := Load("a = \"a \\n b\"")
   373  	assertTree(t, tree, err, map[string]interface{}{
   374  		"a": "a \n b",
   375  	})
   376  
   377  	tree, err = Load("a = \"a \\t b\"")
   378  	assertTree(t, tree, err, map[string]interface{}{
   379  		"a": "a \t b",
   380  	})
   381  
   382  	tree, err = Load("a = \"a \\r b\"")
   383  	assertTree(t, tree, err, map[string]interface{}{
   384  		"a": "a \r b",
   385  	})
   386  
   387  	tree, err = Load("a = \"a \\\\ b\"")
   388  	assertTree(t, tree, err, map[string]interface{}{
   389  		"a": "a \\ b",
   390  	})
   391  }
   392  
   393  func TestEmptyQuotedString(t *testing.T) {
   394  	tree, err := Load(`[""]
   395  "" = 1`)
   396  	assertTree(t, tree, err, map[string]interface{}{
   397  		"": map[string]interface{}{
   398  			"": int64(1),
   399  		},
   400  	})
   401  }
   402  
   403  func TestBools(t *testing.T) {
   404  	tree, err := Load("a = true\nb = false")
   405  	assertTree(t, tree, err, map[string]interface{}{
   406  		"a": true,
   407  		"b": false,
   408  	})
   409  }
   410  
   411  func TestNestedKeys(t *testing.T) {
   412  	tree, err := Load("[a.b.c]\nd = 42")
   413  	assertTree(t, tree, err, map[string]interface{}{
   414  		"a": map[string]interface{}{
   415  			"b": map[string]interface{}{
   416  				"c": map[string]interface{}{
   417  					"d": int64(42),
   418  				},
   419  			},
   420  		},
   421  	})
   422  }
   423  
   424  func TestNestedQuotedUnicodeKeys(t *testing.T) {
   425  	tree, err := Load("[ j . \"ʞ\" . l ]\nd = 42")
   426  	assertTree(t, tree, err, map[string]interface{}{
   427  		"j": map[string]interface{}{
   428  			"ʞ": map[string]interface{}{
   429  				"l": map[string]interface{}{
   430  					"d": int64(42),
   431  				},
   432  			},
   433  		},
   434  	})
   435  
   436  	tree, err = Load("[ g . h . i ]\nd = 42")
   437  	assertTree(t, tree, err, map[string]interface{}{
   438  		"g": map[string]interface{}{
   439  			"h": map[string]interface{}{
   440  				"i": map[string]interface{}{
   441  					"d": int64(42),
   442  				},
   443  			},
   444  		},
   445  	})
   446  
   447  	tree, err = Load("[ d.e.f ]\nk = 42")
   448  	assertTree(t, tree, err, map[string]interface{}{
   449  		"d": map[string]interface{}{
   450  			"e": map[string]interface{}{
   451  				"f": map[string]interface{}{
   452  					"k": int64(42),
   453  				},
   454  			},
   455  		},
   456  	})
   457  }
   458  
   459  func TestArrayOne(t *testing.T) {
   460  	tree, err := Load("a = [1]")
   461  	assertTree(t, tree, err, map[string]interface{}{
   462  		"a": []int64{int64(1)},
   463  	})
   464  }
   465  
   466  func TestArrayZero(t *testing.T) {
   467  	tree, err := Load("a = []")
   468  	assertTree(t, tree, err, map[string]interface{}{
   469  		"a": []interface{}{},
   470  	})
   471  }
   472  
   473  func TestArraySimple(t *testing.T) {
   474  	tree, err := Load("a = [42, 21, 10]")
   475  	assertTree(t, tree, err, map[string]interface{}{
   476  		"a": []int64{int64(42), int64(21), int64(10)},
   477  	})
   478  
   479  	tree, _ = Load("a = [42, 21, 10,]")
   480  	assertTree(t, tree, err, map[string]interface{}{
   481  		"a": []int64{int64(42), int64(21), int64(10)},
   482  	})
   483  }
   484  
   485  func TestArrayMultiline(t *testing.T) {
   486  	tree, err := Load("a = [42,\n21, 10,]")
   487  	assertTree(t, tree, err, map[string]interface{}{
   488  		"a": []int64{int64(42), int64(21), int64(10)},
   489  	})
   490  }
   491  
   492  func TestArrayNested(t *testing.T) {
   493  	tree, err := Load("a = [[42, 21], [10]]")
   494  	assertTree(t, tree, err, map[string]interface{}{
   495  		"a": [][]int64{{int64(42), int64(21)}, {int64(10)}},
   496  	})
   497  }
   498  
   499  func TestNestedArrayComment(t *testing.T) {
   500  	tree, err := Load(`
   501  someArray = [
   502  # does not work
   503  ["entry1"]
   504  ]`)
   505  	assertTree(t, tree, err, map[string]interface{}{
   506  		"someArray": [][]string{{"entry1"}},
   507  	})
   508  }
   509  
   510  func TestNestedEmptyArrays(t *testing.T) {
   511  	tree, err := Load("a = [[[]]]")
   512  	assertTree(t, tree, err, map[string]interface{}{
   513  		"a": [][][]interface{}{{{}}},
   514  	})
   515  }
   516  
   517  func TestArrayNestedStrings(t *testing.T) {
   518  	tree, err := Load("data = [ [\"gamma\", \"delta\"], [\"Foo\"] ]")
   519  	assertTree(t, tree, err, map[string]interface{}{
   520  		"data": [][]string{{"gamma", "delta"}, {"Foo"}},
   521  	})
   522  }
   523  
   524  func TestParseUnknownRvalue(t *testing.T) {
   525  	_, err := Load("a = !bssss")
   526  	if err == nil {
   527  		t.Error("Expecting a parse error")
   528  	}
   529  
   530  	_, err = Load("a = /b")
   531  	if err == nil {
   532  		t.Error("Expecting a parse error")
   533  	}
   534  }
   535  
   536  func TestMissingValue(t *testing.T) {
   537  	_, err := Load("a = ")
   538  	if err.Error() != "(1, 5): expecting a value" {
   539  		t.Error("Bad error message:", err.Error())
   540  	}
   541  }
   542  
   543  func TestUnterminatedArray(t *testing.T) {
   544  	_, err := Load("a = [1,")
   545  	if err.Error() != "(1, 8): unterminated array" {
   546  		t.Error("Bad error message:", err.Error())
   547  	}
   548  
   549  	_, err = Load("a = [1")
   550  	if err.Error() != "(1, 7): unterminated array" {
   551  		t.Error("Bad error message:", err.Error())
   552  	}
   553  
   554  	_, err = Load("a = [1 2")
   555  	if err.Error() != "(1, 8): missing comma" {
   556  		t.Error("Bad error message:", err.Error())
   557  	}
   558  }
   559  
   560  func TestNewlinesInArrays(t *testing.T) {
   561  	tree, err := Load("a = [1,\n2,\n3]")
   562  	assertTree(t, tree, err, map[string]interface{}{
   563  		"a": []int64{int64(1), int64(2), int64(3)},
   564  	})
   565  }
   566  
   567  func TestArrayWithExtraComma(t *testing.T) {
   568  	tree, err := Load("a = [1,\n2,\n3,\n]")
   569  	assertTree(t, tree, err, map[string]interface{}{
   570  		"a": []int64{int64(1), int64(2), int64(3)},
   571  	})
   572  }
   573  
   574  func TestArrayWithExtraCommaComment(t *testing.T) {
   575  	tree, err := Load("a = [1, # wow\n2, # such items\n3, # so array\n]")
   576  	assertTree(t, tree, err, map[string]interface{}{
   577  		"a": []int64{int64(1), int64(2), int64(3)},
   578  	})
   579  }
   580  
   581  func TestSimpleInlineGroup(t *testing.T) {
   582  	tree, err := Load("key = {a = 42}")
   583  	assertTree(t, tree, err, map[string]interface{}{
   584  		"key": map[string]interface{}{
   585  			"a": int64(42),
   586  		},
   587  	})
   588  }
   589  
   590  func TestDoubleInlineGroup(t *testing.T) {
   591  	tree, err := Load("key = {a = 42, b = \"foo\"}")
   592  	assertTree(t, tree, err, map[string]interface{}{
   593  		"key": map[string]interface{}{
   594  			"a": int64(42),
   595  			"b": "foo",
   596  		},
   597  	})
   598  }
   599  
   600  func TestNestedInlineGroup(t *testing.T) {
   601  	tree, err := Load("out = {block0 = {x = 99, y = 100}, block1 = {p = \"999\", q = \"1000\"}}")
   602  	assertTree(t, tree, err, map[string]interface{}{
   603  		"out": map[string]interface{}{
   604  			"block0": map[string]interface{}{
   605  				"x": int64(99),
   606  				"y": int64(100),
   607  			},
   608  			"block1": map[string]interface{}{
   609  				"p": "999",
   610  				"q": "1000",
   611  			},
   612  		},
   613  	})
   614  }
   615  
   616  func TestArrayInNestedInlineGroup(t *testing.T) {
   617  	tree, err := Load(`image = {name = "xxx", palette = {id = 100, colors = ["red", "blue", "green"]}}`)
   618  	assertTree(t, tree, err, map[string]interface{}{
   619  		"image": map[string]interface{}{
   620  			"name": "xxx",
   621  			"palette": map[string]interface{}{
   622  				"id": int64(100),
   623  				"colors": []string{
   624  					"red",
   625  					"blue",
   626  					"green",
   627  				},
   628  			},
   629  		},
   630  	})
   631  }
   632  
   633  func TestExampleInlineGroup(t *testing.T) {
   634  	tree, err := Load(`name = { first = "Tom", last = "Preston-Werner" }
   635  point = { x = 1, y = 2 }`)
   636  	assertTree(t, tree, err, map[string]interface{}{
   637  		"name": map[string]interface{}{
   638  			"first": "Tom",
   639  			"last":  "Preston-Werner",
   640  		},
   641  		"point": map[string]interface{}{
   642  			"x": int64(1),
   643  			"y": int64(2),
   644  		},
   645  	})
   646  }
   647  
   648  func TestInlineGroupBareKeysUnderscore(t *testing.T) {
   649  	tree, err := Load(`foo = { _bar = "buz" }`)
   650  	assertTree(t, tree, err, map[string]interface{}{
   651  		"foo": map[string]interface{}{
   652  			"_bar": "buz",
   653  		},
   654  	})
   655  }
   656  
   657  func TestInlineGroupBareKeysDash(t *testing.T) {
   658  	tree, err := Load(`foo = { -bar = "buz" }`)
   659  	assertTree(t, tree, err, map[string]interface{}{
   660  		"foo": map[string]interface{}{
   661  			"-bar": "buz",
   662  		},
   663  	})
   664  }
   665  
   666  func TestInlineGroupKeyQuoted(t *testing.T) {
   667  	tree, err := Load(`foo = { "bar" = "buz" }`)
   668  	assertTree(t, tree, err, map[string]interface{}{
   669  		"foo": map[string]interface{}{
   670  			"bar": "buz",
   671  		},
   672  	})
   673  }
   674  
   675  func TestExampleInlineGroupInArray(t *testing.T) {
   676  	tree, err := Load(`points = [{ x = 1, y = 2 }]`)
   677  	assertTree(t, tree, err, map[string]interface{}{
   678  		"points": []map[string]interface{}{
   679  			{
   680  				"x": int64(1),
   681  				"y": int64(2),
   682  			},
   683  		},
   684  	})
   685  }
   686  
   687  func TestInlineTableUnterminated(t *testing.T) {
   688  	_, err := Load("foo = {")
   689  	if err.Error() != "(1, 8): unterminated inline table" {
   690  		t.Error("Bad error message:", err.Error())
   691  	}
   692  }
   693  
   694  func TestInlineTableCommaExpected(t *testing.T) {
   695  	_, err := Load("foo = {hello = 53 test = foo}")
   696  	if err.Error() != "(1, 19): unexpected token type in inline table: no value can start with t" {
   697  		t.Error("Bad error message:", err.Error())
   698  	}
   699  }
   700  
   701  func TestInlineTableCommaStart(t *testing.T) {
   702  	_, err := Load("foo = {, hello = 53}")
   703  	if err.Error() != "(1, 8): unexpected token type in inline table: keys cannot contain , character" {
   704  		t.Error("Bad error message:", err.Error())
   705  	}
   706  }
   707  
   708  func TestInlineTableDoubleComma(t *testing.T) {
   709  	_, err := Load("foo = {hello = 53,, foo = 17}")
   710  	if err.Error() != "(1, 19): unexpected token type in inline table: keys cannot contain , character" {
   711  		t.Error("Bad error message:", err.Error())
   712  	}
   713  }
   714  
   715  func TestInlineTableTrailingComma(t *testing.T) {
   716  	_, err := Load("foo = {hello = 53, foo = 17,}")
   717  	if err.Error() != "(1, 28): trailing comma at the end of inline table" {
   718  		t.Error("Bad error message:", err.Error())
   719  	}
   720  }
   721  
   722  func TestAddKeyToInlineTable(t *testing.T) {
   723  	_, err := Load("type = { name = \"Nail\" }\ntype.edible = false")
   724  	if err.Error() != "(2, 1): could not add key or sub-table to exist inline table or its sub-table : type" {
   725  		t.Error("Bad error message:", err.Error())
   726  	}
   727  }
   728  
   729  func TestAddSubTableToInlineTable(t *testing.T) {
   730  	_, err := Load("a = { b = \"c\" }\na.d.e = \"f\"")
   731  	if err.Error() != "(2, 1): could not add key or sub-table to exist inline table or its sub-table : a.d" {
   732  		t.Error("Bad error message:", err.Error())
   733  	}
   734  }
   735  
   736  func TestAddKeyToSubTableOfInlineTable(t *testing.T) {
   737  	_, err := Load("a = { b = { c = \"d\" } }\na.b.e = \"f\"")
   738  	if err.Error() != "(2, 1): could not add key or sub-table to exist inline table or its sub-table : a.b" {
   739  		t.Error("Bad error message:", err.Error())
   740  	}
   741  }
   742  
   743  func TestReDefineInlineTable(t *testing.T) {
   744  	_, err := Load("a = { b = \"c\" }\n[a]\n  d = \"e\"")
   745  	if err.Error() != "(2, 2): could not re-define exist inline table or its sub-table : a" {
   746  		t.Error("Bad error message:", err.Error())
   747  	}
   748  }
   749  
   750  func TestDuplicateGroups(t *testing.T) {
   751  	_, err := Load("[foo]\na=2\n[foo]b=3")
   752  	if err.Error() != "(3, 2): duplicated tables" {
   753  		t.Error("Bad error message:", err.Error())
   754  	}
   755  }
   756  
   757  func TestDuplicateKeys(t *testing.T) {
   758  	_, err := Load("foo = 2\nfoo = 3")
   759  	if err.Error() != "(2, 1): The following key was defined twice: foo" {
   760  		t.Error("Bad error message:", err.Error())
   761  	}
   762  }
   763  
   764  func TestEmptyIntermediateTable(t *testing.T) {
   765  	_, err := Load("[foo..bar]")
   766  	if err.Error() != "(1, 2): invalid table array key: expecting key part after dot" {
   767  		t.Error("Bad error message:", err.Error())
   768  	}
   769  }
   770  
   771  func TestImplicitDeclarationBefore(t *testing.T) {
   772  	tree, err := Load("[a.b.c]\nanswer = 42\n[a]\nbetter = 43")
   773  	assertTree(t, tree, err, map[string]interface{}{
   774  		"a": map[string]interface{}{
   775  			"b": map[string]interface{}{
   776  				"c": map[string]interface{}{
   777  					"answer": int64(42),
   778  				},
   779  			},
   780  			"better": int64(43),
   781  		},
   782  	})
   783  }
   784  
   785  func TestFloatsWithoutLeadingZeros(t *testing.T) {
   786  	_, err := Load("a = .42")
   787  	if err.Error() != "(1, 5): cannot start float with a dot" {
   788  		t.Error("Bad error message:", err.Error())
   789  	}
   790  
   791  	_, err = Load("a = -.42")
   792  	if err.Error() != "(1, 5): cannot start float with a dot" {
   793  		t.Error("Bad error message:", err.Error())
   794  	}
   795  }
   796  
   797  func TestMissingFile(t *testing.T) {
   798  	_, err := LoadFile("foo.toml")
   799  	if err.Error() != "open foo.toml: no such file or directory" &&
   800  		err.Error() != "open foo.toml: The system cannot find the file specified." {
   801  		t.Error("Bad error message:", err.Error())
   802  	}
   803  }
   804  
   805  func TestParseFile(t *testing.T) {
   806  	tree, err := LoadFile("example.toml")
   807  
   808  	assertTree(t, tree, err, map[string]interface{}{
   809  		"title": "TOML Example",
   810  		"owner": map[string]interface{}{
   811  			"name":         "Tom Preston-Werner",
   812  			"organization": "GitHub",
   813  			"bio":          "GitHub Cofounder & CEO\nLikes tater tots and beer.",
   814  			"dob":          time.Date(1979, time.May, 27, 7, 32, 0, 0, time.UTC),
   815  		},
   816  		"database": map[string]interface{}{
   817  			"server":         "192.168.1.1",
   818  			"ports":          []int64{8001, 8001, 8002},
   819  			"connection_max": 5000,
   820  			"enabled":        true,
   821  		},
   822  		"servers": map[string]interface{}{
   823  			"alpha": map[string]interface{}{
   824  				"ip": "10.0.0.1",
   825  				"dc": "eqdc10",
   826  			},
   827  			"beta": map[string]interface{}{
   828  				"ip": "10.0.0.2",
   829  				"dc": "eqdc10",
   830  			},
   831  		},
   832  		"clients": map[string]interface{}{
   833  			"data": []interface{}{
   834  				[]string{"gamma", "delta"},
   835  				[]int64{1, 2},
   836  			},
   837  			"score": 4e-08,
   838  		},
   839  	})
   840  }
   841  
   842  func TestParseFileCRLF(t *testing.T) {
   843  	tree, err := LoadFile("example-crlf.toml")
   844  
   845  	assertTree(t, tree, err, map[string]interface{}{
   846  		"title": "TOML Example",
   847  		"owner": map[string]interface{}{
   848  			"name":         "Tom Preston-Werner",
   849  			"organization": "GitHub",
   850  			"bio":          "GitHub Cofounder & CEO\nLikes tater tots and beer.",
   851  			"dob":          time.Date(1979, time.May, 27, 7, 32, 0, 0, time.UTC),
   852  		},
   853  		"database": map[string]interface{}{
   854  			"server":         "192.168.1.1",
   855  			"ports":          []int64{8001, 8001, 8002},
   856  			"connection_max": 5000,
   857  			"enabled":        true,
   858  		},
   859  		"servers": map[string]interface{}{
   860  			"alpha": map[string]interface{}{
   861  				"ip": "10.0.0.1",
   862  				"dc": "eqdc10",
   863  			},
   864  			"beta": map[string]interface{}{
   865  				"ip": "10.0.0.2",
   866  				"dc": "eqdc10",
   867  			},
   868  		},
   869  		"clients": map[string]interface{}{
   870  			"data": []interface{}{
   871  				[]string{"gamma", "delta"},
   872  				[]int64{1, 2},
   873  			},
   874  			"score": 4e-08,
   875  		},
   876  	})
   877  }
   878  
   879  func TestParseKeyGroupArray(t *testing.T) {
   880  	tree, err := Load("[[foo.bar]] a = 42\n[[foo.bar]] a = 69")
   881  	assertTree(t, tree, err, map[string]interface{}{
   882  		"foo": map[string]interface{}{
   883  			"bar": []map[string]interface{}{
   884  				{"a": int64(42)},
   885  				{"a": int64(69)},
   886  			},
   887  		},
   888  	})
   889  }
   890  
   891  func TestParseKeyGroupArrayUnfinished(t *testing.T) {
   892  	_, err := Load("[[foo.bar]\na = 42")
   893  	if err.Error() != "(1, 10): was expecting token [[, but got unclosed table array key instead" {
   894  		t.Error("Bad error message:", err.Error())
   895  	}
   896  
   897  	_, err = Load("[[foo.[bar]\na = 42")
   898  	if err.Error() != "(1, 3): unexpected token table array key cannot contain ']', was expecting a table array key" {
   899  		t.Error("Bad error message:", err.Error())
   900  	}
   901  }
   902  
   903  func TestParseKeyGroupArrayQueryExample(t *testing.T) {
   904  	tree, err := Load(`
   905        [[book]]
   906        title = "The Stand"
   907        author = "Stephen King"
   908        [[book]]
   909        title = "For Whom the Bell Tolls"
   910        author = "Ernest Hemmingway"
   911        [[book]]
   912        title = "Neuromancer"
   913        author = "William Gibson"
   914      `)
   915  
   916  	assertTree(t, tree, err, map[string]interface{}{
   917  		"book": []map[string]interface{}{
   918  			{"title": "The Stand", "author": "Stephen King"},
   919  			{"title": "For Whom the Bell Tolls", "author": "Ernest Hemmingway"},
   920  			{"title": "Neuromancer", "author": "William Gibson"},
   921  		},
   922  	})
   923  }
   924  
   925  func TestParseKeyGroupArraySpec(t *testing.T) {
   926  	tree, err := Load("[[fruit]]\n name=\"apple\"\n [fruit.physical]\n color=\"red\"\n shape=\"round\"\n [[fruit]]\n name=\"banana\"")
   927  	assertTree(t, tree, err, map[string]interface{}{
   928  		"fruit": []map[string]interface{}{
   929  			{"name": "apple", "physical": map[string]interface{}{"color": "red", "shape": "round"}},
   930  			{"name": "banana"},
   931  		},
   932  	})
   933  }
   934  
   935  func TestTomlValueStringRepresentation(t *testing.T) {
   936  	for idx, item := range []struct {
   937  		Value  interface{}
   938  		Expect string
   939  	}{
   940  		{int64(12345), "12345"},
   941  		{uint64(50), "50"},
   942  		{float64(123.45), "123.45"},
   943  		{true, "true"},
   944  		{"hello world", "\"hello world\""},
   945  		{"\b\t\n\f\r\"\\", "\"\\b\\t\\n\\f\\r\\\"\\\\\""},
   946  		{"\x05", "\"\\u0005\""},
   947  		{time.Date(1979, time.May, 27, 7, 32, 0, 0, time.UTC), "1979-05-27T07:32:00Z"},
   948  		{[]interface{}{"gamma", "delta"}, "[\"gamma\", \"delta\"]"},
   949  		{nil, ""},
   950  	} {
   951  		result, err := tomlValueStringRepresentation(item.Value, "", "", OrderAlphabetical, false)
   952  		if err != nil {
   953  			t.Errorf("Test %d - unexpected error: %s", idx, err)
   954  		}
   955  		if result != item.Expect {
   956  			t.Errorf("Test %d - got '%s', expected '%s'", idx, result, item.Expect)
   957  		}
   958  	}
   959  }
   960  
   961  func TestToStringMapStringString(t *testing.T) {
   962  	tree, err := TreeFromMap(map[string]interface{}{"m": map[string]interface{}{"v": "abc"}})
   963  	if err != nil {
   964  		t.Fatalf("unexpected error: %s", err)
   965  	}
   966  	want := "\n[m]\n  v = \"abc\"\n"
   967  	got := tree.String()
   968  
   969  	if got != want {
   970  		t.Errorf("want:\n%q\ngot:\n%q", want, got)
   971  	}
   972  }
   973  
   974  func assertPosition(t *testing.T, text string, ref map[string]Position) {
   975  	tree, err := Load(text)
   976  	if err != nil {
   977  		t.Errorf("Error loading document text: `%v`", text)
   978  		t.Errorf("Error: %v", err)
   979  	}
   980  	for path, pos := range ref {
   981  		testPos := tree.GetPosition(path)
   982  		if testPos.Invalid() {
   983  			t.Errorf("Failed to query tree path or path has invalid position: %s", path)
   984  		} else if pos != testPos {
   985  			t.Errorf("Expected position %v, got %v instead", pos, testPos)
   986  		}
   987  	}
   988  }
   989  
   990  func TestDocumentPositions(t *testing.T) {
   991  	assertPosition(t,
   992  		"[foo]\nbar=42\nbaz=69",
   993  		map[string]Position{
   994  			"":        {1, 1},
   995  			"foo":     {1, 1},
   996  			"foo.bar": {2, 1},
   997  			"foo.baz": {3, 1},
   998  		})
   999  }
  1000  
  1001  func TestDocumentPositionsWithSpaces(t *testing.T) {
  1002  	assertPosition(t,
  1003  		"  [foo]\n  bar=42\n  baz=69",
  1004  		map[string]Position{
  1005  			"":        {1, 1},
  1006  			"foo":     {1, 3},
  1007  			"foo.bar": {2, 3},
  1008  			"foo.baz": {3, 3},
  1009  		})
  1010  }
  1011  
  1012  func TestDocumentPositionsWithGroupArray(t *testing.T) {
  1013  	assertPosition(t,
  1014  		"[[foo]]\nbar=42\nbaz=69",
  1015  		map[string]Position{
  1016  			"":        {1, 1},
  1017  			"foo":     {1, 1},
  1018  			"foo.bar": {2, 1},
  1019  			"foo.baz": {3, 1},
  1020  		})
  1021  }
  1022  
  1023  func TestNestedTreePosition(t *testing.T) {
  1024  	assertPosition(t,
  1025  		"[foo.bar]\na=42\nb=69",
  1026  		map[string]Position{
  1027  			"":          {1, 1},
  1028  			"foo":       {1, 1},
  1029  			"foo.bar":   {1, 1},
  1030  			"foo.bar.a": {2, 1},
  1031  			"foo.bar.b": {3, 1},
  1032  		})
  1033  }
  1034  
  1035  func TestInvalidGroupArray(t *testing.T) {
  1036  	_, err := Load("[table#key]\nanswer = 42")
  1037  	if err == nil {
  1038  		t.Error("Should error")
  1039  	}
  1040  
  1041  	_, err = Load("[foo.[bar]\na = 42")
  1042  	if err.Error() != "(1, 2): unexpected token table key cannot contain ']', was expecting a table key" {
  1043  		t.Error("Bad error message:", err.Error())
  1044  	}
  1045  }
  1046  
  1047  func TestDoubleEqual(t *testing.T) {
  1048  	_, err := Load("foo= = 2")
  1049  	if err.Error() != "(1, 6): cannot have multiple equals for the same key" {
  1050  		t.Error("Bad error message:", err.Error())
  1051  	}
  1052  }
  1053  
  1054  func TestGroupArrayReassign(t *testing.T) {
  1055  	_, err := Load("[hello]\n[[hello]]")
  1056  	if err.Error() != "(2, 3): key \"hello\" is already assigned and not of type table array" {
  1057  		t.Error("Bad error message:", err.Error())
  1058  	}
  1059  }
  1060  
  1061  func TestInvalidFloatParsing(t *testing.T) {
  1062  	_, err := Load("a=1e_2")
  1063  	if err.Error() != "(1, 3): invalid use of _ in number" {
  1064  		t.Error("Bad error message:", err.Error())
  1065  	}
  1066  
  1067  	_, err = Load("a=1e2_")
  1068  	if err.Error() != "(1, 3): invalid use of _ in number" {
  1069  		t.Error("Bad error message:", err.Error())
  1070  	}
  1071  
  1072  	_, err = Load("a=1__2")
  1073  	if err.Error() != "(1, 3): invalid use of _ in number" {
  1074  		t.Error("Bad error message:", err.Error())
  1075  	}
  1076  
  1077  	_, err = Load("a=_1_2")
  1078  	if err.Error() != "(1, 3): no value can start with _" {
  1079  		t.Error("Bad error message:", err.Error())
  1080  	}
  1081  }
  1082  
  1083  func TestMapKeyIsNum(t *testing.T) {
  1084  	_, err := Load("table={2018=1,2019=2}")
  1085  	if err != nil {
  1086  		t.Error("should be passed")
  1087  	}
  1088  	_, err = Load(`table={"2018"=1,"2019"=2}`)
  1089  	if err != nil {
  1090  		t.Error("should be passed")
  1091  	}
  1092  }
  1093  
  1094  func TestInvalidKeyInlineTable(t *testing.T) {
  1095  	_, err := Load("table={invalid..key = 1}")
  1096  	if err.Error() != "(1, 8): invalid key: expecting key part after dot" {
  1097  		t.Error("Bad error message:", err.Error())
  1098  	}
  1099  }
  1100  
  1101  func TestDottedKeys(t *testing.T) {
  1102  	tree, err := Load(`
  1103  name = "Orange"
  1104  physical.color = "orange"
  1105  physical.shape = "round"
  1106  site."google.com" = true`)
  1107  
  1108  	assertTree(t, tree, err, map[string]interface{}{
  1109  		"name": "Orange",
  1110  		"physical": map[string]interface{}{
  1111  			"color": "orange",
  1112  			"shape": "round",
  1113  		},
  1114  		"site": map[string]interface{}{
  1115  			"google.com": true,
  1116  		},
  1117  	})
  1118  }
  1119  
  1120  func TestInvalidDottedKeyEmptyGroup(t *testing.T) {
  1121  	_, err := Load(`a..b = true`)
  1122  	if err == nil {
  1123  		t.Fatal("should return an error")
  1124  	}
  1125  	if err.Error() != "(1, 1): invalid key: expecting key part after dot" {
  1126  		t.Fatalf("invalid error message: %s", err)
  1127  	}
  1128  }
  1129  
  1130  func TestAccidentalNewlines(t *testing.T) {
  1131  	expected := "The quick brown fox jumps over the lazy dog."
  1132  	tree, err := Load(`str1 = "The quick brown fox jumps over the lazy dog."
  1133  
  1134  str2 = """
  1135  The quick brown \
  1136  
  1137  
  1138    fox jumps over \
  1139      the lazy dog."""
  1140  
  1141  str3 = """\
  1142         The quick brown \` + "   " + `
  1143         fox jumps over \` + "   " + `
  1144         the lazy dog.\` + "   " + `
  1145  	   """`)
  1146  	if err != nil {
  1147  		t.Fatalf("unexpected error: %v", err)
  1148  	}
  1149  
  1150  	got := tree.Get("str1")
  1151  	if got != expected {
  1152  		t.Errorf("expected '%s', got '%s'", expected, got)
  1153  	}
  1154  
  1155  	got = tree.Get("str2")
  1156  	if got != expected {
  1157  		t.Errorf("expected '%s', got '%s'", expected, got)
  1158  	}
  1159  
  1160  	got = tree.Get("str3")
  1161  	if got != expected {
  1162  		t.Errorf("expected '%s', got '%s'", expected, got)
  1163  	}
  1164  }
  1165  
  1166  func TestUint(t *testing.T) {
  1167  	tree, err := Load("hello = 18446744073709551615")
  1168  	assertTree(t, tree, err, map[string]interface{}{
  1169  		"hello": uint64(math.MaxUint64),
  1170  	})
  1171  }
  1172  

View as plain text