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