1
0
mirror of https://github.com/danog/liquid.git synced 2024-12-02 14:57:49 +01:00
liquid/expressions/expressions_test.go

158 lines
3.4 KiB
Go
Raw Normal View History

2017-07-14 02:18:23 +02:00
package expressions
import (
2017-07-21 02:57:52 +02:00
"errors"
"fmt"
2017-07-02 13:51:24 +02:00
"strings"
"testing"
"github.com/stretchr/testify/require"
)
var evaluatorTests = []struct {
in string
expected interface{}
}{
// Literals
2017-06-28 23:18:48 +02:00
{`12`, 12},
{`12.3`, 12.3},
{`true`, true},
{`false`, false},
{`'abc'`, "abc"},
{`"abc"`, "abc"},
2017-06-26 15:06:55 +02:00
// Variables
2017-06-28 23:18:48 +02:00
{`n`, 123},
2017-06-28 19:53:37 +02:00
// Attributes
2017-07-10 16:07:49 +02:00
{`hash.a`, "first"},
{`hash.b.c`, "d"},
{`hash.x`, nil},
2017-06-28 19:53:37 +02:00
{`fruits.first`, "apples"},
{`fruits.last`, "plums"},
{`empty_list.first`, nil},
{`empty_list.last`, nil},
2017-06-28 20:41:46 +02:00
{`"abc".size`, 3},
{`fruits.size`, 4},
{`hash.size`, 3},
2017-07-10 16:07:49 +02:00
{`hash_with_size_key.size`, "key_value"},
2017-06-28 19:53:37 +02:00
// Indices
{`array[1]`, "second"},
{`array[-1]`, "third"}, // undocumented
{`array[100]`, nil},
2017-07-10 16:07:49 +02:00
{`hash[1]`, nil},
{`hash.c[0]`, "r"},
2017-06-28 19:53:37 +02:00
// Expressions
2017-06-28 23:18:48 +02:00
{`(n)`, 123},
2017-06-26 15:06:55 +02:00
// Operators
2017-06-28 23:18:48 +02:00
{`1 == 1`, true},
{`1 == 2`, false},
{`1.0 == 1.0`, true},
{`1.0 == 2.0`, false},
{`1.0 == 1`, true},
{`1 == 1.0`, true},
{`"a" == "a"`, true},
{`"a" == "b"`, false},
{`1 != 1`, false},
{`1 != 2`, true},
{`1.0 != 1.0`, false},
{`1 != 1.0`, false},
{`1 != 2.0`, true},
{`1 < 2`, true},
{`2 < 1`, false},
{`1.0 < 2.0`, true},
{`1.0 < 2`, true},
{`1 < 2.0`, true},
{`1.0 < 2`, true},
{`"a" < "a"`, false},
{`"a" < "b"`, true},
{`"b" < "a"`, false},
{`1 > 2`, false},
{`2 > 1`, true},
{`1 <= 1`, true},
{`1 <= 2`, true},
{`2 <= 1`, false},
{`"a" <= "a"`, true},
{`"a" <= "b"`, true},
{`"b" <= "a"`, false},
{`1 >= 1`, true},
{`1 >= 2`, false},
{`2 >= 1`, true},
{`true and false`, false},
{`true and true`, true},
{`true and true and true`, true},
{`false or false`, false},
{`false or true`, true},
{`"seafood" contains "foo"`, true},
{`"seafood" contains "bar"`, false},
2017-07-03 18:48:00 +02:00
{`array contains "first"`, true},
2017-07-10 16:07:49 +02:00
{`interface_array contains "first"`, true},
2017-07-03 18:48:00 +02:00
{`"foo" contains "missing"`, false},
2017-07-09 17:06:15 +02:00
{`nil contains "missing"`, false},
2017-07-02 13:51:24 +02:00
// filters
{`"seafood" | length`, 8},
}
2017-07-02 13:51:24 +02:00
var evaluatorTestBindings = (map[string]interface{}{
2017-07-10 16:07:49 +02:00
"n": 123,
"array": []string{"first", "second", "third"},
"interface_array": []interface{}{"first", "second", "third"},
"empty_list": []interface{}{},
"fruits": []string{"apples", "oranges", "peaches", "plums"},
"hash": map[string]interface{}{
"a": "first",
"b": map[string]interface{}{"c": "d"},
"c": []string{"r", "g", "b"},
},
2017-07-10 16:07:49 +02:00
"hash_with_size_key": map[string]interface{}{"size": "key_value"},
2017-07-02 13:51:24 +02:00
})
2017-07-15 19:48:35 +02:00
func TestEvaluateString(t *testing.T) {
cfg := NewConfig()
cfg.AddFilter("length", strings.Count)
ctx := NewContext(evaluatorTestBindings, cfg)
for i, test := range evaluatorTests {
t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) {
val, err := EvaluateString(test.in, ctx)
require.NoErrorf(t, err, test.in)
require.Equalf(t, test.expected, val, test.in)
})
}
2017-07-15 19:48:35 +02:00
_, err := EvaluateString("syntax error", ctx)
require.Error(t, err)
_, err = EvaluateString("1 | undefined_filter", ctx)
require.Error(t, err)
2017-07-21 02:57:52 +02:00
cfg.AddFilter("error", func(input interface{}) (string, error) { return "", errors.New("test error") })
_, err = EvaluateString("1 | error", ctx)
require.Error(t, err)
}
2017-07-02 14:35:06 +02:00
func TestClosure(t *testing.T) {
cfg := NewConfig()
ctx := NewContext(map[string]interface{}{"x": 1}, cfg)
expr, err := Parse("x")
2017-07-02 14:35:06 +02:00
require.NoError(t, err)
c1 := closure{expr, ctx}
c2 := c1.Bind("x", 2)
x1, err := c1.Evaluate()
require.NoError(t, err)
x2, err := c2.Evaluate()
2017-07-02 14:35:06 +02:00
require.NoError(t, err)
require.Equal(t, 1, x1)
require.Equal(t, 2, x2)
2017-07-02 14:35:06 +02:00
}