blender/tests/python/rna_array.py
Campbell Barton e955c94ed3 License Headers: Set copyright to "Blender Authors", add AUTHORS
Listing the "Blender Foundation" as copyright holder implied the Blender
Foundation holds copyright to files which may include work from many
developers.

While keeping copyright on headers makes sense for isolated libraries,
Blender's own code may be refactored or moved between files in a way
that makes the per file copyright holders less meaningful.

Copyright references to the "Blender Foundation" have been replaced with
"Blender Authors", with the exception of `./extern/` since these this
contains libraries which are more isolated, any changed to license
headers there can be handled on a case-by-case basis.

Some directories in `./intern/` have also been excluded:

- `./intern/cycles/` it's own `AUTHORS` file is planned.
- `./intern/opensubdiv/`.

An "AUTHORS" file has been added, using the chromium projects authors
file as a template.

Design task: #110784

Ref !110783.
2023-08-16 00:20:26 +10:00

298 lines
9.2 KiB
Python

# SPDX-FileCopyrightText: 2009-2022 Blender Authors
#
# SPDX-License-Identifier: Apache-2.0
import unittest
import random
test = bpy.data.test
# farr - 1-dimensional array of float
# fdarr - dynamic 1-dimensional array of float
# fmarr - 3-dimensional ([3][4][5]) array of float
# fdmarr - dynamic 3-dimensional (ditto size) array of float
# same as above for other types except that the first letter is "i" for int and "b" for bool
class TestArray(unittest.TestCase):
# test that assignment works by: assign -> test value
# - rvalue = list of float
# - rvalue = list of numbers
# test.object
# bpy.data.test.farr[3], iarr[3], barr[...], fmarr, imarr, bmarr
def setUp(self):
test.farr = (1.0, 2.0, 3.0)
test.iarr = (7, 8, 9)
test.barr = (False, True, False)
# test access
# test slice access, negative indices
def test_access(self):
rvals = ([1.0, 2.0, 3.0], [7, 8, 9], [False, True, False])
for arr, rval in zip((test.farr, test.iarr, test.barr), rvals):
self.assertEqual(prop_to_list(arr), rval)
self.assertEqual(arr[0:3], rval)
self.assertEqual(arr[1:2], rval[1:2])
self.assertEqual(arr[-1], arr[2])
self.assertEqual(arr[-2], arr[1])
self.assertEqual(arr[-3], arr[0])
# fail when index out of bounds
def test_access_fail(self):
for arr in (test.farr, test.iarr, test.barr):
self.assertRaises(IndexError, lambda: arr[4])
# test assignment of a whole array
def test_assign_array(self):
# should accept int as float
test.farr = (1, 2, 3)
# fail when: unexpected no. of items, invalid item type
def test_assign_array_fail(self):
def assign_empty_list(arr):
setattr(test, arr, ())
for arr in ("farr", "iarr", "barr"):
self.assertRaises(ValueError, assign_empty_list, arr)
def assign_invalid_float():
test.farr = (1.0, 2.0, "3.0")
def assign_invalid_int():
test.iarr = ("1", 2, 3)
def assign_invalid_bool():
test.barr = (True, 0.123, False)
for func in [assign_invalid_float, assign_invalid_int, assign_invalid_bool]:
self.assertRaises(TypeError, func)
# shouldn't accept float as int
def assign_float_as_int():
test.iarr = (1, 2, 3.0)
self.assertRaises(TypeError, assign_float_as_int)
# non-dynamic arrays cannot change size
def assign_different_size(arr, val):
setattr(test, arr, val)
for arr, val in zip(("iarr", "farr", "barr"), ((1, 2), (1.0, 2.0), (True, False))):
self.assertRaises(ValueError, assign_different_size, arr, val)
# test assignment of specific items
def test_assign_item(self):
for arr, rand_func in zip((test.farr, test.iarr, test.barr), (rand_float, rand_int, rand_bool)):
for i in range(len(arr)):
val = rand_func()
arr[i] = val
self.assertEqual(arr[i], val)
# float prop should accept also int
for i in range(len(test.farr)):
val = rand_int()
test.farr[i] = val
self.assertEqual(test.farr[i], float(val))
#
def test_assign_item_fail(self):
def assign_bad_index(arr):
arr[4] = 1.0
def assign_bad_type(arr):
arr[1] = "123"
for arr in [test.farr, test.iarr, test.barr]:
self.assertRaises(IndexError, assign_bad_index, arr)
# not testing bool because bool allows not only (True|False)
for arr in [test.farr, test.iarr]:
self.assertRaises(TypeError, assign_bad_type, arr)
def test_dynamic_assign_array(self):
# test various lengths here
for arr, rand_func in zip(("fdarr", "idarr", "bdarr"), (rand_float, rand_int, rand_bool)):
for length in range(1, 64):
rval = make_random_array(length, rand_func)
setattr(test, arr, rval)
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
def test_dynamic_assign_array_fail(self):
# could also test too big length here
def assign_empty_list(arr):
setattr(test, arr, ())
for arr in ("fdarr", "idarr", "bdarr"):
self.assertRaises(ValueError, assign_empty_list, arr)
class TestMArray(unittest.TestCase):
def setUp(self):
# reset dynamic array sizes
for arr, func in zip(("fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool)):
setattr(test, arr, make_random_3d_array((3, 4, 5), func))
# test assignment
def test_assign_array(self):
for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)):
# assignment of [3][4][5]
rval = make_random_3d_array((3, 4, 5), func)
setattr(test, arr, rval)
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
# test assignment of [2][4][5], [1][4][5] should work on dynamic arrays
def test_assign_array_fail(self):
def assign_empty_array():
test.fmarr = ()
self.assertRaises(ValueError, assign_empty_array)
def assign_invalid_size(arr, rval):
setattr(test, arr, rval)
# assignment of 3,4,4 or 3,3,5 should raise ex
for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)):
rval = make_random_3d_array((3, 4, 4), func)
self.assertRaises(ValueError, assign_invalid_size, arr, rval)
rval = make_random_3d_array((3, 3, 5), func)
self.assertRaises(ValueError, assign_invalid_size, arr, rval)
rval = make_random_3d_array((3, 3, 3), func)
self.assertRaises(ValueError, assign_invalid_size, arr, rval)
def test_assign_item(self):
# arr[i] = x
for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"),
(rand_float, rand_int, rand_bool) * 2):
rval = make_random_2d_array((4, 5), func)
for i in range(3):
getattr(test, arr)[i] = rval
self.assertEqual(prop_to_list(getattr(test, arr)[i]), rval)
# arr[i][j] = x
for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"),
(rand_float, rand_int, rand_bool) * 2):
arr = getattr(test, arr)
rval = make_random_array(5, func)
for i in range(3):
for j in range(4):
arr[i][j] = rval
self.assertEqual(prop_to_list(arr[i][j]), rval)
def test_assign_item_fail(self):
def assign_wrong_size(arr, i, rval):
getattr(test, arr)[i] = rval
# assign wrong size at level 2
for arr, func in zip(("fmarr", "imarr", "bmarr"), (rand_float, rand_int, rand_bool)):
rval1 = make_random_2d_array((3, 5), func)
rval2 = make_random_2d_array((4, 3), func)
for i in range(3):
self.assertRaises(ValueError, assign_wrong_size, arr, i, rval1)
self.assertRaises(ValueError, assign_wrong_size, arr, i, rval2)
def test_dynamic_assign_array(self):
for arr, func in zip(("fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool)):
# assignment of [3][4][5]
rval = make_random_3d_array((3, 4, 5), func)
setattr(test, arr, rval)
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
# [2][4][5]
rval = make_random_3d_array((2, 4, 5), func)
setattr(test, arr, rval)
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
# [1][4][5]
rval = make_random_3d_array((1, 4, 5), func)
setattr(test, arr, rval)
self.assertEqual(prop_to_list(getattr(test, arr)), rval)
# test access
def test_access(self):
pass
# test slice access, negative indices
def test_access_fail(self):
pass
random.seed()
def rand_int():
return random.randint(-1000, 1000)
def rand_float():
return float(rand_int())
def rand_bool():
return bool(random.randint(0, 1))
def make_random_array(len, rand_func):
arr = []
for i in range(len):
arr.append(rand_func())
return arr
def make_random_2d_array(dimsize, rand_func):
marr = []
for i in range(dimsize[0]):
marr.append([])
for j in range(dimsize[1]):
marr[-1].append(rand_func())
return marr
def make_random_3d_array(dimsize, rand_func):
marr = []
for i in range(dimsize[0]):
marr.append([])
for j in range(dimsize[1]):
marr[-1].append([])
for k in range(dimsize[2]):
marr[-1][-1].append(rand_func())
return marr
def prop_to_list(prop):
ret = []
for x in prop:
if type(x) not in {bool, int, float}:
ret.append(prop_to_list(x))
else:
ret.append(x)
return ret
def suite():
return unittest.TestSuite([
unittest.TestLoader().loadTestsFromTestCase(TestArray),
unittest.TestLoader().loadTestsFromTestCase(TestMArray),
])
if __name__ == "__main__":
unittest.TextTestRunner(verbosity=2).run(suite())