Skip to content

Commit c123cb3

Browse files
authored
Merge pull request #5 from huttotw/fix/float64
fix/float64
2 parents 0d45f64 + 3eeb099 commit c123cb3

File tree

2 files changed

+85
-6
lines changed

2 files changed

+85
-6
lines changed

rule.go

+36
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package grules
22

33
import (
44
"encoding/json"
5+
"math"
56
)
67

78
const (
@@ -128,3 +129,38 @@ func (r Rule) evaluate(props map[string]interface{}, comps map[string]Comparator
128129

129130
return comp(val, r.Value)
130131
}
132+
133+
// UnmarshalJSON will unmarshal a rule, converting any integers to int64 and
134+
// floats to float64s. This is important because of how we can pass data
135+
// as props
136+
func (r *Rule) UnmarshalJSON(data []byte) error {
137+
var m map[string]interface{}
138+
err := json.Unmarshal(data, &m)
139+
if err != nil {
140+
return err
141+
}
142+
143+
var val interface{}
144+
switch m["value"].(type) {
145+
case float64:
146+
if math.Floor(m["value"].(float64))-m["value"].(float64) == 0 {
147+
val = int64(m["value"].(float64))
148+
} else {
149+
val = m["value"]
150+
}
151+
default:
152+
val = m["value"]
153+
}
154+
155+
if m["comparator"] != nil {
156+
r.Comparator = m["comparator"].(string)
157+
}
158+
159+
if m["path"] != nil {
160+
r.Path = m["path"].(string)
161+
}
162+
163+
r.Value = val
164+
165+
return nil
166+
}

rule_test.go

+49-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package grules
22

33
import (
4+
"encoding/json"
5+
"reflect"
46
"testing"
57
)
68

@@ -217,14 +219,14 @@ func TestEngineEvaluate(t *testing.T) {
217219
e.Composites = []Composite{
218220
Composite{
219221
Operator: OperatorAnd,
220-
Rules: []Rule{
221-
Rule{
222-
Comparator: "contains",
223-
Path: "address.bedroom.furniture",
224-
Value: "tv",
222+
Rules: []Rule{
223+
Rule{
224+
Comparator: "contains",
225+
Path: "address.bedroom.furniture",
226+
Value: "tv",
227+
},
225228
},
226229
},
227-
},
228230
}
229231
res := e.Evaluate(props)
230232
if res != true {
@@ -279,3 +281,44 @@ func TestEngineEvaluate(t *testing.T) {
279281
}
280282
})
281283
}
284+
285+
func TestRuleUnmarshalJSON(t *testing.T) {
286+
t.Run("string", func(t *testing.T) {
287+
b := []byte(`{"path":"name","comparator":"eq","value":"trevor"}`)
288+
var r Rule
289+
err := json.Unmarshal(b, &r)
290+
if err != nil {
291+
t.Fatal(err)
292+
}
293+
294+
if reflect.TypeOf(r.Value).Kind() != reflect.String {
295+
t.Fatal("expected value to be of type string")
296+
}
297+
})
298+
299+
t.Run("int64", func(t *testing.T) {
300+
b := []byte(`{"path":"name","comparator":"eq","value":1}`)
301+
var r Rule
302+
err := json.Unmarshal(b, &r)
303+
if err != nil {
304+
t.Fatal(err)
305+
}
306+
307+
if reflect.TypeOf(r.Value).Kind() != reflect.Int64 {
308+
t.Fatal("expected value to be of type int64")
309+
}
310+
})
311+
312+
t.Run("float64", func(t *testing.T) {
313+
b := []byte(`{"path":"name","comparator":"eq","value":1.1}`)
314+
var r Rule
315+
err := json.Unmarshal(b, &r)
316+
if err != nil {
317+
t.Fatal(err)
318+
}
319+
320+
if reflect.TypeOf(r.Value).Kind() != reflect.Float64 {
321+
t.Fatal("expected value to be of type float64")
322+
}
323+
})
324+
}

0 commit comments

Comments
 (0)