1# UserString is a wrapper around the native builtin string type.
2# UserString instances should behave similar to builtin string objects.
3
4import string
5from test import test_support, string_tests
6from UserString import UserString, MutableString
7import warnings
8
9class UserStringTest(
10    string_tests.CommonTest,
11    string_tests.MixinStrUnicodeUserStringTest,
12    string_tests.MixinStrStringUserStringTest,
13    string_tests.MixinStrUserStringTest
14    ):
15
16    type2test = UserString
17
18    # Overwrite the three testing methods, because UserString
19    # can't cope with arguments propagated to UserString
20    # (and we don't test with subclasses)
21    def checkequal(self, result, object, methodname, *args):
22        result = self.fixtype(result)
23        object = self.fixtype(object)
24        # we don't fix the arguments, because UserString can't cope with it
25        realresult = getattr(object, methodname)(*args)
26        self.assertEqual(
27            result,
28            realresult
29        )
30
31    def checkraises(self, exc, obj, methodname, *args):
32        obj = self.fixtype(obj)
33        # we don't fix the arguments, because UserString can't cope with it
34        with self.assertRaises(exc) as cm:
35            getattr(obj, methodname)(*args)
36        self.assertNotEqual(cm.exception.args[0], '')
37
38    def checkcall(self, object, methodname, *args):
39        object = self.fixtype(object)
40        # we don't fix the arguments, because UserString can't cope with it
41        getattr(object, methodname)(*args)
42
43class MutableStringTest(UserStringTest):
44    type2test = MutableString
45
46    # MutableStrings can be hashed => deactivate test
47    def test_hash(self):
48        pass
49
50    def test_setitem(self):
51        s = self.type2test("foo")
52        self.assertRaises(IndexError, s.__setitem__, -4, "bar")
53        self.assertRaises(IndexError, s.__setitem__, 3, "bar")
54        s[-1] = "bar"
55        self.assertEqual(s, "fobar")
56        s[0] = "bar"
57        self.assertEqual(s, "barobar")
58
59    def test_delitem(self):
60        s = self.type2test("foo")
61        self.assertRaises(IndexError, s.__delitem__, -4)
62        self.assertRaises(IndexError, s.__delitem__, 3)
63        del s[-1]
64        self.assertEqual(s, "fo")
65        del s[0]
66        self.assertEqual(s, "o")
67        del s[0]
68        self.assertEqual(s, "")
69
70    def test_setslice(self):
71        s = self.type2test("foo")
72        s[:] = "bar"
73        self.assertEqual(s, "bar")
74        s[1:2] = "foo"
75        self.assertEqual(s, "bfoor")
76        s[1:-1] = UserString("a")
77        self.assertEqual(s, "bar")
78        s[0:10] = 42
79        self.assertEqual(s, "42")
80
81    def test_delslice(self):
82        s = self.type2test("foobar")
83        del s[3:10]
84        self.assertEqual(s, "foo")
85        del s[-1:10]
86        self.assertEqual(s, "fo")
87
88    def test_extended_set_del_slice(self):
89        indices = (0, None, 1, 3, 19, 100, -1, -2, -31, -100)
90        orig = string.ascii_letters + string.digits
91        for start in indices:
92            for stop in indices:
93                # Use indices[1:] when MutableString can handle real
94                # extended slices
95                for step in (None, 1, -1):
96                    s = self.type2test(orig)
97                    L = list(orig)
98                    # Make sure we have a slice of exactly the right length,
99                    # but with (hopefully) different data.
100                    data = L[start:stop:step]
101                    data.reverse()
102                    L[start:stop:step] = data
103                    s[start:stop:step] = "".join(data)
104                    self.assertEqual(s, "".join(L))
105
106                    del L[start:stop:step]
107                    del s[start:stop:step]
108                    self.assertEqual(s, "".join(L))
109
110    def test_immutable(self):
111        s = self.type2test("foobar")
112        s2 = s.immutable()
113        self.assertEqual(s, s2)
114        self.assertIsInstance(s2, UserString)
115
116    def test_iadd(self):
117        s = self.type2test("foo")
118        s += "bar"
119        self.assertEqual(s, "foobar")
120        s += UserString("baz")
121        self.assertEqual(s, "foobarbaz")
122        s += 42
123        self.assertEqual(s, "foobarbaz42")
124
125    def test_imul(self):
126        s = self.type2test("foo")
127        s *= 1
128        self.assertEqual(s, "foo")
129        s *= 2
130        self.assertEqual(s, "foofoo")
131        s *= -1
132        self.assertEqual(s, "")
133
134def test_main():
135    with warnings.catch_warnings():
136        warnings.filterwarnings("ignore", ".*MutableString has been removed",
137                                DeprecationWarning)
138        warnings.filterwarnings("ignore",
139                                ".*__(get|set|del)slice__ has been removed",
140                                DeprecationWarning)
141        test_support.run_unittest(UserStringTest, MutableStringTest)
142
143if __name__ == "__main__":
144    test_main()
145