Skip to content

Commit bf5b0dc

Browse files
author
Kevin Wiesmüller
committed
fix list removal and add tests
1 parent 9786361 commit bf5b0dc

File tree

2 files changed

+130
-14
lines changed

2 files changed

+130
-14
lines changed

typed/remove.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ func (w *removingWalker) doList(t *schema.List) (errs ValidationErrors) {
4848

4949
// If list is null, empty, or atomic just return
5050
if l == nil || l.Length() == 0 || t.ElementRelationship == schema.Atomic {
51+
w.out = l
5152
return nil
5253
}
5354

typed/remove_test.go

Lines changed: 129 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"sigs.k8s.io/structured-merge-diff/v3/value"
99
)
1010

11-
func TestRemove(t *testing.T) {
11+
func TestRemoveDeduced(t *testing.T) {
1212

1313
var cases = []struct {
1414
object YAMLObject
@@ -47,17 +47,16 @@ func TestRemove(t *testing.T) {
4747
expect: `{"a": "value"}`,
4848
},
4949
{
50+
// this is okay, because in a deduced schema `b` is handled as a map not a struct
5051
object: `{"a": "value", "b":{"c":"value"}}`,
5152
remove: fieldpath.NewSet(fieldpath.MakePathOrDie("b")),
5253
deep: false,
53-
// TODO: this seems to behave differently with a non deduced schema: {"a": "value", "b":{"c":"value"}} which is the reason for this PR
5454
expect: `{"a": "value"}`,
5555
},
5656
{
5757
object: `{"a": "value", "b": {"c":"value"}}`,
5858
remove: fieldpath.NewSet(fieldpath.MakePathOrDie("b", "c")),
5959
deep: true,
60-
// TODO: is a null result expected (insted of a {})
6160
expect: `{"a": "value", "b": null}`,
6261
},
6362
{
@@ -70,21 +69,20 @@ func TestRemove(t *testing.T) {
7069
object: `{"a": "value", "b": ["c"]}`,
7170
remove: fieldpath.NewSet(fieldpath.MakePathOrDie("b", "c")),
7271
deep: true,
72+
// TODO: this should fail
7373
expect: `{"a": "value", "b": null}`,
7474
},
7575
{
7676
object: `{"a": "value", "b": ["c", "d"]}`,
7777
remove: fieldpath.NewSet(fieldpath.MakePathOrDie("b", "c")),
7878
deep: true,
79-
// TODO: is this expected?
80-
expect: `{"a": "value", "b": null}`,
79+
expect: `{"a": "value", "b": ["c", "d"]}`,
8180
},
8281
{
8382
object: `{"a": "value", "b": [{"c": "value"}, {"d": "value"}]}`,
8483
remove: fieldpath.NewSet(fieldpath.MakePathOrDie("b", "c")),
8584
deep: true,
86-
// TODO: is this expected?
87-
expect: `{"a": "value", "b": null}`,
85+
expect: `{"a": "value", "b": [{"c": "value"}, {"d": "value"}]}`,
8886
},
8987
{
9088
object: `{"a": "value", "b": {"c":"value", "d":{"e":"value"}}}`,
@@ -132,7 +130,6 @@ func TestRemove(t *testing.T) {
132130
object: `{"a": "value", "b": {"c":"value"}}`,
133131
remove: fieldpath.NewSet(fieldpath.MakePathOrDie("b", "c")),
134132
deep: false,
135-
// TODO: is a null result expected (insted of a {})
136133
expect: `{"a": "value", "b": null}`,
137134
},
138135
{
@@ -145,21 +142,19 @@ func TestRemove(t *testing.T) {
145142
object: `{"a": "value", "b": ["c"]}`,
146143
remove: fieldpath.NewSet(fieldpath.MakePathOrDie("b", "c")),
147144
deep: false,
148-
expect: `{"a": "value", "b": null}`,
145+
expect: `{"a": "value", "b": ["c"]}`,
149146
},
150147
{
151148
object: `{"a": "value", "b": ["c", "d"]}`,
152149
remove: fieldpath.NewSet(fieldpath.MakePathOrDie("b", "c")),
153150
deep: false,
154-
// TODO: is this expected?
155-
expect: `{"a": "value", "b": null}`,
151+
expect: `{"a": "value", "b": ["c", "d"]}`,
156152
},
157153
{
158154
object: `{"a": "value", "b": [{"c": "value"}, {"d": "value"}]}`,
159155
remove: fieldpath.NewSet(fieldpath.MakePathOrDie("b", "c")),
160156
deep: false,
161-
// TODO: is this expected?
162-
expect: `{"a": "value", "b": null}`,
157+
expect: `{"a": "value", "b": [{"c": "value"}, {"d": "value"}]}`,
163158
},
164159
{
165160
object: `{"a": "value", "b": {"c":"value", "d":{"e":"value"}}}`,
@@ -185,7 +180,11 @@ func TestRemove(t *testing.T) {
185180
t.Fatalf("unable to parse/validate object: %v\n%v", err, c.object)
186181
}
187182

188-
expectTyped, err := DeducedParseableType.FromYAML(c.expect)
183+
parseable := &ParseableType{
184+
Schema: obj.schema,
185+
TypeRef: obj.typeRef,
186+
}
187+
expectTyped, err := parseable.FromYAML(c.expect)
189188
if err != nil {
190189
t.Fatalf("unable to parse/validate expected object: %v\n%v", err, c.expect)
191190
}
@@ -206,3 +205,119 @@ func TestRemove(t *testing.T) {
206205
})
207206
}
208207
}
208+
func TestRemove(t *testing.T) {
209+
210+
var cases = []struct {
211+
object YAMLObject
212+
schema YAMLObject
213+
remove *fieldpath.Set
214+
deep bool
215+
expect YAMLObject
216+
}{
217+
{
218+
object: `{"a": "value", "b":{"c":"value"}}`,
219+
schema: `types:
220+
- name: type
221+
map:
222+
fields:
223+
- name: a
224+
type:
225+
scalar: string
226+
- name: b
227+
type:
228+
map:
229+
fields:
230+
- name: c
231+
type:
232+
scalar: string
233+
elementType:
234+
scalar: string
235+
`,
236+
remove: fieldpath.NewSet(fieldpath.MakePathOrDie("b")),
237+
deep: false,
238+
expect: `{"a": "value", "b":{"c":"value"}}`,
239+
},
240+
{
241+
object: `{"a": "value", "b":{"c":"value"}}`,
242+
schema: `types:
243+
- name: type
244+
map:
245+
fields:
246+
- name: a
247+
type:
248+
scalar: string
249+
- name: b
250+
type:
251+
map:
252+
fields:
253+
- name: c
254+
type:
255+
scalar: string
256+
elementType:
257+
scalar: string
258+
`,
259+
remove: fieldpath.NewSet(fieldpath.MakePathOrDie("b")),
260+
deep: true,
261+
expect: `{"a": "value"}`,
262+
},
263+
{
264+
object: `{"a": "value", "b": ["c"]}`,
265+
schema: `types:
266+
- name: type
267+
map:
268+
fields:
269+
- name: a
270+
type:
271+
scalar: string
272+
- name: b
273+
type:
274+
list:
275+
elementType:
276+
scalar: string
277+
elementRelationship: associative
278+
elementType:
279+
scalar: string
280+
`,
281+
remove: fieldpath.NewSet(fieldpath.MakePathOrDie("b", "c")),
282+
deep: true,
283+
expect: `{"a": "value", "b": ["c"]}`,
284+
},
285+
}
286+
287+
for i, c := range cases {
288+
c := c
289+
t.Run(fmt.Sprintf("case-%d", i), func(t *testing.T) {
290+
t.Parallel()
291+
292+
parser, err := NewParser(c.schema)
293+
if err != nil {
294+
t.Fatalf("unable to parse schema: %v\n%v", err, c.schema)
295+
}
296+
297+
parseable := parser.Type("type")
298+
object, err := parseable.FromYAML(c.object)
299+
if err != nil {
300+
t.Fatalf("unable to parse object: %v\n%v", err, c.object)
301+
}
302+
303+
expectTyped, err := parseable.FromYAML(c.expect)
304+
if err != nil {
305+
t.Fatalf("unable to parse expected object: %v\n%v", err, c.expect)
306+
}
307+
expect := expectTyped.AsValue()
308+
309+
var result value.Value
310+
if c.deep {
311+
result = object.RemoveDeep(c.remove).AsValue()
312+
} else {
313+
result = object.RemoveItems(c.remove).AsValue()
314+
}
315+
316+
if !value.Equals(result, expect) {
317+
t.Fatalf("unexpected result after remove:\ngot: %v\nexp: %v",
318+
value.ToString(result), value.ToString(expect),
319+
)
320+
}
321+
})
322+
}
323+
}

0 commit comments

Comments
 (0)