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 }