Home | History | Annotate | Download | only in test
      1 # coding: latin-1
      2 import unittest
      3 import ctypes
      4 
      5 try:
      6     ctypes.c_wchar
      7 except AttributeError:
      8     pass
      9 else:
     10     import _ctypes_test
     11     dll = ctypes.CDLL(_ctypes_test.__file__)
     12     wcslen = dll.my_wcslen
     13     wcslen.argtypes = [ctypes.c_wchar_p]
     14 
     15 
     16     class UnicodeTestCase(unittest.TestCase):
     17         def setUp(self):
     18             self.prev_conv_mode = ctypes.set_conversion_mode("ascii", "strict")
     19 
     20         def tearDown(self):
     21             ctypes.set_conversion_mode(*self.prev_conv_mode)
     22 
     23         def test_ascii_strict(self):
     24             ctypes.set_conversion_mode("ascii", "strict")
     25             # no conversions take place with unicode arguments
     26             self.assertEqual(wcslen(u"abc"), 3)
     27             self.assertEqual(wcslen(u"ab\u2070"), 3)
     28             # string args are converted
     29             self.assertEqual(wcslen("abc"), 3)
     30             self.assertRaises(ctypes.ArgumentError, wcslen, "ab")
     31 
     32         def test_ascii_replace(self):
     33             ctypes.set_conversion_mode("ascii", "replace")
     34             self.assertEqual(wcslen(u"abc"), 3)
     35             self.assertEqual(wcslen(u"ab\u2070"), 3)
     36             self.assertEqual(wcslen("abc"), 3)
     37             self.assertEqual(wcslen("ab"), 3)
     38 
     39         def test_ascii_ignore(self):
     40             ctypes.set_conversion_mode("ascii", "ignore")
     41             self.assertEqual(wcslen(u"abc"), 3)
     42             self.assertEqual(wcslen(u"ab\u2070"), 3)
     43             # ignore error mode skips non-ascii characters
     44             self.assertEqual(wcslen("abc"), 3)
     45             self.assertEqual(wcslen(""), 0)
     46 
     47         def test_latin1_strict(self):
     48             ctypes.set_conversion_mode("latin-1", "strict")
     49             self.assertEqual(wcslen(u"abc"), 3)
     50             self.assertEqual(wcslen(u"ab\u2070"), 3)
     51             self.assertEqual(wcslen("abc"), 3)
     52             self.assertEqual(wcslen(""), 4)
     53 
     54         def test_buffers(self):
     55             ctypes.set_conversion_mode("ascii", "strict")
     56             buf = ctypes.create_unicode_buffer("abc")
     57             self.assertEqual(len(buf), 3+1)
     58 
     59             ctypes.set_conversion_mode("ascii", "replace")
     60             buf = ctypes.create_unicode_buffer("ab")
     61             self.assertEqual(buf[:], u"ab\uFFFD\uFFFD\uFFFD\0")
     62             self.assertEqual(buf[::], u"ab\uFFFD\uFFFD\uFFFD\0")
     63             self.assertEqual(buf[::-1], u"\0\uFFFD\uFFFD\uFFFDba")
     64             self.assertEqual(buf[::2], u"a\uFFFD\uFFFD")
     65             self.assertEqual(buf[6:5:-1], u"")
     66 
     67             ctypes.set_conversion_mode("ascii", "ignore")
     68             buf = ctypes.create_unicode_buffer("ab")
     69             # is that correct? not sure.  But with 'ignore', you get what you pay for..
     70             self.assertEqual(buf[:], u"ab\0\0\0\0")
     71             self.assertEqual(buf[::], u"ab\0\0\0\0")
     72             self.assertEqual(buf[::-1], u"\0\0\0\0ba")
     73             self.assertEqual(buf[::2], u"a\0\0")
     74             self.assertEqual(buf[6:5:-1], u"")
     75 
     76     import _ctypes_test
     77     func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p
     78 
     79     class StringTestCase(UnicodeTestCase):
     80         def setUp(self):
     81             self.prev_conv_mode = ctypes.set_conversion_mode("ascii", "strict")
     82             func.argtypes = [ctypes.c_char_p]
     83             func.restype = ctypes.c_char_p
     84 
     85         def tearDown(self):
     86             ctypes.set_conversion_mode(*self.prev_conv_mode)
     87             func.argtypes = None
     88             func.restype = ctypes.c_int
     89 
     90         def test_ascii_replace(self):
     91             ctypes.set_conversion_mode("ascii", "strict")
     92             self.assertEqual(func("abc"), "abc")
     93             self.assertEqual(func(u"abc"), "abc")
     94             self.assertRaises(ctypes.ArgumentError, func, u"ab")
     95 
     96         def test_ascii_ignore(self):
     97             ctypes.set_conversion_mode("ascii", "ignore")
     98             self.assertEqual(func("abc"), "abc")
     99             self.assertEqual(func(u"abc"), "abc")
    100             self.assertEqual(func(u""), "")
    101 
    102         def test_ascii_replace(self):
    103             ctypes.set_conversion_mode("ascii", "replace")
    104             self.assertEqual(func("abc"), "abc")
    105             self.assertEqual(func(u"abc"), "abc")
    106             self.assertEqual(func(u""), "????")
    107 
    108         def test_buffers(self):
    109             ctypes.set_conversion_mode("ascii", "strict")
    110             buf = ctypes.create_string_buffer(u"abc")
    111             self.assertEqual(len(buf), 3+1)
    112 
    113             ctypes.set_conversion_mode("ascii", "replace")
    114             buf = ctypes.create_string_buffer(u"ab")
    115             self.assertEqual(buf[:], "ab???\0")
    116             self.assertEqual(buf[::], "ab???\0")
    117             self.assertEqual(buf[::-1], "\0???ba")
    118             self.assertEqual(buf[::2], "a??")
    119             self.assertEqual(buf[6:5:-1], "")
    120 
    121             ctypes.set_conversion_mode("ascii", "ignore")
    122             buf = ctypes.create_string_buffer(u"ab")
    123             # is that correct? not sure.  But with 'ignore', you get what you pay for..
    124             self.assertEqual(buf[:], "ab\0\0\0\0")
    125             self.assertEqual(buf[::], "ab\0\0\0\0")
    126             self.assertEqual(buf[::-1], "\0\0\0\0ba")
    127 
    128 if __name__ == '__main__':
    129     unittest.main()
    130