#!/usr/bin/env python
# UserString is a wrapper around the native builtin string type.
# UserString instances should behave similar to builtin string objects.

import string
from test import test_support, string_tests
from UserString import UserString, MutableString
import warnings

class UserStringTest(
    string_tests.CommonTest,
    string_tests.MixinStrUnicodeUserStringTest,
    string_tests.MixinStrStringUserStringTest,
    string_tests.MixinStrUserStringTest
    ):

    type2test = UserString

    # Overwrite the three testing methods, because UserString
    # can't cope with arguments propagated to UserString
    # (and we don't test with subclasses)
    def checkequal(self, result, object, methodname, *args):
        result = self.fixtype(result)
        object = self.fixtype(object)
        # we don't fix the arguments, because UserString can't cope with it
        realresult = getattr(object, methodname)(*args)
        self.assertEqual(
            result,
            realresult
        )

    def checkraises(self, exc, object, methodname, *args):
        object = self.fixtype(object)
        # we don't fix the arguments, because UserString can't cope with it
        self.assertRaises(
            exc,
            getattr(object, methodname),
            *args
        )

    def checkcall(self, object, methodname, *args):
        object = self.fixtype(object)
        # we don't fix the arguments, because UserString can't cope with it
        getattr(object, methodname)(*args)

class MutableStringTest(UserStringTest):
    type2test = MutableString

    # MutableStrings can be hashed => deactivate test
    def test_hash(self):
        pass

    def test_setitem(self):
        s = self.type2test("foo")
        self.assertRaises(IndexError, s.__setitem__, -4, "bar")
        self.assertRaises(IndexError, s.__setitem__, 3, "bar")
        s[-1] = "bar"
        self.assertEqual(s, "fobar")
        s[0] = "bar"
        self.assertEqual(s, "barobar")

    def test_delitem(self):
        s = self.type2test("foo")
        self.assertRaises(IndexError, s.__delitem__, -4)
        self.assertRaises(IndexError, s.__delitem__, 3)
        del s[-1]
        self.assertEqual(s, "fo")
        del s[0]
        self.assertEqual(s, "o")
        del s[0]
        self.assertEqual(s, "")

    def test_setslice(self):
        s = self.type2test("foo")
        s[:] = "bar"
        self.assertEqual(s, "bar")
        s[1:2] = "foo"
        self.assertEqual(s, "bfoor")
        s[1:-1] = UserString("a")
        self.assertEqual(s, "bar")
        s[0:10] = 42
        self.assertEqual(s, "42")

    def test_delslice(self):
        s = self.type2test("foobar")
        del s[3:10]
        self.assertEqual(s, "foo")
        del s[-1:10]
        self.assertEqual(s, "fo")

    def test_extended_set_del_slice(self):
        indices = (0, None, 1, 3, 19, 100, -1, -2, -31, -100)
        orig = string.ascii_letters + string.digits
        for start in indices:
            for stop in indices:
                # Use indices[1:] when MutableString can handle real
                # extended slices
                for step in (None, 1, -1):
                    s = self.type2test(orig)
                    L = list(orig)
                    # Make sure we have a slice of exactly the right length,
                    # but with (hopefully) different data.
                    data = L[start:stop:step]
                    data.reverse()
                    L[start:stop:step] = data
                    s[start:stop:step] = "".join(data)
                    self.assertEqual(s, "".join(L))

                    del L[start:stop:step]
                    del s[start:stop:step]
                    self.assertEqual(s, "".join(L))

    def test_immutable(self):
        s = self.type2test("foobar")
        s2 = s.immutable()
        self.assertEqual(s, s2)
        self.assertIsInstance(s2, UserString)

    def test_iadd(self):
        s = self.type2test("foo")
        s += "bar"
        self.assertEqual(s, "foobar")
        s += UserString("baz")
        self.assertEqual(s, "foobarbaz")
        s += 42
        self.assertEqual(s, "foobarbaz42")

    def test_imul(self):
        s = self.type2test("foo")
        s *= 1
        self.assertEqual(s, "foo")
        s *= 2
        self.assertEqual(s, "foofoo")
        s *= -1
        self.assertEqual(s, "")

def test_main():
    with warnings.catch_warnings():
        warnings.filterwarnings("ignore", ".*MutableString has been removed",
                                DeprecationWarning)
        warnings.filterwarnings("ignore",
                                ".*__(get|set|del)slice__ has been removed",
                                DeprecationWarning)
        test_support.run_unittest(UserStringTest, MutableStringTest)

if __name__ == "__main__":
    test_main()
