Skip to content

Commit 820a1ae

Browse files
authored
Merge pull request #63 from planetlabs/spec-updates
Updates in to the latest spec changes
2 parents 63bf247 + 55a9603 commit 820a1ae

20 files changed

+826
-101
lines changed

filter/array_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,19 @@ func TestArrayComparison(t *testing.T) {
9292
},
9393
}
9494

95+
schema := getSchema(t)
9596
for i, c := range cases {
9697
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
9798
data, err := json.Marshal(c.filter)
9899
require.NoError(t, err)
99100
assert.JSONEq(t, c.data, string(data))
100101

102+
v := map[string]any{}
103+
require.NoError(t, json.Unmarshal(data, &v))
104+
if err := schema.Validate(v); err != nil {
105+
t.Errorf("failed to validate\n%#v", err)
106+
}
107+
101108
filter := &filter.Filter{}
102109
require.NoError(t, json.Unmarshal([]byte(c.data), filter))
103110
assert.Equal(t, c.filter, filter)

filter/boolean_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,19 @@ func TestBoolean(t *testing.T) {
4343
},
4444
}
4545

46+
schema := getSchema(t)
4647
for i, c := range cases {
4748
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
4849
data, err := json.Marshal(c.filter)
4950
require.Nil(t, err)
5051
assert.JSONEq(t, c.data, string(data))
5152

53+
var v bool
54+
require.NoError(t, json.Unmarshal(data, &v))
55+
if err := schema.Validate(v); err != nil {
56+
t.Errorf("failed to validate\n%#v", err)
57+
}
58+
5259
filter := &filter.Filter{}
5360
require.Nil(t, json.Unmarshal([]byte(c.data), filter))
5461
assert.Equal(t, c.filter, filter)

filter/character.go

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ package filter
1616

1717
import (
1818
"encoding/json"
19-
"fmt"
19+
)
20+
21+
const (
22+
caseInsensitiveOp = "casei"
23+
accentInsensitiveOp = "accenti"
2024
)
2125

2226
type CharacterExpression interface {
@@ -46,19 +50,12 @@ func (*CaseInsensitive) characterExpression() {}
4650
func (*CaseInsensitive) patternExpression() {}
4751

4852
func (e *CaseInsensitive) MarshalJSON() ([]byte, error) {
49-
return json.Marshal(map[string]CharacterExpression{"casei": e.Value})
50-
}
51-
52-
func decodeCaseInsensitive(value any) (*CaseInsensitive, error) {
53-
v, err := decodeExpression(value)
54-
if err != nil {
55-
return nil, fmt.Errorf("trouble decoding casei expression: %w", err)
56-
}
57-
c, ok := v.(CharacterExpression)
58-
if !ok {
59-
return nil, fmt.Errorf("expected character expression in casei, got %v", v)
53+
m := map[string]any{
54+
"op": "casei",
55+
"args": []CharacterExpression{e.Value},
6056
}
61-
return &CaseInsensitive{Value: c}, nil
57+
58+
return json.Marshal(m)
6259
}
6360

6461
type AccentInsensitive struct {
@@ -78,7 +75,12 @@ func (*AccentInsensitive) characterExpression() {}
7875
func (*AccentInsensitive) patternExpression() {}
7976

8077
func (e *AccentInsensitive) MarshalJSON() ([]byte, error) {
81-
return json.Marshal(map[string]CharacterExpression{"accenti": e.Value})
78+
m := map[string]any{
79+
"op": "accenti",
80+
"args": []CharacterExpression{e.Value},
81+
}
82+
83+
return json.Marshal(m)
8284
}
8385

8486
type String struct {
@@ -102,15 +104,3 @@ func (*String) arrayItemExpression() {}
102104
func (e *String) MarshalJSON() ([]byte, error) {
103105
return json.Marshal(e.Value)
104106
}
105-
106-
func decodeAccentInsensitive(value any) (*AccentInsensitive, error) {
107-
v, err := decodeExpression(value)
108-
if err != nil {
109-
return nil, fmt.Errorf("trouble decoding accenti expression: %w", err)
110-
}
111-
c, ok := v.(CharacterExpression)
112-
if !ok {
113-
return nil, fmt.Errorf("expected character expression in accenti, got %v", v)
114-
}
115-
return &AccentInsensitive{Value: c}, nil
116-
}

filter/character_test.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func TestCharacter(t *testing.T) {
5252
},
5353
data: `{
5454
"op": "=",
55-
"args": [{"property": "soup"}, {"casei": "chicken"}]
55+
"args": [{"property": "soup"}, {"op": "casei", "args": ["chicken"]}]
5656
}`,
5757
},
5858
{
@@ -65,17 +65,24 @@ func TestCharacter(t *testing.T) {
6565
},
6666
data: `{
6767
"op": "=",
68-
"args": [{"property": "soup"}, {"accenti": "Chícken"}]
68+
"args": [{"property": "soup"}, {"op": "accenti", "args": ["Chícken"]}]
6969
}`,
7070
},
7171
}
7272

73+
schema := getSchema(t)
7374
for i, c := range cases {
7475
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
7576
data, err := json.Marshal(c.filter)
7677
require.Nil(t, err)
7778
assert.JSONEq(t, c.data, string(data))
7879

80+
v := map[string]any{}
81+
require.NoError(t, json.Unmarshal(data, &v))
82+
if err := schema.Validate(v); err != nil {
83+
t.Errorf("failed to validate\n%#v", err)
84+
}
85+
7986
filter := &filter.Filter{}
8087
require.Nil(t, json.Unmarshal([]byte(c.data), filter))
8188
assert.Equal(t, c.filter, filter)

filter/comparison_test.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ func TestComparison(t *testing.T) {
129129
},
130130
data: `{
131131
"op": "like",
132-
"args": [{"property": "name"}, {"casei": "park"}]
132+
"args": [{"property": "name"}, {"op": "casei", "args": ["park"]}]
133133
}`,
134134
},
135135
{
@@ -141,7 +141,7 @@ func TestComparison(t *testing.T) {
141141
},
142142
data: `{
143143
"op": "like",
144-
"args": [{"property": "name"}, {"accenti": "Noël"}]
144+
"args": [{"property": "name"}, {"op": "accenti", "args": ["Noël"]}]
145145
}`,
146146
},
147147
{
@@ -183,12 +183,19 @@ func TestComparison(t *testing.T) {
183183
},
184184
}
185185

186+
schema := getSchema(t)
186187
for i, c := range cases {
187188
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
188189
data, err := json.Marshal(c.filter)
189190
require.NoError(t, err)
190191
assert.JSONEq(t, c.data, string(data))
191192

193+
v := map[string]any{}
194+
require.NoError(t, json.Unmarshal(data, &v))
195+
if err := schema.Validate(v); err != nil {
196+
t.Errorf("failed to validate\n%#v", err)
197+
}
198+
192199
filter := &filter.Filter{}
193200
require.NoError(t, json.Unmarshal([]byte(c.data), filter))
194201
assert.Equal(t, c.filter, filter)

filter/expression.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,6 @@ func decodeExpression(value any) (Expression, error) {
4848
case []any:
4949
return decodeArray(v)
5050
case map[string]any:
51-
if casei, ok := v["casei"]; ok {
52-
return decodeCaseInsensitive(casei)
53-
}
54-
55-
if accenti, ok := v["accenti"]; ok {
56-
return decodeAccentInsensitive(accenti)
57-
}
58-
5951
if dateString, ok := v["date"].(string); ok {
6052
return decodeDate(dateString)
6153
}
@@ -90,10 +82,6 @@ func decodeExpression(value any) (Expression, error) {
9082
}
9183
return decodeOp(opName, args)
9284
}
93-
94-
if function, ok := v["function"].(map[string]any); ok {
95-
return decodeFunction(function)
96-
}
9785
}
9886

9987
return nil, errors.New("unsupported expression")

filter/filter_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package filter_test
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
"github.com/santhosh-tekuri/jsonschema/v5"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func getSchema(t *testing.T) *jsonschema.Schema {
12+
schemaData, err := os.ReadFile("testdata/schema/cql2.json")
13+
require.NoError(t, err)
14+
15+
schema, err := jsonschema.CompileString("cql2.json", string(schemaData))
16+
require.NoError(t, err)
17+
18+
return schema
19+
}

filter/function.go

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,11 @@ package filter
1616

1717
import (
1818
"encoding/json"
19-
"errors"
20-
"fmt"
2119
)
2220

2321
type Function struct {
24-
Name string
25-
Args []Expression
22+
Op string `json:"op"`
23+
Args []Expression `json:"args"`
2624
}
2725

2826
var (
@@ -47,37 +45,11 @@ func (*Function) temporalExpression() {}
4745

4846
func (e *Function) MarshalJSON() ([]byte, error) {
4947
f := map[string]any{
50-
"name": e.Name,
48+
"op": e.Op,
49+
"args": e.Args,
5150
}
52-
if len(e.Args) > 0 {
53-
f["args"] = e.Args
51+
if e.Args == nil {
52+
f["args"] = []Expression{}
5453
}
55-
return json.Marshal(map[string]any{"function": f})
56-
}
57-
58-
func decodeFunction(function map[string]any) (*Function, error) {
59-
name, ok := function["name"].(string)
60-
if !ok {
61-
return nil, errors.New("missing function name")
62-
}
63-
64-
argsValue, ok := function["args"]
65-
if !ok {
66-
return &Function{Name: name}, nil
67-
}
68-
69-
argsSlice, ok := argsValue.([]any)
70-
if !ok {
71-
return nil, errors.New("expected function args to be an array")
72-
}
73-
74-
args := make([]Expression, len(argsSlice))
75-
for i, arg := range argsSlice {
76-
argument, err := decodeExpression(arg)
77-
if err != nil {
78-
return nil, fmt.Errorf("trouble parsing function argument %d: %w", i, err)
79-
}
80-
args[i] = argument
81-
}
82-
return &Function{Name: name, Args: args}, nil
54+
return json.Marshal(f)
8355
}

filter/function_test.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func TestFunction(t *testing.T) {
3434
Expression: &filter.Comparison{
3535
Name: filter.Equals,
3636
Left: &filter.Function{
37-
Name: "testing",
37+
Op: "testing",
3838
Args: []filter.Expression{
3939
&filter.Number{1},
4040
&filter.Number{2},
@@ -46,30 +46,37 @@ func TestFunction(t *testing.T) {
4646
},
4747
data: `{
4848
"op": "=",
49-
"args": [{"function": {"name": "testing", "args": [1, 2, 3]}}, true]
49+
"args": [{"op": "testing", "args": [1, 2, 3]}, true]
5050
}`,
5151
},
5252
{
5353
filter: &filter.Filter{
5454
Expression: &filter.Comparison{
5555
Name: filter.Equals,
56-
Left: &filter.Function{Name: "agreeable"},
56+
Left: &filter.Function{Op: "agreeable"},
5757
Right: &filter.Boolean{false},
5858
},
5959
},
6060
data: `{
6161
"op": "=",
62-
"args": [{"function": {"name": "agreeable"}}, false]
62+
"args": [{"op": "agreeable", "args": []}, false]
6363
}`,
6464
},
6565
}
6666

67+
schema := getSchema(t)
6768
for i, c := range cases {
6869
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
6970
data, err := json.Marshal(c.filter)
7071
require.Nil(t, err)
7172
assert.JSONEq(t, c.data, string(data))
7273

74+
v := map[string]any{}
75+
require.NoError(t, json.Unmarshal(data, &v))
76+
if err := schema.Validate(v); err != nil {
77+
t.Errorf("failed to validate\n%#v", err)
78+
}
79+
7380
filter := &filter.Filter{}
7481
require.Nil(t, json.Unmarshal([]byte(c.data), filter))
7582
assert.Equal(t, c.filter, filter)

filter/logical_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,19 @@ func TestLogical(t *testing.T) {
9595
},
9696
}
9797

98+
schema := getSchema(t)
9899
for i, c := range cases {
99100
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
100101
data, err := json.Marshal(c.filter)
101102
require.Nil(t, err)
102103
assert.JSONEq(t, c.data, string(data))
103104

105+
v := map[string]any{}
106+
require.NoError(t, json.Unmarshal(data, &v))
107+
if err := schema.Validate(v); err != nil {
108+
t.Errorf("failed to validate\n%#v", err)
109+
}
110+
104111
filter := &filter.Filter{}
105112
require.Nil(t, json.Unmarshal([]byte(c.data), filter))
106113
assert.Equal(t, c.filter, filter)

0 commit comments

Comments
 (0)