Skip to content

Commit f23b4a2

Browse files
Hi-Finewm4n
andauthored
feat: support negation within JSON format (#500)
Co-authored-by: Ferdinand Neman <ferdinand.neman@gmail.com>
1 parent 3683cc6 commit f23b4a2

File tree

2 files changed

+43
-6
lines changed

2 files changed

+43
-6
lines changed

pkg/JsonResource.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,6 @@ func buildCompoundOperator(o interface{}, depth int, operator string) (string, b
391391
}
392392
}
393393
if depth > 0 {
394-
395394
return "(" + strings.Join(ands, operator) + ")", false, nil
396395
}
397396

@@ -467,7 +466,7 @@ func joinOperator(v interface{}, operator string) (string, error) {
467466
}
468467
ops := make([]string, len(arr))
469468
for i := 0; i < len(arr); i++ {
470-
ope, err := parseOperand(arr[i], false)
469+
ope, err := parseOperand(arr[i], false, operator == " != ")
471470
if err != nil {
472471

473472
return "", err
@@ -487,12 +486,12 @@ func joinSet(v interface{}, operator string) (string, error) {
487486

488487
return "", fmt.Errorf("set operand count must be 2")
489488
}
490-
leftOpe, err := parseOperand(arr[0], true)
489+
leftOpe, err := parseOperand(arr[0], true, false)
491490
if err != nil {
492491

493492
return "", err
494493
}
495-
rightOpe, err := parseOperand(arr[1], true)
494+
rightOpe, err := parseOperand(arr[1], true, false)
496495
if err != nil {
497496

498497
return "", err
@@ -504,7 +503,7 @@ func joinSet(v interface{}, operator string) (string, error) {
504503
return "", fmt.Errorf("operator has an unexpected type")
505504
}
506505

507-
func parseOperand(o interface{}, noWrap bool) (string, error) {
506+
func parseOperand(o interface{}, noWrap bool, negation bool) (string, error) {
508507
switch operandType := o.(type) {
509508
case string:
510509

@@ -532,6 +531,10 @@ func parseOperand(o interface{}, noWrap bool) (string, error) {
532531
return expr, nil
533532
}
534533

534+
if negation {
535+
return "!(" + expr + ")", nil
536+
}
537+
535538
return "(" + expr + ")", nil
536539
default:
537540

pkg/JsonResource_test.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
package pkg
1616

1717
import (
18-
"github.com/stretchr/testify/assert"
1918
"testing"
19+
20+
"github.com/stretchr/testify/assert"
2021
)
2122

2223
const jsonData = `{
@@ -209,6 +210,33 @@ const expectedBigIntConversion = `rule SpeedUp "When testcar is speeding up we k
209210
}
210211
`
211212

213+
const jsonNegation = `[{
214+
"name": "SpeedConstant",
215+
"desc": "When testcar is not speeding up we keep constant \"speed\".",
216+
"salience": 10,
217+
"when": {
218+
"not": [
219+
{
220+
"and": [
221+
{"eq": ["TestCar.SpeedUp", true]},
222+
{"not": ["TestCar.Speed", 10]}
223+
]
224+
}
225+
]
226+
},
227+
"then": [
228+
{"call": ["Log", {"const": "\"Speed\" constant\n"}]}
229+
]
230+
}]`
231+
232+
const expecteJsonNegation = `rule SpeedConstant "When testcar is not speeding up we keep constant \"speed\"." salience 10 {
233+
when
234+
!(TestCar.SpeedUp == true && TestCar.Speed != 10)
235+
then
236+
Log("\"Speed\" constant\n");
237+
}
238+
`
239+
212240
func TestParseJSONRuleset(t *testing.T) {
213241
rs, err := ParseJSONRule([]byte(jsonData))
214242
assert.NoError(t, err)
@@ -262,3 +290,9 @@ func TestJSONBigIntConversion(t *testing.T) {
262290
assert.NoError(t, err)
263291
assert.Equal(t, expectedBigIntConversion, rs)
264292
}
293+
294+
func TestJsonNegation(t *testing.T) {
295+
rs, err := ParseJSONRuleset([]byte(jsonNegation))
296+
assert.NoError(t, err)
297+
assert.Equal(t, expecteJsonNegation, rs)
298+
}

0 commit comments

Comments
 (0)