Skip to content

Commit 1f3ff14

Browse files
Added Rule Validation Support (#2)
* Rule Validation is supported. * Update README.md * Rule Validation is supported. * Rule Validation is supported. * Rule Validation is supported. * Rule Validation is supported. * Rule Validation is supported. * rule validation support for v0.1.2 * reverted changes for imports. * reverted changes for imports. * reverted changes for imports. * reverted changes for imports. Co-authored-by: shankarparimi <shankar.parimi>
1 parent 947a1e2 commit 1f3ff14

6 files changed

Lines changed: 144 additions & 0 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Golang implementation of JsonLogic (jsonlogic.com), which is an abstract syntax
88

99
Custom operators are supported.
1010

11+
Rules Validation is supported.
12+
1113
## Example
1214

1315
```golang

default.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ func Apply(rule interface{}, data interface{}) (interface{}, error) {
1515
func AddOperation(symbol string, op Operator) error {
1616
return defaultJL.AddOperation(symbol, op)
1717
}
18+
19+
func Validate(rule interface{}) error {
20+
return defaultJL.Validate(rule)
21+
}

interface.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package jsonlogic
44
type LogicApplier interface {
55
Apply(rule interface{}, data interface{}) (interface{}, error)
66
AddOperation(symbol string, op Operator) error
7+
Validate(rule interface{}) error
78
}
89

910
// RuleType is the type of rule

jsonlogic.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ func (jl *jsonLogic) AddOperation(symbol string, op Operator) error {
2121
return nil
2222
}
2323

24+
func (jl *jsonLogic) Validate(rule interface{}) error {
25+
return jl.validate(rule)
26+
}
27+
2428
func (jl *jsonLogic) mustAddOperation(symbol string, op Operator) {
2529
if err := jl.AddOperation(symbol, op); err != nil {
2630
log.Fatal(err)

validator.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package jsonlogic
2+
3+
import (
4+
"fmt"
5+
)
6+
7+
//TODO: Call operator Specific Validate Methods.
8+
func (jl *jsonLogic) validate(rule RuleType) error {
9+
switch rule := rule.(type) {
10+
case nil, bool, float64, string:
11+
return nil
12+
case map[string]interface{}:
13+
for opName, params := range rule {
14+
_, ok := jl.ops[opName]
15+
if !ok {
16+
return fmt.Errorf("invalid operator: " + opName)
17+
}
18+
if err := jl.validate(params); err != nil {
19+
return err
20+
}
21+
}
22+
case []interface{}:
23+
for _, param := range rule {
24+
if err := jl.validate(param); err != nil {
25+
return err
26+
}
27+
}
28+
29+
}
30+
31+
return nil
32+
}

validator_test.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package jsonlogic_test
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"github.com/HuanTeng/go-jsonlogic"
7+
"reflect"
8+
"testing"
9+
)
10+
11+
var cases = []TestCase{
12+
{
13+
name: "valid Rule:0",
14+
rule: `{
15+
">": [
16+
{
17+
"var": "variable1.value"
18+
}]
19+
}`,
20+
expect: nil,
21+
},
22+
{
23+
name: "invalid Rule",
24+
rule: `{
25+
">": [
26+
{
27+
"variable": "variable1.value"
28+
}]
29+
}`,
30+
expect: fmt.Errorf("invalid operator: variable"),
31+
},
32+
{
33+
name: "Valid Rule:1",
34+
rule: `{
35+
"or": {
36+
">": [
37+
{
38+
"var": "variable1.value"
39+
},
40+
{
41+
"var": "variable1.value"
42+
}
43+
],
44+
"<": [
45+
[
46+
{
47+
"var": "variable1.value"
48+
},
49+
{
50+
"var": "variable1.value"
51+
}
52+
],
53+
70
54+
]
55+
}
56+
}`,
57+
expect: nil,
58+
},
59+
{
60+
name: "Invalid Rule - 1",
61+
rule: `{
62+
"or": {
63+
"equals": [
64+
{
65+
"var": "variable1.value"
66+
},
67+
{
68+
"var": "variable2.value"
69+
}
70+
],
71+
"fuzzy_match": [
72+
[
73+
{
74+
"var": "variable1.value"
75+
},
76+
{
77+
"var": "variable2.value"
78+
}
79+
],
80+
70
81+
]
82+
}
83+
}`,
84+
expect: fmt.Errorf("invalid operator: equals"),
85+
},
86+
}
87+
88+
func TestJsonLogic_Validate(t *testing.T) {
89+
var rule interface{}
90+
for _, c := range cases {
91+
t.Run(c.name, func(t *testing.T) {
92+
if err := json.Unmarshal([]byte(c.rule), &rule); err != nil {
93+
t.Errorf("rule error: %s", err)
94+
}
95+
err := jsonlogic.Validate(rule)
96+
if !reflect.DeepEqual(err, c.expect) {
97+
t.Errorf("Case %s: expect error %+v got %+v", c.name, c.expect, err)
98+
}
99+
})
100+
}
101+
}

0 commit comments

Comments
 (0)