Skip to content

Commit d5dca23

Browse files
author
jennybuckley
committed
Make remvoveItems copy, and include nodes in ToFieldSet
1 parent f75341c commit d5dca23

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

typed/toset_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,8 @@ var fieldsetCases = []fieldsetTestCase{{
166166
{`{"arbitraryWavelengthColor":{"IR":255}}`, _NS(_P("arbitraryWavelengthColor"))},
167167
{`{"args":[]}`, _NS(_P("args"))},
168168
{`{"args":null}`, _NS(_P("args"))},
169-
{`{"args":[null]}`, _NS(_P("args"))},
170-
{`{"args":[{"key":"a","value":"b"},{"key":"c","value":"d"}]}`, _NS(_P("args"))},
169+
{`{"args":[null]}`,_NS(_P("args"))},
170+
{`{"args":[{"key":"a","value":"b"},{"key":"c","value":"d"}]}`,_NS(_P("args"))},
171171
},
172172
}, {
173173
name: "associative list",
@@ -221,11 +221,15 @@ var fieldsetCases = []fieldsetTestCase{{
221221
pairs: []objSetPair{
222222
{`{"list":[]}`, _NS()},
223223
{`{"list":[{"key":"a","id":1,"value":{"a":"a"}}]}`, _NS(
224+
_P("list", _KBF("key", _SV("a"), "id", _IV(1))),
224225
_P("list", _KBF("key", _SV("a"), "id", _IV(1)), "key"),
225226
_P("list", _KBF("key", _SV("a"), "id", _IV(1)), "id"),
226227
_P("list", _KBF("key", _SV("a"), "id", _IV(1)), "value", "a"),
227228
)},
228229
{`{"list":[{"key":"a","id":1},{"key":"a","id":2},{"key":"b","id":1}]}`, _NS(
230+
_P("list", _KBF("key", _SV("a"), "id", _IV(1))),
231+
_P("list", _KBF("key", _SV("a"), "id", _IV(2))),
232+
_P("list", _KBF("key", _SV("b"), "id", _IV(1))),
229233
_P("list", _KBF("key", _SV("a"), "id", _IV(1)), "key"),
230234
_P("list", _KBF("key", _SV("a"), "id", _IV(1)), "id"),
231235
_P("list", _KBF("key", _SV("a"), "id", _IV(2)), "key"),

typed/typed.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type TypedValue interface {
3131
AsValue() *value.Value
3232
// Validate returns an error with a list of every spec violation.
3333
Validate() error
34-
// ToFieldSet creates a set containing every leaf field mentioned, or
34+
// ToFieldSet creates a set containing every leaf field and item mentioned, or
3535
// validation errors, if any were encountered.
3636
ToFieldSet() (*fieldpath.Set, error)
3737
// Merge returns the result of merging tv and pso ("partially specified
@@ -109,6 +109,7 @@ func (tv typedValue) ToFieldSet() (*fieldpath.Set, error) {
109109
s := fieldpath.NewSet()
110110
w := tv.walker()
111111
w.leafFieldCallback = func(p fieldpath.Path) { s.Insert(p) }
112+
w.nodeFieldCallback = func(p fieldpath.Path) { s.Insert(p) }
112113
if errs := w.validate(); len(errs) != 0 {
113114
return nil, errs
114115
}
@@ -163,8 +164,10 @@ func (tv typedValue) Compare(rhs TypedValue) (c *Comparison, err error) {
163164

164165
// RemoveItems removes each provided list or map item from the value.
165166
func (tv typedValue) RemoveItems(items *fieldpath.Set) TypedValue {
166-
removeItemsWithSchema(&tv.value, items, tv.schema, tv.typeRef)
167-
return tv
167+
copied := tv
168+
copied.value, _ = value.FromUnstructured(tv.value.ToUnstructured(true))
169+
removeItemsWithSchema(&copied.value, items, copied.schema, copied.typeRef)
170+
return copied
168171
}
169172

170173
func merge(lhs, rhs typedValue, rule, postRule mergeRule) (TypedValue, error) {

typed/validate.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ type validatingObjectWalker struct {
4242
// * untyped fields
4343
leafFieldCallback func(fieldpath.Path)
4444

45+
// If set, this is called on "node fields":
46+
// * list items
47+
// * map items
48+
nodeFieldCallback func(fieldpath.Path)
49+
4550
// internal housekeeping--don't set when constructing.
4651
inLeaf bool // Set to true if we're in a "big leaf"--atomic map/list
4752
}
@@ -67,6 +72,21 @@ func (v *validatingObjectWalker) doLeaf() {
6772
}
6873
}
6974

75+
// doNode should be called on nodes after descending into children
76+
func (v *validatingObjectWalker) doNode() {
77+
if v.inLeaf {
78+
// We're in a "big leaf", an atomic map or list. Ignore
79+
// subsequent leaves.
80+
return
81+
}
82+
83+
if v.nodeFieldCallback != nil {
84+
// At the moment, this is only used to build fieldsets; we can
85+
// add more than the path in here if needed.
86+
v.nodeFieldCallback(v.path)
87+
}
88+
}
89+
7090
func (v validatingObjectWalker) doScalar(t schema.Scalar) ValidationErrors {
7191
if errs := v.validateScalar(t, &v.value, ""); len(errs) > 0 {
7292
return errs
@@ -144,6 +164,8 @@ func (v validatingObjectWalker) visitListItems(t schema.List, list *value.List)
144164
v2.value = child
145165
v2.typeRef = t.ElementType
146166
errs = append(errs, v2.validate()...)
167+
168+
v2.doNode()
147169
}
148170
return errs
149171
}
@@ -175,6 +197,8 @@ func (v validatingObjectWalker) visitMapItems(t schema.Map, m *value.Map) (errs
175197
v2.value = item.Value
176198
v2.typeRef = t.ElementType
177199
errs = append(errs, v2.validate()...)
200+
201+
v2.doNode()
178202
}
179203
return errs
180204
}

0 commit comments

Comments
 (0)