1from ctypes import *
2import unittest
3
4class SimpleTestCase(unittest.TestCase):
5    def test_cint(self):
6        x = c_int()
7        self.assertEqual(x._objects, None)
8        x.value = 42
9        self.assertEqual(x._objects, None)
10        x = c_int(99)
11        self.assertEqual(x._objects, None)
12
13    def test_ccharp(self):
14        x = c_char_p()
15        self.assertEqual(x._objects, None)
16        x.value = "abc"
17        self.assertEqual(x._objects, "abc")
18        x = c_char_p("spam")
19        self.assertEqual(x._objects, "spam")
20
21class StructureTestCase(unittest.TestCase):
22    def test_cint_struct(self):
23        class X(Structure):
24            _fields_ = [("a", c_int),
25                        ("b", c_int)]
26
27        x = X()
28        self.assertEqual(x._objects, None)
29        x.a = 42
30        x.b = 99
31        self.assertEqual(x._objects, None)
32
33    def test_ccharp_struct(self):
34        class X(Structure):
35            _fields_ = [("a", c_char_p),
36                        ("b", c_char_p)]
37        x = X()
38        self.assertEqual(x._objects, None)
39
40        x.a = "spam"
41        x.b = "foo"
42        self.assertEqual(x._objects, {"0": "spam", "1": "foo"})
43
44    def test_struct_struct(self):
45        class POINT(Structure):
46            _fields_ = [("x", c_int), ("y", c_int)]
47        class RECT(Structure):
48            _fields_ = [("ul", POINT), ("lr", POINT)]
49
50        r = RECT()
51        r.ul.x = 0
52        r.ul.y = 1
53        r.lr.x = 2
54        r.lr.y = 3
55        self.assertEqual(r._objects, None)
56
57        r = RECT()
58        pt = POINT(1, 2)
59        r.ul = pt
60        self.assertEqual(r._objects, {'0': {}})
61        r.ul.x = 22
62        r.ul.y = 44
63        self.assertEqual(r._objects, {'0': {}})
64        r.lr = POINT()
65        self.assertEqual(r._objects, {'0': {}, '1': {}})
66
67class ArrayTestCase(unittest.TestCase):
68    def test_cint_array(self):
69        INTARR = c_int * 3
70
71        ia = INTARR()
72        self.assertEqual(ia._objects, None)
73        ia[0] = 1
74        ia[1] = 2
75        ia[2] = 3
76        self.assertEqual(ia._objects, None)
77
78        class X(Structure):
79            _fields_ = [("x", c_int),
80                        ("a", INTARR)]
81
82        x = X()
83        x.x = 1000
84        x.a[0] = 42
85        x.a[1] = 96
86        self.assertEqual(x._objects, None)
87        x.a = ia
88        self.assertEqual(x._objects, {'1': {}})
89
90class PointerTestCase(unittest.TestCase):
91    def test_p_cint(self):
92        i = c_int(42)
93        x = pointer(i)
94        self.assertEqual(x._objects, {'1': i})
95
96class DeletePointerTestCase(unittest.TestCase):
97    def X_test(self):
98        class X(Structure):
99            _fields_ = [("p", POINTER(c_char_p))]
100        x = X()
101        i = c_char_p("abc def")
102        from sys import getrefcount as grc
103        print "2?", grc(i)
104        x.p = pointer(i)
105        print "3?", grc(i)
106        for i in range(320):
107            c_int(99)
108            x.p[0]
109        print x.p[0]
110##        del x
111##        print "2?", grc(i)
112##        del i
113        import gc
114        gc.collect()
115        for i in range(320):
116            c_int(99)
117            x.p[0]
118        print x.p[0]
119        print x.p.contents
120##        print x._objects
121
122        x.p[0] = "spam spam"
123##        print x.p[0]
124        print "+" * 42
125        print x._objects
126
127class PointerToStructure(unittest.TestCase):
128    def test(self):
129        class POINT(Structure):
130            _fields_ = [("x", c_int), ("y", c_int)]
131        class RECT(Structure):
132            _fields_ = [("a", POINTER(POINT)),
133                        ("b", POINTER(POINT))]
134        r = RECT()
135        p1 = POINT(1, 2)
136
137        r.a = pointer(p1)
138        r.b = pointer(p1)
139##        from pprint import pprint as pp
140##        pp(p1._objects)
141##        pp(r._objects)
142
143        r.a[0].x = 42
144        r.a[0].y = 99
145
146        # to avoid leaking when tests are run several times
147        # clean up the types left in the cache.
148        from ctypes import _pointer_type_cache
149        del _pointer_type_cache[POINT]
150
151if __name__ == "__main__":
152    unittest.main()
153