|
|
@@ -760,3 +760,99 @@ func TestIndexExpressionParsing(t *testing.T) {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+func TestHashLiteralParsing(t *testing.T) {
|
|
|
+ input := `{"one": 1, "two":2, "three": 3}`
|
|
|
+
|
|
|
+ l := lexer.New(input)
|
|
|
+ p := New(l)
|
|
|
+ program := p.ParseProgram()
|
|
|
+ checkParseErrors(t, p)
|
|
|
+
|
|
|
+ stmt := program.Statements[0].(*ast.ExpressionStatement)
|
|
|
+ hash, ok := stmt.Expression.(*ast.HashLiteral)
|
|
|
+ if !ok {
|
|
|
+ t.Fatalf("exp is not ast.HashLiteral. got=%T", stmt.Expression)
|
|
|
+ }
|
|
|
+ if len(hash.Pairs) != 3 {
|
|
|
+ t.Errorf("hash.Pairs has wrong length. got=%d", len(hash.Pairs))
|
|
|
+ }
|
|
|
+
|
|
|
+ expected := map[string]int64{
|
|
|
+ "one": 1,
|
|
|
+ "two": 2,
|
|
|
+ "three": 3,
|
|
|
+ }
|
|
|
+ for k, v := range hash.Pairs {
|
|
|
+ literal, ok := k.(*ast.StringLiteral)
|
|
|
+ if !ok {
|
|
|
+ t.Errorf("key is not ast.StringLiteral. got =%T", k)
|
|
|
+ }
|
|
|
+
|
|
|
+ expectedVal := expected[literal.String()]
|
|
|
+ testIntegerLiteral(t, v, expectedVal)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestEmptyHashLiteralParsing(t *testing.T) {
|
|
|
+ input := `{}`
|
|
|
+
|
|
|
+ l := lexer.New(input)
|
|
|
+ p := New(l)
|
|
|
+ program := p.ParseProgram()
|
|
|
+ checkParseErrors(t, p)
|
|
|
+
|
|
|
+ stmt := program.Statements[0].(*ast.ExpressionStatement)
|
|
|
+ hash, ok := stmt.Expression.(*ast.HashLiteral)
|
|
|
+ if !ok {
|
|
|
+ t.Fatalf("exp is not ast.HashLiteral. got=%T", stmt.Expression)
|
|
|
+ }
|
|
|
+ if len(hash.Pairs) != 0 {
|
|
|
+ t.Errorf("hash.Pairs has wrong length. got=%d", len(hash.Pairs))
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestParsingHashLiteralsWithExpressions(t *testing.T) {
|
|
|
+ input := `{"one": 0 + 1, "two": 10 - 8, "three": 15 / 5}`
|
|
|
+
|
|
|
+ l := lexer.New(input)
|
|
|
+ p := New(l)
|
|
|
+ program := p.ParseProgram()
|
|
|
+ checkParseErrors(t, p)
|
|
|
+
|
|
|
+ stmt := program.Statements[0].(*ast.ExpressionStatement)
|
|
|
+ hash, ok := stmt.Expression.(*ast.HashLiteral)
|
|
|
+ if !ok {
|
|
|
+ t.Fatalf("exp is not ast.HashLiteral. got=%T", stmt.Expression)
|
|
|
+ }
|
|
|
+ if len(hash.Pairs) != 3 {
|
|
|
+ t.Errorf("hash.Pairs has wrong length. got=%d", len(hash.Pairs))
|
|
|
+ }
|
|
|
+
|
|
|
+ tests := map[string]func(ast.Expression){
|
|
|
+ "one": func(e ast.Expression) {
|
|
|
+ testInfixExpression(t, e, 0, "+", 1)
|
|
|
+ },
|
|
|
+ "two": func(e ast.Expression) {
|
|
|
+ testInfixExpression(t, e, 10, "-", 8)
|
|
|
+ },
|
|
|
+ "three": func(e ast.Expression) {
|
|
|
+ testInfixExpression(t, e, 15, "/", 5)
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ for key, value := range hash.Pairs {
|
|
|
+ literal, ok := key.(*ast.StringLiteral)
|
|
|
+ if !ok {
|
|
|
+ t.Errorf("key is not ast.StringLiteral. got=%T", key)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ testFunc, ok := tests[literal.String()]
|
|
|
+ if !ok {
|
|
|
+ t.Errorf("No test function for key %q found.", literal.String())
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ testFunc(value)
|
|
|
+ }
|
|
|
+}
|