1"""
2Test handling of the private typecodes:
3    _C_NSBOOL, _C_CHAR_AS_INT, _C_CHAR_AS_TEXT and _C_UNICHAR
4
5These typecodes don't actually exists in the ObjC runtime but
6are private to PyObjC. We use these to simplify the bridge code
7while at the same time getting a higher fidelity bridge.
8
9TODO:
10- Add support for UniChar
11- Add support for char-as-int
12- Add support for char-as-text
13
14  (all these need the 0 terminated support as well)
15
16- Add tests for calling methods from ObjC
17- Add tests with these types in struct definitions
18- Review test cases to make sure the tests are complete enough
19"""
20import weakref
21from PyObjCTools.TestSupport import *
22from PyObjCTest.fnd import NSObject
23
24from PyObjCTest.specialtypecodes import *
25import array
26
27def setupMetaData():
28    objc.registerMetaDataForSelector("OC_TestSpecialTypeCode", "BOOLValue",
29        dict(
30            retval=dict(type=objc._C_NSBOOL),
31        ))
32
33    objc.registerMetaDataForSelector("OC_TestSpecialTypeCode", "BOOLArray",
34        dict(
35            retval=dict(type=objc._C_PTR+objc._C_NSBOOL, c_array_of_fixed_length=4),
36        ))
37
38    objc.registerMetaDataForSelector("OC_TestSpecialTypeCode", "BOOLArg:andBOOLArg:",
39        dict(
40            arguments={
41                2: dict(type=objc._C_NSBOOL),
42                3: dict(type=objc._C_NSBOOL),
43            }
44        ))
45    objc.registerMetaDataForSelector("OC_TestSpecialTypeCode", "BOOLArrayOf4In:",
46        dict(
47            arguments={
48                2: dict(type=objc._C_PTR+objc._C_NSBOOL, type_modifier=objc._C_IN, c_array_of_fixed_length=4),
49            }
50        ))
51    objc.registerMetaDataForSelector("OC_TestSpecialTypeCode", "BOOLArrayOf4Out:",
52        dict(
53            arguments={
54                2: dict(type=objc._C_PTR+objc._C_NSBOOL, type_modifier=objc._C_OUT, c_array_of_fixed_length=4),
55            }
56        ))
57    objc.registerMetaDataForSelector("OC_TestSpecialTypeCode", "BOOLArrayOf4InOut:",
58        dict(
59            arguments={
60                2: dict(type=objc._C_PTR+objc._C_NSBOOL, type_modifier=objc._C_INOUT, c_array_of_fixed_length=4),
61            }
62        ))
63    objc.registerMetaDataForSelector("OC_TestSpecialTypeCode", "BOOLArrayOfCount:In:",
64        dict(
65            arguments={
66                3: dict(type=objc._C_PTR+objc._C_NSBOOL, type_modifier=objc._C_IN, c_array_of_lenght_in_arg=2),
67            }
68        ))
69    objc.registerMetaDataForSelector("OC_TestSpecialTypeCode", "BOOLArrayOfCount:Out:",
70        dict(
71            arguments={
72                3: dict(type=objc._C_PTR+objc._C_NSBOOL, type_modifier=objc._C_OUT, c_array_of_lenght_in_arg=2),
73            }
74        ))
75    objc.registerMetaDataForSelector("OC_TestSpecialTypeCode", "BOOLArrayOfCount:InOut:",
76        dict(
77            arguments={
78                3: dict(type=objc._C_PTR+objc._C_NSBOOL, type_modifier=objc._C_INOUT, c_array_of_lenght_in_arg=2),
79            }
80        ))
81
82
83setupMetaData()
84
85class TestTypeCode_BOOL (TestCase):
86    def testReturnValue(self):
87        o = OC_TestSpecialTypeCode.alloc().init()
88
89        self.assert_(o.BOOLValue() is True)
90        self.assert_(o.BOOLValue() is False)
91
92    def testReturnValueArray(self):
93        o = OC_TestSpecialTypeCode.alloc().init()
94
95        v = o.BOOLArray()
96        self.assertEquals(len(v), 4)
97        self.assert_(v[0] is True)
98        self.assert_(v[1] is False)
99        self.assert_(v[2] is True)
100        self.assert_(v[3] is False)
101
102    def testSimpleArg(self):
103        o = OC_TestSpecialTypeCode.alloc().init()
104
105        v = o.BOOLArg_andBOOLArg_(True, False)
106        self.assertEquals(v, (1, 0))
107
108        v = o.BOOLArg_andBOOLArg_(False, True)
109        self.assertEquals(v, (0, 1))
110
111    def testFixedArrayIn(self):
112        o = OC_TestSpecialTypeCode.alloc().init()
113
114        v = o.BOOLArrayOf4In_([True, False, True, False])
115        self.assertEquals(v, (1, 0, 1, 0))
116
117        v = o.BOOLArrayOf4In_([False, True, False, True])
118        self.assertEquals(v, (0, 1, 0, 1))
119
120        a = array.array('b', [1, 0, 1, 0])
121        v = o.BOOLArrayOf4In_(a)
122        self.assertEquals(v, (1, 0, 1, 0))
123
124        # It should not be possible to use a string as an array of booleans
125        self.assertRaises(ValueError, o.BOOLArrayOf4In_, "\x00\x01\x00\x01")
126
127    def testFixedArrayOut(self):
128        o = OC_TestSpecialTypeCode.alloc().init()
129
130        v = o.BOOLArrayOf4Out_(None)
131        self.assertEquals(v, (True, False, True, False))
132
133        v = o.BOOLArrayOf4Out_(None)
134        self.assertEquals(v, (False, True, False, True))
135
136        v = o.BOOLArrayOf4Out_(None)
137        self.assertEquals(v, (True, True, True, True))
138
139        v = o.BOOLArrayOf4Out_(None)
140        self.assertEquals(v, (False, False, False, False))
141
142        o = OC_TestSpecialTypeCode.alloc().init()
143        a = array.array('b', [0] * 4)
144        v = o.BOOLArrayOf4Out_(a)
145        self.assert_(v is a)
146        self.assertEquals(v[0], 1)
147        self.assertEquals(v[1], 0)
148        self.assertEquals(v[2], 1)
149        self.assertEquals(v[3], 0)
150
151    def testFixedArrayInOut_(self):
152        o = OC_TestSpecialTypeCode.alloc().init()
153
154        v, w = o.BOOLArrayOf4InOut_([True, False, True, False])
155        self.assertEquals(v, (True, False, True, False))
156        self.assertEquals(w, (True, True, True, True))
157
158        v, w = o.BOOLArrayOf4InOut_([False, True, False, True])
159        self.assertEquals(v, (False, True, False, True))
160        self.assertEquals(w, (False, False, False, False))
161
162        # It should not be possible to use a string as an array of booleans
163        self.assertRaises(ValueError, o.BOOLArrayOf4InOut_, "\x00\x01\x00\x01")
164
165if __name__ == "__main__":
166    main()
167