svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r23023:HEAD
[blender.git] / release / test / rna_array.py
1 import unittest
2 import random
3
4 test= bpy.data.test
5
6 # farr - 1-dimensional array of float
7 # fdarr - dynamic 1-dimensional array of float
8 # fmarr - 3-dimensional ([3][4][5]) array of float
9 # fdmarr - dynamic 3-dimensional (ditto size) array of float
10
11 # same as above for other types except that the first letter is "i" for int and "b" for bool
12
13 class TestArray(unittest.TestCase):
14         # test that assignment works by: assign -> test value
15         # - rvalue = list of float
16         # - rvalue = list of numbers
17         # test.object
18         # bpy.data.test.farr[3], iarr[3], barr[...], fmarr, imarr, bmarr
19
20         def setUp(self):
21                 test.farr= (1.0, 2.0, 3.0)
22                 test.iarr= (7, 8, 9)
23                 test.barr= (False, True, False)
24         
25         # test access
26         # test slice access, negative indices
27         def test_access(self):
28                 rvals= ([1.0, 2.0, 3.0], [7, 8, 9], [False, True, False])
29                 for arr, rval in zip((test.farr, test.iarr, test.barr), rvals):
30                         self.assertEqual(prop_to_list(arr), rval)
31                         self.assertEqual(arr[0:3], rval)
32                         self.assertEqual(arr[1:2], rval[1:2])
33                         self.assertEqual(arr[-1], arr[2])
34                         self.assertEqual(arr[-2], arr[1])
35                         self.assertEqual(arr[-3], arr[0])
36
37         # fail when index out of bounds
38         def test_access_fail(self):
39                 for arr in (test.farr, test.iarr, test.barr):
40                         self.assertRaises(IndexError, lambda : arr[4])
41         
42         # test assignment of a whole array
43         def test_assign_array(self):
44                 # should accept int as float
45                 test.farr= (1, 2, 3)
46
47         # fail when: unexpected no. of items, invalid item type
48         def test_assign_array_fail(self):
49                 def assign_empty_list(arr):
50                         setattr(test, arr, ())
51
52                 for arr in ("farr", "iarr", "barr"):
53                         self.assertRaises(ValueError, assign_empty_list, arr)
54
55                 def assign_invalid_float():
56                         test.farr= (1.0, 2.0, "3.0")
57
58                 def assign_invalid_int():
59                         test.iarr= ("1", 2, 3)
60
61                 def assign_invalid_bool():
62                         test.barr= (True, 0.123, False)
63
64                 for func in [assign_invalid_float, assign_invalid_int, assign_invalid_bool]:
65                         self.assertRaises(TypeError, func)
66
67                 # shouldn't accept float as int
68                 def assign_float_as_int():
69                         test.iarr= (1, 2, 3.0)
70                 self.assertRaises(TypeError, assign_float_as_int)
71
72                 # non-dynamic arrays cannot change size
73                 def assign_different_size(arr, val):
74                         setattr(test, arr, val)
75                 for arr, val in zip(("iarr", "farr", "barr"), ((1, 2), (1.0, 2.0), (True, False))):
76                         self.assertRaises(ValueError, assign_different_size, arr, val)
77
78         # test assignment of specific items
79         def test_assign_item(self):
80                 for arr, rand_func in zip((test.farr, test.iarr, test.barr), (rand_float, rand_int, rand_bool)):
81                         for i in range(len(arr)):
82                                 val= rand_func()
83                                 arr[i]= val
84                                 
85                                 self.assertEqual(arr[i], val)
86
87                 # float prop should accept also int
88                 for i in range(len(test.farr)):
89                         val= rand_int()
90                         test.farr[i]= val
91                         self.assertEqual(test.farr[i], float(val))
92
93                 # 
94
95         def test_assign_item_fail(self):
96                 def assign_bad_index(arr):
97                         arr[4] = 1.0
98
99                 def assign_bad_type(arr):
100                         arr[1]= "123"
101                         
102                 for arr in [test.farr, test.iarr, test.barr]:
103                         self.assertRaises(IndexError, assign_bad_index, arr)
104
105                 # not testing bool because bool allows not only (True|False)
106                 for arr in [test.farr, test.iarr]:      
107                         self.assertRaises(TypeError, assign_bad_type, arr)
108
109         def test_dynamic_assign_array(self):
110                 # test various lengths here
111                 for arr, rand_func in zip(("fdarr", "idarr", "bdarr"), (rand_float, rand_int, rand_bool)):
112                         for length in range(1, 64):
113                                 rval= make_random_array(length, rand_func)
114                                 setattr(test, arr, rval)
115                                 self.assertEqual(prop_to_list(getattr(test, arr)), rval)
116
117         def test_dynamic_assign_array_fail(self):
118                 # could also test too big length here
119                 
120                 def assign_empty_list(arr):
121                         setattr(test, arr, ())
122
123                 for arr in ("fdarr", "idarr", "bdarr"):
124                         self.assertRaises(ValueError, assign_empty_list, arr)
125
126
127 class TestMArray(unittest.TestCase):
128         def setUp(self):
129                 # reset dynamic array sizes
130                 for arr, func in zip(("fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool)):
131                         setattr(test, arr, make_random_3d_array((3, 4, 5), func))
132
133         # test assignment
134         def test_assign_array(self):
135                 for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)):
136                         # assignment of [3][4][5]
137                         rval= make_random_3d_array((3, 4, 5), func)
138                         setattr(test, arr, rval)
139                         self.assertEqual(prop_to_list(getattr(test, arr)), rval)
140
141                 # test assignment of [2][4][5], [1][4][5] should work on dynamic arrays
142
143         def test_assign_array_fail(self):
144                 def assign_empty_array():
145                         test.fmarr= ()
146                 self.assertRaises(ValueError, assign_empty_array)
147
148                 def assign_invalid_size(arr, rval):
149                         setattr(test, arr, rval)
150
151                 # assignment of 3,4,4 or 3,3,5 should raise ex
152                 for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)):
153                         rval= make_random_3d_array((3, 4, 4), func)
154                         self.assertRaises(ValueError, assign_invalid_size, arr, rval)
155
156                         rval= make_random_3d_array((3, 3, 5), func)
157                         self.assertRaises(ValueError, assign_invalid_size, arr, rval)
158
159                         rval= make_random_3d_array((3, 3, 3), func)
160                         self.assertRaises(ValueError, assign_invalid_size, arr, rval)
161
162         def test_assign_item(self):
163                 # arr[i] = x
164                 for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool) * 2):
165                         rval= make_random_2d_array((4, 5), func)
166
167                         for i in range(3):
168                                 getattr(test, arr)[i]= rval
169                                 self.assertEqual(prop_to_list(getattr(test, arr)[i]), rval)
170
171                 # arr[i][j] = x
172                 for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool) * 2):
173
174                         arr= getattr(test, arr)
175                         rval= make_random_array(5, func)
176
177                         for i in range(3):
178                                 for j in range(4):
179                                         arr[i][j]= rval
180                                         self.assertEqual(prop_to_list(arr[i][j]), rval)
181
182
183         def test_assign_item_fail(self):
184                 def assign_wrong_size(arr, i, rval):
185                         getattr(test, arr)[i]= rval
186
187                 # assign wrong size at level 2
188                 for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)):
189                         rval1= make_random_2d_array((3, 5), func)
190                         rval2= make_random_2d_array((4, 3), func)
191
192                         for i in range(3):
193                                 self.assertRaises(ValueError, assign_wrong_size, arr, i, rval1)
194                                 self.assertRaises(ValueError, assign_wrong_size, arr, i, rval2)
195
196         def test_dynamic_assign_array(self):
197                 for arr, func in zip(("fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool)):
198                         # assignment of [3][4][5]
199                         rval= make_random_3d_array((3, 4, 5), func)
200                         setattr(test, arr, rval)
201                         self.assertEqual(prop_to_list(getattr(test, arr)), rval)
202
203                         # [2][4][5]
204                         rval= make_random_3d_array((2, 4, 5), func)
205                         setattr(test, arr, rval)
206                         self.assertEqual(prop_to_list(getattr(test, arr)), rval)
207
208                         # [1][4][5]
209                         rval= make_random_3d_array((1, 4, 5), func)
210                         setattr(test, arr, rval)
211                         self.assertEqual(prop_to_list(getattr(test, arr)), rval)
212
213
214         # test access
215         def test_access(self):
216                 pass
217
218         # test slice access, negative indices
219         def test_access_fail(self):
220                 pass
221
222 random.seed()
223
224 def rand_int():
225         return random.randint(-1000, 1000)
226
227 def rand_float():
228         return float(rand_int())
229
230 def rand_bool():
231         return bool(random.randint(0, 1))
232
233 def make_random_array(len, rand_func):
234         arr= []
235         for i in range(len):
236                 arr.append(rand_func())
237                 
238         return arr
239
240 def make_random_2d_array(dimsize, rand_func):
241         marr= []
242         for i in range(dimsize[0]):
243                 marr.append([])
244
245                 for j in range(dimsize[1]):
246                         marr[-1].append(rand_func())
247
248         return marr
249
250 def make_random_3d_array(dimsize, rand_func):
251         marr= []
252         for i in range(dimsize[0]):
253                 marr.append([])
254
255                 for j in range(dimsize[1]):
256                         marr[-1].append([])
257
258                         for k in range(dimsize[2]):
259                                 marr[-1][-1].append(rand_func())
260
261         return marr
262
263 def prop_to_list(prop):
264         ret= []
265
266         for x in prop:
267                 if type(x) not in (bool, int, float):
268                         ret.append(prop_to_list(x))
269                 else:
270                         ret.append(x)
271
272         return ret
273
274 def suite():
275         return unittest.TestSuite([unittest.TestLoader().loadTestsFromTestCase(TestArray), unittest.TestLoader().loadTestsFromTestCase(TestMArray)])
276
277 if __name__ == "__main__":
278         unittest.TextTestRunner(verbosity=2).run(suite())
279