Skip to content

Commit

Permalink
fix(bindnode): listpairs value assembly handles complex reprs
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rvagg committed Jun 5, 2023
1 parent 557bc45 commit c951feb
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 3 deletions.
7 changes: 4 additions & 3 deletions node/bindnode/repr.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func (w *_nodeRepr) LookupByIndex(idx int64) (datamodel.Node, error) {
continue
}
if curField == idx {
return buildListpairsField(basicnode.NewString(field.Name()), value)
return buildListpairsField(basicnode.NewString(field.Name()), reprNode(value))
}
curField++
}
Expand Down Expand Up @@ -384,7 +384,7 @@ func (w *_listpairsIteratorRepr) Next() (index int64, value datamodel.Node, _ er
if value.IsAbsent() || w.nextIndex > w.reprEnd {
continue
}
field, err := buildListpairsField(key, value)
field, err := buildListpairsField(key, reprNode(value))
if err != nil {
return 0, nil, err
}
Expand Down Expand Up @@ -1167,7 +1167,8 @@ func (w *_listpairsFieldListAssemblerRepr) AssembleValue() datamodel.NodeAssembl
case 1:
return w.parent.AssembleKey()
case 2:
return w.parent.AssembleValue()
asm := w.parent.AssembleValue()
return assemblerRepr(asm.(*_assembler))
default:
return _errorAssembler{fmt.Errorf("bindnode: too many values in listpairs field")}
}
Expand Down
67 changes: 67 additions & 0 deletions node/tests/schemaStructReprListpairs.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ func SchemaTestStructReprListPairs(t *testing.T, engine Engine) {
},
schema.SpawnStructRepresentationListPairs(),
))
ts.Accumulate(schema.SpawnStruct("NestedListPairs",
[]schema.StructField{
schema.SpawnStructField("str", "String", false, false),
schema.SpawnStructField("lp", "OneListPair", false, false),
},
schema.SpawnStructRepresentationListPairs(),
))
engine.Init(t, ts)

t.Run("onelistpair works", func(t *testing.T) {
Expand Down Expand Up @@ -257,4 +264,64 @@ func SchemaTestStructReprListPairs(t *testing.T, engine Engine) {
qt.Check(t, n, NodeContentEquals, anr)
})
})

t.Run("nestedlistpairs works", func(t *testing.T) {
np := engine.PrototypeByName("NestedListPairs")
nrp := engine.PrototypeByName("NestedListPairs.Repr")
var n schema.TypedNode
t.Run("typed-create", func(t *testing.T) {
n = fluent.MustBuildMap(np, 1, func(ma fluent.MapAssembler) {
ma.AssembleEntry("str").AssignString("boop")
ma.AssembleEntry("lp").CreateMap(1, func(ma fluent.MapAssembler) {
ma.AssembleEntry("field").AssignString("valoo")
})
}).(schema.TypedNode)
t.Run("typed-read", func(t *testing.T) {
qt.Assert(t, n.Kind(), qt.Equals, datamodel.Kind_Map)
qt.Check(t, n.Length(), qt.Equals, int64(2))
qt.Check(t, must.String(must.Node(n.LookupByString("str"))), qt.Equals, "boop")
lp := must.Node(n.LookupByString("lp"))
qt.Check(t, lp.Kind(), qt.Equals, datamodel.Kind_Map)
qt.Check(t, must.String(must.Node(lp.LookupByString("field"))), qt.Equals, "valoo")
})
t.Run("repr-read", func(t *testing.T) {
nr := n.Representation()
qt.Assert(t, nr.Kind(), qt.Equals, datamodel.Kind_List)
qt.Check(t, nr.Length(), qt.Equals, int64(2))
kv := must.Node(nr.LookupByIndex(0))
qt.Assert(t, nr.Kind(), qt.Equals, datamodel.Kind_List)
qt.Check(t, kv.Length(), qt.Equals, int64(2))
qt.Check(t, must.String(must.Node(kv.LookupByIndex(0))), qt.Equals, "str")
qt.Check(t, must.String(must.Node(kv.LookupByIndex(1))), qt.Equals, "boop")
kv = must.Node(nr.LookupByIndex(1))
qt.Assert(t, nr.Kind(), qt.Equals, datamodel.Kind_List)
qt.Check(t, kv.Length(), qt.Equals, int64(2))
qt.Check(t, must.String(must.Node(kv.LookupByIndex(0))), qt.Equals, "lp")
lp := must.Node(kv.LookupByIndex(1))
qt.Check(t, lp.Kind(), qt.Equals, datamodel.Kind_List)
kv = must.Node(lp.LookupByIndex(0))
qt.Check(t, kv.Length(), qt.Equals, int64(2))
qt.Check(t, must.String(must.Node(kv.LookupByIndex(0))), qt.Equals, "field")
qt.Check(t, must.String(must.Node(kv.LookupByIndex(1))), qt.Equals, "valoo")
})
})
t.Run("repr-create", func(t *testing.T) {
nr := fluent.MustBuildList(nrp, 1, func(la fluent.ListAssembler) {
la.AssembleValue().CreateList(2, func(la fluent.ListAssembler) {
la.AssembleValue().AssignString("str")
la.AssembleValue().AssignString("boop")
})
la.AssembleValue().CreateList(2, func(la fluent.ListAssembler) {
la.AssembleValue().AssignString("lp")
la.AssembleValue().CreateList(2, func(la fluent.ListAssembler) {
la.AssembleValue().CreateList(2, func(la fluent.ListAssembler) {
la.AssembleValue().AssignString("field")
la.AssembleValue().AssignString("valoo")
})
})
})
})
qt.Check(t, n, NodeContentEquals, nr)
})
})
}

0 comments on commit c951feb

Please sign in to comment.