Commit da77ee03 authored by YOU's avatar YOU Committed by Dylan Trotter

Implement str.lower, upper, title (#93)

parent 24d08dca
...@@ -314,6 +314,15 @@ func strLen(f *Frame, o *Object) (*Object, *BaseException) { ...@@ -314,6 +314,15 @@ func strLen(f *Frame, o *Object) (*Object, *BaseException) {
return NewInt(len(toStrUnsafe(o).Value())).ToObject(), nil return NewInt(len(toStrUnsafe(o).Value())).ToObject(), nil
} }
func strLower(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
expectedTypes := []*Type{StrType}
if raised := checkMethodArgs(f, "lower", args, expectedTypes...); raised != nil {
return nil, raised
}
s := toStrUnsafe(args[0]).Value()
return NewStr(strings.ToLower(s)).ToObject(), nil
}
func strLT(f *Frame, v, w *Object) (*Object, *BaseException) { func strLT(f *Frame, v, w *Object) (*Object, *BaseException) {
return strCompare(v, w, True, False, False), nil return strCompare(v, w, True, False, False), nil
} }
...@@ -520,9 +529,12 @@ func initStrType(dict map[string]*Object) { ...@@ -520,9 +529,12 @@ func initStrType(dict map[string]*Object) {
dict["decode"] = newBuiltinFunction("decode", strDecode).ToObject() dict["decode"] = newBuiltinFunction("decode", strDecode).ToObject()
dict["endswith"] = newBuiltinFunction("endswith", strEndsWith).ToObject() dict["endswith"] = newBuiltinFunction("endswith", strEndsWith).ToObject()
dict["join"] = newBuiltinFunction("join", strJoin).ToObject() dict["join"] = newBuiltinFunction("join", strJoin).ToObject()
dict["lower"] = newBuiltinFunction("lower", strLower).ToObject()
dict["split"] = newBuiltinFunction("split", strSplit).ToObject() dict["split"] = newBuiltinFunction("split", strSplit).ToObject()
dict["startswith"] = newBuiltinFunction("startswith", strStartsWith).ToObject() dict["startswith"] = newBuiltinFunction("startswith", strStartsWith).ToObject()
dict["strip"] = newBuiltinFunction("strip", strStrip).ToObject() dict["strip"] = newBuiltinFunction("strip", strStrip).ToObject()
dict["title"] = newBuiltinFunction("title", strTitle).ToObject()
dict["upper"] = newBuiltinFunction("upper", strUpper).ToObject()
StrType.slots.Add = &binaryOpSlot{strAdd} StrType.slots.Add = &binaryOpSlot{strAdd}
StrType.slots.Contains = &binaryOpSlot{strContains} StrType.slots.Contains = &binaryOpSlot{strContains}
StrType.slots.Eq = &binaryOpSlot{strEq} StrType.slots.Eq = &binaryOpSlot{strEq}
...@@ -731,6 +743,24 @@ func strStartsEndsWith(f *Frame, method string, args Args) (*Object, *BaseExcept ...@@ -731,6 +743,24 @@ func strStartsEndsWith(f *Frame, method string, args Args) (*Object, *BaseExcept
return False.ToObject(), nil return False.ToObject(), nil
} }
func strTitle(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
expectedTypes := []*Type{StrType}
if raised := checkMethodArgs(f, "title", args, expectedTypes...); raised != nil {
return nil, raised
}
s := toStrUnsafe(args[0]).Value()
return NewStr(strings.Title(strings.ToLower(s))).ToObject(), nil
}
func strUpper(f *Frame, args Args, kwargs KWArgs) (*Object, *BaseException) {
expectedTypes := []*Type{StrType}
if raised := checkMethodArgs(f, "upper", args, expectedTypes...); raised != nil {
return nil, raised
}
s := toStrUnsafe(args[0]).Value()
return NewStr(strings.ToUpper(s)).ToObject(), nil
}
func init() { func init() {
InternStr("") InternStr("")
for i := 0; i < 256; i++ { for i := 0; i < 256; i++ {
......
...@@ -266,6 +266,15 @@ func TestStrMethods(t *testing.T) { ...@@ -266,6 +266,15 @@ func TestStrMethods(t *testing.T) {
{"join", wrapArgs("nope", newTestTuple("foo")), NewStr("foo").ToObject(), nil}, {"join", wrapArgs("nope", newTestTuple("foo")), NewStr("foo").ToObject(), nil},
{"join", wrapArgs(",", newTestList("foo", "bar", 3.14)), nil, mustCreateException(TypeErrorType, "sequence item 2: expected string, float found")}, {"join", wrapArgs(",", newTestList("foo", "bar", 3.14)), nil, mustCreateException(TypeErrorType, "sequence item 2: expected string, float found")},
{"join", wrapArgs("\xff", newTestList(NewUnicode("foo"), NewUnicode("bar"))), nil, mustCreateException(UnicodeDecodeErrorType, "'utf8' codec can't decode byte 0xff in position 0")}, {"join", wrapArgs("\xff", newTestList(NewUnicode("foo"), NewUnicode("bar"))), nil, mustCreateException(UnicodeDecodeErrorType, "'utf8' codec can't decode byte 0xff in position 0")},
{"lower", wrapArgs(""), NewStr("").ToObject(), nil},
{"lower", wrapArgs("a"), NewStr("a").ToObject(), nil},
{"lower", wrapArgs("A"), NewStr("a").ToObject(), nil},
{"lower", wrapArgs(" A"), NewStr(" a").ToObject(), nil},
{"lower", wrapArgs("abc"), NewStr("abc").ToObject(), nil},
{"lower", wrapArgs("ABC"), NewStr("abc").ToObject(), nil},
{"lower", wrapArgs("aBC"), NewStr("abc").ToObject(), nil},
{"lower", wrapArgs("abc def", 123), nil, mustCreateException(TypeErrorType, "'lower' of 'str' requires 1 arguments")},
{"lower", wrapArgs(123), nil, mustCreateException(TypeErrorType, "unbound method lower() must be called with str instance as first argument (got int instance instead)")},
{"split", wrapArgs("foo,bar", ","), newTestList("foo", "bar").ToObject(), nil}, {"split", wrapArgs("foo,bar", ","), newTestList("foo", "bar").ToObject(), nil},
{"split", wrapArgs("1,2,3", ",", 1), newTestList("1", "2,3").ToObject(), nil}, {"split", wrapArgs("1,2,3", ",", 1), newTestList("1", "2,3").ToObject(), nil},
{"split", wrapArgs("a \tb\nc"), newTestList("a", "b", "c").ToObject(), nil}, {"split", wrapArgs("a \tb\nc"), newTestList("a", "b", "c").ToObject(), nil},
...@@ -295,6 +304,24 @@ func TestStrMethods(t *testing.T) { ...@@ -295,6 +304,24 @@ func TestStrMethods(t *testing.T) {
{"strip", wrapArgs("foo", "bar", "baz"), nil, mustCreateException(TypeErrorType, "'strip' of 'str' requires 2 arguments")}, {"strip", wrapArgs("foo", "bar", "baz"), nil, mustCreateException(TypeErrorType, "'strip' of 'str' requires 2 arguments")},
{"strip", wrapArgs("\xfboo", NewUnicode("o")), nil, mustCreateException(UnicodeDecodeErrorType, "'utf8' codec can't decode byte 0xfb in position 0")}, {"strip", wrapArgs("\xfboo", NewUnicode("o")), nil, mustCreateException(UnicodeDecodeErrorType, "'utf8' codec can't decode byte 0xfb in position 0")},
{"strip", wrapArgs("foo", NewUnicode("o")), NewUnicode("f").ToObject(), nil}, {"strip", wrapArgs("foo", NewUnicode("o")), NewUnicode("f").ToObject(), nil},
{"title", wrapArgs(""), NewStr("").ToObject(), nil},
{"title", wrapArgs("a"), NewStr("A").ToObject(), nil},
{"title", wrapArgs("A"), NewStr("A").ToObject(), nil},
{"title", wrapArgs(" a"), NewStr(" A").ToObject(), nil},
{"title", wrapArgs("abc def"), NewStr("Abc Def").ToObject(), nil},
{"title", wrapArgs("ABC DEF"), NewStr("Abc Def").ToObject(), nil},
{"title", wrapArgs("aBC dEF"), NewStr("Abc Def").ToObject(), nil},
{"title", wrapArgs("abc def", 123), nil, mustCreateException(TypeErrorType, "'title' of 'str' requires 1 arguments")},
{"title", wrapArgs(123), nil, mustCreateException(TypeErrorType, "unbound method title() must be called with str instance as first argument (got int instance instead)")},
{"upper", wrapArgs(""), NewStr("").ToObject(), nil},
{"upper", wrapArgs("a"), NewStr("A").ToObject(), nil},
{"upper", wrapArgs("A"), NewStr("A").ToObject(), nil},
{"upper", wrapArgs(" a"), NewStr(" A").ToObject(), nil},
{"upper", wrapArgs("abc"), NewStr("ABC").ToObject(), nil},
{"upper", wrapArgs("ABC"), NewStr("ABC").ToObject(), nil},
{"upper", wrapArgs("aBC"), NewStr("ABC").ToObject(), nil},
{"upper", wrapArgs("abc def", 123), nil, mustCreateException(TypeErrorType, "'upper' of 'str' requires 1 arguments")},
{"upper", wrapArgs(123), nil, mustCreateException(TypeErrorType, "unbound method upper() must be called with str instance as first argument (got int instance instead)")},
} }
for _, cas := range cases { for _, cas := range cases {
testCase := invokeTestCase{args: cas.args, want: cas.want, wantExc: cas.wantExc} testCase := invokeTestCase{args: cas.args, want: cas.want, wantExc: cas.wantExc}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment