Skip to content

Commit f2b3685

Browse files
committed
Add and or funcs
1 parent d46d974 commit f2b3685

File tree

6 files changed

+266
-0
lines changed

6 files changed

+266
-0
lines changed

func.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ func standardFunctions() *FunctionCollection {
5656
EqualFunc,
5757
MoreThanFunc,
5858
LessThanFunc,
59+
AndFunc,
60+
OrFunc,
5961

6062
// Metadata
6163
MetadataFunc,

func_and.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package dasel
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
)
7+
8+
var AndFunc = BasicFunction{
9+
name: "and",
10+
runFn: func(c *Context, s *Step, args []string) (Values, error) {
11+
if err := requireXOrMoreArgs("filter", args, 1); err != nil {
12+
return nil, err
13+
}
14+
15+
input := c.inputValue(s)
16+
17+
runComparison := func(value Value, selector string) (bool, error) {
18+
gotValues, err := performSubQuery(c, value, selector)
19+
if err != nil {
20+
return false, err
21+
}
22+
23+
if len(gotValues) > 1 {
24+
return false, fmt.Errorf("and expects selector to return a single value")
25+
}
26+
27+
if len(gotValues) == 0 {
28+
return false, nil
29+
}
30+
31+
return IsTruthy(gotValues[0]), nil
32+
}
33+
34+
res := make(Values, 0)
35+
36+
for _, val := range input {
37+
valPassed := true
38+
for _, cmp := range args {
39+
pass, err := runComparison(val, cmp)
40+
if err != nil {
41+
return nil, err
42+
}
43+
if !pass {
44+
valPassed = false
45+
break
46+
}
47+
}
48+
res = append(res, Value{Value: reflect.ValueOf(valPassed)})
49+
}
50+
51+
return res, nil
52+
},
53+
}

func_and_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package dasel
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestAndFunc(t *testing.T) {
8+
t.Run(
9+
"NoneEqualMoreThan",
10+
selectTest(
11+
"numbers.all().and(equal(.,2),moreThan(.,2))",
12+
map[string]interface{}{
13+
"numbers": []interface{}{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
14+
},
15+
[]interface{}{
16+
false, false, false, false, false, false, false, false, false, false,
17+
},
18+
),
19+
)
20+
t.Run(
21+
"SomeEqualMoreThan",
22+
selectTest(
23+
"numbers.all().and(equal(.,4),moreThan(.,2))",
24+
map[string]interface{}{
25+
"numbers": []interface{}{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
26+
},
27+
[]interface{}{
28+
false, false, false, false, true, false, false, false, false, false,
29+
},
30+
),
31+
)
32+
}

func_filter_test.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,98 @@ func TestFilterFunc(t *testing.T) {
9191
},
9292
),
9393
)
94+
95+
t.Run(
96+
"Filter And",
97+
selectTest(
98+
"all().filter(and(equal(primary,true),equal(name,red))).name",
99+
[]interface{}{
100+
map[string]interface{}{
101+
"name": "red",
102+
"hex": "ff0000",
103+
"primary": true,
104+
},
105+
map[string]interface{}{
106+
"name": "green",
107+
"hex": "00ff00",
108+
"primary": true,
109+
},
110+
map[string]interface{}{
111+
"name": "blue",
112+
"hex": "0000ff",
113+
"primary": true,
114+
},
115+
map[string]interface{}{
116+
"name": "orange",
117+
"hex": "ffa500",
118+
"primary": false,
119+
},
120+
},
121+
[]interface{}{
122+
"red",
123+
},
124+
),
125+
)
126+
127+
t.Run(
128+
"Filter And",
129+
selectTest(
130+
"all().filter(and(equal(primary,true),equal(name,orange))).name",
131+
[]interface{}{
132+
map[string]interface{}{
133+
"name": "red",
134+
"hex": "ff0000",
135+
"primary": true,
136+
},
137+
map[string]interface{}{
138+
"name": "green",
139+
"hex": "00ff00",
140+
"primary": true,
141+
},
142+
map[string]interface{}{
143+
"name": "blue",
144+
"hex": "0000ff",
145+
"primary": true,
146+
},
147+
map[string]interface{}{
148+
"name": "orange",
149+
"hex": "ffa500",
150+
"primary": false,
151+
},
152+
},
153+
[]interface{}{},
154+
),
155+
)
156+
157+
t.Run(
158+
"Filter Or",
159+
selectTest(
160+
"all().filter(or(equal(primary,true),equal(name,orange))).name",
161+
[]interface{}{
162+
map[string]interface{}{
163+
"name": "red",
164+
"hex": "ff0000",
165+
"primary": true,
166+
},
167+
map[string]interface{}{
168+
"name": "green",
169+
"hex": "00ff00",
170+
"primary": true,
171+
},
172+
map[string]interface{}{
173+
"name": "blue",
174+
"hex": "0000ff",
175+
"primary": true,
176+
},
177+
map[string]interface{}{
178+
"name": "orange",
179+
"hex": "ffa500",
180+
"primary": false,
181+
},
182+
},
183+
[]interface{}{
184+
"red", "green", "blue", "orange",
185+
},
186+
),
187+
)
94188
}

func_or.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package dasel
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
)
7+
8+
var OrFunc = BasicFunction{
9+
name: "or",
10+
runFn: func(c *Context, s *Step, args []string) (Values, error) {
11+
if err := requireXOrMoreArgs("or", args, 1); err != nil {
12+
return nil, err
13+
}
14+
15+
input := c.inputValue(s)
16+
17+
runComparison := func(value Value, selector string) (bool, error) {
18+
gotValues, err := performSubQuery(c, value, selector)
19+
if err != nil {
20+
return false, err
21+
}
22+
23+
if len(gotValues) > 1 {
24+
return false, fmt.Errorf("or expects selector to return a single value")
25+
}
26+
27+
if len(gotValues) == 0 {
28+
return false, nil
29+
}
30+
31+
return IsTruthy(gotValues[0]), nil
32+
}
33+
34+
res := make(Values, 0)
35+
36+
for _, val := range input {
37+
valPassed := false
38+
for _, cmp := range args {
39+
pass, err := runComparison(val, cmp)
40+
if err != nil {
41+
return nil, err
42+
}
43+
if pass {
44+
valPassed = true
45+
break
46+
}
47+
}
48+
res = append(res, Value{Value: reflect.ValueOf(valPassed)})
49+
}
50+
51+
return res, nil
52+
},
53+
}

func_or_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package dasel
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestOrFunc(t *testing.T) {
8+
t.Run(
9+
"NoneEqualMoreThan",
10+
selectTest(
11+
"numbers.all().or(equal(.,2),moreThan(.,2))",
12+
map[string]interface{}{
13+
"numbers": []interface{}{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
14+
},
15+
[]interface{}{
16+
false, false, true, true, true, true, true, true, true, true,
17+
},
18+
),
19+
)
20+
t.Run(
21+
"SomeEqualMoreThan",
22+
selectTest(
23+
"numbers.all().or(equal(.,0),moreThan(.,2))",
24+
map[string]interface{}{
25+
"numbers": []interface{}{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
26+
},
27+
[]interface{}{
28+
true, false, false, true, true, true, true, true, true, true,
29+
},
30+
),
31+
)
32+
}

0 commit comments

Comments
 (0)