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