Fix strings lexing and add a few tests
diff --git a/lexer.go b/lexer.go index 3db06eb..698406b 100644 --- a/lexer.go +++ b/lexer.go
@@ -305,7 +305,7 @@ l.emitWithValue(tokenString, growing_string) l.pos += 1 l.ignore() - return lexVoid + return lexRvalue } if l.follow("\\\"") {
diff --git a/lexer_test.go b/lexer_test.go index 03a1740..de0ccc6 100644 --- a/lexer_test.go +++ b/lexer_test.go
@@ -150,6 +150,56 @@ }) } +func TestArrayNestedString(t *testing.T) { + testFlow(t, "a = [ [\"hello\", \"world\"] ]", []token{ + token{tokenKey, "a"}, + token{tokenEqual, "="}, + token{tokenLeftBracket, "["}, + token{tokenLeftBracket, "["}, + token{tokenString, "hello"}, + token{tokenComma, ","}, + token{tokenString, "world"}, + token{tokenRightBracket, "]"}, + token{tokenRightBracket, "]"}, + token{tokenEOF, ""}, + }) +} + +func TestArrayNestedInts(t *testing.T) { + testFlow(t, "a = [ [42, 21], [10] ]", []token{ + token{tokenKey, "a"}, + token{tokenEqual, "="}, + token{tokenLeftBracket, "["}, + token{tokenLeftBracket, "["}, + token{tokenInteger, "42"}, + token{tokenComma, ","}, + token{tokenInteger, "21"}, + token{tokenRightBracket, "]"}, + token{tokenComma, ","}, + token{tokenLeftBracket, "["}, + token{tokenInteger, "10"}, + token{tokenRightBracket, "]"}, + token{tokenRightBracket, "]"}, + token{tokenEOF, ""}, + }) +} + +func TestArrayInts(t *testing.T) { + testFlow(t, "a = [ 42, 21, 10, ]", []token{ + token{tokenKey, "a"}, + token{tokenEqual, "="}, + token{tokenLeftBracket, "["}, + token{tokenInteger, "42"}, + token{tokenComma, ","}, + token{tokenInteger, "21"}, + token{tokenComma, ","}, + token{tokenInteger, "10"}, + token{tokenComma, ","}, + token{tokenRightBracket, "]"}, + token{tokenEOF, ""}, + }) +} + func TestKeyEqualArrayBools(t *testing.T) { testFlow(t, "foo = [true, false, true]", []token{ token{tokenKey, "foo"},
diff --git a/parser.go b/parser.go index d18c8a8..e9c9f52 100644 --- a/parser.go +++ b/parser.go
@@ -162,6 +162,8 @@ panic("unterminated array") } if follow.typ != tokenRightBracket && follow.typ != tokenComma { + fmt.Println(follow.typ) + fmt.Println(follow.val) panic("missing comma") } if follow.typ == tokenComma {
diff --git a/parser_test.go b/parser_test.go index ce97375..a3e9cbc 100644 --- a/parser_test.go +++ b/parser_test.go
@@ -6,7 +6,11 @@ "time" ) -func assertTree(t *testing.T, tree *TomlTree, ref map[string]interface{}) { +func assertTree(t *testing.T, tree *TomlTree, err error, ref map[string]interface{}) { + if (err != nil) { + t.Fatal("Non-nil error:", err.Error()) + return + } for k, v := range ref { if fmt.Sprintf("%v", tree.Get(k)) != fmt.Sprintf("%v", v) { t.Log("was expecting", v, "at", k, "but got", tree.Get(k)) @@ -25,21 +29,21 @@ } func TestSimpleKV(t *testing.T) { - tree, _ := Load("a = 42") - assertTree(t, tree, map[string]interface{}{ + tree, err := Load("a = 42") + assertTree(t, tree, err, map[string]interface{}{ "a": int64(42), }) tree, _ = Load("a = 42\nb = 21") - assertTree(t, tree, map[string]interface{}{ + assertTree(t, tree, err, map[string]interface{}{ "a": int64(42), "b": int64(21), }) } func TestSimpleNumbers(t *testing.T) { - tree, _ := Load("a = +42\nb = -21\nc = +4.2\nd = -2.1") - assertTree(t, tree, map[string]interface{}{ + tree, err := Load("a = +42\nb = -21\nc = +4.2\nd = -2.1") + assertTree(t, tree, err, map[string]interface{}{ "a": int64(42), "b": int64(-21), "c": float64(4.2), @@ -48,74 +52,82 @@ } func TestSimpleDate(t *testing.T) { - tree, _ := Load("a = 1979-05-27T07:32:00Z") - assertTree(t, tree, map[string]interface{}{ + tree, err := Load("a = 1979-05-27T07:32:00Z") + assertTree(t, tree, err, map[string]interface{}{ "a": time.Date(1979, time.May, 27, 7, 32, 0, 0, time.UTC), }) } func TestSimpleString(t *testing.T) { - tree, _ := Load("a = \"hello world\"") - assertTree(t, tree, map[string]interface{}{ + tree, err := Load("a = \"hello world\"") + assertTree(t, tree, err, map[string]interface{}{ "a": "hello world", }) } func TestBools(t *testing.T) { - tree, _ := Load("a = true\nb = false") - assertTree(t, tree, map[string]interface{}{ + tree, err := Load("a = true\nb = false") + assertTree(t, tree, err, map[string]interface{}{ "a": true, "b": false, }) } func TestNestedKeys(t *testing.T) { - tree, _ := Load("[a.b.c]\nd = 42") - assertTree(t, tree, map[string]interface{}{ + tree, err := Load("[a.b.c]\nd = 42") + assertTree(t, tree, err, map[string]interface{}{ "a.b.c.d": int64(42), }) } func TestArrayOne(t *testing.T) { - tree, _ := Load("a = [1]") - assertTree(t, tree, map[string]interface{}{ + tree, err := Load("a = [1]") + assertTree(t, tree, err, map[string]interface{}{ "a": []int64{int64(1)}, }) } func TestArrayZero(t *testing.T) { - tree, _ := Load("a = []") - assertTree(t, tree, map[string]interface{}{ + tree, err := Load("a = []") + assertTree(t, tree, err, map[string]interface{}{ "a": []interface{}{}, }) } func TestArraySimple(t *testing.T) { - tree, _ := Load("a = [42, 21, 10]") - assertTree(t, tree, map[string]interface{}{ + fmt.Println("test") + tree, err := Load("a = [42, 21, 10]") + assertTree(t, tree, err, map[string]interface{}{ "a": []int64{int64(42), int64(21), int64(10)}, }) - + fmt.Println("blah") tree, _ = Load("a = [42, 21, 10,]") - assertTree(t, tree, map[string]interface{}{ + assertTree(t, tree, err, map[string]interface{}{ "a": []int64{int64(42), int64(21), int64(10)}, }) } func TestArrayMultiline(t *testing.T) { - tree, _ := Load("a = [42,\n21, 10,]") - assertTree(t, tree, map[string]interface{}{ + tree, err := Load("a = [42,\n21, 10,]") + assertTree(t, tree, err, map[string]interface{}{ "a": []int64{int64(42), int64(21), int64(10)}, }) } func TestArrayNested(t *testing.T) { - tree, _ := Load("a = [[42, 21], [10]]") - assertTree(t, tree, map[string]interface{}{ + tree, err := Load("a = [[42, 21], [10]]") + assertTree(t, tree, err, map[string]interface{}{ "a": [][]int64{[]int64{int64(42), int64(21)}, []int64{int64(10)}}, }) } +func TestArrayNestedStrings(t *testing.T) { + tree, err := Load("data = [ [\"gamma\", \"delta\"] ]") + assertTree(t, tree, err, map[string]interface{}{ + "data": [][]string{[]string{"gamma", "delta"}}, + }) +} + func TestMissingValue(t *testing.T) { _, err := Load("a = ") if (err.Error() != "expecting a value") { @@ -139,10 +151,8 @@ func TestParseFile(t *testing.T) { tree, err := LoadFile("example.toml") - if (err != nil) { - t.Fatal("Non-nil error:", err.Error()) - } - assertTree(t, tree, map[string]interface{}{ + + assertTree(t, tree, err, map[string]interface{}{ "a": [][]int64{[]int64{int64(42), int64(21)}, []int64{int64(10)}}, }) } \ No newline at end of file