Skip to content

Commit e3ab704

Browse files
committed
fix(bindnode): listpairs value assembly handles complex reprs
current impl works on scalar assemblies but borks when you try to assemble a child that has a non-scalar; so nested listpairs in listpairs doesn't work because we've not been passing representation assemblers properly
1 parent 1fd7e14 commit e3ab704

File tree

2 files changed

+71
-3
lines changed

2 files changed

+71
-3
lines changed

node/bindnode/repr.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ func (w *_nodeRepr) LookupByIndex(idx int64) (datamodel.Node, error) {
189189
continue
190190
}
191191
if curField == idx {
192-
return buildListpairsField(basicnode.NewString(field.Name()), value)
192+
return buildListpairsField(basicnode.NewString(field.Name()), reprNode(value))
193193
}
194194
curField++
195195
}
@@ -384,7 +384,7 @@ func (w *_listpairsIteratorRepr) Next() (index int64, value datamodel.Node, _ er
384384
if value.IsAbsent() || w.nextIndex > w.reprEnd {
385385
continue
386386
}
387-
field, err := buildListpairsField(key, value)
387+
field, err := buildListpairsField(key, reprNode(value))
388388
if err != nil {
389389
return 0, nil, err
390390
}
@@ -1167,7 +1167,8 @@ func (w *_listpairsFieldListAssemblerRepr) AssembleValue() datamodel.NodeAssembl
11671167
case 1:
11681168
return w.parent.AssembleKey()
11691169
case 2:
1170-
return w.parent.AssembleValue()
1170+
asm := w.parent.AssembleValue()
1171+
return assemblerRepr(asm.(*_assembler))
11711172
default:
11721173
return _errorAssembler{fmt.Errorf("bindnode: too many values in listpairs field")}
11731174
}

node/tests/schemaStructReprListpairs.go

+67
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ func SchemaTestStructReprListPairs(t *testing.T, engine Engine) {
3232
},
3333
schema.SpawnStructRepresentationListPairs(),
3434
))
35+
ts.Accumulate(schema.SpawnStruct("NestedListPairs",
36+
[]schema.StructField{
37+
schema.SpawnStructField("str", "String", false, false),
38+
schema.SpawnStructField("lp", "OneListPair", false, false),
39+
},
40+
schema.SpawnStructRepresentationListPairs(),
41+
))
3542
engine.Init(t, ts)
3643

3744
t.Run("onelistpair works", func(t *testing.T) {
@@ -257,4 +264,64 @@ func SchemaTestStructReprListPairs(t *testing.T, engine Engine) {
257264
qt.Check(t, n, NodeContentEquals, anr)
258265
})
259266
})
267+
268+
t.Run("nestedlistpairs works", func(t *testing.T) {
269+
np := engine.PrototypeByName("NestedListPairs")
270+
nrp := engine.PrototypeByName("NestedListPairs.Repr")
271+
var n schema.TypedNode
272+
t.Run("typed-create", func(t *testing.T) {
273+
n = fluent.MustBuildMap(np, 1, func(ma fluent.MapAssembler) {
274+
ma.AssembleEntry("str").AssignString("boop")
275+
ma.AssembleEntry("lp").CreateMap(1, func(ma fluent.MapAssembler) {
276+
ma.AssembleEntry("field").AssignString("valoo")
277+
})
278+
}).(schema.TypedNode)
279+
t.Run("typed-read", func(t *testing.T) {
280+
qt.Assert(t, n.Kind(), qt.Equals, datamodel.Kind_Map)
281+
qt.Check(t, n.Length(), qt.Equals, int64(2))
282+
qt.Check(t, must.String(must.Node(n.LookupByString("str"))), qt.Equals, "boop")
283+
lp := must.Node(n.LookupByString("lp"))
284+
qt.Check(t, lp.Kind(), qt.Equals, datamodel.Kind_Map)
285+
qt.Check(t, must.String(must.Node(lp.LookupByString("field"))), qt.Equals, "valoo")
286+
})
287+
t.Run("repr-read", func(t *testing.T) {
288+
nr := n.Representation()
289+
qt.Assert(t, nr.Kind(), qt.Equals, datamodel.Kind_List)
290+
qt.Check(t, nr.Length(), qt.Equals, int64(2))
291+
kv := must.Node(nr.LookupByIndex(0))
292+
qt.Assert(t, nr.Kind(), qt.Equals, datamodel.Kind_List)
293+
qt.Check(t, kv.Length(), qt.Equals, int64(2))
294+
qt.Check(t, must.String(must.Node(kv.LookupByIndex(0))), qt.Equals, "str")
295+
qt.Check(t, must.String(must.Node(kv.LookupByIndex(1))), qt.Equals, "boop")
296+
kv = must.Node(nr.LookupByIndex(1))
297+
qt.Assert(t, nr.Kind(), qt.Equals, datamodel.Kind_List)
298+
qt.Check(t, kv.Length(), qt.Equals, int64(2))
299+
qt.Check(t, must.String(must.Node(kv.LookupByIndex(0))), qt.Equals, "lp")
300+
lp := must.Node(kv.LookupByIndex(1))
301+
qt.Check(t, lp.Kind(), qt.Equals, datamodel.Kind_List)
302+
kv = must.Node(lp.LookupByIndex(0))
303+
qt.Check(t, kv.Length(), qt.Equals, int64(2))
304+
qt.Check(t, must.String(must.Node(kv.LookupByIndex(0))), qt.Equals, "field")
305+
qt.Check(t, must.String(must.Node(kv.LookupByIndex(1))), qt.Equals, "valoo")
306+
})
307+
})
308+
t.Run("repr-create", func(t *testing.T) {
309+
nr := fluent.MustBuildList(nrp, 1, func(la fluent.ListAssembler) {
310+
la.AssembleValue().CreateList(2, func(la fluent.ListAssembler) {
311+
la.AssembleValue().AssignString("str")
312+
la.AssembleValue().AssignString("boop")
313+
})
314+
la.AssembleValue().CreateList(2, func(la fluent.ListAssembler) {
315+
la.AssembleValue().AssignString("lp")
316+
la.AssembleValue().CreateList(2, func(la fluent.ListAssembler) {
317+
la.AssembleValue().CreateList(2, func(la fluent.ListAssembler) {
318+
la.AssembleValue().AssignString("field")
319+
la.AssembleValue().AssignString("valoo")
320+
})
321+
})
322+
})
323+
})
324+
qt.Check(t, n, NodeContentEquals, nr)
325+
})
326+
})
260327
}

0 commit comments

Comments
 (0)