github.com/pygolin/runtime@v0.0.0-20201208210830-a62e3cd39798/str_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  	"fmt"
    19  	"math/big"
    20  	"reflect"
    21  	"runtime"
    22  	"testing"
    23  )
    24  
    25  func TestNewStr(t *testing.T) {
    26  	expected := &Str{Object: Object{typ: StrType}, value: "foo"}
    27  	s := NewStr("foo")
    28  	if !reflect.DeepEqual(s, expected) {
    29  		t.Errorf(`NewStr("foo") = %+v, expected %+v`, *s, *expected)
    30  	}
    31  }
    32  
    33  func BenchmarkNewStr(b *testing.B) {
    34  	var ret *Str
    35  	for i := 0; i < b.N; i++ {
    36  		ret = NewStr("foo")
    37  	}
    38  	runtime.KeepAlive(ret)
    39  }
    40  
    41  // # On a 64bit system:
    42  // >>> hash("foo")
    43  // -4177197833195190597
    44  // >>> hash("bar")
    45  // 327024216814240868
    46  // >>> hash("baz")
    47  // 327024216814240876
    48  func TestHashString(t *testing.T) {
    49  	truncateInt := func(i int64) int { return int(i) } // Support for 32bit platforms
    50  	cases := []struct {
    51  		value string
    52  		hash  int
    53  	}{
    54  		{"foo", truncateInt(-4177197833195190597)},
    55  		{"bar", truncateInt(327024216814240868)},
    56  		{"baz", truncateInt(327024216814240876)},
    57  	}
    58  	for _, cas := range cases {
    59  		if h := hashString(cas.value); h != cas.hash {
    60  			t.Errorf("hashString(%q) = %d, expected %d", cas.value, h, cas.hash)
    61  		}
    62  	}
    63  }
    64  
    65  func TestStrBinaryOps(t *testing.T) {
    66  	fun := wrapFuncForTest(func(f *Frame, fn binaryOpFunc, v *Object, w *Object) (*Object, *BaseException) {
    67  		return fn(f, v, w)
    68  	})
    69  	cases := []invokeTestCase{
    70  		{args: wrapArgs(Add, "foo", "bar"), want: NewStr("foobar").ToObject()},
    71  		{args: wrapArgs(Add, "foo", NewUnicode("bar")), want: NewUnicode("foobar").ToObject()},
    72  		{args: wrapArgs(Add, "baz", ""), want: NewStr("baz").ToObject()},
    73  		{args: wrapArgs(Add, "", newObject(ObjectType)), wantExc: mustCreateException(TypeErrorType, "unsupported operand type(s) for +: 'str' and 'object'")},
    74  		{args: wrapArgs(Add, None, ""), wantExc: mustCreateException(TypeErrorType, "unsupported operand type(s) for +: 'NoneType' and 'str'")},
    75  		{args: wrapArgs(Mod, "%s", 42), want: NewStr("42").ToObject()},
    76  		{args: wrapArgs(Mod, "%3s", 42), want: NewStr(" 42").ToObject()},
    77  		{args: wrapArgs(Mod, "%03s", 42), want: NewStr(" 42").ToObject()},
    78  		{args: wrapArgs(Mod, "%f", 3.14), want: NewStr("3.140000").ToObject()},
    79  		{args: wrapArgs(Mod, "%10f", 3.14), want: NewStr("  3.140000").ToObject()},
    80  		{args: wrapArgs(Mod, "%010f", 3.14), want: NewStr("003.140000").ToObject()},
    81  		{args: wrapArgs(Mod, "abc %d", NewLong(big.NewInt(123))), want: NewStr("abc 123").ToObject()},
    82  		{args: wrapArgs(Mod, "%d", 3.14), want: NewStr("3").ToObject()},
    83  		{args: wrapArgs(Mod, "%%", NewTuple()), want: NewStr("%").ToObject()},
    84  		{args: wrapArgs(Mod, "%3%", NewTuple()), want: NewStr("  %").ToObject()},
    85  		{args: wrapArgs(Mod, "%03%", NewTuple()), want: NewStr("  %").ToObject()},
    86  		{args: wrapArgs(Mod, "%r", "abc"), want: NewStr("'abc'").ToObject()},
    87  		{args: wrapArgs(Mod, "%6r", "abc"), want: NewStr(" 'abc'").ToObject()},
    88  		{args: wrapArgs(Mod, "%06r", "abc"), want: NewStr(" 'abc'").ToObject()},
    89  		{args: wrapArgs(Mod, "%s %s", true), wantExc: mustCreateException(TypeErrorType, "not enough arguments for format string")},
    90  		{args: wrapArgs(Mod, "%Z", None), wantExc: mustCreateException(ValueErrorType, "invalid format spec")},
    91  		{args: wrapArgs(Mod, "%s", NewDict()), want: NewStr("{}").ToObject()},
    92  		{args: wrapArgs(Mod, "% d", 23), wantExc: mustCreateException(NotImplementedErrorType, "conversion flags not yet supported")},
    93  		{args: wrapArgs(Mod, "%.3f", 102.1), wantExc: mustCreateException(NotImplementedErrorType, "field width not yet supported")},
    94  		{args: wrapArgs(Mod, "%x", 0x1f), want: NewStr("1f").ToObject()},
    95  		{args: wrapArgs(Mod, "%X", 0xffff), want: NewStr("FFFF").ToObject()},
    96  		{args: wrapArgs(Mod, "%x", 1.2), want: NewStr("1").ToObject()},
    97  		{args: wrapArgs(Mod, "abc %x", NewLong(big.NewInt(123))), want: NewStr("abc 7b").ToObject()},
    98  		{args: wrapArgs(Mod, "%x", None), wantExc: mustCreateException(TypeErrorType, "an integer is required")},
    99  		{args: wrapArgs(Mod, "%f", None), wantExc: mustCreateException(TypeErrorType, "float argument required, not NoneType")},
   100  		{args: wrapArgs(Mod, "%s", newTestTuple(123, None)), wantExc: mustCreateException(TypeErrorType, "not all arguments converted during string formatting")},
   101  		{args: wrapArgs(Mod, "%d", newTestTuple("123")), wantExc: mustCreateException(TypeErrorType, "an integer is required")},
   102  		{args: wrapArgs(Mod, "%o", newTestTuple(123)), want: NewStr("173").ToObject()},
   103  		{args: wrapArgs(Mod, "%o", 8), want: NewStr("10").ToObject()},
   104  		{args: wrapArgs(Mod, "%o", -8), want: NewStr("-10").ToObject()},
   105  		{args: wrapArgs(Mod, "%03o", newTestTuple(123)), want: NewStr("173").ToObject()},
   106  		{args: wrapArgs(Mod, "%04o", newTestTuple(123)), want: NewStr("0173").ToObject()},
   107  		{args: wrapArgs(Mod, "%o", newTestTuple("123")), wantExc: mustCreateException(TypeErrorType, "an integer is required")},
   108  		{args: wrapArgs(Mod, "%o", None), wantExc: mustCreateException(TypeErrorType, "an integer is required")},
   109  		{args: wrapArgs(Mod, "%(foo)s", "bar"), wantExc: mustCreateException(TypeErrorType, "format requires a mapping")},
   110  		{args: wrapArgs(Mod, "%(foo)s %(bar)d", newTestDict("foo", "baz", "bar", 123)), want: NewStr("baz 123").ToObject()},
   111  		{args: wrapArgs(Mod, "%(foo)s", newTestDict()), wantExc: mustCreateException(KeyErrorType, "'foo'")},
   112  		{args: wrapArgs(Mod, "%(foo)s %s", newTestDict("foo", "bar")), wantExc: mustCreateException(TypeErrorType, "not enough arguments for format string")},
   113  		{args: wrapArgs(Mod, "%s %(foo)s", newTestDict("foo", "bar")), want: NewStr("{'foo': 'bar'} bar").ToObject()},
   114  		{args: wrapArgs(Mul, "", 10), want: NewStr("").ToObject()},
   115  		{args: wrapArgs(Mul, "foo", -2), want: NewStr("").ToObject()},
   116  		{args: wrapArgs(Mul, "foobar", 0), want: NewStr("").ToObject()},
   117  		{args: wrapArgs(Mul, "aloha", 2), want: NewStr("alohaaloha").ToObject()},
   118  		{args: wrapArgs(Mul, 1, "baz"), want: NewStr("baz").ToObject()},
   119  		{args: wrapArgs(Mul, newObject(ObjectType), "qux"), wantExc: mustCreateException(TypeErrorType, "unsupported operand type(s) for *: 'object' and 'str'")},
   120  		{args: wrapArgs(Mul, "foo", ""), wantExc: mustCreateException(TypeErrorType, "unsupported operand type(s) for *: 'str' and 'str'")},
   121  		{args: wrapArgs(Mul, "bar", MaxInt), wantExc: mustCreateException(OverflowErrorType, "result too large")},
   122  	}
   123  	for _, cas := range cases {
   124  		if err := runInvokeTestCase(fun, &cas); err != "" {
   125  			t.Error(err)
   126  		}
   127  	}
   128  }
   129  
   130  func TestStrCompare(t *testing.T) {
   131  	cases := []invokeTestCase{
   132  		{args: wrapArgs("", ""), want: compareAllResultEq},
   133  		{args: wrapArgs("foo", "foo"), want: compareAllResultEq},
   134  		{args: wrapArgs("", "foo"), want: compareAllResultLT},
   135  		{args: wrapArgs("foo", ""), want: compareAllResultGT},
   136  		{args: wrapArgs("bar", "baz"), want: compareAllResultLT},
   137  	}
   138  	for _, cas := range cases {
   139  		if err := runInvokeTestCase(compareAll, &cas); err != "" {
   140  			t.Error(err)
   141  		}
   142  	}
   143  }
   144  
   145  func TestStrContains(t *testing.T) {
   146  	cases := []invokeTestCase{
   147  		{args: wrapArgs("foobar", "foo"), want: True.ToObject()},
   148  		{args: wrapArgs("abcdef", "bar"), want: False.ToObject()},
   149  		{args: wrapArgs("", ""), want: True.ToObject()},
   150  		{args: wrapArgs("foobar", NewUnicode("bar")), want: True.ToObject()},
   151  		{args: wrapArgs("", 102.1), wantExc: mustCreateException(TypeErrorType, "'in <string>' requires string as left operand, not float")},
   152  	}
   153  	for _, cas := range cases {
   154  		if err := runInvokeMethodTestCase(StrType, "__contains__", &cas); err != "" {
   155  			t.Error(err)
   156  		}
   157  	}
   158  }
   159  
   160  func TestStrDecode(t *testing.T) {
   161  	cases := []invokeTestCase{
   162  		{args: wrapArgs("foo"), want: NewUnicode("foo").ToObject()},
   163  		{args: wrapArgs("foo\xffbar", "utf8", "replace"), want: NewUnicode("foo\ufffdbar").ToObject()},
   164  		{args: wrapArgs("foo\xffbar", "utf8", "ignore"), want: NewUnicode("foobar").ToObject()},
   165  		// Bad error handler name only triggers LookupError when an
   166  		// error is encountered.
   167  		{args: wrapArgs("foobar", "utf8", "noexist"), want: NewUnicode("foobar").ToObject()},
   168  		{args: wrapArgs("foo\xffbar", "utf8", "noexist"), wantExc: mustCreateException(LookupErrorType, "unknown error handler name 'noexist'")},
   169  		{args: wrapArgs("foobar", "noexist"), wantExc: mustCreateException(LookupErrorType, "unknown encoding: noexist")},
   170  		{args: wrapArgs("foo\xffbar"), wantExc: mustCreateException(UnicodeDecodeErrorType, "'utf8' codec can't decode byte 0xff in position 3")},
   171  		// Surrogates are not valid UTF-8 and should raise, unlike
   172  		// CPython 2.x.
   173  		{args: wrapArgs("foo\xef\xbf\xbdbar", "utf8", "strict"), wantExc: mustCreateException(UnicodeDecodeErrorType, "'utf8' codec can't decode byte 0xef in position 3")},
   174  	}
   175  	for _, cas := range cases {
   176  		if err := runInvokeMethodTestCase(StrType, "decode", &cas); err != "" {
   177  			t.Error(err)
   178  		}
   179  	}
   180  }
   181  
   182  func TestStrGetItem(t *testing.T) {
   183  	intIndexType := newTestClass("IntIndex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   184  		"__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   185  			return NewInt(2).ToObject(), nil
   186  		}).ToObject(),
   187  	}))
   188  	longIndexType := newTestClass("LongIndex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   189  		"__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   190  			return NewLong(big.NewInt(2)).ToObject(), nil
   191  		}).ToObject(),
   192  	}))
   193  	cases := []invokeTestCase{
   194  		{args: wrapArgs("bar", 1), want: NewStr("a").ToObject()},
   195  		{args: wrapArgs("foo", 3.14), wantExc: mustCreateException(TypeErrorType, "string indices must be integers or slice, not float")},
   196  		{args: wrapArgs("bar", big.NewInt(1)), want: NewStr("a").ToObject()},
   197  		{args: wrapArgs("baz", -1), want: NewStr("z").ToObject()},
   198  		{args: wrapArgs("baz", newObject(intIndexType)), want: NewStr("z").ToObject()},
   199  		{args: wrapArgs("baz", newObject(longIndexType)), want: NewStr("z").ToObject()},
   200  		{args: wrapArgs("baz", -4), wantExc: mustCreateException(IndexErrorType, "index out of range")},
   201  		{args: wrapArgs("", 0), wantExc: mustCreateException(IndexErrorType, "index out of range")},
   202  		{args: wrapArgs("foo", 3), wantExc: mustCreateException(IndexErrorType, "index out of range")},
   203  		{args: wrapArgs("bar", newTestSlice(None, 2)), want: NewStr("ba").ToObject()},
   204  		{args: wrapArgs("bar", newTestSlice(1, 3)), want: NewStr("ar").ToObject()},
   205  		{args: wrapArgs("bar", newTestSlice(1, None)), want: NewStr("ar").ToObject()},
   206  		{args: wrapArgs("foobarbaz", newTestSlice(1, 8, 2)), want: NewStr("obra").ToObject()},
   207  		{args: wrapArgs("abc", newTestSlice(None, None, -1)), want: NewStr("cba").ToObject()},
   208  		{args: wrapArgs("bar", newTestSlice(1, 2, 0)), wantExc: mustCreateException(ValueErrorType, "slice step cannot be zero")},
   209  	}
   210  	for _, cas := range cases {
   211  		if err := runInvokeMethodTestCase(StrType, "__getitem__", &cas); err != "" {
   212  			t.Error(err)
   213  		}
   214  	}
   215  }
   216  
   217  func TestStrNew(t *testing.T) {
   218  	dummy := newObject(ObjectType)
   219  	dummyStr := NewStr(fmt.Sprintf("<object object at %p>", dummy))
   220  	fooType := newTestClass("Foo", []*Type{ObjectType}, newStringDict(map[string]*Object{
   221  		"__str__": newBuiltinFunction("__str__", func(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
   222  			return NewInt(123).ToObject(), nil
   223  		}).ToObject(),
   224  	}))
   225  	foo := newObject(fooType)
   226  	strictEqType := newTestClassStrictEq("StrictEq", StrType)
   227  	subType := newTestClass("SubType", []*Type{StrType}, newStringDict(map[string]*Object{}))
   228  	subTypeObject := (&Str{Object: Object{typ: subType}, value: "abc"}).ToObject()
   229  	goodSlotType := newTestClass("GoodSlot", []*Type{ObjectType}, newStringDict(map[string]*Object{
   230  		"__str__": newBuiltinFunction("__str__", func(_ *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   231  			return NewStr("abc").ToObject(), nil
   232  		}).ToObject(),
   233  	}))
   234  	badSlotType := newTestClass("BadSlot", []*Type{ObjectType}, newStringDict(map[string]*Object{
   235  		"__str__": newBuiltinFunction("__str__", func(_ *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   236  			return newObject(ObjectType), nil
   237  		}).ToObject(),
   238  	}))
   239  	slotSubTypeType := newTestClass("SlotSubType", []*Type{ObjectType}, newStringDict(map[string]*Object{
   240  		"__str__": newBuiltinFunction("__str__", func(_ *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   241  			return subTypeObject, nil
   242  		}).ToObject(),
   243  	}))
   244  	cases := []invokeTestCase{
   245  		{wantExc: mustCreateException(TypeErrorType, "'__new__' requires 1 arguments")},
   246  		{args: wrapArgs(IntType.ToObject()), wantExc: mustCreateException(TypeErrorType, "str.__new__(int): int is not a subtype of str")},
   247  		{args: wrapArgs(StrType.ToObject(), NewInt(1).ToObject(), NewInt(2).ToObject()), wantExc: mustCreateException(TypeErrorType, "str() takes at most 1 argument (2 given)")},
   248  		{args: wrapArgs(StrType.ToObject(), foo), wantExc: mustCreateException(TypeErrorType, "__str__ returned non-string (type int)")},
   249  		{args: wrapArgs(StrType.ToObject()), want: NewStr("").ToObject()},
   250  		{args: wrapArgs(StrType.ToObject(), NewDict().ToObject()), want: NewStr("{}").ToObject()},
   251  		{args: wrapArgs(StrType.ToObject(), dummy), want: dummyStr.ToObject()},
   252  		{args: wrapArgs(strictEqType, "foo"), want: (&Str{Object: Object{typ: strictEqType}, value: "foo"}).ToObject()},
   253  		{args: wrapArgs(StrType, newObject(goodSlotType)), want: NewStr("abc").ToObject()},
   254  		{args: wrapArgs(StrType, newObject(badSlotType)), wantExc: mustCreateException(TypeErrorType, "__str__ returned non-string (type object)")},
   255  		{args: wrapArgs(StrType, newObject(slotSubTypeType)), want: subTypeObject},
   256  		{args: wrapArgs(strictEqType, newObject(goodSlotType)), want: (&Str{Object: Object{typ: strictEqType}, value: "abc"}).ToObject()},
   257  		{args: wrapArgs(strictEqType, newObject(badSlotType)), wantExc: mustCreateException(TypeErrorType, "__str__ returned non-string (type object)")},
   258  	}
   259  	for _, cas := range cases {
   260  		if err := runInvokeMethodTestCase(StrType, "__new__", &cas); err != "" {
   261  			t.Error(err)
   262  		}
   263  	}
   264  }
   265  
   266  func TestStrRepr(t *testing.T) {
   267  	cases := []invokeTestCase{
   268  		{args: wrapArgs("foo"), want: NewStr(`'foo'`).ToObject()},
   269  		{args: wrapArgs("on\nmultiple\nlines"), want: NewStr(`'on\nmultiple\nlines'`).ToObject()},
   270  		{args: wrapArgs("\x00\x00"), want: NewStr(`'\x00\x00'`).ToObject()},
   271  	}
   272  	for _, cas := range cases {
   273  		if err := runInvokeMethodTestCase(StrType, "__repr__", &cas); err != "" {
   274  			t.Error(err)
   275  		}
   276  	}
   277  }
   278  
   279  func TestStrMethods(t *testing.T) {
   280  	fooType := newTestClass("Foo", []*Type{ObjectType}, newStringDict(map[string]*Object{"bar": None}))
   281  	intIndexType := newTestClass("IntIndex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   282  		"__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   283  			return NewInt(2).ToObject(), nil
   284  		}).ToObject(),
   285  	}))
   286  	longIndexType := newTestClass("LongIndex", []*Type{ObjectType}, newStringDict(map[string]*Object{
   287  		"__index__": newBuiltinFunction("__index__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   288  			return NewLong(big.NewInt(2)).ToObject(), nil
   289  		}).ToObject(),
   290  	}))
   291  	intIntType := newTestClass("IntInt", []*Type{ObjectType}, newStringDict(map[string]*Object{
   292  		"__int__": newBuiltinFunction("__int__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   293  			return NewInt(2).ToObject(), nil
   294  		}).ToObject(),
   295  	}))
   296  	longIntType := newTestClass("LongInt", []*Type{ObjectType}, newStringDict(map[string]*Object{
   297  		"__int__": newBuiltinFunction("__int__", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) {
   298  			return NewLong(big.NewInt(2)).ToObject(), nil
   299  		}).ToObject(),
   300  	}))
   301  	cases := []struct {
   302  		methodName string
   303  		args       Args
   304  		want       *Object
   305  		wantExc    *BaseException
   306  	}{
   307  		{"capitalize", wrapArgs(""), NewStr("").ToObject(), nil},
   308  		{"capitalize", wrapArgs("foobar"), NewStr("Foobar").ToObject(), nil},
   309  		{"capitalize", wrapArgs("FOOBAR"), NewStr("Foobar").ToObject(), nil},
   310  		{"capitalize", wrapArgs("ùBAR"), NewStr("ùbar").ToObject(), nil},
   311  		{"capitalize", wrapArgs("вол"), NewStr("вол").ToObject(), nil},
   312  		{"capitalize", wrapArgs("foobar", 123), nil, mustCreateException(TypeErrorType, "'capitalize' of 'str' requires 1 arguments")},
   313  		{"capitalize", wrapArgs("ВОЛ"), NewStr("ВОЛ").ToObject(), nil},
   314  		{"center", wrapArgs("foobar", 9, "#"), NewStr("##foobar#").ToObject(), nil},
   315  		{"center", wrapArgs("foobar", 10, "#"), NewStr("##foobar##").ToObject(), nil},
   316  		{"center", wrapArgs("foobar", 3, "#"), NewStr("foobar").ToObject(), nil},
   317  		{"center", wrapArgs("foobar", -1, "#"), NewStr("foobar").ToObject(), nil},
   318  		{"center", wrapArgs("foobar", 10, "##"), nil, mustCreateException(TypeErrorType, "center() argument 2 must be char, not str")},
   319  		{"center", wrapArgs("foobar", 10, ""), nil, mustCreateException(TypeErrorType, "center() argument 2 must be char, not str")},
   320  		{"count", wrapArgs("", "a"), NewInt(0).ToObject(), nil},
   321  		{"count", wrapArgs("five", ""), NewInt(5).ToObject(), nil},
   322  		{"count", wrapArgs("abba", "bb"), NewInt(1).ToObject(), nil},
   323  		{"count", wrapArgs("abbba", "bb"), NewInt(1).ToObject(), nil},
   324  		{"count", wrapArgs("abbbba", "bb"), NewInt(2).ToObject(), nil},
   325  		{"count", wrapArgs("abcdeffdeabcb", "b"), NewInt(3).ToObject(), nil},
   326  		{"count", wrapArgs(""), nil, mustCreateException(TypeErrorType, "'count' of 'str' requires 2 arguments")},
   327  		{"endswith", wrapArgs("", ""), True.ToObject(), nil},
   328  		{"endswith", wrapArgs("", "", 1), False.ToObject(), nil},
   329  		{"endswith", wrapArgs("foobar", "bar"), True.ToObject(), nil},
   330  		{"endswith", wrapArgs("foobar", "bar", 0, -2), False.ToObject(), nil},
   331  		{"endswith", wrapArgs("foobar", "foo", 0, 3), True.ToObject(), nil},
   332  		{"endswith", wrapArgs("foobar", "bar", 3, 5), False.ToObject(), nil},
   333  		{"endswith", wrapArgs("foobar", "bar", 5, 3), False.ToObject(), nil},
   334  		{"endswith", wrapArgs("bar", "foobar"), False.ToObject(), nil},
   335  		{"endswith", wrapArgs("foo", newTestTuple("barfoo", "oo").ToObject()), True.ToObject(), nil},
   336  		{"endswith", wrapArgs("foo", 123), nil, mustCreateException(TypeErrorType, "endswith first arg must be str, unicode, or tuple, not int")},
   337  		{"endswith", wrapArgs("foo", newTestTuple(123).ToObject()), nil, mustCreateException(TypeErrorType, "expected a str")},
   338  		{"find", wrapArgs("", ""), NewInt(0).ToObject(), nil},
   339  		{"find", wrapArgs("", "", 1), NewInt(-1).ToObject(), nil},
   340  		{"find", wrapArgs("", "", -1), NewInt(0).ToObject(), nil},
   341  		{"find", wrapArgs("", "", None, -1), NewInt(0).ToObject(), nil},
   342  		{"find", wrapArgs("foobar", "bar"), NewInt(3).ToObject(), nil},
   343  		{"find", wrapArgs("foobar", "bar", fooType), nil, mustCreateException(TypeErrorType, "slice indices must be integers or None or have an __index__ method")},
   344  		{"find", wrapArgs("foobar", "bar", NewInt(MaxInt)), NewInt(-1).ToObject(), nil},
   345  		{"find", wrapArgs("foobar", "bar", None, NewInt(MaxInt)), NewInt(3).ToObject(), nil},
   346  		{"find", wrapArgs("foobar", "bar", newObject(intIndexType)), NewInt(3).ToObject(), nil},
   347  		{"find", wrapArgs("foobar", "bar", None, newObject(intIndexType)), NewInt(-1).ToObject(), nil},
   348  		{"find", wrapArgs("foobar", "bar", newObject(longIndexType)), NewInt(3).ToObject(), nil},
   349  		{"find", wrapArgs("foobar", "bar", None, newObject(longIndexType)), NewInt(-1).ToObject(), nil},
   350  		// TODO: Support unicode substring.
   351  		{"find", wrapArgs("foobar", NewUnicode("bar")), nil, mustCreateException(TypeErrorType, "'find/index' requires a 'str' object but received a 'unicode'")},
   352  		{"find", wrapArgs("foobar", "bar", "baz"), nil, mustCreateException(TypeErrorType, "slice indices must be integers or None or have an __index__ method")},
   353  		{"find", wrapArgs("foobar", "bar", 0, "baz"), nil, mustCreateException(TypeErrorType, "slice indices must be integers or None or have an __index__ method")},
   354  		{"find", wrapArgs("foobar", "bar", None), NewInt(3).ToObject(), nil},
   355  		{"find", wrapArgs("foobar", "bar", 0, None), NewInt(3).ToObject(), nil},
   356  		{"find", wrapArgs("foobar", "bar", 0, -2), NewInt(-1).ToObject(), nil},
   357  		{"find", wrapArgs("foobar", "foo", 0, 3), NewInt(0).ToObject(), nil},
   358  		{"find", wrapArgs("foobar", "foo", 10), NewInt(-1).ToObject(), nil},
   359  		{"find", wrapArgs("foobar", "foo", 3, 3), NewInt(-1).ToObject(), nil},
   360  		{"find", wrapArgs("foobar", "bar", 3, 5), NewInt(-1).ToObject(), nil},
   361  		{"find", wrapArgs("foobar", "bar", 5, 3), NewInt(-1).ToObject(), nil},
   362  		{"find", wrapArgs("bar", "foobar"), NewInt(-1).ToObject(), nil},
   363  		{"find", wrapArgs("bar", "a", 1, 10), NewInt(1).ToObject(), nil},
   364  		{"find", wrapArgs("bar", "a", NewLong(big.NewInt(1)), 10), NewInt(1).ToObject(), nil},
   365  		{"find", wrapArgs("bar", "a", 0, NewLong(big.NewInt(2))), NewInt(1).ToObject(), nil},
   366  		{"find", wrapArgs("bar", "a", 1, 3), NewInt(1).ToObject(), nil},
   367  		{"find", wrapArgs("bar", "a", 0, -1), NewInt(1).ToObject(), nil},
   368  		{"find", wrapArgs("foo", newTestTuple("barfoo", "oo").ToObject()), nil, mustCreateException(TypeErrorType, "'find/index' requires a 'str' object but received a 'tuple'")},
   369  		{"find", wrapArgs("foo", 123), nil, mustCreateException(TypeErrorType, "'find/index' requires a 'str' object but received a 'int'")},
   370  		{"index", wrapArgs("", ""), NewInt(0).ToObject(), nil},
   371  		{"index", wrapArgs("", "", 1), nil, mustCreateException(ValueErrorType, "substring not found")},
   372  		{"index", wrapArgs("", "", -1), NewInt(0).ToObject(), nil},
   373  		{"index", wrapArgs("", "", None, -1), NewInt(0).ToObject(), nil},
   374  		{"index", wrapArgs("foobar", "bar"), NewInt(3).ToObject(), nil},
   375  		{"index", wrapArgs("foobar", "bar", fooType), nil, mustCreateException(TypeErrorType, "slice indices must be integers or None or have an __index__ method")},
   376  		{"index", wrapArgs("foobar", "bar", NewInt(MaxInt)), nil, mustCreateException(ValueErrorType, "substring not found")},
   377  		{"index", wrapArgs("foobar", "bar", None, NewInt(MaxInt)), NewInt(3).ToObject(), nil},
   378  		{"index", wrapArgs("foobar", "bar", newObject(intIndexType)), NewInt(3).ToObject(), nil},
   379  		{"index", wrapArgs("foobar", "bar", None, newObject(intIndexType)), nil, mustCreateException(ValueErrorType, "substring not found")},
   380  		{"index", wrapArgs("foobar", "bar", newObject(longIndexType)), NewInt(3).ToObject(), nil},
   381  		{"index", wrapArgs("foobar", "bar", None, newObject(longIndexType)), nil, mustCreateException(ValueErrorType, "substring not found")},
   382  		//TODO: Support unicode substring.
   383  		{"index", wrapArgs("foobar", NewUnicode("bar")), nil, mustCreateException(TypeErrorType, "'find/index' requires a 'str' object but received a 'unicode'")},
   384  		{"index", wrapArgs("foobar", "bar", "baz"), nil, mustCreateException(TypeErrorType, "slice indices must be integers or None or have an __index__ method")},
   385  		{"index", wrapArgs("foobar", "bar", 0, "baz"), nil, mustCreateException(TypeErrorType, "slice indices must be integers or None or have an __index__ method")},
   386  		{"index", wrapArgs("foobar", "bar", None), NewInt(3).ToObject(), nil},
   387  		{"index", wrapArgs("foobar", "bar", 0, None), NewInt(3).ToObject(), nil},
   388  		{"index", wrapArgs("foobar", "bar", 0, -2), nil, mustCreateException(ValueErrorType, "substring not found")},
   389  		{"index", wrapArgs("foobar", "foo", 0, 3), NewInt(0).ToObject(), nil},
   390  		{"index", wrapArgs("foobar", "foo", 10), nil, mustCreateException(ValueErrorType, "substring not found")},
   391  		{"index", wrapArgs("foobar", "foo", 3, 3), nil, mustCreateException(ValueErrorType, "substring not found")},
   392  		{"index", wrapArgs("foobar", "bar", 3, 5), nil, mustCreateException(ValueErrorType, "substring not found")},
   393  		{"index", wrapArgs("foobar", "bar", 5, 3), nil, mustCreateException(ValueErrorType, "substring not found")},
   394  		{"index", wrapArgs("bar", "foobar"), nil, mustCreateException(ValueErrorType, "substring not found")},
   395  		{"index", wrapArgs("bar", "a", 1, 10), NewInt(1).ToObject(), nil},
   396  		{"index", wrapArgs("bar", "a", NewLong(big.NewInt(1)), 10), NewInt(1).ToObject(), nil},
   397  		{"index", wrapArgs("bar", "a", 0, NewLong(big.NewInt(2))), NewInt(1).ToObject(), nil},
   398  		{"index", wrapArgs("bar", "a", 1, 3), NewInt(1).ToObject(), nil},
   399  		{"index", wrapArgs("bar", "a", 0, -1), NewInt(1).ToObject(), nil},
   400  		{"index", wrapArgs("foo", newTestTuple("barfoo", "oo").ToObject()), nil, mustCreateException(TypeErrorType, "'find/index' requires a 'str' object but received a 'tuple'")},
   401  		{"index", wrapArgs("foo", 123), nil, mustCreateException(TypeErrorType, "'find/index' requires a 'str' object but received a 'int'")},
   402  		{"index", wrapArgs("barbaz", "ba"), NewInt(0).ToObject(), nil},
   403  		{"index", wrapArgs("barbaz", "ba", 1), NewInt(3).ToObject(), nil},
   404  		{"isalnum", wrapArgs("123abc"), True.ToObject(), nil},
   405  		{"isalnum", wrapArgs(""), False.ToObject(), nil},
   406  		{"isalnum", wrapArgs("#$%"), False.ToObject(), nil},
   407  		{"isalnum", wrapArgs("abc#123"), False.ToObject(), nil},
   408  		{"isalnum", wrapArgs("123abc", "efg"), nil, mustCreateException(TypeErrorType, "'isalnum' of 'str' requires 1 arguments")},
   409  		{"isalpha", wrapArgs("xyz"), True.ToObject(), nil},
   410  		{"isalpha", wrapArgs(""), False.ToObject(), nil},
   411  		{"isalpha", wrapArgs("#$%"), False.ToObject(), nil},
   412  		{"isalpha", wrapArgs("abc#123"), False.ToObject(), nil},
   413  		{"isalpha", wrapArgs("absd", "efg"), nil, mustCreateException(TypeErrorType, "'isalpha' of 'str' requires 1 arguments")},
   414  		{"isdigit", wrapArgs("abc"), False.ToObject(), nil},
   415  		{"isdigit", wrapArgs("123"), True.ToObject(), nil},
   416  		{"isdigit", wrapArgs(""), False.ToObject(), nil},
   417  		{"isdigit", wrapArgs("abc#123"), False.ToObject(), nil},
   418  		{"isdigit", wrapArgs("123", "456"), nil, mustCreateException(TypeErrorType, "'isdigit' of 'str' requires 1 arguments")},
   419  		{"islower", wrapArgs("abc"), True.ToObject(), nil},
   420  		{"islower", wrapArgs("ABC"), False.ToObject(), nil},
   421  		{"islower", wrapArgs(""), False.ToObject(), nil},
   422  		{"islower", wrapArgs("abc#123"), False.ToObject(), nil},
   423  		{"islower", wrapArgs("123", "456"), nil, mustCreateException(TypeErrorType, "'islower' of 'str' requires 1 arguments")},
   424  		{"isupper", wrapArgs("abc"), False.ToObject(), nil},
   425  		{"isupper", wrapArgs("ABC"), True.ToObject(), nil},
   426  		{"isupper", wrapArgs(""), False.ToObject(), nil},
   427  		{"isupper", wrapArgs("abc#123"), False.ToObject(), nil},
   428  		{"isupper", wrapArgs("123", "456"), nil, mustCreateException(TypeErrorType, "'isupper' of 'str' requires 1 arguments")},
   429  		{"isspace", wrapArgs(""), False.ToObject(), nil},
   430  		{"isspace", wrapArgs(" "), True.ToObject(), nil},
   431  		{"isspace", wrapArgs("\n\t\v\f\r      "), True.ToObject(), nil},
   432  		{"isspace", wrapArgs(""), False.ToObject(), nil},
   433  		{"isspace", wrapArgs("asdad"), False.ToObject(), nil},
   434  		{"isspace", wrapArgs("       "), True.ToObject(), nil},
   435  		{"isspace", wrapArgs("    ", "456"), nil, mustCreateException(TypeErrorType, "'isspace' of 'str' requires 1 arguments")},
   436  		{"istitle", wrapArgs("abc"), False.ToObject(), nil},
   437  		{"istitle", wrapArgs("Abc&D"), True.ToObject(), nil},
   438  		{"istitle", wrapArgs("ABc&D"), False.ToObject(), nil},
   439  		{"istitle", wrapArgs(""), False.ToObject(), nil},
   440  		{"istitle", wrapArgs("abc#123"), False.ToObject(), nil},
   441  		{"istitle", wrapArgs("ABc&D", "456"), nil, mustCreateException(TypeErrorType, "'istitle' of 'str' requires 1 arguments")},
   442  		{"join", wrapArgs(",", newTestList("foo", "bar")), NewStr("foo,bar").ToObject(), nil},
   443  		{"join", wrapArgs(":", newTestList("foo", "bar", NewUnicode("baz"))), NewUnicode("foo:bar:baz").ToObject(), nil},
   444  		{"join", wrapArgs("nope", NewTuple()), NewStr("").ToObject(), nil},
   445  		{"join", wrapArgs("nope", newTestTuple("foo")), NewStr("foo").ToObject(), nil},
   446  		{"join", wrapArgs(",", newTestList("foo", "bar", 3.14)), nil, mustCreateException(TypeErrorType, "sequence item 2: expected string, float found")},
   447  		{"join", wrapArgs("\xff", newTestList(NewUnicode("foo"), NewUnicode("bar"))), nil, mustCreateException(UnicodeDecodeErrorType, "'utf8' codec can't decode byte 0xff in position 0")},
   448  		{"ljust", wrapArgs("foobar", 10, "#"), NewStr("foobar####").ToObject(), nil},
   449  		{"ljust", wrapArgs("foobar", 3, "#"), NewStr("foobar").ToObject(), nil},
   450  		{"ljust", wrapArgs("foobar", -1, "#"), NewStr("foobar").ToObject(), nil},
   451  		{"ljust", wrapArgs("foobar", 10, "##"), nil, mustCreateException(TypeErrorType, "ljust() argument 2 must be char, not str")},
   452  		{"ljust", wrapArgs("foobar", 10, ""), nil, mustCreateException(TypeErrorType, "ljust() argument 2 must be char, not str")},
   453  		{"lower", wrapArgs(""), NewStr("").ToObject(), nil},
   454  		{"lower", wrapArgs("a"), NewStr("a").ToObject(), nil},
   455  		{"lower", wrapArgs("A"), NewStr("a").ToObject(), nil},
   456  		{"lower", wrapArgs(" A"), NewStr(" a").ToObject(), nil},
   457  		{"lower", wrapArgs("abc"), NewStr("abc").ToObject(), nil},
   458  		{"lower", wrapArgs("ABC"), NewStr("abc").ToObject(), nil},
   459  		{"lower", wrapArgs("aBC"), NewStr("abc").ToObject(), nil},
   460  		{"lower", wrapArgs("abc def", 123), nil, mustCreateException(TypeErrorType, "'lower' of 'str' requires 1 arguments")},
   461  		{"lower", wrapArgs(123), nil, mustCreateException(TypeErrorType, "unbound method lower() must be called with str instance as first argument (got int instance instead)")},
   462  		{"lower", wrapArgs("вол"), NewStr("вол").ToObject(), nil},
   463  		{"lower", wrapArgs("ВОЛ"), NewStr("ВОЛ").ToObject(), nil},
   464  		{"lstrip", wrapArgs("foo "), NewStr("foo ").ToObject(), nil},
   465  		{"lstrip", wrapArgs(" foo bar "), NewStr("foo bar ").ToObject(), nil},
   466  		{"lstrip", wrapArgs("foo foo", "o"), NewStr("foo foo").ToObject(), nil},
   467  		{"lstrip", wrapArgs("foo foo", "f"), NewStr("oo foo").ToObject(), nil},
   468  		{"lstrip", wrapArgs("foo bar", "abr"), NewStr("foo bar").ToObject(), nil},
   469  		{"lstrip", wrapArgs("foo bar", "fo"), NewStr(" bar").ToObject(), nil},
   470  		{"lstrip", wrapArgs("foo", NewUnicode("f")), NewUnicode("oo").ToObject(), nil},
   471  		{"lstrip", wrapArgs("123", 3), nil, mustCreateException(TypeErrorType, "strip arg must be None, str or unicode")},
   472  		{"lstrip", wrapArgs("foo", "bar", "baz"), nil, mustCreateException(TypeErrorType, "'strip' of 'str' requires 2 arguments")},
   473  		{"lstrip", wrapArgs("\xfboo", NewUnicode("o")), nil, mustCreateException(UnicodeDecodeErrorType, "'utf8' codec can't decode byte 0xfb in position 0")},
   474  		{"lstrip", wrapArgs("foo", NewUnicode("o")), NewUnicode("f").ToObject(), nil},
   475  		{"rfind", wrapArgs("", ""), NewInt(0).ToObject(), nil},
   476  		{"rfind", wrapArgs("", "", 1), NewInt(-1).ToObject(), nil},
   477  		{"rfind", wrapArgs("", "", -1), NewInt(0).ToObject(), nil},
   478  		{"rfind", wrapArgs("", "", None, -1), NewInt(0).ToObject(), nil},
   479  		{"rfind", wrapArgs("foobar", "bar"), NewInt(3).ToObject(), nil},
   480  		{"rfind", wrapArgs("foobar", "bar", fooType), nil, mustCreateException(TypeErrorType, "slice indices must be integers or None or have an __index__ method")},
   481  		{"rfind", wrapArgs("foobar", "bar", NewInt(MaxInt)), NewInt(-1).ToObject(), nil},
   482  		{"rfind", wrapArgs("foobar", "bar", None, NewInt(MaxInt)), NewInt(3).ToObject(), nil},
   483  		{"rfind", wrapArgs("foobar", "bar", newObject(intIndexType)), NewInt(3).ToObject(), nil},
   484  		{"rfind", wrapArgs("foobar", "bar", None, newObject(intIndexType)), NewInt(-1).ToObject(), nil},
   485  		{"rfind", wrapArgs("foobar", "bar", newObject(longIndexType)), NewInt(3).ToObject(), nil},
   486  		{"rfind", wrapArgs("foobar", "bar", None, newObject(longIndexType)), NewInt(-1).ToObject(), nil},
   487  		//r TODO: Support unicode substring.
   488  		{"rfind", wrapArgs("foobar", NewUnicode("bar")), nil, mustCreateException(TypeErrorType, "'find/index' requires a 'str' object but received a 'unicode'")},
   489  		{"rfind", wrapArgs("foobar", "bar", "baz"), nil, mustCreateException(TypeErrorType, "slice indices must be integers or None or have an __index__ method")},
   490  		{"rfind", wrapArgs("foobar", "bar", 0, "baz"), nil, mustCreateException(TypeErrorType, "slice indices must be integers or None or have an __index__ method")},
   491  		{"rfind", wrapArgs("foobar", "bar", None), NewInt(3).ToObject(), nil},
   492  		{"rfind", wrapArgs("foobar", "bar", 0, None), NewInt(3).ToObject(), nil},
   493  		{"rfind", wrapArgs("foobar", "bar", 0, -2), NewInt(-1).ToObject(), nil},
   494  		{"rfind", wrapArgs("foobar", "foo", 0, 3), NewInt(0).ToObject(), nil},
   495  		{"rfind", wrapArgs("foobar", "foo", 10), NewInt(-1).ToObject(), nil},
   496  		{"rfind", wrapArgs("foobar", "foo", 3, 3), NewInt(-1).ToObject(), nil},
   497  		{"rfind", wrapArgs("foobar", "bar", 3, 5), NewInt(-1).ToObject(), nil},
   498  		{"rfind", wrapArgs("foobar", "bar", 5, 3), NewInt(-1).ToObject(), nil},
   499  		{"rfind", wrapArgs("bar", "foobar"), NewInt(-1).ToObject(), nil},
   500  		{"rfind", wrapArgs("bar", "a", 1, 10), NewInt(1).ToObject(), nil},
   501  		{"rfind", wrapArgs("bar", "a", NewLong(big.NewInt(1)), 10), NewInt(1).ToObject(), nil},
   502  		{"rfind", wrapArgs("bar", "a", 0, NewLong(big.NewInt(2))), NewInt(1).ToObject(), nil},
   503  		{"rfind", wrapArgs("bar", "a", 1, 3), NewInt(1).ToObject(), nil},
   504  		{"rfind", wrapArgs("bar", "a", 0, -1), NewInt(1).ToObject(), nil},
   505  		{"rfind", wrapArgs("foo", newTestTuple("barfoo", "oo").ToObject()), nil, mustCreateException(TypeErrorType, "'find/index' requires a 'str' object but received a 'tuple'")},
   506  		{"rfind", wrapArgs("foo", 123), nil, mustCreateException(TypeErrorType, "'find/index' requires a 'str' object but received a 'int'")},
   507  		{"rfind", wrapArgs("barbaz", "ba"), NewInt(3).ToObject(), nil},
   508  		{"rfind", wrapArgs("barbaz", "ba", None, 4), NewInt(0).ToObject(), nil},
   509  		{"rindex", wrapArgs("", ""), NewInt(0).ToObject(), nil},
   510  		{"rindex", wrapArgs("", "", 1), nil, mustCreateException(ValueErrorType, "substring not found")},
   511  		{"rindex", wrapArgs("", "", -1), NewInt(0).ToObject(), nil},
   512  		{"rindex", wrapArgs("", "", None, -1), NewInt(0).ToObject(), nil},
   513  		{"rindex", wrapArgs("foobar", "bar"), NewInt(3).ToObject(), nil},
   514  		{"rindex", wrapArgs("foobar", "bar", fooType), nil, mustCreateException(TypeErrorType, "slice indices must be integers or None or have an __index__ method")},
   515  		{"rindex", wrapArgs("foobar", "bar", NewInt(MaxInt)), nil, mustCreateException(ValueErrorType, "substring not found")},
   516  		{"rindex", wrapArgs("foobar", "bar", None, NewInt(MaxInt)), NewInt(3).ToObject(), nil},
   517  		{"rindex", wrapArgs("foobar", "bar", newObject(intIndexType)), NewInt(3).ToObject(), nil},
   518  		{"rindex", wrapArgs("foobar", "bar", None, newObject(intIndexType)), nil, mustCreateException(ValueErrorType, "substring not found")},
   519  		{"rindex", wrapArgs("foobar", "bar", newObject(longIndexType)), NewInt(3).ToObject(), nil},
   520  		{"rindex", wrapArgs("foobar", "bar", None, newObject(longIndexType)), nil, mustCreateException(ValueErrorType, "substring not found")},
   521  		// TODO: Support unicode substring.
   522  		{"rindex", wrapArgs("foobar", NewUnicode("bar")), nil, mustCreateException(TypeErrorType, "'find/index' requires a 'str' object but received a 'unicode'")},
   523  		{"rindex", wrapArgs("foobar", "bar", "baz"), nil, mustCreateException(TypeErrorType, "slice indices must be integers or None or have an __index__ method")},
   524  		{"rindex", wrapArgs("foobar", "bar", 0, "baz"), nil, mustCreateException(TypeErrorType, "slice indices must be integers or None or have an __index__ method")},
   525  		{"rindex", wrapArgs("foobar", "bar", None), NewInt(3).ToObject(), nil},
   526  		{"rindex", wrapArgs("foobar", "bar", 0, None), NewInt(3).ToObject(), nil},
   527  		{"rindex", wrapArgs("foobar", "bar", 0, -2), nil, mustCreateException(ValueErrorType, "substring not found")},
   528  		{"rindex", wrapArgs("foobar", "foo", 0, 3), NewInt(0).ToObject(), nil},
   529  		{"rindex", wrapArgs("foobar", "foo", 10), nil, mustCreateException(ValueErrorType, "substring not found")},
   530  		{"rindex", wrapArgs("foobar", "foo", 3, 3), nil, mustCreateException(ValueErrorType, "substring not found")},
   531  		{"rindex", wrapArgs("foobar", "bar", 3, 5), nil, mustCreateException(ValueErrorType, "substring not found")},
   532  		{"rindex", wrapArgs("foobar", "bar", 5, 3), nil, mustCreateException(ValueErrorType, "substring not found")},
   533  		{"rindex", wrapArgs("bar", "foobar"), nil, mustCreateException(ValueErrorType, "substring not found")},
   534  		{"rindex", wrapArgs("bar", "a", 1, 10), NewInt(1).ToObject(), nil},
   535  		{"rindex", wrapArgs("bar", "a", NewLong(big.NewInt(1)), 10), NewInt(1).ToObject(), nil},
   536  		{"rindex", wrapArgs("bar", "a", 0, NewLong(big.NewInt(2))), NewInt(1).ToObject(), nil},
   537  		{"rindex", wrapArgs("bar", "a", 1, 3), NewInt(1).ToObject(), nil},
   538  		{"rindex", wrapArgs("bar", "a", 0, -1), NewInt(1).ToObject(), nil},
   539  		{"rindex", wrapArgs("foo", newTestTuple("barfoo", "oo").ToObject()), nil, mustCreateException(TypeErrorType, "'find/index' requires a 'str' object but received a 'tuple'")},
   540  		{"rindex", wrapArgs("foo", 123), nil, mustCreateException(TypeErrorType, "'find/index' requires a 'str' object but received a 'int'")},
   541  		{"rindex", wrapArgs("barbaz", "ba"), NewInt(3).ToObject(), nil},
   542  		{"rindex", wrapArgs("barbaz", "ba", None, 4), NewInt(0).ToObject(), nil},
   543  		{"rjust", wrapArgs("foobar", 10, "#"), NewStr("####foobar").ToObject(), nil},
   544  		{"rjust", wrapArgs("foobar", 3, "#"), NewStr("foobar").ToObject(), nil},
   545  		{"rjust", wrapArgs("foobar", -1, "#"), NewStr("foobar").ToObject(), nil},
   546  		{"rjust", wrapArgs("foobar", 10, "##"), nil, mustCreateException(TypeErrorType, "rjust() argument 2 must be char, not str")},
   547  		{"rjust", wrapArgs("foobar", 10, ""), nil, mustCreateException(TypeErrorType, "rjust() argument 2 must be char, not str")},
   548  		{"split", wrapArgs("foo,bar", ","), newTestList("foo", "bar").ToObject(), nil},
   549  		{"split", wrapArgs("1,2,3", ",", 1), newTestList("1", "2,3").ToObject(), nil},
   550  		{"split", wrapArgs("a \tb\nc"), newTestList("a", "b", "c").ToObject(), nil},
   551  		{"split", wrapArgs("a \tb\nc", None), newTestList("a", "b", "c").ToObject(), nil},
   552  		{"split", wrapArgs("a \tb\nc", None, -1), newTestList("a", "b", "c").ToObject(), nil},
   553  		{"split", wrapArgs("a \tb\nc", None, 1), newTestList("a", "b\nc").ToObject(), nil},
   554  		{"split", wrapArgs("foo", 1), nil, mustCreateException(TypeErrorType, "expected a str separator")},
   555  		{"split", wrapArgs("foo", ""), nil, mustCreateException(ValueErrorType, "empty separator")},
   556  		{"split", wrapArgs(""), newTestList().ToObject(), nil},
   557  		{"split", wrapArgs(" "), newTestList().ToObject(), nil},
   558  		{"split", wrapArgs("", "x"), newTestList("").ToObject(), nil},
   559  		{"split", wrapArgs(" ", " ", 1), newTestList("", "").ToObject(), nil},
   560  		{"split", wrapArgs("aa", "a", 2), newTestList("", "", "").ToObject(), nil},
   561  		{"split", wrapArgs(" a ", "a"), newTestList(" ", " ").ToObject(), nil},
   562  		{"split", wrapArgs("a b c d", None, 1), newTestList("a", "b c d").ToObject(), nil},
   563  		{"split", wrapArgs("a b c d "), newTestList("a", "b", "c", "d").ToObject(), nil},
   564  		{"split", wrapArgs(" a b c d ", None, 1), newTestList("a", "b c d ").ToObject(), nil},
   565  		{"split", wrapArgs("   a b c d ", None, 0), newTestList("a b c d ").ToObject(), nil},
   566  		{"splitlines", wrapArgs(""), NewList().ToObject(), nil},
   567  		{"splitlines", wrapArgs("\n"), newTestList("").ToObject(), nil},
   568  		{"splitlines", wrapArgs("foo"), newTestList("foo").ToObject(), nil},
   569  		{"splitlines", wrapArgs("foo\r"), newTestList("foo").ToObject(), nil},
   570  		{"splitlines", wrapArgs("foo\r", true), newTestList("foo\r").ToObject(), nil},
   571  		{"splitlines", wrapArgs("foo\r\nbar\n", big.NewInt(12)), newTestList("foo\r\n", "bar\n").ToObject(), nil},
   572  		{"splitlines", wrapArgs("foo\n\r\nbar\n\n"), newTestList("foo", "", "bar", "").ToObject(), nil},
   573  		{"splitlines", wrapArgs("foo", newObject(ObjectType)), nil, mustCreateException(TypeErrorType, "an integer is required")},
   574  		{"splitlines", wrapArgs("foo", "bar", "baz"), nil, mustCreateException(TypeErrorType, "'splitlines' of 'str' requires 2 arguments")},
   575  		{"splitlines", wrapArgs("foo", overflowLong), nil, mustCreateException(OverflowErrorType, "Python int too large to convert to a Go int")},
   576  		{"startswith", wrapArgs("", ""), True.ToObject(), nil},
   577  		{"startswith", wrapArgs("", "", 1), False.ToObject(), nil},
   578  		{"startswith", wrapArgs("foobar", "foo"), True.ToObject(), nil},
   579  		{"startswith", wrapArgs("foobar", "foo", 2), False.ToObject(), nil},
   580  		{"startswith", wrapArgs("foobar", "bar", 3), True.ToObject(), nil},
   581  		{"startswith", wrapArgs("foobar", "bar", 3, 5), False.ToObject(), nil},
   582  		{"startswith", wrapArgs("foobar", "bar", 5, 3), False.ToObject(), nil},
   583  		{"startswith", wrapArgs("foo", "foobar"), False.ToObject(), nil},
   584  		{"startswith", wrapArgs("foo", newTestTuple("foobar", "fo").ToObject()), True.ToObject(), nil},
   585  		{"startswith", wrapArgs("foo", 123), nil, mustCreateException(TypeErrorType, "startswith first arg must be str, unicode, or tuple, not int")},
   586  		{"startswith", wrapArgs("foo", "f", "123"), nil, mustCreateException(TypeErrorType, "'startswith' requires a 'int' object but received a 'str'")},
   587  		{"startswith", wrapArgs("foo", newTestTuple(123).ToObject()), nil, mustCreateException(TypeErrorType, "expected a str")},
   588  		{"strip", wrapArgs("foo "), NewStr("foo").ToObject(), nil},
   589  		{"strip", wrapArgs(" foo bar "), NewStr("foo bar").ToObject(), nil},
   590  		{"strip", wrapArgs("foo foo", "o"), NewStr("foo f").ToObject(), nil},
   591  		{"strip", wrapArgs("foo bar", "abr"), NewStr("foo ").ToObject(), nil},
   592  		{"strip", wrapArgs("foo", NewUnicode("o")), NewUnicode("f").ToObject(), nil},
   593  		{"strip", wrapArgs("123", 3), nil, mustCreateException(TypeErrorType, "strip arg must be None, str or unicode")},
   594  		{"strip", wrapArgs("foo", "bar", "baz"), nil, mustCreateException(TypeErrorType, "'strip' of 'str' requires 2 arguments")},
   595  		{"strip", wrapArgs("\xfboo", NewUnicode("o")), nil, mustCreateException(UnicodeDecodeErrorType, "'utf8' codec can't decode byte 0xfb in position 0")},
   596  		{"strip", wrapArgs("foo", NewUnicode("o")), NewUnicode("f").ToObject(), nil},
   597  		{"partition", wrapArgs("foo", ""), nil, mustCreateException(ValueErrorType, "empty separator")},
   598  		{"partition", wrapArgs("foo", ":"), newTestTuple("foo", "", "").ToObject(), nil},
   599  		{"partition", wrapArgs(":foo", ":"), newTestTuple("", ":", "foo").ToObject(), nil},
   600  		{"partition", wrapArgs("foo:", ":"), newTestTuple("foo", ":", "").ToObject(), nil},
   601  		{"partition", wrapArgs("foo:bar", ":"), newTestTuple("foo", ":", "bar").ToObject(), nil},
   602  		{"partition", wrapArgs("foo:bar:zor", ":"), newTestTuple("foo", ":", "bar:zor").ToObject(), nil},
   603  		{"rpartition", wrapArgs("foo", ""), nil, mustCreateException(ValueErrorType, "empty separator")},
   604  		{"rpartition", wrapArgs("foo", ":"), newTestTuple("", "", "foo").ToObject(), nil},
   605  		{"rpartition", wrapArgs(":foo", ":"), newTestTuple("", ":", "foo").ToObject(), nil},
   606  		{"rpartition", wrapArgs("foo:", ":"), newTestTuple("foo", ":", "").ToObject(), nil},
   607  		{"rpartition", wrapArgs("foo:bar", ":"), newTestTuple("foo", ":", "bar").ToObject(), nil},
   608  		{"rpartition", wrapArgs("foo:bar:zor", ":"), newTestTuple("foo:bar", ":", "zor").ToObject(), nil},
   609  		{"replace", wrapArgs("one!two!three!", "!", "@", 1), NewStr("one@two!three!").ToObject(), nil},
   610  		{"replace", wrapArgs("one!two!three!", "!", ""), NewStr("onetwothree").ToObject(), nil},
   611  		{"replace", wrapArgs("one!two!three!", "!", "@", 2), NewStr("one@two@three!").ToObject(), nil},
   612  		{"replace", wrapArgs("one!two!three!", "!", "@", 3), NewStr("one@two@three@").ToObject(), nil},
   613  		{"replace", wrapArgs("one!two!three!", "!", "@", 4), NewStr("one@two@three@").ToObject(), nil},
   614  		{"replace", wrapArgs("one!two!three!", "!", "@", 0), NewStr("one!two!three!").ToObject(), nil},
   615  		{"replace", wrapArgs("one!two!three!", "!", "@"), NewStr("one@two@three@").ToObject(), nil},
   616  		{"replace", wrapArgs("one!two!three!", "x", "@"), NewStr("one!two!three!").ToObject(), nil},
   617  		{"replace", wrapArgs("one!two!three!", "x", "@", 2), NewStr("one!two!three!").ToObject(), nil},
   618  		{"replace", wrapArgs("\xd0\xb2\xd0\xbe\xd0\xbb", "", "\x00", -1), NewStr("\x00\xd0\x00\xb2\x00\xd0\x00\xbe\x00\xd0\x00\xbb\x00").ToObject(), nil},
   619  		{"replace", wrapArgs("\xd0\xb2\xd0\xbe\xd0\xbb", "", "\x01\x02", -1), NewStr("\x01\x02\xd0\x01\x02\xb2\x01\x02\xd0\x01\x02\xbe\x01\x02\xd0\x01\x02\xbb\x01\x02").ToObject(), nil},
   620  		{"replace", wrapArgs("abc", "", "-"), NewStr("-a-b-c-").ToObject(), nil},
   621  		{"replace", wrapArgs("abc", "", "-", 3), NewStr("-a-b-c").ToObject(), nil},
   622  		{"replace", wrapArgs("abc", "", "-", 0), NewStr("abc").ToObject(), nil},
   623  		{"replace", wrapArgs("", "", ""), NewStr("").ToObject(), nil},
   624  		{"replace", wrapArgs("", "", "a"), NewStr("a").ToObject(), nil},
   625  		{"replace", wrapArgs("abc", "a", "--", 0), NewStr("abc").ToObject(), nil},
   626  		{"replace", wrapArgs("abc", "xy", "--"), NewStr("abc").ToObject(), nil},
   627  		{"replace", wrapArgs("123", "123", ""), NewStr("").ToObject(), nil},
   628  		{"replace", wrapArgs("123123", "123", ""), NewStr("").ToObject(), nil},
   629  		{"replace", wrapArgs("123x123", "123", ""), NewStr("x").ToObject(), nil},
   630  		{"replace", wrapArgs("one!two!three!", "!", "@", NewLong(big.NewInt(1))), NewStr("one@two!three!").ToObject(), nil},
   631  		{"replace", wrapArgs("foobar", "bar", "baz", newObject(intIntType)), NewStr("foobaz").ToObject(), nil},
   632  		{"replace", wrapArgs("foobar", "bar", "baz", newObject(longIntType)), NewStr("foobaz").ToObject(), nil},
   633  		{"replace", wrapArgs("", "", "x"), NewStr("x").ToObject(), nil},
   634  		{"replace", wrapArgs("", "", "x", -1), NewStr("x").ToObject(), nil},
   635  		{"replace", wrapArgs("", "", "x", 0), NewStr("").ToObject(), nil},
   636  		{"replace", wrapArgs("", "", "x", 1), NewStr("").ToObject(), nil},
   637  		{"replace", wrapArgs("", "", "x", 1000), NewStr("").ToObject(), nil},
   638  		// TODO: Support unicode substring.
   639  		{"replace", wrapArgs("foobar", "", NewUnicode("bar")), nil, mustCreateException(TypeErrorType, "'replace' requires a 'str' object but received a 'unicode'")},
   640  		{"replace", wrapArgs("foobar", NewUnicode("bar"), ""), nil, mustCreateException(TypeErrorType, "'replace' requires a 'str' object but received a 'unicode'")},
   641  		{"replace", wrapArgs("foobar", "bar", "baz", None), nil, mustCreateException(TypeErrorType, "an integer is required")},
   642  		{"replace", wrapArgs("foobar", "bar", "baz", newObject(intIndexType)), nil, mustCreateException(TypeErrorType, "an integer is required")},
   643  		{"replace", wrapArgs("foobar", "bar", "baz", newObject(longIndexType)), nil, mustCreateException(TypeErrorType, "an integer is required")},
   644  		{"rstrip", wrapArgs("foo "), NewStr("foo").ToObject(), nil},
   645  		{"rstrip", wrapArgs(" foo bar "), NewStr(" foo bar").ToObject(), nil},
   646  		{"rstrip", wrapArgs("foo foo", "o"), NewStr("foo f").ToObject(), nil},
   647  		{"rstrip", wrapArgs("foo bar", "abr"), NewStr("foo ").ToObject(), nil},
   648  		{"rstrip", wrapArgs("foo", NewUnicode("o")), NewUnicode("f").ToObject(), nil},
   649  		{"rstrip", wrapArgs("123", 3), nil, mustCreateException(TypeErrorType, "strip arg must be None, str or unicode")},
   650  		{"rstrip", wrapArgs("foo", "bar", "baz"), nil, mustCreateException(TypeErrorType, "'strip' of 'str' requires 2 arguments")},
   651  		{"rstrip", wrapArgs("\xfboo", NewUnicode("o")), nil, mustCreateException(UnicodeDecodeErrorType, "'utf8' codec can't decode byte 0xfb in position 0")},
   652  		{"rstrip", wrapArgs("foo", NewUnicode("o")), NewUnicode("f").ToObject(), nil},
   653  		{"title", wrapArgs(""), NewStr("").ToObject(), nil},
   654  		{"title", wrapArgs("a"), NewStr("A").ToObject(), nil},
   655  		{"title", wrapArgs("A"), NewStr("A").ToObject(), nil},
   656  		{"title", wrapArgs(" a"), NewStr(" A").ToObject(), nil},
   657  		{"title", wrapArgs("abc def"), NewStr("Abc Def").ToObject(), nil},
   658  		{"title", wrapArgs("ABC DEF"), NewStr("Abc Def").ToObject(), nil},
   659  		{"title", wrapArgs("aBC dEF"), NewStr("Abc Def").ToObject(), nil},
   660  		{"title", wrapArgs("abc def", 123), nil, mustCreateException(TypeErrorType, "'title' of 'str' requires 1 arguments")},
   661  		{"title", wrapArgs(123), nil, mustCreateException(TypeErrorType, "unbound method title() must be called with str instance as first argument (got int instance instead)")},
   662  		{"title", wrapArgs("вол"), NewStr("вол").ToObject(), nil},
   663  		{"title", wrapArgs("ВОЛ"), NewStr("ВОЛ").ToObject(), nil},
   664  		{"upper", wrapArgs(""), NewStr("").ToObject(), nil},
   665  		{"upper", wrapArgs("a"), NewStr("A").ToObject(), nil},
   666  		{"upper", wrapArgs("A"), NewStr("A").ToObject(), nil},
   667  		{"upper", wrapArgs(" a"), NewStr(" A").ToObject(), nil},
   668  		{"upper", wrapArgs("abc"), NewStr("ABC").ToObject(), nil},
   669  		{"upper", wrapArgs("ABC"), NewStr("ABC").ToObject(), nil},
   670  		{"upper", wrapArgs("aBC"), NewStr("ABC").ToObject(), nil},
   671  		{"upper", wrapArgs("abc def", 123), nil, mustCreateException(TypeErrorType, "'upper' of 'str' requires 1 arguments")},
   672  		{"upper", wrapArgs(123), nil, mustCreateException(TypeErrorType, "unbound method upper() must be called with str instance as first argument (got int instance instead)")},
   673  		{"upper", wrapArgs("вол"), NewStr("вол").ToObject(), nil},
   674  		{"upper", wrapArgs("ВОЛ"), NewStr("ВОЛ").ToObject(), nil},
   675  		{"zfill", wrapArgs("123", 2), NewStr("123").ToObject(), nil},
   676  		{"zfill", wrapArgs("123", 3), NewStr("123").ToObject(), nil},
   677  		{"zfill", wrapArgs("123", 4), NewStr("0123").ToObject(), nil},
   678  		{"zfill", wrapArgs("+123", 3), NewStr("+123").ToObject(), nil},
   679  		{"zfill", wrapArgs("+123", 4), NewStr("+123").ToObject(), nil},
   680  		{"zfill", wrapArgs("+123", 5), NewStr("+0123").ToObject(), nil},
   681  		{"zfill", wrapArgs("-123", 3), NewStr("-123").ToObject(), nil},
   682  		{"zfill", wrapArgs("-123", 4), NewStr("-123").ToObject(), nil},
   683  		{"zfill", wrapArgs("-123", 5), NewStr("-0123").ToObject(), nil},
   684  		{"zfill", wrapArgs("123", NewLong(big.NewInt(3))), NewStr("123").ToObject(), nil},
   685  		{"zfill", wrapArgs("123", NewLong(big.NewInt(5))), NewStr("00123").ToObject(), nil},
   686  		{"zfill", wrapArgs("", 0), NewStr("").ToObject(), nil},
   687  		{"zfill", wrapArgs("", 1), NewStr("0").ToObject(), nil},
   688  		{"zfill", wrapArgs("", 3), NewStr("000").ToObject(), nil},
   689  		{"zfill", wrapArgs("", -1), NewStr("").ToObject(), nil},
   690  		{"zfill", wrapArgs("34", 1), NewStr("34").ToObject(), nil},
   691  		{"zfill", wrapArgs("34", 4), NewStr("0034").ToObject(), nil},
   692  		{"zfill", wrapArgs("34", None), nil, mustCreateException(TypeErrorType, "an integer is required")},
   693  		{"zfill", wrapArgs("", True), NewStr("0").ToObject(), nil},
   694  		{"zfill", wrapArgs("", False), NewStr("").ToObject(), nil},
   695  		{"zfill", wrapArgs("34", NewStr("test")), nil, mustCreateException(TypeErrorType, "an integer is required")},
   696  		{"zfill", wrapArgs("34"), nil, mustCreateException(TypeErrorType, "'zfill' of 'str' requires 2 arguments")},
   697  		{"swapcase", wrapArgs(""), NewStr("").ToObject(), nil},
   698  		{"swapcase", wrapArgs("a"), NewStr("A").ToObject(), nil},
   699  		{"swapcase", wrapArgs("A"), NewStr("a").ToObject(), nil},
   700  		{"swapcase", wrapArgs(" A"), NewStr(" a").ToObject(), nil},
   701  		{"swapcase", wrapArgs("abc"), NewStr("ABC").ToObject(), nil},
   702  		{"swapcase", wrapArgs("ABC"), NewStr("abc").ToObject(), nil},
   703  		{"swapcase", wrapArgs("aBC"), NewStr("Abc").ToObject(), nil},
   704  		{"swapcase", wrapArgs("abc def", 123), nil, mustCreateException(TypeErrorType, "'swapcase' of 'str' requires 1 arguments")},
   705  		{"swapcase", wrapArgs(123), nil, mustCreateException(TypeErrorType, "unbound method swapcase() must be called with str instance as first argument (got int instance instead)")},
   706  		{"swapcase", wrapArgs("вол"), NewStr("вол").ToObject(), nil},
   707  		{"swapcase", wrapArgs("ВОЛ"), NewStr("ВОЛ").ToObject(), nil},
   708  	}
   709  	for _, cas := range cases {
   710  		testCase := invokeTestCase{args: cas.args, want: cas.want, wantExc: cas.wantExc}
   711  		if err := runInvokeMethodTestCase(StrType, cas.methodName, &testCase); err != "" {
   712  			t.Error(err)
   713  		}
   714  	}
   715  }
   716  
   717  func TestStrStr(t *testing.T) {
   718  	cases := []invokeTestCase{
   719  		{args: wrapArgs("foo"), want: NewStr("foo").ToObject()},
   720  		{args: wrapArgs("on\nmultiple\nlines"), want: NewStr("on\nmultiple\nlines").ToObject()},
   721  		{args: wrapArgs("\x00\x00"), want: NewStr("\x00\x00").ToObject()},
   722  	}
   723  	for _, cas := range cases {
   724  		if err := runInvokeMethodTestCase(StrType, "__str__", &cas); err != "" {
   725  			t.Error(err)
   726  		}
   727  	}
   728  }