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

     1  package tests
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/ipld/go-ipld-prime/datamodel"
     7  	"github.com/ipld/go-ipld-prime/schema"
     8  )
     9  
    10  func SchemaTestUnionKeyed(t *testing.T, engine Engine) {
    11  	ts := schema.TypeSystem{}
    12  	ts.Init()
    13  	ts.Accumulate(schema.SpawnString("String"))
    14  	ts.Accumulate(schema.SpawnString("Strung"))
    15  	ts.Accumulate(schema.SpawnUnion("StrStr",
    16  		[]schema.TypeName{
    17  			"String",
    18  			"Strung",
    19  		},
    20  		schema.SpawnUnionRepresentationKeyed(map[string]schema.TypeName{
    21  			"a": "String",
    22  			"b": "Strung",
    23  		}),
    24  	))
    25  	engine.Init(t, ts)
    26  
    27  	specs := []testcase{
    28  		{
    29  			name:     "InhabitantA",
    30  			typeJson: `{"String":"whee"}`,
    31  			reprJson: `{"a":"whee"}`,
    32  			typePoints: []testcasePoint{
    33  				{"", datamodel.Kind_Map},
    34  				{"String", "whee"},
    35  				//{"Strung", datamodel.ErrNotExists{}}, // TODO: need better error typing from traversal package.
    36  			},
    37  			reprPoints: []testcasePoint{
    38  				{"", datamodel.Kind_Map},
    39  				{"a", "whee"},
    40  				//{"b", datamodel.ErrNotExists{}}, // TODO: need better error typing from traversal package.
    41  			},
    42  		},
    43  		{
    44  			name:     "InhabitantB",
    45  			typeJson: `{"Strung":"whee"}`,
    46  			reprJson: `{"b":"whee"}`,
    47  			typePoints: []testcasePoint{
    48  				{"", datamodel.Kind_Map},
    49  				//{"String", datamodel.ErrNotExists{}}, // TODO: need better error typing from traversal package.
    50  				{"Strung", "whee"},
    51  			},
    52  			reprPoints: []testcasePoint{
    53  				{"", datamodel.Kind_Map},
    54  				//{"a", datamodel.ErrNotExists{}}, // TODO: need better error typing from traversal package.
    55  				{"b", "whee"},
    56  			},
    57  		},
    58  	}
    59  
    60  	np := engine.PrototypeByName("StrStr")
    61  	nrp := engine.PrototypeByName("StrStr.Repr")
    62  	for _, tcase := range specs {
    63  		tcase.Test(t, np, nrp)
    64  	}
    65  }
    66  
    67  // Test keyed unions again, but this time with more complex types as children.
    68  //
    69  // The previous tests used scalar types as the children; this exercises most things,
    70  // but also has a couple (extremely non-obvious) simplifications:
    71  // namely, because the default representation for strings are "natural" representations,
    72  // the ReprAssemblers are actually aliases of the type-level Assemblers!
    73  // Aaaand that makes a few things "work" by coincidence that wouldn't otherwise fly.
    74  func SchemaTestUnionKeyedComplexChildren(t *testing.T, engine Engine) {
    75  	ts := schema.TypeSystem{}
    76  	ts.Init()
    77  	ts.Accumulate(schema.SpawnString("String"))
    78  	ts.Accumulate(schema.SpawnStruct("SmolStruct",
    79  		[]schema.StructField{
    80  			schema.SpawnStructField("s", "String", false, false),
    81  		},
    82  		schema.SpawnStructRepresentationMap(map[string]string{
    83  			"s": "q",
    84  		}),
    85  	))
    86  	ts.Accumulate(schema.SpawnUnion("WheeUnion",
    87  		[]schema.TypeName{
    88  			"String",
    89  			"SmolStruct",
    90  		},
    91  		schema.SpawnUnionRepresentationKeyed(map[string]schema.TypeName{
    92  			"a": "String",
    93  			"b": "SmolStruct",
    94  		}),
    95  	))
    96  	engine.Init(t, ts)
    97  
    98  	specs := []testcase{
    99  		{
   100  			name:     "InhabitantA",
   101  			typeJson: `{"String":"whee"}`,
   102  			reprJson: `{"a":"whee"}`,
   103  			typePoints: []testcasePoint{
   104  				{"", datamodel.Kind_Map},
   105  				{"String", "whee"},
   106  				//{"SmolStruct", datamodel.ErrNotExists{}}, // TODO: need better error typing from traversal package.
   107  			},
   108  			reprPoints: []testcasePoint{
   109  				{"", datamodel.Kind_Map},
   110  				{"a", "whee"},
   111  				//{"b", datamodel.ErrNotExists{}}, // TODO: need better error typing from traversal package.
   112  			},
   113  		},
   114  		{
   115  			name:     "InhabitantB",
   116  			typeJson: `{"SmolStruct":{"s":"whee"}}`,
   117  			reprJson: `{"b":{"q":"whee"}}`,
   118  			typePoints: []testcasePoint{
   119  				{"", datamodel.Kind_Map},
   120  				//{"String", datamodel.ErrNotExists{}}, // TODO: need better error typing from traversal package.
   121  				{"SmolStruct", datamodel.Kind_Map},
   122  				{"SmolStruct/s", "whee"},
   123  			},
   124  			reprPoints: []testcasePoint{
   125  				{"", datamodel.Kind_Map},
   126  				//{"a", datamodel.ErrNotExists{}}, // TODO: need better error typing from traversal package.
   127  				{"b", datamodel.Kind_Map},
   128  				{"b/q", "whee"},
   129  			},
   130  		},
   131  	}
   132  
   133  	np := engine.PrototypeByName("WheeUnion")
   134  	nrp := engine.PrototypeByName("WheeUnion.Repr")
   135  	for _, tcase := range specs {
   136  		tcase.Test(t, np, nrp)
   137  	}
   138  }
   139  
   140  // TestUnionKeyedReset puts a union inside a list, so that we can use the list's reuse of assembler as a test of the assembler's reset feature.
   141  // The value inside the union is also more complex than a scalar value so that we test resetting gets passed down, too.
   142  func SchemaTestUnionKeyedReset(t *testing.T, engine Engine) {
   143  	ts := schema.TypeSystem{}
   144  	ts.Init()
   145  	ts.Accumulate(schema.SpawnString("String"))
   146  	ts.Accumulate(schema.SpawnStruct("SmolStruct",
   147  		[]schema.StructField{
   148  			schema.SpawnStructField("s", "String", false, false),
   149  		},
   150  		schema.SpawnStructRepresentationMap(map[string]string{
   151  			"s": "q",
   152  		}),
   153  	))
   154  	ts.Accumulate(schema.SpawnUnion("WheeUnion",
   155  		[]schema.TypeName{
   156  			"String",
   157  			"SmolStruct",
   158  		},
   159  		schema.SpawnUnionRepresentationKeyed(map[string]schema.TypeName{
   160  			"a": "String",
   161  			"b": "SmolStruct",
   162  		}),
   163  	))
   164  	ts.Accumulate(schema.SpawnList("OuterList",
   165  		"WheeUnion", false,
   166  	))
   167  	engine.Init(t, ts)
   168  
   169  	specs := []testcase{
   170  		{
   171  			typeJson: `[{"SmolStruct":{"s":"one"}}, {"SmolStruct":{"s":"two"}}, {"String":"three"}]`,
   172  			reprJson: `[{"b":{"q":"one"}}, {"b":{"q":"two"}}, {"a":"three"}]`,
   173  			typePoints: []testcasePoint{
   174  				{"0/SmolStruct/s", "one"},
   175  				{"1/SmolStruct/s", "two"},
   176  				{"2/String", "three"},
   177  			},
   178  			reprPoints: []testcasePoint{
   179  				{"0/b/q", "one"},
   180  				{"1/b/q", "two"},
   181  				{"2/a", "three"},
   182  			},
   183  		},
   184  	}
   185  
   186  	np := engine.PrototypeByName("OuterList")
   187  	nrp := engine.PrototypeByName("OuterList.Repr")
   188  	for _, tcase := range specs {
   189  		tcase.Test(t, np, nrp)
   190  	}
   191  }