github.com/ipld/go-ipld-prime@v0.21.0/node/tests/schemaStruct.go (about)

     1  package tests
     2  
     3  import (
     4  	"testing"
     5  
     6  	qt "github.com/frankban/quicktest"
     7  
     8  	"github.com/ipld/go-ipld-prime/datamodel"
     9  	"github.com/ipld/go-ipld-prime/fluent"
    10  	"github.com/ipld/go-ipld-prime/must"
    11  	"github.com/ipld/go-ipld-prime/node/basicnode"
    12  	"github.com/ipld/go-ipld-prime/schema"
    13  )
    14  
    15  func SchemaTestRequiredFields(t *testing.T, engine Engine) {
    16  	ts := schema.TypeSystem{}
    17  	ts.Init()
    18  	ts.Accumulate(schema.SpawnString("String"))
    19  	ts.Accumulate(schema.SpawnStruct("StructOne",
    20  		[]schema.StructField{
    21  			schema.SpawnStructField("a", "String", false, false),
    22  			schema.SpawnStructField("b", "String", false, false),
    23  		},
    24  		schema.SpawnStructRepresentationMap(map[string]string{
    25  			// no renames.  we expect a simpler error message in this case.
    26  		}),
    27  	))
    28  	ts.Accumulate(schema.SpawnStruct("StructTwo",
    29  		[]schema.StructField{
    30  			schema.SpawnStructField("a", "String", false, false),
    31  			schema.SpawnStructField("b", "String", false, false),
    32  		},
    33  		schema.SpawnStructRepresentationMap(map[string]string{
    34  			"b": "z",
    35  		}),
    36  	))
    37  	engine.Init(t, ts)
    38  
    39  	t.Run("building-type-without-required-fields-errors", func(t *testing.T) {
    40  		np := engine.PrototypeByName("StructOne")
    41  
    42  		nb := np.NewBuilder()
    43  		ma, _ := nb.BeginMap(0)
    44  		err := ma.Finish()
    45  
    46  		qt.Check(t, err, qt.ErrorAs, &schema.ErrMissingRequiredField{})
    47  		qt.Check(t, err.Error(), qt.Equals, `missing required fields: a,b`)
    48  	})
    49  	t.Run("building-representation-without-required-fields-errors", func(t *testing.T) {
    50  		nrp := engine.PrototypeByName("StructOne.Repr")
    51  
    52  		nb := nrp.NewBuilder()
    53  		ma, _ := nb.BeginMap(0)
    54  		err := ma.Finish()
    55  
    56  		qt.Check(t, err, qt.ErrorAs, &schema.ErrMissingRequiredField{})
    57  		qt.Check(t, err.Error(), qt.Equals, `missing required fields: a,b`)
    58  	})
    59  	t.Run("building-representation-with-renames-without-required-fields-errors", func(t *testing.T) {
    60  		nrp := engine.PrototypeByName("StructTwo.Repr")
    61  
    62  		nb := nrp.NewBuilder()
    63  		ma, _ := nb.BeginMap(0)
    64  		err := ma.Finish()
    65  
    66  		qt.Check(t, err, qt.ErrorAs, &schema.ErrMissingRequiredField{})
    67  		qt.Check(t, err.Error(), qt.Equals, `missing required fields: a,b (serial:"z")`)
    68  	})
    69  }
    70  
    71  func SchemaTestStructNesting(t *testing.T, engine Engine) {
    72  	ts := schema.TypeSystem{}
    73  	ts.Init()
    74  	ts.Accumulate(schema.SpawnString("String"))
    75  	ts.Accumulate(schema.SpawnStruct("SmolStruct",
    76  		[]schema.StructField{
    77  			schema.SpawnStructField("s", "String", false, false),
    78  		},
    79  		schema.SpawnStructRepresentationMap(map[string]string{
    80  			"s": "q",
    81  		}),
    82  	))
    83  	ts.Accumulate(schema.SpawnStruct("GulpoStruct",
    84  		[]schema.StructField{
    85  			schema.SpawnStructField("x", "SmolStruct", false, false),
    86  		},
    87  		schema.SpawnStructRepresentationMap(map[string]string{
    88  			"x": "r",
    89  		}),
    90  	))
    91  	engine.Init(t, ts)
    92  
    93  	np := engine.PrototypeByName("GulpoStruct")
    94  	nrp := engine.PrototypeByName("GulpoStruct.Repr")
    95  	var n schema.TypedNode
    96  	t.Run("typed-create", func(t *testing.T) {
    97  		n = fluent.MustBuildMap(np, 1, func(ma fluent.MapAssembler) {
    98  			ma.AssembleEntry("x").CreateMap(1, func(ma fluent.MapAssembler) {
    99  				ma.AssembleEntry("s").AssignString("woo")
   100  			})
   101  		}).(schema.TypedNode)
   102  		t.Run("typed-read", func(t *testing.T) {
   103  			qt.Assert(t, n.Kind(), qt.Equals, datamodel.Kind_Map)
   104  			qt.Check(t, n.Length(), qt.Equals, int64(1))
   105  
   106  			n2 := must.Node(n.LookupByString("x"))
   107  			qt.Assert(t, n2.Kind(), qt.Equals, datamodel.Kind_Map)
   108  
   109  			n2Seg := must.Node(n.LookupBySegment(datamodel.PathSegmentOfString("x")))
   110  			qt.Check(t, n2, NodeContentEquals, n2Seg)
   111  
   112  			n2Node := must.Node(n.LookupByNode(basicnode.NewString("x")))
   113  			qt.Check(t, n2, NodeContentEquals, n2Node)
   114  
   115  			qt.Check(t, must.String(must.Node(n2.LookupByString("s"))), qt.Equals, "woo")
   116  		})
   117  		t.Run("repr-read", func(t *testing.T) {
   118  			nr := n.Representation()
   119  			qt.Assert(t, nr.Kind(), qt.Equals, datamodel.Kind_Map)
   120  			qt.Check(t, nr.Length(), qt.Equals, int64(1))
   121  
   122  			n2 := must.Node(nr.LookupByString("r"))
   123  			qt.Assert(t, n2.Kind(), qt.Equals, datamodel.Kind_Map)
   124  
   125  			n2Seg := must.Node(nr.LookupBySegment(datamodel.PathSegmentOfString("r")))
   126  			qt.Check(t, n2, NodeContentEquals, n2Seg)
   127  
   128  			n2Node := must.Node(nr.LookupByNode(basicnode.NewString("r")))
   129  			qt.Check(t, n2, NodeContentEquals, n2Node)
   130  
   131  			qt.Check(t, must.String(must.Node(n2.LookupByString("q"))), qt.Equals, "woo")
   132  		})
   133  	})
   134  	t.Run("repr-create", func(t *testing.T) {
   135  		nr := fluent.MustBuildMap(nrp, 1, func(ma fluent.MapAssembler) {
   136  			ma.AssembleEntry("r").CreateMap(1, func(ma fluent.MapAssembler) {
   137  				ma.AssembleEntry("q").AssignString("woo")
   138  			})
   139  		})
   140  		qt.Check(t, n, NodeContentEquals, nr)
   141  	})
   142  }