github.com/ipld/go-ipld-prime@v0.21.0/node/tests/schemaScalars.go (about) 1 package tests 2 3 import ( 4 "fmt" 5 "testing" 6 7 qt "github.com/frankban/quicktest" 8 9 "github.com/ipld/go-ipld-prime/datamodel" 10 "github.com/ipld/go-ipld-prime/schema" 11 ) 12 13 func assignValue(am datamodel.NodeAssembler, value interface{}) error { 14 switch value := value.(type) { 15 case bool: 16 return am.AssignBool(value) 17 case int64: 18 return am.AssignInt(value) 19 case float64: 20 return am.AssignFloat(value) 21 case string: 22 return am.AssignString(value) 23 case []byte: 24 return am.AssignBytes(value) 25 default: 26 panic(fmt.Sprintf("%T", value)) 27 } 28 } 29 30 func SchemaTestScalars(t *testing.T, engine Engine) { 31 ts := schema.TypeSystem{} 32 ts.Init() 33 34 ts.Accumulate(schema.SpawnBool("Bool")) 35 ts.Accumulate(schema.SpawnInt("Int")) 36 ts.Accumulate(schema.SpawnFloat("Float")) 37 ts.Accumulate(schema.SpawnString("String")) 38 ts.Accumulate(schema.SpawnBytes("Bytes")) 39 engine.Init(t, ts) 40 41 var tests = []struct { 42 name string 43 kind datamodel.Kind 44 value interface{} 45 }{ 46 {"Bool", datamodel.Kind_Bool, true}, 47 {"Int", datamodel.Kind_Int, int64(23)}, 48 {"Float", datamodel.Kind_Float, 12.25}, 49 {"String", datamodel.Kind_String, "foo"}, 50 {"Bytes", datamodel.Kind_Bytes, []byte("bar")}, 51 } 52 53 // We test each of the five scalar prototypes in subtests. 54 for _, testProto := range tests { 55 56 // For both the regular node and its repr version, 57 // getting the right value for the kind should work. 58 for _, useRepr := range []bool{false, true} { 59 60 protoName := testProto.name 61 if useRepr { 62 protoName += ".Repr" 63 } 64 np := engine.PrototypeByName(protoName) 65 66 // For each prototype, we try assigning all scalar values. 67 for _, testAssign := range tests { 68 69 // We try both AssignKind and AssignNode. 70 for _, useAssignNode := range []bool{false, true} { 71 testName := fmt.Sprintf("%s-Assign%s", protoName, testAssign.name) 72 if useAssignNode { 73 testName = fmt.Sprintf("%s-AssignNode-%s", protoName, testAssign.name) 74 } 75 t.Run(testName, func(t *testing.T) { 76 nb := np.NewBuilder() 77 78 // Assigning null, a list, or a map, should always fail. 79 err := nb.AssignNull() 80 qt.Check(t, err, qt.Not(qt.IsNil)) 81 _, err = nb.BeginMap(-1) 82 qt.Check(t, err, qt.Not(qt.IsNil)) 83 _, err = nb.BeginList(-1) 84 qt.Check(t, err, qt.Not(qt.IsNil)) 85 86 // Assigning the right value for the kind should succeed. 87 if useAssignNode { 88 np2 := engine.PrototypeByName(testAssign.name) 89 nb2 := np2.NewBuilder() 90 qt.Check(t, assignValue(nb2, testAssign.value), qt.IsNil) 91 n2 := nb2.Build() 92 93 err = nb.AssignNode(n2) 94 } else { 95 err = assignValue(nb, testAssign.value) 96 } 97 if testAssign.kind == testProto.kind { 98 qt.Check(t, err, qt.IsNil) 99 } else { 100 qt.Check(t, err, qt.Not(qt.IsNil)) 101 102 // Assign something anyway, just so we can Build later. 103 err := assignValue(nb, testProto.value) 104 qt.Check(t, err, qt.IsNil) 105 } 106 107 n := nb.Build() 108 109 var gotValue interface{} 110 err = nil 111 switch testAssign.kind { 112 case datamodel.Kind_Bool: 113 gotValue, err = n.AsBool() 114 case datamodel.Kind_Int: 115 gotValue, err = n.AsInt() 116 case datamodel.Kind_Float: 117 gotValue, err = n.AsFloat() 118 case datamodel.Kind_String: 119 gotValue, err = n.AsString() 120 case datamodel.Kind_Bytes: 121 gotValue, err = n.AsBytes() 122 default: 123 t.Fatal(testAssign.kind) 124 } 125 if testAssign.kind == testProto.kind { 126 qt.Check(t, err, qt.IsNil) 127 qt.Check(t, gotValue, qt.DeepEquals, testAssign.value) 128 } else { 129 qt.Check(t, err, qt.Not(qt.IsNil)) 130 } 131 132 // Using Node methods which should never 133 // work on scalar kinds. 134 135 _, err = n.LookupByString("foo") 136 qt.Check(t, err, qt.Not(qt.IsNil)) 137 _, err = n.LookupByIndex(3) 138 qt.Check(t, err, qt.Not(qt.IsNil)) 139 qt.Check(t, n.MapIterator(), qt.IsNil) 140 qt.Check(t, n.ListIterator(), qt.IsNil) 141 qt.Check(t, n.Length(), qt.Equals, int64(-1)) 142 qt.Check(t, n.IsAbsent(), qt.IsFalse) 143 qt.Check(t, n.IsNull(), qt.IsFalse) 144 }) 145 } 146 } 147 } 148 } 149 }