Browse Source

fix: Adding unit tests

Matthias Ladkau 3 years ago
parent
commit
d001b749e0

+ 81 - 64
interpreter/rt_general.go

@@ -210,10 +210,14 @@ type operatorRuntime struct {
 errorDetailString produces a detail string for errors.
 */
 func (rt *operatorRuntime) errorDetailString(token *parser.LexToken, opVal interface{}) string {
-	if token.Identifier {
+	if !token.Identifier {
 		return token.Val
 	}
 
+	if opVal == nil {
+		opVal = "NULL"
+	}
+
 	return fmt.Sprintf("%v=%v", token.Val, opVal)
 }
 
@@ -223,27 +227,30 @@ numVal returns a transformed number value.
 func (rt *operatorRuntime) numVal(op func(float64) interface{}, vs parser.Scope,
 	is map[string]interface{}) (interface{}, error) {
 
+	var ret interface{}
+
 	errorutil.AssertTrue(len(rt.node.Children) == 1,
 		fmt.Sprint("Operation requires 1 operand", rt.node))
 
 	res, err := rt.node.Children[0].Runtime.Eval(vs, is)
-	if err != nil {
-		return nil, err
-	}
+	if err == nil {
 
-	// Check if the value is a number
+		// Check if the value is a number
 
-	resNum, ok := res.(float64)
+		resNum, ok := res.(float64)
 
-	if !ok {
+		if !ok {
 
-		// Produce a runtime error if the value is not a number
+			// Produce a runtime error if the value is not a number
 
-		return nil, rt.erp.NewRuntimeError(util.ErrNotANumber,
-			rt.errorDetailString(rt.node.Children[0].Token, res), rt.node.Children[0])
+			return nil, rt.erp.NewRuntimeError(util.ErrNotANumber,
+				rt.errorDetailString(rt.node.Children[0].Token, res), rt.node.Children[0])
+		}
+
+		ret = op(resNum)
 	}
 
-	return op(resNum), nil
+	return ret, err
 }
 
 /*
@@ -251,24 +258,26 @@ boolVal returns a transformed boolean value.
 */
 func (rt *operatorRuntime) boolVal(op func(bool) interface{},
 	vs parser.Scope, is map[string]interface{}) (interface{}, error) {
-	var err error
+
+	var ret interface{}
 
 	errorutil.AssertTrue(len(rt.node.Children) == 1,
 		fmt.Sprint("Operation requires 1 operand", rt.node))
 
 	res, err := rt.node.Children[0].Runtime.Eval(vs, is)
-	if err != nil {
-		return nil, err
-	}
+	if err == nil {
 
-	resBool, ok := res.(bool)
+		resBool, ok := res.(bool)
 
-	if !ok {
-		return nil, rt.erp.NewRuntimeError(util.ErrNotABoolean,
-			rt.errorDetailString(rt.node.Children[0].Token, res), rt.node.Children[0])
+		if !ok {
+			return nil, rt.erp.NewRuntimeError(util.ErrNotABoolean,
+				rt.errorDetailString(rt.node.Children[0].Token, res), rt.node.Children[0])
+		}
+
+		ret = op(resBool)
 	}
 
-	return op(resBool), nil
+	return ret, err
 }
 
 /*
@@ -290,13 +299,15 @@ func (rt *operatorRuntime) numOp(op func(float64, float64) interface{},
 			if res1Num, ok = res1.(float64); !ok {
 				err = rt.erp.NewRuntimeError(util.ErrNotANumber,
 					rt.errorDetailString(rt.node.Children[0].Token, res1), rt.node.Children[0])
+
 			} else {
 				if res2Num, ok = res2.(float64); !ok {
 					err = rt.erp.NewRuntimeError(util.ErrNotANumber,
 						rt.errorDetailString(rt.node.Children[1].Token, res2), rt.node.Children[1])
+
 				} else {
 
-					return op(res1Num, res2Num), nil
+					return op(res1Num, res2Num), err
 				}
 			}
 		}
@@ -311,20 +322,21 @@ genOp executes an operation on two general values.
 func (rt *operatorRuntime) genOp(op func(interface{}, interface{}) interface{},
 	vs parser.Scope, is map[string]interface{}) (interface{}, error) {
 
+	var ret interface{}
+
 	errorutil.AssertTrue(len(rt.node.Children) == 2,
 		fmt.Sprint("Operation requires 2 operands", rt.node))
 
 	res1, err := rt.node.Children[0].Runtime.Eval(vs, is)
-	if err != nil {
-		return nil, err
-	}
+	if err == nil {
+		var res2 interface{}
 
-	res2, err := rt.node.Children[1].Runtime.Eval(vs, is)
-	if err != nil {
-		return nil, err
+		if res2, err = rt.node.Children[1].Runtime.Eval(vs, is); err == nil {
+			ret = op(res1, res2)
+		}
 	}
 
-	return op(res1, res2), nil
+	return ret, err
 }
 
 /*
@@ -333,20 +345,21 @@ strOp executes an operation on two string values.
 func (rt *operatorRuntime) strOp(op func(string, string) interface{},
 	vs parser.Scope, is map[string]interface{}) (interface{}, error) {
 
+	var ret interface{}
+
 	errorutil.AssertTrue(len(rt.node.Children) == 2,
 		fmt.Sprint("Operation requires 2 operands", rt.node))
 
 	res1, err := rt.node.Children[0].Runtime.Eval(vs, is)
-	if err != nil {
-		return nil, err
-	}
+	if err == nil {
+		var res2 interface{}
 
-	res2, err := rt.node.Children[1].Runtime.Eval(vs, is)
-	if err != nil {
-		return nil, err
+		if res2, err = rt.node.Children[1].Runtime.Eval(vs, is); err == nil {
+			ret = op(fmt.Sprint(res1), fmt.Sprint(res2))
+		}
 	}
 
-	return op(fmt.Sprint(res1), fmt.Sprint(res2)), nil
+	return ret, err
 }
 
 /*
@@ -355,32 +368,34 @@ boolOp executes an operation on two boolean values.
 func (rt *operatorRuntime) boolOp(op func(bool, bool) interface{},
 	vs parser.Scope, is map[string]interface{}) (interface{}, error) {
 
+	var res interface{}
+
 	errorutil.AssertTrue(len(rt.node.Children) == 2,
 		fmt.Sprint("Operation requires 2 operands", rt.node))
 
 	res1, err := rt.node.Children[0].Runtime.Eval(vs, is)
-	if err != nil {
-		return nil, err
-	}
+	if err == nil {
+		var res2 interface{}
 
-	res2, err := rt.node.Children[1].Runtime.Eval(vs, is)
-	if err != nil {
-		return nil, err
-	}
+		if res2, err = rt.node.Children[1].Runtime.Eval(vs, is); err == nil {
 
-	res1bool, ok := res1.(bool)
-	if !ok {
-		return nil, rt.erp.NewRuntimeError(util.ErrNotABoolean,
-			rt.errorDetailString(rt.node.Children[0].Token, res1), rt.node.Children[0])
-	}
+			res1bool, ok := res1.(bool)
+			if !ok {
+				return nil, rt.erp.NewRuntimeError(util.ErrNotABoolean,
+					rt.errorDetailString(rt.node.Children[0].Token, res1), rt.node.Children[0])
+			}
 
-	res2bool, ok := res2.(bool)
-	if !ok {
-		return nil, rt.erp.NewRuntimeError(util.ErrNotABoolean,
-			rt.errorDetailString(rt.node.Children[1].Token, res2), rt.node.Children[0])
+			res2bool, ok := res2.(bool)
+			if !ok {
+				return nil, rt.erp.NewRuntimeError(util.ErrNotABoolean,
+					rt.errorDetailString(rt.node.Children[1].Token, res2), rt.node.Children[0])
+			}
+
+			res = op(res1bool, res2bool)
+		}
 	}
 
-	return op(res1bool, res2bool), nil
+	return res, err
 }
 
 /*
@@ -389,24 +404,26 @@ listOp executes an operation on a value and a list.
 func (rt *operatorRuntime) listOp(op func(interface{}, []interface{}) interface{},
 	vs parser.Scope, is map[string]interface{}) (interface{}, error) {
 
+	var res interface{}
+
 	errorutil.AssertTrue(len(rt.node.Children) == 2,
 		fmt.Sprint("Operation requires 2 operands", rt.node))
 
 	res1, err := rt.node.Children[0].Runtime.Eval(vs, is)
-	if err != nil {
-		return nil, err
-	}
+	if err == nil {
+		var res2 interface{}
 
-	res2, err := rt.node.Children[1].Runtime.Eval(vs, is)
-	if err != nil {
-		return nil, err
-	}
+		if res2, err = rt.node.Children[1].Runtime.Eval(vs, is); err == nil {
 
-	res2list, ok := res2.([]interface{})
-	if !ok {
-		return nil, rt.erp.NewRuntimeError(util.ErrNotAList,
-			rt.errorDetailString(rt.node.Children[1].Token, res2), rt.node.Children[0])
+			res2list, ok := res2.([]interface{})
+			if !ok {
+				err = rt.erp.NewRuntimeError(util.ErrNotAList,
+					rt.errorDetailString(rt.node.Children[1].Token, res2), rt.node.Children[0])
+			} else {
+				res = op(res1, res2list)
+			}
+		}
 	}
 
-	return op(res1, res2list), nil
+	return res, err
 }

+ 100 - 0
interpreter/rt_general_test.go

@@ -32,6 +32,29 @@ func TestGeneralErrorCases(t *testing.T) {
 		t.Error("Unexpected result:", err)
 		return
 	}
+
+	n, _ = parser.Parse("a", "a")
+	inv = &invalidRuntime{newBaseRuntime(NewECALRuntimeProvider("a", nil, nil), n)}
+	n.Runtime = inv
+
+	n2, _ := parser.Parse("a", "a")
+	inv2 := &invalidRuntime{newBaseRuntime(NewECALRuntimeProvider("a", nil, nil), n2)}
+	n2.Runtime = inv2
+	n.Children = append(n.Children, n2)
+
+	if err := inv.Validate().Error(); err != "ECAL error in a: Invalid construct (Unknown node: identifier) (Line:1 Pos:1)" {
+		t.Error("Unexpected result:", err)
+		return
+	}
+
+	n, _ = parser.Parse("a", "a")
+	void := &voidRuntime{newBaseRuntime(NewECALRuntimeProvider("a", nil, nil), n)}
+	n.Runtime = void
+
+	if res, err := void.Eval(nil, nil); err != nil || res != nil {
+		t.Error("Unexpected result:", res, err)
+		return
+	}
 }
 
 func TestImporting(t *testing.T) {
@@ -65,6 +88,17 @@ statements
 		t.Error("Unexpected result: ", vsRes, res, err)
 		return
 	}
+
+	n, _ := parser.Parse("a", "a")
+	imp := &importRuntime{newBaseRuntime(NewECALRuntimeProvider("a", nil, nil), n)}
+	n.Runtime = imp
+	imp.erp = NewECALRuntimeProvider("ECALTestRuntime", nil, nil)
+	imp.erp.ImportLocator = nil
+
+	if res, err := imp.Eval(nil, nil); err == nil || err.Error() != "ECAL error in ECALTestRuntime: Runtime error (No import locator was specified) (Line:1 Pos:1)" {
+		t.Error("Unexpected result:", res, err)
+		return
+	}
 }
 
 func TestLogging(t *testing.T) {
@@ -102,3 +136,69 @@ error: bar` {
 		return
 	}
 }
+
+func TestOperatorRuntimeErrors(t *testing.T) {
+
+	n, _ := parser.Parse("a", "a")
+	op := &operatorRuntime{newBaseRuntime(NewECALRuntimeProvider("a", nil, nil), n)}
+
+	if res := op.errorDetailString(n.Token, "foo"); res != "a=foo" {
+		t.Error("Unexpected result:", res)
+	}
+
+	n.Token.Identifier = false
+
+	if res := op.errorDetailString(n.Token, "foo"); res != "a" {
+		t.Error("Unexpected result:", res)
+	}
+
+	n.Token.Identifier = true
+
+	res, err := UnitTestEval(
+		`+ "a"`, nil)
+
+	if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a number (a) (Line:1 Pos:3)" {
+		t.Error("Unexpected result: ", res, err)
+		return
+	}
+
+	res, err = UnitTestEval(
+		`x := "a"; + x`, nil)
+
+	if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a number (x=a) (Line:1 Pos:13)" {
+		t.Error("Unexpected result: ", res, err)
+		return
+	}
+
+	res, err = UnitTestEval(
+		`not "a"`, nil)
+
+	if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a boolean (a) (Line:1 Pos:5)" {
+		t.Error("Unexpected result: ", res, err)
+		return
+	}
+
+	res, err = UnitTestEval(
+		`a:= 5; a or 6`, nil)
+
+	if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a boolean (a=5) (Line:1 Pos:8)" {
+		t.Error("Unexpected result: ", res, err)
+		return
+	}
+
+	res, err = UnitTestEval(
+		`true or 2`, nil)
+
+	if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a boolean (2) (Line:1 Pos:1)" {
+		t.Error("Unexpected result: ", res, err)
+		return
+	}
+
+	res, err = UnitTestEval(
+		`a := "foo"; x in a`, nil)
+
+	if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Operand is not a list (a=foo) (Line:1 Pos:13)" {
+		t.Error("Unexpected result: ", res, err)
+		return
+	}
+}

+ 0 - 9
interpreter/rt_sink.go

@@ -43,15 +43,6 @@ func (rt *sinkRuntime) Validate() error {
 
 	if err == nil {
 
-		nameNode := rt.node.Children[0]
-
-		// Make sure there is a constant as a name
-
-		if _, ok := nameNode.Runtime.(*identifierRuntime); !ok {
-			return rt.erp.NewRuntimeError(util.ErrInvalidConstruct,
-				"Must have an identifier as sink name", rt.node)
-		}
-
 		// Check that all children are valid
 
 		for _, child := range rt.node.Children[1:] {

+ 79 - 0
interpreter/rt_sink_test.go

@@ -297,3 +297,82 @@ rule2 - Handling request: test.event`[1:] {
 		return
 	}
 }
+
+func TestSinkErrorConditions(t *testing.T) {
+
+	vs := scope.NewScope(scope.GlobalScope)
+
+	_, err := UnitTestEval(
+		`
+sink test
+    apa
+    kindmatch [ "test.event", "foo.*" ],
+    statematch { "a" : null },
+	{
+        log("rule1 - Handling request: ", event.kind)
+	}
+`, vs)
+
+	if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Invalid construct (Unknown expression in sink declaration apa) (Line:3 Pos:5)" {
+		t.Error("Unexpected result:", err)
+		return
+	}
+
+	_, err = UnitTestEval(
+		`
+sink test
+    kindmatch 1,
+    statematch { "a" : null },
+	{
+        log("rule1 - Handling request: ", event.kind)
+	}
+`, vs)
+
+	if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Invalid construct (Expected a list as value) (Line:3 Pos:5)" {
+		t.Error("Unexpected result:", err)
+		return
+	}
+
+	_, err = UnitTestEval(
+		`
+sink test
+    statematch { "a" : null },
+	{
+        log("rule1 - Handling request: ", event.kind)
+	}
+`, vs)
+
+	if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Invalid state (Cannot add rule without a kind match: test) (Line:2 Pos:1)" {
+		t.Error("Unexpected result:", err)
+		return
+	}
+
+	_, err = UnitTestEval(
+		`
+sink test
+    priority "Hans",
+	{
+        log("rule1 - Handling request: ", event.kind)
+	}
+`, vs)
+
+	if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Invalid construct (Expected a number as value) (Line:3 Pos:5)" {
+		t.Error("Unexpected result:", err)
+		return
+	}
+
+	_, err = UnitTestEval(
+		`
+sink test
+    statematch "Hans",
+	{
+        log("rule1 - Handling request: ", event.kind)
+	}
+`, vs)
+
+	if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Invalid construct (Expected a map as value) (Line:3 Pos:5)" {
+		t.Error("Unexpected result:", err)
+		return
+	}
+
+}

+ 15 - 19
interpreter/rt_statements.go

@@ -344,41 +344,37 @@ func (rt *loopRuntime) Eval(vs parser.Scope, is map[string]interface{}) (interfa
 				if err == nil {
 
 					if len(vars) == 1 {
-						if err = vs.SetValue(vars[0], res); err != nil {
-							err = rt.erp.NewRuntimeError(util.ErrVarAccess,
-								err.Error(), rt.node)
-						}
+						err = vs.SetValue(vars[0], res)
 
 					} else if resList, ok := res.([]interface{}); ok {
 
 						if len(vars) != len(resList) {
-							return nil, rt.erp.NewRuntimeError(util.ErrInvalidState,
-								fmt.Sprintf("Assigned number of variables is different to "+
-									"number of values (%v variables vs %v values)",
-									len(vars), len(resList)), rt.node)
+							err = fmt.Errorf("Assigned number of variables is different to "+
+								"number of values (%v variables vs %v values)",
+								len(vars), len(resList))
 						}
 
-						for i, v := range vars {
-							if err == nil {
-								if err = vs.SetValue(v, resList[i]); err != nil {
-									err = rt.erp.NewRuntimeError(util.ErrVarAccess,
-										err.Error(), rt.node)
+						if err == nil {
+							for i, v := range vars {
+								if err == nil {
+									err = vs.SetValue(v, resList[i])
 								}
 							}
 						}
 
 					} else {
 
-						return nil, rt.erp.NewRuntimeError(util.ErrInvalidState,
-							fmt.Sprintf("Result for loop variable is not a list (value is %v)", res),
-							rt.node)
+						err = fmt.Errorf("Result for loop variable is not a list (value is %v)", res)
+					}
+
+					if err != nil {
+						return nil, rt.erp.NewRuntimeError(util.ErrRuntimeError,
+							err.Error(), rt.node)
 					}
 
 					// Execute block
 
-					if err == nil {
-						_, err = rt.node.Children[1].Runtime.Eval(vs, is)
-					}
+					_, err = rt.node.Children[1].Runtime.Eval(vs, is)
 				}
 
 				// Check for continue

+ 35 - 2
interpreter/rt_statements_test.go

@@ -804,6 +804,19 @@ Info->c-0`[1:] {
 		return
 	}
 
+	_, err = UnitTestEval(
+		`
+x := { "c": 0, "a":2, "b":4}
+for [1, b] in x {
+  testlog("Info", "->", a, "-", b)
+}
+	   `, vs)
+
+	if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Invalid construct (Must have a list of simple variables on the left side of the In expression) (Line:3 Pos:1)" {
+		t.Error("Unexpected result:", err)
+		return
+	}
+
 	// Test continue
 
 	_, err = UnitTestEval(`
@@ -857,6 +870,26 @@ for a[t] in 1 {
 		t.Error("Unexpected result:", err)
 		return
 	}
+
+	_, err = UnitTestEval(`
+for [a, b] in [[1,2],[3,4],3] {
+}
+	   `[1:], vs)
+
+	if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Runtime error (Result for loop variable is not a list (value is 3)) (Line:1 Pos:1)" {
+		t.Error("Unexpected result:", err)
+		return
+	}
+
+	_, err = UnitTestEval(`
+for [a, b] in [[1,2],[3,4],[5,6,7]] {
+}
+	   `[1:], vs)
+
+	if err == nil || err.Error() != "ECAL error in ECALTestRuntime: Runtime error (Assigned number of variables is different to number of values (2 variables vs 3 values)) (Line:1 Pos:1)" {
+		t.Error("Unexpected result:", err)
+		return
+	}
 }
 
 func TestTryStatements(t *testing.T) {
@@ -971,8 +1004,8 @@ error: Something else happened: {
   "type": "test 13"
 }
 Runtime error: {
-  "detail": "a",
-  "error": "ECAL error in ECALTestRuntime: Operand is not a number (a) (Line:11 Pos:12)",
+  "detail": "a=NULL",
+  "error": "ECAL error in ECALTestRuntime: Operand is not a number (a=NULL) (Line:11 Pos:12)",
   "line": 11,
   "pos": 12,
   "source": "ECALTestRuntime",

+ 13 - 17
interpreter/rt_value.go

@@ -157,18 +157,15 @@ func (rt *mapValueRuntime) Eval(vs parser.Scope, is map[string]interface{}) (int
 
 	if err == nil {
 		for _, kvp := range rt.node.Children {
+			var key, val interface{}
 
-			key, err := kvp.Children[0].Runtime.Eval(vs, is)
-			if err != nil {
-				return nil, err
-			}
-
-			val, err := kvp.Children[1].Runtime.Eval(vs, is)
-			if err != nil {
-				return nil, err
+			if err == nil {
+				if key, err = kvp.Children[0].Runtime.Eval(vs, is); err == nil {
+					if val, err = kvp.Children[1].Runtime.Eval(vs, is); err == nil {
+						m[key] = val
+					}
+				}
 			}
-
-			m[key] = val
 		}
 	}
 
@@ -198,17 +195,16 @@ func (rt *listValueRuntime) Eval(vs parser.Scope, is map[string]interface{}) (in
 	var l []interface{}
 
 	if err == nil {
-
 		for _, item := range rt.node.Children {
+			if err == nil {
+				var val interface{}
+				if val, err = item.Runtime.Eval(vs, is); err == nil {
+					l = append(l, val)
+				}
 
-			val, err := item.Runtime.Eval(vs, is)
-			if err != nil {
-				return nil, err
 			}
-
-			l = append(l, val)
 		}
 	}
 
-	return l, nil
+	return l, err
 }

+ 2 - 2
parser/lexer.go

@@ -695,11 +695,11 @@ func lexValue(l *lexer) lexFunc {
 			return nil
 		}
 
-		l.emitTokenAndValue(TokenSTRING, s, true, true)
+		l.emitTokenAndValue(TokenSTRING, s, false, true)
 
 	} else {
 
-		l.emitTokenAndValue(TokenSTRING, l.input[l.start+2:l.pos-1], true, false)
+		l.emitTokenAndValue(TokenSTRING, l.input[l.start+2:l.pos-1], false, false)
 	}
 
 	//  Set newline

+ 10 - 10
parser/lexer_test.go

@@ -167,7 +167,7 @@ func TestAssignmentLexing(t *testing.T) {
 
 	input = `name:=a[1] + b["d"] + c[a]`
 	if res := LexToList("mytest", input); fmt.Sprint(res) !=
-		`["name" := "a" [ v:"1" ] + "b" [ "d" ] + "c" [ "a" ] EOF]` {
+		`["name" := "a" [ v:"1" ] + "b" [ v:"d" ] + "c" [ "a" ] EOF]` {
 		t.Error("Unexpected lexer result:", res)
 		return
 	}
@@ -185,7 +185,7 @@ if a == 1 {
 }
 `
 	if res := LexToList("mytest", input); fmt.Sprint(res) !=
-		`[<IF> "a" == v:"1" { "print" ( "xxx" ) } <ELIF> "b" > v:"2" { "print" ( "yyy" ) } <ELSE> { "print" ( "zzz" ) } EOF]` {
+		`[<IF> "a" == v:"1" { "print" ( v:"xxx" ) } <ELIF> "b" > v:"2" { "print" ( v:"yyy" ) } <ELSE> { "print" ( v:"zzz" ) } EOF]` {
 		t.Error("Unexpected lexer result:", res)
 		return
 	}
@@ -208,7 +208,7 @@ for true {
 }
 `
 	if res := LexToList("mytest", input); fmt.Sprint(res) !=
-		`[<FOR> <TRUE> { "x" := "1" <BREAK> ; <CONTINUE> } EOF]` {
+		`[<FOR> <TRUE> { "x" := v:"1" <BREAK> ; <CONTINUE> } EOF]` {
 		t.Error("Unexpected lexer result:", res)
 		return
 	}
@@ -225,7 +225,7 @@ func TestStringLexing(t *testing.T) {
 	}
 
 	input = `name "test"  'bla'`
-	if res := LexToList("mytest", input); fmt.Sprint(res) != `["name" "test" "bla" EOF]` {
+	if res := LexToList("mytest", input); fmt.Sprint(res) != `["name" v:"test" v:"bla" EOF]` {
 		t.Error("Unexpected lexer result:", res)
 		return
 	}
@@ -240,7 +240,7 @@ func TestStringLexing(t *testing.T) {
 	input = `name r"te
 	st"  'bla'`
 	res := LexToList("mytest", input)
-	if fmt.Sprint(res) != `["name" "te\n\tst" "bla" EOF]` {
+	if fmt.Sprint(res) != `["name" v:"te\n\tst" v:"bla" EOF]` {
 		t.Error("Unexpected lexer result:", res)
 		return
 	}
@@ -254,7 +254,7 @@ func TestStringLexing(t *testing.T) {
 
 	input = `"test\n\ttest"  '\nfoo\u0028bar' "test{foo}.5w3f"`
 	res = LexToList("mytest", input)
-	if fmt.Sprint(res) != `["test\n\ttest" "\nfoo(bar" "test{foo}.5w3f" EOF]` {
+	if fmt.Sprint(res) != `[v:"test\n\ttest" v:"\nfoo(bar" v:"test{foo}.5w3f" EOF]` {
 		t.Error("Unexpected lexer result:", res)
 		return
 	}
@@ -272,7 +272,7 @@ func TestCommentLexing(t *testing.T) {
 	x*/ 'b/* - */la' /*test*/`
 	if res := LexToList("mytest", input); fmt.Sprint(res) != `["name" /*  foo
 		bar
-	x */ "b/* - */la" /* test */ EOF]` {
+	x */ v:"b/* - */la" /* test */ EOF]` {
 		t.Error("Unexpected lexer result:", res)
 		return
 	}
@@ -314,9 +314,9 @@ suppresses [ "myothersink" ]
 {
   a := 1
 }`
-	if res := LexToList("mytest", input); fmt.Sprint(res) != `[<SINK> "mysink" "\nA comment"... <KINDMATCH> `+
-		`[ "foo" . "bar" . * ] , <SCOPEMATCH> [ "data.read" , "data.write" ] , <STATEMATCH> `+
-		`{ "a" : v:"1" , "b" : <NULL> } , <PRIORITY> v:"0" , <SUPPRESSES> [ "myothersink" ] `+
+	if res := LexToList("mytest", input); fmt.Sprint(res) != `[<SINK> v:"mysink" v:"\nA comment"... <KINDMATCH> `+
+		`[ "foo" . "bar" . * ] , <SCOPEMATCH> [ v:"data.read" , v:"data.write" ] , <STATEMATCH> `+
+		`{ "a" : v:"1" , "b" : <NULL> } , <PRIORITY> v:"0" , <SUPPRESSES> [ v:"myothersink" ] `+
 		`{ "a" := v:"1" } EOF]` {
 		t.Error("Unexpected lexer result:", res)
 		return

+ 1 - 1
parser/parser_main_test.go

@@ -148,7 +148,7 @@ func TestErrorConditions(t *testing.T) {
 	}()
 
 	input = `"foo"`
-	if ast, err := Parse("test", input); err == nil || err.Error() != `Parse error in test: Unknown term (id:5 ("foo")) (Line:1 Pos:1)` {
+	if ast, err := Parse("test", input); err == nil || err.Error() != `Parse error in test: Unknown term (id:5 (v:"foo")) (Line:1 Pos:1)` {
 		t.Errorf("Unexpected result: %v\nAST:\n%v", err, ast)
 		return
 	}