1"""
2Test handling of the private typecodes:  _C_CHAR_AS_BYTE
3
4This typecode doesn't actually exists in the ObjC runtime but
5are private to PyObjC. We use these to simplify the bridge code
6while at the same time getting a higher fidelity bridge.
7
8- Add tests for calling methods from ObjC
9"""
10import weakref, objc, sys
11from PyObjCTools.TestSupport import *
12from PyObjCTest.fnd import NSObject
13
14from PyObjCTest.specialtypecodes import *
15import array
16
17def setupMetaData():
18    objc.registerMetaDataForSelector(b"OC_TestSpecialTypeCode", b"byteValue",
19        dict(
20            retval=dict(type=objc._C_CHAR_AS_TEXT),
21        ))
22
23    objc.registerMetaDataForSelector(b"OC_TestSpecialTypeCode", b"byteArray",
24        dict(
25            retval=dict(type=objc._C_PTR+objc._C_CHAR_AS_TEXT, c_array_of_fixed_length=4),
26        ))
27
28    objc.registerMetaDataForSelector(b"OC_TestSpecialTypeCode", b"byteString",
29        dict(
30            retval=dict(type=objc._C_PTR + objc._C_CHAR_AS_TEXT, c_array_delimited_by_null=True),
31        ))
32
33    objc.registerMetaDataForSelector(b"OC_TestSpecialTypeCode", b"byteStringArg:",
34        dict(
35            arguments={
36                2: dict(type=objc._C_PTR + objc._C_CHAR_AS_TEXT, c_array_delimited_by_null=True, type_modifier=objc._C_IN),
37            }
38        ))
39
40    objc.registerMetaDataForSelector(b"OC_TestSpecialTypeCode", b"byteArg:andbyteArg:",
41        dict(
42            arguments={
43                2: dict(type=objc._C_CHAR_AS_TEXT),
44                3: dict(type=objc._C_CHAR_AS_TEXT),
45            }
46        ))
47    objc.registerMetaDataForSelector(b"OC_TestSpecialTypeCode", b"byteArrayOf4In:",
48        dict(
49            arguments={
50                2: dict(type=objc._C_PTR+objc._C_CHAR_AS_TEXT, type_modifier=objc._C_IN, c_array_of_fixed_length=4),
51            }
52        ))
53    objc.registerMetaDataForSelector(b"OC_TestSpecialTypeCode", b"byteArrayOf4Out:",
54        dict(
55            arguments={
56                2: dict(type=objc._C_PTR+objc._C_CHAR_AS_TEXT, type_modifier=objc._C_OUT, c_array_of_fixed_length=4),
57            }
58        ))
59    objc.registerMetaDataForSelector(b"OC_TestSpecialTypeCode", b"byteArrayOf4InOut:",
60        dict(
61            arguments={
62                2: dict(type=objc._C_PTR+objc._C_CHAR_AS_TEXT, type_modifier=objc._C_INOUT, c_array_of_fixed_length=4),
63            }
64        ))
65    objc.registerMetaDataForSelector(b"OC_TestSpecialTypeCode", b"byteArrayOfCount:In:",
66        dict(
67            arguments={
68                3: dict(type=objc._C_PTR+objc._C_CHAR_AS_TEXT, type_modifier=objc._C_IN, c_array_of_lenght_in_arg=2),
69            }
70        ))
71    objc.registerMetaDataForSelector(b"OC_TestSpecialTypeCode", b"byteArrayOfCount:Out:",
72        dict(
73            arguments={
74                3: dict(type=objc._C_PTR+objc._C_CHAR_AS_TEXT, type_modifier=objc._C_OUT, c_array_of_lenght_in_arg=2),
75            }
76        ))
77    objc.registerMetaDataForSelector(b"OC_TestSpecialTypeCode", b"byteArrayOfCount:InOut:",
78        dict(
79            arguments={
80                3: dict(type=objc._C_PTR+objc._C_CHAR_AS_TEXT, type_modifier=objc._C_INOUT, c_array_of_lenght_in_arg=2),
81            }
82        ))
83
84
85setupMetaData()
86
87class TestTypeCode_byte (TestCase):
88    def testReturnValue(self):
89        o = OC_TestSpecialTypeCode.alloc().init()
90
91        self.assertEquals(o.byteValue(), b'a')
92        self.assertEquals(o.byteValue(), b'\x37')
93        self.assertEquals(o.byteValue(), b'z')
94
95    def testReturnValueArray(self):
96        o = OC_TestSpecialTypeCode.alloc().init()
97
98        v = o.byteArray()
99        self.assertEquals(len(v), 4)
100        self.assertIsInstance(v, bytes)
101
102        if sys.version_info[0] == 2:
103            self.assertEquals(v[0], b'\x64')
104            self.assertEquals(v[1], b'\xc8')
105            self.assertEquals(v[2], b'\x96')
106            self.assertEquals(v[3], b'\x63')
107        else:
108            self.assertEquals(v[0], 0x64)
109            self.assertEquals(v[1], 0xc8)
110            self.assertEquals(v[2], 0x96)
111            self.assertEquals(v[3], 0x63)
112
113    def testReturnValueString(self):
114        o = OC_TestSpecialTypeCode.alloc().init()
115
116        v = o.byteString()
117        self.assertIsInstance(v, bytes)
118        self.assertEquals(v, b"hello world");
119
120    def testSimpleArg(self):
121        o = OC_TestSpecialTypeCode.alloc().init()
122
123        v = o.byteArg_andbyteArg_(b'\x44', b'\x99')
124        self.assertEquals(v, (unichr(0x44), unichr(0x99)))
125
126        v = o.byteArg_andbyteArg_(b'a', b'b')
127        self.assertEquals(v, ('a', 'b'))
128
129        self.assertRaises(ValueError, o.byteArg_andbyteArg_, 200, 100)
130
131    def testStringArgument(self):
132        o = OC_TestSpecialTypeCode.alloc().init()
133
134        v = o.byteStringArg_(b"hello world")
135        self.assertEquals(v, "hello world")
136        self.assertIsInstance(v, unicode)
137
138        v = o.byteStringArg_([b'a', b'b'])
139        self.assertIsInstance(v, unicode)
140        self.assertEquals(v, "ab")
141
142        self.assertRaises(ValueError,  o.byteStringArg_, [99, 100, 100, 0])
143
144    def testFixedArrayIn(self):
145        o = OC_TestSpecialTypeCode.alloc().init()
146
147        v = o.byteArrayOf4In_(b"work")
148        self.assertEquals(v, "work")
149
150        v = o.byteArrayOf4In_([b'a', b'b', b'c', b'd'])
151        self.assertEquals(v, 'abcd')
152
153        a = array.array('B', [200, 150, 80, 20])
154        v = o.byteArrayOf4In_(a)
155        self.assertEquals(v, u''.join([
156            unichr(200), unichr(150), unichr(80), unichr(20)]))
157
158    def testFixedArrayOut(self):
159        o = OC_TestSpecialTypeCode.alloc().init()
160
161        v = o.byteArrayOf4Out_(None)
162        self.assertEquals(v, b"boat")
163
164        o = OC_TestSpecialTypeCode.alloc().init()
165        a = array.array('b', [0] * 4)
166        v = o.byteArrayOf4Out_(a)
167        self.assertIs(v, a)
168        self.assertEquals(v[0], ord('b'))
169        self.assertEquals(v[1], ord('o'))
170        self.assertEquals(v[2], ord('a'))
171        self.assertEquals(v[3], ord('t'))
172
173    def testFixedArrayInOut_(self):
174        o = OC_TestSpecialTypeCode.alloc().init()
175
176        v, w = o.byteArrayOf4InOut_(b"foot")
177        self.assertEquals(v, "foot")
178        self.assertEquals(w, b"hand")
179
180if __name__ == "__main__":
181    main()
182