github.com/pygolin/runtime@v0.0.0-20201208210830-a62e3cd39798/descriptor_test.go (about) 1 // Copyright 2016 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package runtime 16 17 import ( 18 "testing" 19 ) 20 21 func TestPropertyDelete(t *testing.T) { 22 dummy := newObject(ObjectType) 23 cases := []invokeTestCase{ 24 {args: wrapArgs(newProperty(nil, nil, wrapFuncForTest(func(f *Frame, o *Object) (*Object, *BaseException) { return None, nil })), dummy), want: None}, 25 {args: wrapArgs(newProperty(nil, nil, wrapFuncForTest(func(f *Frame, o *Object) (*Object, *BaseException) { return nil, f.RaiseType(ValueErrorType, "bar") })), dummy), wantExc: mustCreateException(ValueErrorType, "bar")}, 26 {args: wrapArgs(newProperty(nil, nil, nil), dummy), wantExc: mustCreateException(AttributeErrorType, "can't delete attribute")}, 27 } 28 for _, cas := range cases { 29 if err := runInvokeMethodTestCase(PropertyType, "__delete__", &cas); err != "" { 30 t.Error(err) 31 } 32 } 33 } 34 35 func TestPropertyGet(t *testing.T) { 36 dummy := newObject(ObjectType) 37 cases := []invokeTestCase{ 38 {args: wrapArgs(newProperty(wrapFuncForTest(func(f *Frame, o *Object) (*Object, *BaseException) { return o, nil }), nil, nil), dummy, ObjectType), want: dummy}, 39 {args: wrapArgs(newProperty(wrapFuncForTest(func(f *Frame, o *Object) (*Object, *BaseException) { return nil, f.RaiseType(ValueErrorType, "bar") }), nil, nil), dummy, ObjectType), wantExc: mustCreateException(ValueErrorType, "bar")}, 40 {args: wrapArgs(newProperty(nil, nil, nil), dummy, ObjectType), wantExc: mustCreateException(AttributeErrorType, "unreadable attribute")}, 41 } 42 for _, cas := range cases { 43 if err := runInvokeMethodTestCase(PropertyType, "__get__", &cas); err != "" { 44 t.Error(err) 45 } 46 } 47 } 48 49 func TestPropertyInit(t *testing.T) { 50 fun := wrapFuncForTest(func(f *Frame, args ...*Object) (*Object, *BaseException) { 51 o, raised := PropertyType.Call(f, args, nil) 52 if raised != nil { 53 return nil, raised 54 } 55 p := toPropertyUnsafe(o) 56 return newTestTuple(p.get, p.set, p.del).ToObject(), nil 57 }) 58 cases := []invokeTestCase{ 59 {want: NewTuple(None, None, None).ToObject()}, 60 {args: wrapArgs("foo"), want: newTestTuple("foo", None, None).ToObject()}, 61 {args: wrapArgs("foo", None), want: newTestTuple("foo", None, None).ToObject()}, 62 {args: wrapArgs("foo", None, "bar"), want: newTestTuple("foo", None, "bar").ToObject()}, 63 {args: wrapArgs(1, 2, 3, 4), wantExc: mustCreateException(TypeErrorType, "'__init__' requires 3 arguments")}, 64 } 65 for _, cas := range cases { 66 if err := runInvokeTestCase(fun, &cas); err != "" { 67 t.Error(err) 68 } 69 } 70 } 71 72 func TestPropertySet(t *testing.T) { 73 dummy := newObject(ObjectType) 74 cases := []invokeTestCase{ 75 {args: wrapArgs(newProperty(nil, wrapFuncForTest(func(_ *Frame, _, _ *Object) (*Object, *BaseException) { return None, nil }), nil), dummy, 123), want: None}, 76 {args: wrapArgs(newProperty(nil, wrapFuncForTest(func(f *Frame, _, _ *Object) (*Object, *BaseException) { return nil, f.RaiseType(ValueErrorType, "bar") }), nil), dummy, 123), wantExc: mustCreateException(ValueErrorType, "bar")}, 77 {args: wrapArgs(newProperty(nil, nil, nil), dummy, 123), wantExc: mustCreateException(AttributeErrorType, "can't set attribute")}, 78 } 79 for _, cas := range cases { 80 if err := runInvokeMethodTestCase(PropertyType, "__set__", &cas); err != "" { 81 t.Error(err) 82 } 83 } 84 } 85 86 func TestMakeStructFieldDescriptor(t *testing.T) { 87 e := mustNotRaise(RuntimeErrorType.Call(NewRootFrame(), wrapArgs("foo"), nil)) 88 fun := newBuiltinFunction("TestMakeStructFieldDescriptor", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) { 89 if raised := checkMethodArgs(f, "TestMakeStructFieldDescriptor", args, TypeType, StrType, StrType, ObjectType); raised != nil { 90 return nil, raised 91 } 92 t := toTypeUnsafe(args[0]) 93 desc := makeStructFieldDescriptor(t, toStrUnsafe(args[1]).Value(), toStrUnsafe(args[2]).Value(), fieldDescriptorRO) 94 get, raised := GetAttr(f, desc, NewStr("__get__"), nil) 95 if raised != nil { 96 return nil, raised 97 } 98 return get.Call(f, wrapArgs(args[3], t), nil) 99 }).ToObject() 100 cases := []invokeTestCase{ 101 {args: wrapArgs(ObjectType, "dict", "__dict__", newObject(ObjectType)), want: None}, 102 {args: wrapArgs(ObjectType, "dict", "__dict__", newBuiltinFunction("foo", func(*Frame, Args, KWArgs) (*Object, *BaseException) { return nil, nil })), want: NewDict().ToObject()}, 103 {args: wrapArgs(IntType, "value", "value", 42), want: NewInt(42).ToObject()}, 104 {args: wrapArgs(StrType, "value", "value", 42), wantExc: mustCreateException(TypeErrorType, "descriptor 'value' for 'str' objects doesn't apply to 'int' objects")}, 105 {args: wrapArgs(BaseExceptionType, "args", "args", e), want: NewTuple(NewStr("foo").ToObject()).ToObject()}, 106 } 107 for _, cas := range cases { 108 if err := runInvokeTestCase(fun, &cas); err != "" { 109 t.Error(err) 110 } 111 } 112 } 113 114 func TestMakeStructFieldDescriptorRWGet(t *testing.T) { 115 fun := newBuiltinFunction("TestMakeStructFieldDescriptorRW_get", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) { 116 if raised := checkMethodArgs(f, "TestMakeStructFieldDescriptorRW_get", args, TypeType, StrType, StrType, ObjectType); raised != nil { 117 return nil, raised 118 } 119 t := toTypeUnsafe(args[0]) 120 desc := makeStructFieldDescriptor(t, toStrUnsafe(args[1]).Value(), toStrUnsafe(args[2]).Value(), fieldDescriptorRW) 121 get, raised := GetAttr(f, desc, NewStr("__get__"), nil) 122 if raised != nil { 123 return nil, raised 124 } 125 return get.Call(f, wrapArgs(args[3], t), nil) 126 }).ToObject() 127 cases := []invokeTestCase{ 128 {args: wrapArgs(FileType, "Softspace", "softspace", newObject(FileType)), want: NewInt(0).ToObject()}, 129 {args: wrapArgs(FileType, "Softspace", "softspace", 42), wantExc: mustCreateException(TypeErrorType, "descriptor 'softspace' for 'file' objects doesn't apply to 'int' objects")}, 130 } 131 for _, cas := range cases { 132 if err := runInvokeTestCase(fun, &cas); err != "" { 133 t.Error(err) 134 } 135 } 136 } 137 138 func TestMakeStructFieldDescriptorRWSet(t *testing.T) { 139 fun := newBuiltinFunction("TestMakeStructFieldDescriptorRW_set", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) { 140 if raised := checkMethodArgs(f, "TestMakeStructFieldDescriptorRW_set", args, TypeType, StrType, StrType, ObjectType, ObjectType); raised != nil { 141 return nil, raised 142 } 143 t := toTypeUnsafe(args[0]) 144 desc := makeStructFieldDescriptor(t, toStrUnsafe(args[1]).Value(), toStrUnsafe(args[2]).Value(), fieldDescriptorRW) 145 set, raised := GetAttr(f, desc, NewStr("__set__"), nil) 146 if raised != nil { 147 return nil, raised 148 } 149 return set.Call(f, wrapArgs(args[3], args[4]), nil) 150 }).ToObject() 151 cases := []invokeTestCase{ 152 {args: wrapArgs(FileType, "Softspace", "softspace", newObject(FileType), NewInt(0).ToObject()), want: None}, 153 {args: wrapArgs(FileType, "Softspace", "softspace", newObject(FileType), NewInt(0)), want: None}, 154 {args: wrapArgs(FileType, "Softspace", "softspace", newObject(FileType), "wrong"), wantExc: mustCreateException(TypeErrorType, "an int is required")}, 155 {args: wrapArgs(FileType, "Softspace", "softspace", 42, NewInt(0)), wantExc: mustCreateException(TypeErrorType, "descriptor 'softspace' for 'file' objects doesn't apply to 'int' objects")}, 156 } 157 for _, cas := range cases { 158 if err := runInvokeTestCase(fun, &cas); err != "" { 159 t.Error(err) 160 } 161 } 162 }