1 package builtins
2
3 import (
4 "reflect"
5 "strings"
6
7 "github.com/noirbizarre/gonja/exec"
8 )
9
10 var Tests = exec.TestSet{
11 "callable": testCallable,
12 "defined": testDefined,
13 "divisibleby": testDivisibleby,
14 "eq": testEqual,
15 "equalto": testEqual,
16 "==": testEqual,
17
18 "even": testEven,
19 "ge": testGreaterEqual,
20 ">=": testGreaterEqual,
21 "gt": testGreaterThan,
22 "greaterthan": testGreaterThan,
23 ">": testGreaterThan,
24 "in": testIn,
25 "iterable": testIterable,
26 "le": testLessEqual,
27 "<=": testLessEqual,
28 "lower": testLower,
29 "lt": testLessThan,
30 "lessthan": testLessThan,
31 "<": testLessThan,
32 "mapping": testMapping,
33 "ne": testNotEqual,
34 "!=": testNotEqual,
35 "none": testNone,
36 "number": testNumber,
37 "odd": testOdd,
38 "sameas": testSameas,
39 "sequence": testIterable,
40 "string": testString,
41 "undefined": testUndefined,
42 "upper": testUpper,
43 }
44
45 func testCallable(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
46 return in.IsCallable(), nil
47 }
48
49 func testDefined(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
50 return !(in.IsError() || in.IsNil()), nil
51 }
52
53 func testDivisibleby(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
54 param := params.First()
55 if param.Integer() == 0 {
56 return false, nil
57 }
58 return in.Integer()%param.Integer() == 0, nil
59 }
60
61 func testEqual(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
62 param := params.First()
63 return in.Interface() == param.Interface(), nil
64 }
65
66 func testEven(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
67 if !in.IsInteger() {
68 return false, nil
69 }
70 return in.Integer()%2 == 0, nil
71 }
72
73 func testGreaterEqual(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
74 param := params.Args[0]
75 if !in.IsNumber() || !param.IsNumber() {
76 return false, nil
77 }
78 return in.Float() >= param.Float(), nil
79 }
80
81 func testGreaterThan(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
82 param := params.Args[0]
83 if !in.IsNumber() || !param.IsNumber() {
84 return false, nil
85 }
86 return in.Float() > param.Float(), nil
87 }
88
89 func testIn(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
90 seq := params.First()
91 return seq.Contains(in), nil
92 }
93
94 func testIterable(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
95 return in.CanSlice(), nil
96 }
97
98 func testLessEqual(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
99 param := params.Args[0]
100 if !in.IsNumber() || !param.IsNumber() {
101 return false, nil
102 }
103 return in.Float() <= param.Float(), nil
104 }
105
106 func testLower(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
107 if !in.IsString() {
108 return false, nil
109 }
110 return strings.ToLower(in.String()) == in.String(), nil
111 }
112
113 func testLessThan(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
114 param := params.Args[0]
115 if !in.IsNumber() || !param.IsNumber() {
116 return false, nil
117 }
118 return in.Float() < param.Float(), nil
119 }
120
121 func testMapping(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
122 return in.IsDict(), nil
123 }
124
125 func testNotEqual(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
126 param := params.Args[0]
127 return in.Interface() != param.Interface(), nil
128 }
129
130 func testNone(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
131 return in.IsNil(), nil
132 }
133
134 func testNumber(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
135 return in.IsNumber(), nil
136 }
137
138 func testOdd(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
139 if !in.IsInteger() {
140 return false, nil
141 }
142 return in.Integer()%2 == 1, nil
143 }
144
145 func testSameas(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
146 param := params.Args[0]
147 if in.IsNil() && param.IsNil() {
148 return true, nil
149 } else if param.Val.CanAddr() && in.Val.CanAddr() {
150 return param.Val.Addr() == in.Val.Addr(), nil
151 }
152 return reflect.Indirect(param.Val) == reflect.Indirect(in.Val), nil
153 }
154
155 func testString(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
156 return in.IsString(), nil
157 }
158
159 func testUndefined(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
160 defined, err := testDefined(ctx, in, params)
161 return !defined, err
162 }
163
164 func testUpper(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) {
165 if !in.IsString() {
166 return false, nil
167 }
168 return strings.ToUpper(in.String()) == in.String(), nil
169 }
170
View as plain text