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