Add some tests
This commit is contained in:
		
							
								
								
									
										187
									
								
								expr_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								expr_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,187 @@ | ||||
| package salix | ||||
|  | ||||
| import ( | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| func TestAdd(t *testing.T) { | ||||
| 	res := execStr(t, `#(3 + 1)`, nil) | ||||
| 	if res != "4" { | ||||
| 		t.Errorf("Expected 4, got %s", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestSub(t *testing.T) { | ||||
| 	res := execStr(t, `#(3 - 1)`, nil) | ||||
| 	if res != "2" { | ||||
| 		t.Errorf("Expected 2, got %s", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestMul(t *testing.T) { | ||||
| 	res := execStr(t, `#(3 * 2)`, nil) | ||||
| 	if res != "6" { | ||||
| 		t.Errorf("Expected 6, got %s", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestDiv(t *testing.T) { | ||||
| 	res := execStr(t, `#(8 / 4)`, nil) | ||||
| 	if res != "2" { | ||||
| 		t.Errorf("Expected 2, got %s", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestMod(t *testing.T) { | ||||
| 	res := execStr(t, `#(4 % 4)`, nil) | ||||
| 	if res != "0" { | ||||
| 		t.Errorf("Expected 0, got %s", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestEq(t *testing.T) { | ||||
| 	res := execStr(t, `#("x" == "y")`, nil) | ||||
| 	if res != "false" { | ||||
| 		t.Errorf("Expected false, got %s", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestGEq(t *testing.T) { | ||||
| 	res := execStr(t, `#(2 >= 2)`, nil) | ||||
| 	if res != "true" { | ||||
| 		t.Errorf("Expected true, got %s", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestGt(t *testing.T) { | ||||
| 	res := execStr(t, `#(len("hi") > 2)`, nil) | ||||
| 	if res != "false" { | ||||
| 		t.Errorf("Expected false, got %s", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestLEq(t *testing.T) { | ||||
| 	res := execStr(t, `#(4 <= 4)`, nil) | ||||
| 	if res != "true" { | ||||
| 		t.Errorf("Expected true, got %s", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestLt(t *testing.T) { | ||||
| 	res := execStr(t, `#(4 < 4)`, nil) | ||||
| 	if res != "false" { | ||||
| 		t.Errorf("Expected false, got %s", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestAnd(t *testing.T) { | ||||
| 	res := execStr(t, `#(true && false)`, nil) | ||||
| 	if res != "false" { | ||||
| 		t.Errorf("Expected false, got %s", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestOr(t *testing.T) { | ||||
| 	res := execStr(t, `#(true || false)`, nil) | ||||
| 	if res != "true" { | ||||
| 		t.Errorf("Expected true, got %s", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestInString(t *testing.T) { | ||||
| 	res := execStr(t, `#("h" in "hello")`, nil) | ||||
| 	if res != "true" { | ||||
| 		t.Errorf("Expected true, got %s", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestInSlice(t *testing.T) { | ||||
| 	res := execStr(t, `#(5 in slice) #(6 in slice)`, map[string]any{"slice": []int{1, 2, 3, 4, 5}}) | ||||
| 	if res != "true false" { | ||||
| 		t.Errorf("Expected %q, got %q", "true false", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestInMap(t *testing.T) { | ||||
| 	res := execStr(t, `#(3.4234 in map)`, map[string]any{"map": map[float32]uint{3.4234: 0}}) | ||||
| 	if res != "true" { | ||||
| 		t.Errorf("Expected %q, got %q", "true", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestParenExpr(t *testing.T) { | ||||
| 	res := execStr(t, `#(5 - 4.0 - 3 - 2) #(5 - (4.0 - 3) - 2)`, nil) | ||||
| 	if res != "-4 2" { | ||||
| 		t.Errorf("Expected %q, got %q", "4 -2", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestCoalescing(t *testing.T) { | ||||
| 	res := execStr(t, `#(hello | "nothing") #(x | "nothing")`, map[string]any{"hello": "world"}) | ||||
| 	if res != "world nothing" { | ||||
| 		t.Errorf("Expected %q, got %q", "world nothing", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestTernary(t *testing.T) { | ||||
| 	res := execStr(t, `#(2.0 == 2.0 ? "equal" : "non-equal") #(2.0 == 2.5 ? "equal" : "non-equal")`, nil) | ||||
| 	if res != "equal non-equal" { | ||||
| 		t.Errorf("Expected %q, got %q", "equal non-equal", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestNot(t *testing.T) { | ||||
| 	res := execStr(t, `#(!true)`, nil) | ||||
| 	if res != "false" { | ||||
| 		t.Errorf("Expected %q, got %q", "false", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestIndex(t *testing.T) { | ||||
| 	res := execStr(t, `#(x[0]) #(y["hello"])`, map[string]any{ | ||||
| 		"x": []int{0, 1, 2}, | ||||
| 		"y": map[string]string{"hello": "world"}, | ||||
| 	}) | ||||
| 	if res != "0 world" { | ||||
| 		t.Errorf("Expected %q, got %q", "equal non-equal", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestFuncCall(t *testing.T) { | ||||
| 	res := execStr(t, `#(len(3.0))`, nil) | ||||
| 	if res != "-1" { | ||||
| 		t.Errorf("Expected %q, got %q", "-1", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestAssignment(t *testing.T) { | ||||
| 	res := execStr(t, `#(x = 4)#(x)`, nil) | ||||
| 	if res != "4" { | ||||
| 		t.Errorf("Expected %q, got %q", "4", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestMethodCall(t *testing.T) { | ||||
| 	res := execStr(t, `#(t.String())`, map[string]any{ | ||||
| 		"t": time.Date(2023, time.April, 26, 0, 0, 0, 0, time.UTC), | ||||
| 	}) | ||||
| 	if res != "2023-04-26 00:00:00 +0000 UTC" { | ||||
| 		t.Errorf("Expected %q, got %q", "2023-04-26 00:00:00 +0000 UTC", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func execStr(t *testing.T, tmplStr string, vars map[string]any) string { | ||||
| 	t.Helper() | ||||
| 	tmpl, err := New().ParseString("test", tmplStr) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	sb := &strings.Builder{} | ||||
| 	err = tmpl.WithVarMap(vars).Execute(sb) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	return sb.String() | ||||
| } | ||||
							
								
								
									
										4
									
								
								salix.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								salix.go
									
									
									
									
									
								
							| @@ -103,6 +103,10 @@ func (t Template) Execute(w io.Writer) error { | ||||
| } | ||||
|  | ||||
| func (t *Template) execute(w io.Writer, nodes []ast.Node, local map[string]any) error { | ||||
| 	if local == nil { | ||||
| 		local = map[string]any{} | ||||
| 	} | ||||
|  | ||||
| 	for i := 0; i < len(nodes); i++ { | ||||
| 		switch node := nodes[i].(type) { | ||||
| 		case ast.Text: | ||||
|   | ||||
							
								
								
									
										90
									
								
								tag_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								tag_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| package salix | ||||
|  | ||||
| import ( | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| func TestIf(t *testing.T) { | ||||
| 	const tmplStr = `#if(weather.Temp > 30): | ||||
|     <p>It's a hot day!</p> | ||||
| #elif(weather.Temp < 0): | ||||
|     <p>It's freezing!</p> | ||||
| #else: | ||||
|     <p>The temperature is #(weather.Temp)</p> | ||||
| #!if` | ||||
|  | ||||
| 	type weather struct { | ||||
| 		Temp int | ||||
| 	} | ||||
|  | ||||
| 	res := execStr(t, tmplStr, map[string]any{ | ||||
| 		"weather": weather{Temp: 40}, | ||||
| 	}) | ||||
| 	res = strings.TrimSpace(res) | ||||
| 	if res != "<p>It's a hot day!</p>" { | ||||
| 		t.Errorf("Expected %q, got %q", "<p>It's a hot day!</p>", res) | ||||
| 	} | ||||
|  | ||||
| 	res = execStr(t, tmplStr, map[string]any{ | ||||
| 		"weather": weather{Temp: -1}, | ||||
| 	}) | ||||
| 	res = strings.TrimSpace(res) | ||||
| 	if res != "<p>It's freezing!</p>" { | ||||
| 		t.Errorf("Expected %q, got %q", "<p>It's freezing!</p>", res) | ||||
| 	} | ||||
|  | ||||
| 	res = execStr(t, tmplStr, map[string]any{ | ||||
| 		"weather": weather{Temp: 25}, | ||||
| 	}) | ||||
| 	res = strings.TrimSpace(res) | ||||
| 	if res != "<p>The temperature is 25</p>" { | ||||
| 		t.Errorf("Expected %q, got %q", "<p>The temperature is 25</p>", res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestFor(t *testing.T) { | ||||
| 	const tmplStr = `#for(item in items): | ||||
| #(item) | ||||
| #!for` | ||||
|  | ||||
| 	res := execStr(t, tmplStr, map[string]any{ | ||||
| 		"items": []any{1.2, 3, "Hello", 4 + 2i, "-2", false, nil}, | ||||
| 	}) | ||||
|  | ||||
| 	expected := `1.2 | ||||
| 3 | ||||
| Hello | ||||
| (4+2i) | ||||
| -2 | ||||
| false | ||||
| <nil> | ||||
| ` | ||||
|  | ||||
| 	if res != expected { | ||||
| 		t.Errorf("Expected %q, got %q", expected, res) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestForTwoArgs(t *testing.T) { | ||||
| 	const tmplStr = `#for(i, item in items): | ||||
| #(i) #(item) | ||||
| #!for` | ||||
|  | ||||
| 	res := execStr(t, tmplStr, map[string]any{ | ||||
| 		"items": []any{1.2, 3, "Hello", 4 + 2i, "-2", false, nil}, | ||||
| 	}) | ||||
|  | ||||
| 	expected := `0 1.2 | ||||
| 1 3 | ||||
| 2 Hello | ||||
| 3 (4+2i) | ||||
| 4 -2 | ||||
| 5 false | ||||
| 6 <nil> | ||||
| ` | ||||
|  | ||||
| 	if res != expected { | ||||
| 		t.Errorf("Expected %q, got %q", expected, res) | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user