github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-runtime-src/runtime/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 grumpy
    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  }