github.com/google/grumpy@v0.0.0-20171122020858-3ec87959189c/runtime/core_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  	"fmt"
    19  	"math/big"
    20  	"reflect"
    21  	"regexp"
    22  	"runtime"
    23  	"testing"
    24  )
    25  
    26  func TestAssert(t *testing.T) {
    27  	assert := newBuiltinFunction("TestAssert", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
    28  		switch argc := len(args); argc {
    29  		case 1:
    30  			if raised := Assert(f, args[0], nil); raised != nil {
    31  				return nil, raised
    32  			}
    33  		case 2:
    34  			if raised := Assert(f, args[0], args[1]); raised != nil {
    35  				return nil, raised
    36  			}
    37  		default:
    38  			return nil, f.RaiseType(SystemErrorType, fmt.Sprintf("Assert expected 1 or 2 args, got %d", argc))
    39  		}
    40  		return None, nil
    41  	}).ToObject()
    42  	emptyAssert := toBaseExceptionUnsafe(mustNotRaise(AssertionErrorType.Call(NewRootFrame(), nil, nil)))
    43  	cases := []invokeTestCase{
    44  		{args: wrapArgs(true), want: None},
    45  		{args: wrapArgs(NewTuple(None)), want: None},
    46  		{args: wrapArgs(None), wantExc: emptyAssert},
    47  		{args: wrapArgs(NewDict()), wantExc: emptyAssert},
    48  		{args: wrapArgs(false, "foo"), wantExc: mustCreateException(AssertionErrorType, "foo")},
    49  	}
    50  	for _, cas := range cases {
    51  		if err := runInvokeTestCase(assert, &cas); err != "" {
    52  			t.Error(err)
    53  		}
    54  	}
    55  }
    56  
    57  func TestBinaryOps(t *testing.T) {
    58  	fooType := newTestClass("Foo", []*Type{ObjectType}, newStringDict(map[string]*Object{
    59  		"__add__": newBuiltinFunction("__add__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    60  			return NewStr("foo add").ToObject(), nil
    61  		}).ToObject(),
    62  		"__radd__": newBuiltinFunction("__add__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    63  			return NewStr("foo radd").ToObject(), nil
    64  		}).ToObject(),
    65  	}))
    66  	barType := newTestClass("Bar", []*Type{fooType}, NewDict())
    67  	bazType := newTestClass("Baz", []*Type{IntType}, newStringDict(map[string]*Object{
    68  		"__rdiv__": newBuiltinFunction("__rdiv__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    69  			s, raised := ToStr(f, args[1])
    70  			if raised != nil {
    71  				return nil, raised
    72  			}
    73  			return s.ToObject(), nil
    74  		}).ToObject(),
    75  	}))
    76  	inplaceType := newTestClass("Inplace", []*Type{ObjectType}, newStringDict(map[string]*Object{
    77  		"__iadd__": newBuiltinFunction("__iadd__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    78  			return args[1], nil
    79  		}).ToObject(),
    80  		"__iand__": newBuiltinFunction("__iand__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    81  			return args[1], nil
    82  		}).ToObject(),
    83  		"__idiv__": newBuiltinFunction("__idiv__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    84  			return args[1], nil
    85  		}).ToObject(),
    86  		"__ilshift__": newBuiltinFunction("__ilshift__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    87  			return args[1], nil
    88  		}).ToObject(),
    89  		"__imod__": newBuiltinFunction("__imod__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    90  			return args[1], nil
    91  		}).ToObject(),
    92  		"__imul__": newBuiltinFunction("__imul__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    93  			return args[1], nil
    94  		}).ToObject(),
    95  		"__ior__": newBuiltinFunction("__ior__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    96  			return args[1], nil
    97  		}).ToObject(),
    98  		"__irshift__": newBuiltinFunction("__irshift__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
    99  			return args[1], nil
   100  		}).ToObject(),
   101  		"__isub__": newBuiltinFunction("__isub__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   102  			return args[1], nil
   103  		}).ToObject(),
   104  		"__ixor__": newBuiltinFunction("__ixor__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   105  			return args[1], nil
   106  		}).ToObject(),
   107  	}))
   108  	cases := []struct {
   109  		fun     func(f *Frame, v, w *Object) (*Object, *BaseException)
   110  		v, w    *Object
   111  		want    *Object
   112  		wantExc *BaseException
   113  	}{
   114  		{Add, NewStr("foo").ToObject(), NewStr("bar").ToObject(), NewStr("foobar").ToObject(), nil},
   115  		{Add, NewStr("foo").ToObject(), NewStr("bar").ToObject(), NewStr("foobar").ToObject(), nil},
   116  		{Add, newObject(fooType), newObject(ObjectType), NewStr("foo add").ToObject(), nil},
   117  		{And, NewInt(-42).ToObject(), NewInt(244).ToObject(), NewInt(212).ToObject(), nil},
   118  		{And, NewInt(42).ToObject(), NewStr("foo").ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for &: 'int' and 'str'")},
   119  		{Add, newObject(fooType), newObject(barType), NewStr("foo add").ToObject(), nil},
   120  		{Div, NewInt(123).ToObject(), newObject(bazType), NewStr("123").ToObject(), nil},
   121  		{IAdd, NewStr("foo").ToObject(), NewStr("bar").ToObject(), NewStr("foobar").ToObject(), nil},
   122  		{IAdd, NewStr("foo").ToObject(), NewStr("bar").ToObject(), NewStr("foobar").ToObject(), nil},
   123  		{IAdd, newObject(fooType), newObject(ObjectType), NewStr("foo add").ToObject(), nil},
   124  		{IAdd, newObject(inplaceType), NewStr("foo").ToObject(), NewStr("foo").ToObject(), nil},
   125  		{IAnd, NewInt(9).ToObject(), NewInt(12).ToObject(), NewInt(8).ToObject(), nil},
   126  		{IAnd, newObject(inplaceType), NewStr("foo").ToObject(), NewStr("foo").ToObject(), nil},
   127  		{IAnd, newObject(ObjectType), newObject(fooType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for &: 'object' and 'Foo'")},
   128  		{IDiv, NewInt(123).ToObject(), newObject(bazType), NewStr("123").ToObject(), nil},
   129  		{IDiv, newObject(inplaceType), NewInt(42).ToObject(), NewInt(42).ToObject(), nil},
   130  		{ILShift, newObject(inplaceType), NewInt(123).ToObject(), NewInt(123).ToObject(), nil},
   131  		{IMod, NewInt(24).ToObject(), NewInt(6).ToObject(), NewInt(0).ToObject(), nil},
   132  		{IMod, newObject(inplaceType), NewFloat(3.14).ToObject(), NewFloat(3.14).ToObject(), nil},
   133  		{IMul, NewStr("foo").ToObject(), NewInt(3).ToObject(), NewStr("foofoofoo").ToObject(), nil},
   134  		{IMul, newObject(inplaceType), True.ToObject(), True.ToObject(), nil},
   135  		{IMul, newObject(ObjectType), newObject(fooType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for *: 'object' and 'Foo'")},
   136  		{IOr, newObject(inplaceType), NewInt(42).ToObject(), NewInt(42).ToObject(), nil},
   137  		{IOr, NewInt(9).ToObject(), NewInt(12).ToObject(), NewInt(13).ToObject(), nil},
   138  		{IOr, newObject(ObjectType), newObject(fooType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for |: 'object' and 'Foo'")},
   139  		{IRShift, newObject(inplaceType), NewInt(123).ToObject(), NewInt(123).ToObject(), nil},
   140  		{ISub, NewInt(3).ToObject(), NewInt(-3).ToObject(), NewInt(6).ToObject(), nil},
   141  		{ISub, newObject(inplaceType), None, None, nil},
   142  		{IXor, newObject(inplaceType), None, None, nil},
   143  		{IXor, NewInt(9).ToObject(), NewInt(12).ToObject(), NewInt(5).ToObject(), nil},
   144  		{IXor, newObject(ObjectType), newObject(fooType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for ^: 'object' and 'Foo'")},
   145  		{Mod, NewInt(24).ToObject(), NewInt(6).ToObject(), NewInt(0).ToObject(), nil},
   146  		{Mul, NewStr("foo").ToObject(), NewInt(3).ToObject(), NewStr("foofoofoo").ToObject(), nil},
   147  		{Mul, newObject(ObjectType), newObject(fooType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for *: 'object' and 'Foo'")},
   148  		{Or, NewInt(-42).ToObject(), NewInt(244).ToObject(), NewInt(-10).ToObject(), nil},
   149  		{Or, NewInt(42).ToObject(), NewStr("foo").ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for |: 'int' and 'str'")},
   150  		{Pow, NewInt(2).ToObject(), NewInt(-2).ToObject(), NewFloat(0.25).ToObject(), nil},
   151  		{Pow, NewInt(2).ToObject(), newObject(fooType), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for **: 'int' and 'Foo'")},
   152  		{Sub, NewInt(3).ToObject(), NewInt(-3).ToObject(), NewInt(6).ToObject(), nil},
   153  		{Xor, NewInt(-42).ToObject(), NewInt(244).ToObject(), NewInt(-222).ToObject(), nil},
   154  		{Xor, NewInt(42).ToObject(), NewStr("foo").ToObject(), nil, mustCreateException(TypeErrorType, "unsupported operand type(s) for ^: 'int' and 'str'")},
   155  	}
   156  	for _, cas := range cases {
   157  		testCase := invokeTestCase{wrapArgs(cas.v, cas.w), nil, cas.want, cas.wantExc}
   158  		if err := runInvokeTestCase(wrapFuncForTest(cas.fun), &testCase); err != "" {
   159  			t.Error(err)
   160  		}
   161  	}
   162  }
   163  
   164  func TestCompare(t *testing.T) {
   165  	badCmpType := newTestClass("BadCmp", []*Type{ObjectType}, newStringDict(map[string]*Object{
   166  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   167  			return nil, f.RaiseType(TypeErrorType, "uh oh")
   168  		}).ToObject(),
   169  	}))
   170  	cmpLtType := newTestClass("Lt", []*Type{ObjectType}, newStringDict(map[string]*Object{
   171  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   172  			return NewInt(-1).ToObject(), nil
   173  		}).ToObject(),
   174  	}))
   175  	cmpEqType := newTestClass("Eq", []*Type{ObjectType}, newStringDict(map[string]*Object{
   176  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   177  			return NewInt(0).ToObject(), nil
   178  		}).ToObject(),
   179  	}))
   180  	cmpGtType := newTestClass("Gt", []*Type{ObjectType}, newStringDict(map[string]*Object{
   181  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   182  			return NewInt(1).ToObject(), nil
   183  		}).ToObject(),
   184  	}))
   185  	cmpByEqType := newTestClass("EqCmp", []*Type{IntType}, newStringDict(map[string]*Object{
   186  		"__eq__": newBuiltinFunction("__eq__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   187  			return True.ToObject(), nil
   188  		}).ToObject(),
   189  	}))
   190  	badCmpByEqType := newTestClass("BadEqCmp", []*Type{IntType}, newStringDict(map[string]*Object{
   191  		"__eq__": newBuiltinFunction("__eq__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   192  			return nil, f.RaiseType(TypeErrorType, "uh oh")
   193  		}).ToObject(),
   194  	}))
   195  	badNonZeroType := newTestClass("BadNonZeroType", []*Type{ObjectType}, newStringDict(map[string]*Object{
   196  		"__nonzero__": newBuiltinFunction("__nonzero__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   197  			return nil, f.RaiseType(TypeErrorType, "uh oh")
   198  		}).ToObject(),
   199  	}))
   200  	worseCmpByEqType := newTestClass("WorseEqCmp", []*Type{IntType}, newStringDict(map[string]*Object{
   201  		"__eq__": newBuiltinFunction("__eq__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   202  			return newObject(badNonZeroType), nil
   203  		}).ToObject(),
   204  	}))
   205  	cmpNonIntResultType := newTestClass("CmpNonIntResult", []*Type{ObjectType}, newStringDict(map[string]*Object{
   206  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   207  			return NewStr("foo").ToObject(), nil
   208  		}).ToObject(),
   209  	}))
   210  	cases := []invokeTestCase{
   211  		// Test `__cmp__` less than.
   212  		{args: wrapArgs(newObject(cmpLtType), None), want: NewInt(-1).ToObject()},
   213  		{args: wrapArgs(None, newObject(cmpGtType)), want: NewInt(-1).ToObject()},
   214  		// Test `__cmp__` equals.
   215  		{args: wrapArgs(newObject(cmpEqType), None), want: NewInt(0).ToObject()},
   216  		{args: wrapArgs(None, newObject(cmpEqType)), want: NewInt(0).ToObject()},
   217  		// Test `__cmp__` greater than.
   218  		{args: wrapArgs(newObject(cmpGtType), None), want: NewInt(1).ToObject()},
   219  		{args: wrapArgs(None, newObject(cmpLtType)), want: NewInt(1).ToObject()},
   220  		// Test `__cmp__` fallback to rich comparison.
   221  		{args: wrapArgs(newObject(cmpByEqType), None), want: NewInt(0).ToObject()},
   222  		{args: wrapArgs(None, newObject(cmpByEqType)), want: NewInt(0).ToObject()},
   223  		// Test bad `__cmp__` fallback to rich comparison.
   224  		{args: wrapArgs(newObject(badCmpByEqType), None), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   225  		{args: wrapArgs(None, newObject(badCmpByEqType)), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   226  		// Test bad `__cmp__` fallback to rich comparison where a bad object is returned from `__eq__`.
   227  		{args: wrapArgs(newObject(worseCmpByEqType), None), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   228  		{args: wrapArgs(None, newObject(worseCmpByEqType)), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   229  		// Test bad `__cmp__`.
   230  		{args: wrapArgs(newObject(badCmpType), None), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   231  		{args: wrapArgs(None, newObject(badCmpType)), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   232  		// Test bad `__cmp__` with non-int result.
   233  		{args: wrapArgs(newObject(cmpNonIntResultType), None), wantExc: mustCreateException(TypeErrorType, "an integer is required")},
   234  		{args: wrapArgs(None, newObject(cmpNonIntResultType)), wantExc: mustCreateException(TypeErrorType, "an integer is required")},
   235  	}
   236  	for _, cas := range cases {
   237  		if err := runInvokeTestCase(wrapFuncForTest(Compare), &cas); err != "" {
   238  			t.Error(err)
   239  		}
   240  	}
   241  }
   242  
   243  func TestCompareDefault(t *testing.T) {
   244  	o1, o2 := newObject(ObjectType), newObject(ObjectType)
   245  	// Make sure uintptr(o1) < uintptr(o2).
   246  	if uintptr(o1.toPointer()) > uintptr(o2.toPointer()) {
   247  		o1, o2 = o2, o1
   248  	}
   249  	// When type names are equal, comparison should fall back to comparing
   250  	// the pointer values of the types of the objects.
   251  	fakeObjectType := newTestClass("object", []*Type{ObjectType}, NewDict())
   252  	o3, o4 := newObject(fakeObjectType), newObject(ObjectType)
   253  	if uintptr(o3.typ.toPointer()) > uintptr(o4.typ.toPointer()) {
   254  		o3, o4 = o4, o3
   255  	}
   256  	// An int subtype that equals anything, but doesn't override other
   257  	// comparison methods.
   258  	eqType := newTestClass("Eq", []*Type{IntType}, newStringDict(map[string]*Object{
   259  		"__eq__": newBuiltinFunction("__eq__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   260  			return True.ToObject(), nil
   261  		}).ToObject(),
   262  		"__repr__": newBuiltinFunction("__repr__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   263  			return NewStr("<Foo>").ToObject(), nil
   264  		}).ToObject(),
   265  	}))
   266  	cases := []invokeTestCase{
   267  		{args: wrapArgs(true, o1), want: compareAllResultLT},
   268  		{args: wrapArgs(o1, -306), want: compareAllResultGT},
   269  		{args: wrapArgs(-306, o1), want: compareAllResultLT},
   270  		{args: wrapArgs(NewList(), None), want: compareAllResultGT},
   271  		{args: wrapArgs(None, "foo"), want: compareAllResultLT},
   272  		{args: wrapArgs(o1, o1), want: compareAllResultEq},
   273  		{args: wrapArgs(o1, o2), want: compareAllResultLT},
   274  		{args: wrapArgs(o2, o1), want: compareAllResultGT},
   275  		{args: wrapArgs(o3, o4), want: compareAllResultLT},
   276  		{args: wrapArgs(o4, o3), want: compareAllResultGT},
   277  		// The equality test should dispatch to the eqType instance and
   278  		// return true.
   279  		{args: wrapArgs(42, newObject(eqType)), want: newTestTuple(false, false, true, true, true, true).ToObject()},
   280  	}
   281  	for _, cas := range cases {
   282  		if err := runInvokeTestCase(compareAll, &cas); err != "" {
   283  			t.Error(err)
   284  		}
   285  	}
   286  }
   287  
   288  func TestContains(t *testing.T) {
   289  	cases := []invokeTestCase{
   290  		{args: wrapArgs(NewTuple(), 42), want: False.ToObject()},
   291  		{args: wrapArgs(newTestList("foo", "bar"), "bar"), want: True.ToObject()},
   292  		{args: wrapArgs(newTestDict(1, "foo", 2, "bar", 3, "baz"), 2), want: True.ToObject()},
   293  		{args: wrapArgs("foobar", "ooba"), want: True.ToObject()},
   294  		{args: wrapArgs("qux", "ooba"), want: False.ToObject()},
   295  		{args: wrapArgs(3.14, None), wantExc: mustCreateException(TypeErrorType, "'float' object is not iterable")},
   296  	}
   297  	for _, cas := range cases {
   298  		if err := runInvokeTestCase(wrapFuncForTest(Contains), &cas); err != "" {
   299  			t.Error(err)
   300  		}
   301  	}
   302  }
   303  
   304  // DelAttr is tested in TestObjectDelAttr.
   305  
   306  func TestDelItem(t *testing.T) {
   307  	delItem := newBuiltinFunction("TestDelItem", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   308  		if raised := checkFunctionArgs(f, "TestDelItem", args, ObjectType, ObjectType); raised != nil {
   309  			return nil, raised
   310  		}
   311  		o := args[0]
   312  		if raised := DelItem(f, o, args[1]); raised != nil {
   313  			return nil, raised
   314  		}
   315  		return args[0], nil
   316  	}).ToObject()
   317  	cases := []invokeTestCase{
   318  		{args: wrapArgs(newTestDict("foo", None), "foo"), want: NewDict().ToObject()},
   319  		{args: wrapArgs(NewDict(), "foo"), wantExc: mustCreateException(KeyErrorType, "foo")},
   320  		{args: wrapArgs(123, "bar"), wantExc: mustCreateException(TypeErrorType, "'int' object does not support item deletion")},
   321  	}
   322  	for _, cas := range cases {
   323  		if err := runInvokeTestCase(delItem, &cas); err != "" {
   324  			t.Error(err)
   325  		}
   326  	}
   327  }
   328  
   329  func TestFormatException(t *testing.T) {
   330  	fun := wrapFuncForTest(func(f *Frame, t *Type, args ...*Object) (string, *BaseException) {
   331  		e, raised := t.Call(f, args, nil)
   332  		if raised != nil {
   333  			return "", raised
   334  		}
   335  		f.Raise(e, nil, nil)
   336  		s := FormatExc(f)
   337  		f.RestoreExc(nil, nil)
   338  		return s, nil
   339  	})
   340  	cases := []invokeTestCase{
   341  		{args: wrapArgs(ExceptionType), want: NewStr("Exception\n").ToObject()},
   342  		{args: wrapArgs(AttributeErrorType, ""), want: NewStr("AttributeError\n").ToObject()},
   343  		{args: wrapArgs(TypeErrorType, 123), want: NewStr("TypeError: 123\n").ToObject()},
   344  		{args: wrapArgs(AttributeErrorType, "hello", "there"), want: NewStr("AttributeError: ('hello', 'there')\n").ToObject()},
   345  	}
   346  	for _, cas := range cases {
   347  		if err := runInvokeTestCase(fun, &cas); err != "" {
   348  			t.Error(err)
   349  		}
   350  	}
   351  }
   352  
   353  func TestGetAttr(t *testing.T) {
   354  	getAttr := newBuiltinFunction("TestGetAttr", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   355  		expectedTypes := []*Type{ObjectType, StrType, ObjectType}
   356  		argc := len(args)
   357  		if argc == 2 {
   358  			expectedTypes = expectedTypes[:2]
   359  		}
   360  		if raised := checkFunctionArgs(f, "TestGetAttr", args, expectedTypes...); raised != nil {
   361  			return nil, raised
   362  		}
   363  		var def *Object
   364  		if argc > 2 {
   365  			def = args[2]
   366  		}
   367  		s, raised := ToStr(f, args[1])
   368  		if raised != nil {
   369  			return nil, raised
   370  		}
   371  		return GetAttr(f, args[0], s, def)
   372  	}).ToObject()
   373  	fooResult := newObject(ObjectType)
   374  	fooType := newTestClass("Foo", []*Type{ObjectType}, newStringDict(map[string]*Object{
   375  		"__getattribute__": newBuiltinFunction("__getattribute__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   376  			return fooResult, nil
   377  		}).ToObject(),
   378  	}))
   379  	barType := newTestClass("Bar", []*Type{ObjectType}, newStringDict(map[string]*Object{
   380  		"__getattribute__": newBuiltinFunction("__getattribute__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   381  			return nil, f.RaiseType(TypeErrorType, "uh oh")
   382  		}).ToObject(),
   383  	}))
   384  	cases := []invokeTestCase{
   385  		{args: wrapArgs(newObject(fooType), "bar"), want: fooResult},
   386  		{args: wrapArgs(newObject(fooType), "baz", None), want: fooResult},
   387  		{args: wrapArgs(newObject(ObjectType), "qux", None), want: None},
   388  		{args: wrapArgs(NewTuple(), "noexist"), wantExc: mustCreateException(AttributeErrorType, "'tuple' object has no attribute 'noexist'")},
   389  		{args: wrapArgs(DictType, "noexist"), wantExc: mustCreateException(AttributeErrorType, "type object 'dict' has no attribute 'noexist'")},
   390  		{args: wrapArgs(newObject(barType), "noexist"), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   391  	}
   392  	for _, cas := range cases {
   393  		if err := runInvokeTestCase(getAttr, &cas); err != "" {
   394  			t.Error(err)
   395  		}
   396  	}
   397  }
   398  
   399  func TestGetItem(t *testing.T) {
   400  	cases := []invokeTestCase{
   401  		{args: wrapArgs(newStringDict(map[string]*Object{"foo": None}), "foo"), want: None},
   402  		{args: wrapArgs(NewDict(), "bar"), wantExc: mustCreateException(KeyErrorType, "bar")},
   403  		{args: wrapArgs(true, "baz"), wantExc: mustCreateException(TypeErrorType, "'bool' object has no attribute '__getitem__'")},
   404  	}
   405  	for _, cas := range cases {
   406  		if err := runInvokeTestCase(wrapFuncForTest(GetItem), &cas); err != "" {
   407  			t.Error(err)
   408  		}
   409  	}
   410  }
   411  
   412  func TestHash(t *testing.T) {
   413  	badHash := newTestClass("badHash", []*Type{ObjectType}, newStringDict(map[string]*Object{
   414  		"__hash__": newBuiltinFunction("__hash__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   415  			return args[0], nil
   416  		}).ToObject(),
   417  	}))
   418  	o := newObject(ObjectType)
   419  	cases := []invokeTestCase{
   420  		{args: wrapArgs("foo"), want: hashFoo},
   421  		{args: wrapArgs(123), want: NewInt(123).ToObject()},
   422  		{args: wrapArgs(o), want: NewInt(int(uintptr(o.toPointer()))).ToObject()},
   423  		{args: wrapArgs(NewList()), wantExc: mustCreateException(TypeErrorType, "unhashable type: 'list'")},
   424  		{args: wrapArgs(NewDict()), wantExc: mustCreateException(TypeErrorType, "unhashable type: 'dict'")},
   425  		{args: wrapArgs(newObject(badHash)), wantExc: mustCreateException(TypeErrorType, "an integer is required")},
   426  	}
   427  	for _, cas := range cases {
   428  		if err := runInvokeTestCase(wrapFuncForTest(Hash), &cas); err != "" {
   429  			t.Error(err)
   430  		}
   431  	}
   432  }
   433  
   434  func TestHex(t *testing.T) {
   435  	badHex := newTestClass("badHex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   436  		"__hex__": newBuiltinFunction("__hex__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   437  			return NewInt(123).ToObject(), nil
   438  		}).ToObject(),
   439  	}))
   440  	goodHex := newTestClass("goodHex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   441  		"__hex__": newBuiltinFunction("__hex__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   442  			return NewStr("0x123").ToObject(), nil
   443  		}).ToObject(),
   444  	}))
   445  	cases := []invokeTestCase{
   446  		{args: wrapArgs(-123), want: NewStr("-0x7b").ToObject()},
   447  		{args: wrapArgs(123), want: NewStr("0x7b").ToObject()},
   448  		{args: wrapArgs(newObject(goodHex)), want: NewStr("0x123").ToObject()},
   449  		{args: wrapArgs(NewList()), wantExc: mustCreateException(TypeErrorType, "hex() argument can't be converted to hex")},
   450  		{args: wrapArgs(NewDict()), wantExc: mustCreateException(TypeErrorType, "hex() argument can't be converted to hex")},
   451  		{args: wrapArgs(newObject(badHex)), wantExc: mustCreateException(TypeErrorType, "__hex__ returned non-string (type int)")},
   452  	}
   453  	for _, cas := range cases {
   454  		if err := runInvokeTestCase(wrapFuncForTest(Hex), &cas); err != "" {
   455  			t.Error(err)
   456  		}
   457  	}
   458  }
   459  
   460  func TestIndex(t *testing.T) {
   461  	goodType := newTestClass("GoodIndex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   462  		"__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   463  			return NewInt(123).ToObject(), nil
   464  		}).ToObject(),
   465  	}))
   466  	longType := newTestClass("LongIndex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   467  		"__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   468  			return NewLong(big.NewInt(123)).ToObject(), nil
   469  		}).ToObject(),
   470  	}))
   471  	raiseType := newTestClass("RaiseIndex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   472  		"__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   473  			return nil, f.RaiseType(RuntimeErrorType, "uh oh")
   474  		}).ToObject(),
   475  	}))
   476  	badType := newTestClass("BadIndex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   477  		"__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   478  			return NewFloat(3.14).ToObject(), nil
   479  		}).ToObject(),
   480  	}))
   481  	cases := []invokeTestCase{
   482  		{args: wrapArgs(42), want: NewInt(42).ToObject()},
   483  		{args: wrapArgs(newObject(goodType)), want: NewInt(123).ToObject()},
   484  		{args: wrapArgs(newObject(longType)), want: NewLong(big.NewInt(123)).ToObject()},
   485  		{args: wrapArgs(newObject(raiseType)), wantExc: mustCreateException(RuntimeErrorType, "uh oh")},
   486  		{args: wrapArgs(newObject(badType)), wantExc: mustCreateException(TypeErrorType, "__index__ returned non-(int,long) (type float)")},
   487  		{args: wrapArgs("abc"), want: None},
   488  	}
   489  	for _, cas := range cases {
   490  		if err := runInvokeTestCase(wrapFuncForTest(Index), &cas); err != "" {
   491  			t.Error(err)
   492  		}
   493  	}
   494  	cases = []invokeTestCase{
   495  		{args: wrapArgs(42), want: NewInt(42).ToObject()},
   496  		{args: wrapArgs(newObject(goodType)), want: NewInt(123).ToObject()},
   497  		{args: wrapArgs(newObject(raiseType)), wantExc: mustCreateException(RuntimeErrorType, "uh oh")},
   498  	}
   499  	for _, cas := range cases {
   500  		if err := runInvokeMethodTestCase(cas.args[0].typ, "__index__", &cas); err != "" {
   501  			t.Error(err)
   502  		}
   503  	}
   504  }
   505  
   506  func TestInvert(t *testing.T) {
   507  	cases := []invokeTestCase{
   508  		{args: wrapArgs(42), want: NewInt(-43).ToObject()},
   509  		{args: wrapArgs(0), want: NewInt(-1).ToObject()},
   510  		{args: wrapArgs(-35935), want: NewInt(35934).ToObject()},
   511  		{args: wrapArgs("foo"), wantExc: mustCreateException(TypeErrorType, "bad operand type for unary ~: 'str'")},
   512  	}
   513  	for _, cas := range cases {
   514  		if err := runInvokeTestCase(wrapFuncForTest(Invert), &cas); err != "" {
   515  			t.Error(err)
   516  		}
   517  	}
   518  }
   519  
   520  func TestIsInstanceIsSubclass(t *testing.T) {
   521  	fooType := newTestClass("Foo", []*Type{ObjectType}, NewDict())
   522  	barType := newTestClass("Bar", []*Type{fooType, IntType}, NewDict())
   523  	cases := []struct {
   524  		o         *Object
   525  		classinfo *Object
   526  		want      *Object
   527  		wantExc   *BaseException
   528  	}{
   529  		{newObject(ObjectType), ObjectType.ToObject(), True.ToObject(), nil},
   530  		{NewInt(42).ToObject(), StrType.ToObject(), False.ToObject(), nil},
   531  		{None, NewTuple(NoneType.ToObject(), IntType.ToObject()).ToObject(), True.ToObject(), nil},
   532  		{NewStr("foo").ToObject(), NewTuple(NoneType.ToObject(), IntType.ToObject()).ToObject(), False.ToObject(), nil},
   533  		{NewStr("foo").ToObject(), NewTuple(IntType.ToObject(), NoneType.ToObject()).ToObject(), False.ToObject(), nil},
   534  		{None, NewTuple().ToObject(), False.ToObject(), nil},
   535  		{newObject(barType), fooType.ToObject(), True.ToObject(), nil},
   536  		{newObject(barType), IntType.ToObject(), True.ToObject(), nil},
   537  		{newObject(fooType), IntType.ToObject(), False.ToObject(), nil},
   538  		{newObject(ObjectType), None, nil, mustCreateException(TypeErrorType, "classinfo must be a type or tuple of types")},
   539  		{newObject(ObjectType), NewTuple(None).ToObject(), nil, mustCreateException(TypeErrorType, "classinfo must be a type or tuple of types")},
   540  	}
   541  	for _, cas := range cases {
   542  		// IsInstance
   543  		testCase := invokeTestCase{args: wrapArgs(cas.o, cas.classinfo), want: cas.want, wantExc: cas.wantExc}
   544  		if err := runInvokeTestCase(wrapFuncForTest(IsInstance), &testCase); err != "" {
   545  			t.Error(err)
   546  		}
   547  		// IsSubclass
   548  		testCase.args = wrapArgs(cas.o.Type(), cas.classinfo)
   549  		if err := runInvokeTestCase(wrapFuncForTest(IsSubclass), &testCase); err != "" {
   550  			t.Error(err)
   551  		}
   552  	}
   553  	// Test that IsSubclass raises when first arg is not a type.
   554  	testCase := invokeTestCase{args: wrapArgs(None, NoneType), wantExc: mustCreateException(TypeErrorType, "issubclass() arg 1 must be a class")}
   555  	if err := runInvokeTestCase(wrapFuncForTest(IsSubclass), &testCase); err != "" {
   556  		t.Error(err)
   557  	}
   558  }
   559  
   560  func TestIsTrue(t *testing.T) {
   561  	badNonZeroType := newTestClass("BadNonZeroType", []*Type{ObjectType}, newStringDict(map[string]*Object{
   562  		"__nonzero__": newBuiltinFunction("__nonzero__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   563  			return None, nil
   564  		}).ToObject(),
   565  	}))
   566  	badLenType := newTestClass("BadLen", []*Type{ObjectType}, newStringDict(map[string]*Object{
   567  		"__len__": newBuiltinFunction("__len__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   568  			return None, nil
   569  		}).ToObject(),
   570  	}))
   571  	cases := []invokeTestCase{
   572  		// Bool
   573  		{args: wrapArgs(true), want: True.ToObject()},
   574  		{args: wrapArgs(false), want: False.ToObject()},
   575  		// Dict
   576  		{args: wrapArgs(NewDict()), want: False.ToObject()},
   577  		{args: wrapArgs(newStringDict(map[string]*Object{"foo": True.ToObject()})), want: True.ToObject()},
   578  		// Int
   579  		{args: wrapArgs(0), want: False.ToObject()},
   580  		{args: wrapArgs(-1020), want: True.ToObject()},
   581  		{args: wrapArgs(1698391283), want: True.ToObject()},
   582  		// None
   583  		{args: wrapArgs(None), want: False.ToObject()},
   584  		// Object
   585  		{args: wrapArgs(newObject(ObjectType)), want: True.ToObject()},
   586  		// Str
   587  		{args: wrapArgs(""), want: False.ToObject()},
   588  		{args: wrapArgs("\x00"), want: True.ToObject()},
   589  		{args: wrapArgs("foo"), want: True.ToObject()},
   590  		// Tuple
   591  		{args: wrapArgs(NewTuple()), want: False.ToObject()},
   592  		{args: wrapArgs(newTestTuple("foo", None)), want: True.ToObject()},
   593  		// Funky types
   594  		{args: wrapArgs(newObject(badNonZeroType)), wantExc: mustCreateException(TypeErrorType, "__nonzero__ should return bool, returned NoneType")},
   595  		{args: wrapArgs(newObject(badLenType)), wantExc: mustCreateException(TypeErrorType, "an integer is required")},
   596  	}
   597  	for _, cas := range cases {
   598  		if err := runInvokeTestCase(wrapFuncForTest(IsTrue), &cas); err != "" {
   599  			t.Error(err)
   600  		}
   601  	}
   602  }
   603  
   604  func TestIter(t *testing.T) {
   605  	fun := newBuiltinFunction("TestIter", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   606  		if argc := len(args); argc != 1 {
   607  			return nil, f.RaiseType(SystemErrorType, fmt.Sprintf("Iter expected 1 arg, got %d", argc))
   608  		}
   609  		i, raised := Iter(f, args[0])
   610  		if raised != nil {
   611  			return nil, raised
   612  		}
   613  		return Next(f, i)
   614  	}).ToObject()
   615  	cases := []invokeTestCase{
   616  		{args: wrapArgs(NewTuple()), wantExc: mustCreateException(StopIterationType, "")},
   617  		{args: wrapArgs(newTestTuple(42, "foo")), want: NewInt(42).ToObject()},
   618  		{args: wrapArgs(newTestList("foo")), want: NewStr("foo").ToObject()},
   619  		{args: wrapArgs("foo"), want: NewStr("f").ToObject()},
   620  		{args: wrapArgs(123), wantExc: mustCreateException(TypeErrorType, "'int' object is not iterable")},
   621  	}
   622  	for _, cas := range cases {
   623  		if err := runInvokeTestCase(fun, &cas); err != "" {
   624  			t.Error(err)
   625  		}
   626  	}
   627  }
   628  
   629  func TestNeg(t *testing.T) {
   630  	cases := []invokeTestCase{
   631  		{args: wrapArgs(42), want: NewInt(-42).ToObject()},
   632  		{args: wrapArgs(1.2), want: NewFloat(-1.2).ToObject()},
   633  		{args: wrapArgs(NewLong(big.NewInt(123))), want: NewLong(big.NewInt(-123)).ToObject()},
   634  		{args: wrapArgs("foo"), wantExc: mustCreateException(TypeErrorType, "bad operand type for unary -: 'str'")},
   635  	}
   636  	for _, cas := range cases {
   637  		if err := runInvokeTestCase(wrapFuncForTest(Neg), &cas); err != "" {
   638  			t.Error(err)
   639  		}
   640  	}
   641  }
   642  
   643  func TestNext(t *testing.T) {
   644  	fun := newBuiltinFunction("TestNext", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   645  		if argc := len(args); argc != 1 {
   646  			return nil, f.RaiseType(SystemErrorType, fmt.Sprintf("Next expected 1 arg, got %d", argc))
   647  		}
   648  		iter := args[0]
   649  		var elems []*Object
   650  		elem, raised := Next(f, iter)
   651  		for ; raised == nil; elem, raised = Next(f, iter) {
   652  			elems = append(elems, elem)
   653  		}
   654  		if !raised.isInstance(StopIterationType) {
   655  			return nil, raised
   656  		}
   657  		f.RestoreExc(nil, nil)
   658  		return NewTuple(elems...).ToObject(), nil
   659  	}).ToObject()
   660  	testElems := []*Object{NewInt(42).ToObject(), NewStr("foo").ToObject(), newObject(ObjectType)}
   661  	cases := []invokeTestCase{
   662  		{args: wrapArgs(mustNotRaise(Iter(NewRootFrame(), NewTuple().ToObject()))), want: NewTuple().ToObject()},
   663  		{args: wrapArgs(mustNotRaise(Iter(NewRootFrame(), NewTuple(testElems...).ToObject()))), want: NewTuple(testElems...).ToObject()},
   664  		{args: wrapArgs(mustNotRaise(Iter(NewRootFrame(), NewList(testElems...).ToObject()))), want: NewTuple(testElems...).ToObject()},
   665  		{args: wrapArgs(123), wantExc: mustCreateException(TypeErrorType, "int object is not an iterator")},
   666  	}
   667  	for _, cas := range cases {
   668  		if err := runInvokeTestCase(fun, &cas); err != "" {
   669  			t.Error(err)
   670  		}
   671  	}
   672  }
   673  
   674  func TestLen(t *testing.T) {
   675  	badLenType := newTestClass("BadLen", []*Type{ObjectType}, newStringDict(map[string]*Object{
   676  		"__len__": newBuiltinFunction("__len__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   677  			return None, nil
   678  		}).ToObject(),
   679  	}))
   680  	cases := []invokeTestCase{
   681  		{args: wrapArgs(NewDict()), want: NewInt(0).ToObject()},
   682  		{args: wrapArgs(newStringDict(map[string]*Object{"foo": NewStr("foo value").ToObject(), "bar": NewStr("bar value").ToObject()})), want: NewInt(2).ToObject()},
   683  		{args: wrapArgs(NewTuple()), want: NewInt(0).ToObject()},
   684  		{args: wrapArgs(NewTuple(None, None, None)), want: NewInt(3).ToObject()},
   685  		{args: wrapArgs(10), wantExc: mustCreateException(TypeErrorType, "object of type 'int' has no len()")},
   686  		{args: wrapArgs(newObject(badLenType)), wantExc: mustCreateException(TypeErrorType, "an integer is required")},
   687  	}
   688  	for _, cas := range cases {
   689  		if err := runInvokeTestCase(wrapFuncForTest(Len), &cas); err != "" {
   690  			t.Error(err)
   691  		}
   692  	}
   693  }
   694  
   695  func TestLenRaise(t *testing.T) {
   696  	testTypes := []*Type{
   697  		DictType,
   698  		TupleType,
   699  	}
   700  	for _, typ := range testTypes {
   701  		cases := []invokeTestCase{
   702  			{args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, fmt.Sprintf("unbound method __len__() must be called with %s instance as first argument (got nothing instead)", typ.Name()))},
   703  			{args: wrapArgs(newObject(ObjectType)), wantExc: mustCreateException(TypeErrorType, fmt.Sprintf("unbound method __len__() must be called with %s instance as first argument (got object instance instead)", typ.Name()))},
   704  			{args: wrapArgs(newObject(ObjectType), newObject(ObjectType)), wantExc: mustCreateException(TypeErrorType, fmt.Sprintf("unbound method __len__() must be called with %s instance as first argument (got object instance instead)", typ.Name()))},
   705  		}
   706  		for _, cas := range cases {
   707  			if err := runInvokeMethodTestCase(typ, "__len__", &cas); err != "" {
   708  				t.Error(err)
   709  			}
   710  		}
   711  	}
   712  }
   713  
   714  func TestInvokePositionalArgs(t *testing.T) {
   715  	fun := newBuiltinFunction("TestInvokePositionalArgs", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   716  		return NewTuple(args.makeCopy()...).ToObject(), nil
   717  	}).ToObject()
   718  	cases := []struct {
   719  		varargs *Object
   720  		args    Args
   721  		want    *Object
   722  	}{
   723  		{nil, nil, NewTuple().ToObject()},
   724  		{NewTuple(NewInt(2).ToObject()).ToObject(), nil, NewTuple(NewInt(2).ToObject()).ToObject()},
   725  		{nil, []*Object{NewStr("foo").ToObject()}, NewTuple(NewStr("foo").ToObject()).ToObject()},
   726  		{NewTuple(NewFloat(3.14).ToObject()).ToObject(), []*Object{NewStr("foo").ToObject()}, NewTuple(NewStr("foo").ToObject(), NewFloat(3.14).ToObject()).ToObject()},
   727  		{NewList(NewFloat(3.14).ToObject()).ToObject(), []*Object{NewStr("foo").ToObject()}, NewTuple(NewStr("foo").ToObject(), NewFloat(3.14).ToObject()).ToObject()},
   728  	}
   729  	for _, cas := range cases {
   730  		got, raised := Invoke(NewRootFrame(), fun, cas.args, cas.varargs, nil, nil)
   731  		switch checkResult(got, cas.want, raised, nil) {
   732  		case checkInvokeResultExceptionMismatch:
   733  			t.Errorf("PackArgs(%v, %v) raised %v, want nil", cas.args, cas.varargs, raised)
   734  		case checkInvokeResultReturnValueMismatch:
   735  			t.Errorf("PackArgs(%v, %v) = %v, want %v", cas.args, cas.varargs, got, cas.want)
   736  		}
   737  	}
   738  }
   739  
   740  func TestInvokeKeywordArgs(t *testing.T) {
   741  	fun := newBuiltinFunction("TestInvokeKeywordArgs", func(f *Frame, _ Args, kwargs KWArgs) (*Object, *BaseException) {
   742  		got := map[string]*Object{}
   743  		for _, kw := range kwargs {
   744  			got[kw.Name] = kw.Value
   745  		}
   746  		return newStringDict(got).ToObject(), nil
   747  	}).ToObject()
   748  	d := NewDict()
   749  	d.SetItem(NewRootFrame(), NewInt(123).ToObject(), None)
   750  	cases := []struct {
   751  		keywords KWArgs
   752  		kwargs   *Object
   753  		want     *Object
   754  		wantExc  *BaseException
   755  	}{
   756  		{nil, nil, NewDict().ToObject(), nil},
   757  		{wrapKWArgs("foo", 42), nil, newTestDict("foo", 42).ToObject(), nil},
   758  		{nil, newTestDict("foo", None).ToObject(), newTestDict("foo", None).ToObject(), nil},
   759  		{wrapKWArgs("foo", 42), newTestDict("bar", None).ToObject(), newTestDict("foo", 42, "bar", None).ToObject(), nil},
   760  		{nil, NewList().ToObject(), nil, mustCreateException(TypeErrorType, "argument after ** must be a dict, not list")},
   761  		{nil, d.ToObject(), nil, mustCreateException(TypeErrorType, "keywords must be strings")},
   762  	}
   763  	for _, cas := range cases {
   764  		got, raised := Invoke(NewRootFrame(), fun, nil, nil, cas.keywords, cas.kwargs)
   765  		switch checkResult(got, cas.want, raised, cas.wantExc) {
   766  		case checkInvokeResultExceptionMismatch:
   767  			t.Errorf("PackKwargs(%v, %v) raised %v, want %v", cas.keywords, cas.kwargs, raised, cas.wantExc)
   768  		case checkInvokeResultReturnValueMismatch:
   769  			t.Errorf("PackKwargs(%v, %v) = %v, want %v", cas.keywords, cas.kwargs, got, cas.want)
   770  		}
   771  	}
   772  }
   773  
   774  func TestOct(t *testing.T) {
   775  	badOct := newTestClass("badOct", []*Type{ObjectType}, newStringDict(map[string]*Object{
   776  		"__oct__": newBuiltinFunction("__oct__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   777  			return NewInt(123).ToObject(), nil
   778  		}).ToObject(),
   779  	}))
   780  	goodOct := newTestClass("goodOct", []*Type{ObjectType}, newStringDict(map[string]*Object{
   781  		"__oct__": newBuiltinFunction("__oct__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   782  			return NewStr("0123").ToObject(), nil
   783  		}).ToObject(),
   784  	}))
   785  	cases := []invokeTestCase{
   786  		{args: wrapArgs(-123), want: NewStr("-0173").ToObject()},
   787  		{args: wrapArgs(123), want: NewStr("0173").ToObject()},
   788  		{args: wrapArgs(newObject(goodOct)), want: NewStr("0123").ToObject()},
   789  		{args: wrapArgs(NewList()), wantExc: mustCreateException(TypeErrorType, "oct() argument can't be converted to oct")},
   790  		{args: wrapArgs(NewDict()), wantExc: mustCreateException(TypeErrorType, "oct() argument can't be converted to oct")},
   791  		{args: wrapArgs(newObject(badOct)), wantExc: mustCreateException(TypeErrorType, "__oct__ returned non-string (type int)")},
   792  	}
   793  	for _, cas := range cases {
   794  		if err := runInvokeTestCase(wrapFuncForTest(Oct), &cas); err != "" {
   795  			t.Error(err)
   796  		}
   797  	}
   798  }
   799  
   800  func TestPos(t *testing.T) {
   801  	pos := newTestClass("pos", []*Type{ObjectType}, newStringDict(map[string]*Object{
   802  		"__pos__": newBuiltinFunction("__pos__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   803  			return NewInt(-42).ToObject(), nil
   804  		}).ToObject(),
   805  	}))
   806  	cases := []invokeTestCase{
   807  		{args: wrapArgs(42), want: NewInt(42).ToObject()},
   808  		{args: wrapArgs(1.2), want: NewFloat(1.2).ToObject()},
   809  		{args: wrapArgs(NewLong(big.NewInt(123))), want: NewLong(big.NewInt(123)).ToObject()},
   810  		{args: wrapArgs(newObject(pos)), want: NewInt(-42).ToObject()},
   811  		{args: wrapArgs("foo"), wantExc: mustCreateException(TypeErrorType, "bad operand type for unary +: 'str'")},
   812  	}
   813  	for _, cas := range cases {
   814  		if err := runInvokeTestCase(wrapFuncForTest(Pos), &cas); err != "" {
   815  			t.Error(err)
   816  		}
   817  	}
   818  }
   819  
   820  func TestPyPrint(t *testing.T) {
   821  	fun := wrapFuncForTest(func(f *Frame, args *Tuple, sep, end string) (string, *BaseException) {
   822  		return captureStdout(f, func() *BaseException {
   823  			return pyPrint(NewRootFrame(), args.elems, sep, end, Stdout)
   824  		})
   825  	})
   826  	cases := []invokeTestCase{
   827  		{args: wrapArgs(NewTuple(), "", "\n"), want: NewStr("\n").ToObject()},
   828  		{args: wrapArgs(NewTuple(), "", ""), want: NewStr("").ToObject()},
   829  		{args: wrapArgs(newTestTuple("abc", 123), " ", "\n"), want: NewStr("abc 123\n").ToObject()},
   830  		{args: wrapArgs(newTestTuple("foo"), "", " "), want: NewStr("foo ").ToObject()},
   831  	}
   832  	for _, cas := range cases {
   833  		if err := runInvokeTestCase(fun, &cas); err != "" {
   834  			t.Error(err)
   835  		}
   836  	}
   837  }
   838  
   839  // TODO(corona10): Re-enable once #282 is addressed.
   840  /*func TestPrint(t *testing.T) {
   841  	fun := wrapFuncForTest(func(f *Frame, args *Tuple, nl bool) (string, *BaseException) {
   842  		return captureStdout(f, func() *BaseException {
   843  			return Print(NewRootFrame(), args.elems, nl)
   844  		})
   845  	})
   846  	cases := []invokeTestCase{
   847  		{args: wrapArgs(NewTuple(), true), want: NewStr("\n").ToObject()},
   848  		{args: wrapArgs(NewTuple(), false), want: NewStr("").ToObject()},
   849  		{args: wrapArgs(newTestTuple("abc", 123), true), want: NewStr("abc 123\n").ToObject()},
   850  		{args: wrapArgs(newTestTuple("foo"), false), want: NewStr("foo ").ToObject()},
   851  	}
   852  	for _, cas := range cases {
   853  		if err := runInvokeTestCase(fun, &cas); err != "" {
   854  			t.Error(err)
   855  		}
   856  	}
   857  }*/
   858  
   859  func TestReprRaise(t *testing.T) {
   860  	testTypes := []*Type{
   861  		BaseExceptionType,
   862  		BoolType,
   863  		DictType,
   864  		IntType,
   865  		FunctionType,
   866  		StrType,
   867  		TupleType,
   868  		TypeType,
   869  	}
   870  	for _, typ := range testTypes {
   871  		cases := []invokeTestCase{
   872  			{args: wrapArgs(), wantExc: mustCreateException(TypeErrorType, fmt.Sprintf("unbound method __repr__() must be called with %s instance as first argument (got nothing instead)", typ.Name()))},
   873  			{args: wrapArgs(newObject(ObjectType)), wantExc: mustCreateException(TypeErrorType, fmt.Sprintf("unbound method __repr__() must be called with %s instance as first argument (got object instance instead)", typ.Name()))},
   874  		}
   875  		for _, cas := range cases {
   876  			if err := runInvokeMethodTestCase(typ, "__repr__", &cas); err != "" {
   877  				t.Error(err)
   878  			}
   879  		}
   880  	}
   881  }
   882  
   883  func TestReprMethodReturnsNonStr(t *testing.T) {
   884  	// Don't use runInvokeTestCase since it takes repr(args) and in this
   885  	// case repr will raise.
   886  	typ := newTestClass("Foo", []*Type{ObjectType}, newStringDict(map[string]*Object{
   887  		"__repr__": newBuiltinFunction("__repr__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   888  			return None, nil
   889  		}).ToObject(),
   890  	}))
   891  	_, raised := Repr(NewRootFrame(), newObject(typ))
   892  	wantExc := mustCreateException(TypeErrorType, "__repr__ returned non-string (type NoneType)")
   893  	if !exceptionsAreEquivalent(raised, wantExc) {
   894  		t.Errorf(`Repr() raised %v, want %v`, raised, wantExc)
   895  	}
   896  }
   897  
   898  func TestResolveClass(t *testing.T) {
   899  	f := NewRootFrame()
   900  	cases := []struct {
   901  		class   *Dict
   902  		local   *Object
   903  		globals *Dict
   904  		name    string
   905  		want    *Object
   906  		wantExc *BaseException
   907  	}{
   908  		{newStringDict(map[string]*Object{"foo": NewStr("bar").ToObject()}), NewStr("baz").ToObject(), NewDict(), "foo", NewStr("bar").ToObject(), nil},
   909  		{newStringDict(map[string]*Object{"str": NewInt(42).ToObject()}), nil, NewDict(), "str", NewInt(42).ToObject(), nil},
   910  		{NewDict(), nil, newStringDict(map[string]*Object{"foo": NewStr("bar").ToObject()}), "foo", NewStr("bar").ToObject(), nil},
   911  		{NewDict(), nil, NewDict(), "str", StrType.ToObject(), nil},
   912  		{NewDict(), nil, NewDict(), "foo", nil, mustCreateException(NameErrorType, "name 'foo' is not defined")},
   913  	}
   914  	for _, cas := range cases {
   915  		f.globals = cas.globals
   916  		got, raised := ResolveClass(f, cas.class, cas.local, NewStr(cas.name))
   917  		switch checkResult(got, cas.want, raised, cas.wantExc) {
   918  		case checkInvokeResultExceptionMismatch:
   919  			t.Errorf("ResolveClass(%v, %q) raised %v, want %v", cas.globals, cas.name, raised, cas.wantExc)
   920  		case checkInvokeResultReturnValueMismatch:
   921  			t.Errorf("ResolveClass(%v, %q) = %v, want %v", cas.globals, cas.name, got, cas.want)
   922  		}
   923  	}
   924  }
   925  
   926  func TestResolveGlobal(t *testing.T) {
   927  	fun := wrapFuncForTest(func(f *Frame, globals *Dict, name *Str) (*Object, *BaseException) {
   928  		f.globals = globals
   929  		return ResolveGlobal(f, name)
   930  	})
   931  	cases := []invokeTestCase{
   932  		{args: wrapArgs(newStringDict(map[string]*Object{"foo": NewStr("bar").ToObject()}), "foo"), want: NewStr("bar").ToObject()},
   933  		{args: wrapArgs(NewDict(), "str"), want: StrType.ToObject()},
   934  		{args: wrapArgs(NewDict(), "foo"), wantExc: mustCreateException(NameErrorType, "name 'foo' is not defined")},
   935  	}
   936  	for _, cas := range cases {
   937  		if err := runInvokeTestCase(fun, &cas); err != "" {
   938  			t.Error(err)
   939  		}
   940  	}
   941  }
   942  
   943  func TestRichCompare(t *testing.T) {
   944  	badCmpType := newTestClass("BadCmp", []*Type{ObjectType}, newStringDict(map[string]*Object{
   945  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   946  			return nil, f.RaiseType(TypeErrorType, "uh oh")
   947  		}).ToObject(),
   948  	}))
   949  	cmpEqType := newTestClass("BadCmp", []*Type{ObjectType}, newStringDict(map[string]*Object{
   950  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   951  			return NewInt(0).ToObject(), nil
   952  		}).ToObject(),
   953  	}))
   954  	cmpByEqType := newTestClass("Eq", []*Type{IntType}, newStringDict(map[string]*Object{
   955  		"__eq__": newBuiltinFunction("__eq__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   956  			return True.ToObject(), nil
   957  		}).ToObject(),
   958  		"__cmp__": newBuiltinFunction("__cmp__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   959  			return NotImplemented, nil
   960  		}).ToObject(),
   961  	}))
   962  	badCmpEqType := newTestClass("Eq", []*Type{IntType}, newStringDict(map[string]*Object{
   963  		"__eq__": newBuiltinFunction("__eq__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   964  			return nil, f.RaiseType(TypeErrorType, "uh oh")
   965  		}).ToObject(),
   966  	}))
   967  	cases := []invokeTestCase{
   968  		// Test `__eq__` fallback to `__cmp__`.
   969  		{args: wrapArgs(newObject(cmpEqType), newObject(cmpEqType)), want: compareAllResultEq},
   970  		// Test `__cmp__` fallback to `__eq__`.
   971  		{args: wrapArgs(newObject(cmpByEqType), newObject(cmpByEqType)), want: compareAllResultEq},
   972  		// Test rich compare fallback to bad `__cmp__`.
   973  		{args: wrapArgs(newObject(badCmpType), newObject(badCmpType)), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   974  		// Test bad `__eq__` where the second object being compared is a subclass of the first.
   975  		{args: wrapArgs(NewInt(13).ToObject(), newObject(badCmpEqType)), wantExc: mustCreateException(TypeErrorType, "uh oh")},
   976  	}
   977  	for _, cas := range cases {
   978  		if err := runInvokeTestCase(compareAll, &cas); err != "" {
   979  			t.Error(err)
   980  		}
   981  	}
   982  }
   983  
   984  func TestCheckLocal(t *testing.T) {
   985  	o := newObject(ObjectType)
   986  	cases := []invokeTestCase{
   987  		{args: wrapArgs(o, "foo"), want: None},
   988  		{args: wrapArgs(UnboundLocal, "bar"), wantExc: mustCreateException(UnboundLocalErrorType, "local variable 'bar' referenced before assignment")},
   989  	}
   990  	for _, cas := range cases {
   991  		if err := runInvokeTestCase(wrapFuncForTest(CheckLocal), &cas); err != "" {
   992  			t.Error(err)
   993  		}
   994  	}
   995  }
   996  
   997  func TestSetItem(t *testing.T) {
   998  	setItem := newBuiltinFunction("TestSetItem", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
   999  		if raised := checkFunctionArgs(f, "TestSetItem", args, ObjectType, ObjectType, ObjectType); raised != nil {
  1000  			return nil, raised
  1001  		}
  1002  		o := args[0]
  1003  		if raised := SetItem(f, o, args[1], args[2]); raised != nil {
  1004  			return nil, raised
  1005  		}
  1006  		return o, nil
  1007  	}).ToObject()
  1008  	cases := []invokeTestCase{
  1009  		{args: wrapArgs(NewDict(), "bar", None), want: newTestDict("bar", None).ToObject()},
  1010  		{args: wrapArgs(123, "bar", None), wantExc: mustCreateException(TypeErrorType, "'int' object has no attribute '__setitem__'")},
  1011  	}
  1012  	for _, cas := range cases {
  1013  		if err := runInvokeTestCase(setItem, &cas); err != "" {
  1014  			t.Error(err)
  1015  		}
  1016  	}
  1017  }
  1018  
  1019  func TestStartThread(t *testing.T) {
  1020  	c := make(chan bool)
  1021  	callable := newBuiltinFunction("TestStartThread", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
  1022  		close(c)
  1023  		return None, nil
  1024  	}).ToObject()
  1025  	StartThread(callable)
  1026  	// Deadlock indicates the thread didn't start.
  1027  	<-c
  1028  }
  1029  
  1030  func TestStartThreadRaises(t *testing.T) {
  1031  	// Since there's no way to notify that the goroutine has returned we
  1032  	// can't actually test the exception output but we can at least make
  1033  	// sure the callable ran and didn't blow up the rest of the program.
  1034  	c := make(chan bool)
  1035  	callable := newBuiltinFunction("TestStartThreadRaises", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
  1036  		defer close(c)
  1037  		return nil, f.RaiseType(ExceptionType, "foo")
  1038  	}).ToObject()
  1039  	StartThread(callable)
  1040  	<-c
  1041  }
  1042  
  1043  func TestTie(t *testing.T) {
  1044  	targets := make([]*Object, 3)
  1045  	cases := []struct {
  1046  		t       TieTarget
  1047  		o       *Object
  1048  		want    *Object
  1049  		wantExc *BaseException
  1050  	}{
  1051  		{TieTarget{Target: &targets[0]}, NewInt(42).ToObject(), NewTuple(NewInt(42).ToObject()).ToObject(), nil},
  1052  		{TieTarget{Target: &targets[0]}, NewTuple().ToObject(), NewTuple(NewTuple().ToObject()).ToObject(), nil},
  1053  		{
  1054  			TieTarget{
  1055  				Children: []TieTarget{{Target: &targets[0]}, {Target: &targets[1]}},
  1056  			},
  1057  			NewList(NewStr("foo").ToObject(), NewStr("bar").ToObject()).ToObject(),
  1058  			NewTuple(NewStr("foo").ToObject(), NewStr("bar").ToObject()).ToObject(),
  1059  			nil,
  1060  		},
  1061  		{
  1062  			TieTarget{
  1063  				Children: []TieTarget{
  1064  					{Target: &targets[0]},
  1065  					{Children: []TieTarget{{Target: &targets[1]}, {Target: &targets[2]}}},
  1066  				},
  1067  			},
  1068  			NewTuple(NewStr("foo").ToObject(), NewTuple(NewStr("bar").ToObject(), NewStr("baz").ToObject()).ToObject()).ToObject(),
  1069  			NewTuple(NewStr("foo").ToObject(), NewStr("bar").ToObject(), NewStr("baz").ToObject()).ToObject(),
  1070  			nil,
  1071  		},
  1072  		{
  1073  			TieTarget{
  1074  				Children: []TieTarget{
  1075  					{Target: &targets[0]},
  1076  					{Target: &targets[1]},
  1077  				},
  1078  			},
  1079  			NewList(NewStr("foo").ToObject()).ToObject(),
  1080  			nil,
  1081  			mustCreateException(ValueErrorType, "need more than 1 values to unpack"),
  1082  		},
  1083  		{
  1084  			TieTarget{Children: []TieTarget{{Target: &targets[0]}}},
  1085  			NewTuple(NewInt(1).ToObject(), NewInt(2).ToObject()).ToObject(),
  1086  			nil,
  1087  			mustCreateException(ValueErrorType, "too many values to unpack"),
  1088  		},
  1089  	}
  1090  	for _, cas := range cases {
  1091  		for i := range targets {
  1092  			targets[i] = nil
  1093  		}
  1094  		var got *Object
  1095  		raised := Tie(NewRootFrame(), cas.t, cas.o)
  1096  		if raised == nil {
  1097  			var elems []*Object
  1098  			for _, t := range targets {
  1099  				if t == nil {
  1100  					break
  1101  				}
  1102  				elems = append(elems, t)
  1103  			}
  1104  			got = NewTuple(elems...).ToObject()
  1105  		}
  1106  		switch checkResult(got, cas.want, raised, cas.wantExc) {
  1107  		case checkInvokeResultExceptionMismatch:
  1108  			t.Errorf("Tie(%+v, %v) raised %v, want %v", cas.t, cas.o, raised, cas.wantExc)
  1109  		case checkInvokeResultReturnValueMismatch:
  1110  			t.Errorf("Tie(%+v, %v) = %v, want %v", cas.t, cas.o, got, cas.want)
  1111  		}
  1112  	}
  1113  }
  1114  
  1115  func TestToInt(t *testing.T) {
  1116  	fun := wrapFuncForTest(func(f *Frame, o *Object) (*Tuple, *BaseException) {
  1117  		i, raised := ToInt(f, o)
  1118  		if raised != nil {
  1119  			return nil, raised
  1120  		}
  1121  		return newTestTuple(i, i.Type()), nil
  1122  	})
  1123  	cases := []invokeTestCase{
  1124  		{args: wrapArgs(42), want: newTestTuple(42, IntType).ToObject()},
  1125  		{args: wrapArgs(big.NewInt(123)), want: newTestTuple(123, LongType).ToObject()},
  1126  	}
  1127  	for _, cas := range cases {
  1128  		if err := runInvokeTestCase(fun, &cas); err != "" {
  1129  			t.Error(err)
  1130  		}
  1131  	}
  1132  }
  1133  
  1134  func TestToIntValue(t *testing.T) {
  1135  	cases := []invokeTestCase{
  1136  		{args: wrapArgs(42), want: NewInt(42).ToObject()},
  1137  		{args: wrapArgs(big.NewInt(123)), want: NewInt(123).ToObject()},
  1138  		{args: wrapArgs(overflowLong), wantExc: mustCreateException(OverflowErrorType, "Python int too large to convert to a Go int")},
  1139  	}
  1140  	for _, cas := range cases {
  1141  		if err := runInvokeTestCase(wrapFuncForTest(ToIntValue), &cas); err != "" {
  1142  			t.Error(err)
  1143  		}
  1144  	}
  1145  }
  1146  
  1147  func TestToNative(t *testing.T) {
  1148  	foo := newObject(ObjectType)
  1149  	cases := []struct {
  1150  		o       *Object
  1151  		want    interface{}
  1152  		wantExc *BaseException
  1153  	}{
  1154  		{True.ToObject(), true, nil},
  1155  		{NewInt(42).ToObject(), 42, nil},
  1156  		{NewStr("bar").ToObject(), "bar", nil},
  1157  		{foo, foo, nil},
  1158  	}
  1159  	for _, cas := range cases {
  1160  		got, raised := ToNative(NewRootFrame(), cas.o)
  1161  		if !exceptionsAreEquivalent(raised, cas.wantExc) {
  1162  			t.Errorf("ToNative(%v) raised %v, want %v", cas.o, raised, cas.wantExc)
  1163  		} else if raised == nil && (!got.IsValid() || !reflect.DeepEqual(got.Interface(), cas.want)) {
  1164  			t.Errorf("ToNative(%v) = %v, want %v", cas.o, got, cas.want)
  1165  		}
  1166  	}
  1167  }
  1168  
  1169  func BenchmarkGetAttr(b *testing.B) {
  1170  	f := NewRootFrame()
  1171  	attr := NewStr("bar")
  1172  	fooType := newTestClass("Foo", []*Type{ObjectType}, NewDict())
  1173  	foo := newObject(fooType)
  1174  	if raised := SetAttr(f, foo, attr, NewInt(123).ToObject()); raised != nil {
  1175  		panic(raised)
  1176  	}
  1177  	b.ResetTimer()
  1178  	for i := 0; i < b.N; i++ {
  1179  		mustNotRaise(GetAttr(f, foo, attr, nil))
  1180  	}
  1181  }
  1182  
  1183  // SetAttr is tested in TestObjectSetAttr.
  1184  
  1185  func exceptionsAreEquivalent(e1 *BaseException, e2 *BaseException) bool {
  1186  	if e1 == nil && e2 == nil {
  1187  		return true
  1188  	}
  1189  	if e1 == nil || e2 == nil {
  1190  		return false
  1191  	}
  1192  	if e1.typ != e2.typ {
  1193  		return false
  1194  	}
  1195  	if e1.args == nil && e2.args == nil {
  1196  		return true
  1197  	}
  1198  	if e1.args == nil || e2.args == nil {
  1199  		return false
  1200  	}
  1201  	f := NewRootFrame()
  1202  	b, raised := IsTrue(f, mustNotRaise(Eq(f, e1.args.ToObject(), e2.args.ToObject())))
  1203  	if raised != nil {
  1204  		panic(raised)
  1205  	}
  1206  	return b
  1207  }
  1208  
  1209  func getFuncName(f interface{}) string {
  1210  	s := runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
  1211  	return regexp.MustCompile(`\w+$`).FindString(s)
  1212  }
  1213  
  1214  // wrapFuncForTest creates a callable object that invokes fun, passing the
  1215  // current frame as its first argument followed by caller provided args.
  1216  func wrapFuncForTest(fun interface{}) *Object {
  1217  	return newBuiltinFunction(getFuncName(fun), func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
  1218  		callable, raised := WrapNative(f, reflect.ValueOf(fun))
  1219  		if raised != nil {
  1220  			return nil, raised
  1221  		}
  1222  		argc := len(args)
  1223  		nativeArgs := make(Args, argc+1, argc+1)
  1224  		nativeArgs[0] = f.ToObject()
  1225  		copy(nativeArgs[1:], args)
  1226  		return callable.Call(f, nativeArgs, nil)
  1227  	}).ToObject()
  1228  }
  1229  
  1230  func mustCreateException(t *Type, msg string) *BaseException {
  1231  	if !t.isSubclass(BaseExceptionType) {
  1232  		panic(fmt.Sprintf("type does not inherit from BaseException: %s", t.Name()))
  1233  	}
  1234  	e := toBaseExceptionUnsafe(newObject(t))
  1235  	if msg == "" {
  1236  		e.args = NewTuple()
  1237  	} else {
  1238  		e.args = NewTuple(NewStr(msg).ToObject())
  1239  	}
  1240  	return e
  1241  }
  1242  
  1243  func mustNotRaise(o *Object, raised *BaseException) *Object {
  1244  	if raised != nil {
  1245  		panic(raised)
  1246  	}
  1247  	return o
  1248  }
  1249  
  1250  var (
  1251  	compareAll = wrapFuncForTest(func(f *Frame, v, w *Object) (*Object, *BaseException) {
  1252  		lt, raised := LT(f, v, w)
  1253  		if raised != nil {
  1254  			return nil, raised
  1255  		}
  1256  		le, raised := LE(f, v, w)
  1257  		if raised != nil {
  1258  			return nil, raised
  1259  		}
  1260  		eq, raised := Eq(f, v, w)
  1261  		if raised != nil {
  1262  			return nil, raised
  1263  		}
  1264  		ne, raised := NE(f, v, w)
  1265  		if raised != nil {
  1266  			return nil, raised
  1267  		}
  1268  		ge, raised := GE(f, v, w)
  1269  		if raised != nil {
  1270  			return nil, raised
  1271  		}
  1272  		gt, raised := GT(f, v, w)
  1273  		if raised != nil {
  1274  			return nil, raised
  1275  		}
  1276  		return NewTuple(lt, le, eq, ne, ge, gt).ToObject(), nil
  1277  	})
  1278  	compareAllResultLT = newTestTuple(true, true, false, true, false, false).ToObject()
  1279  	compareAllResultEq = newTestTuple(false, true, true, false, true, false).ToObject()
  1280  	compareAllResultGT = newTestTuple(false, false, false, true, true, true).ToObject()
  1281  )