diff options
Diffstat (limited to 'tests/gtests')
-rw-r--r-- | tests/gtests/alembic/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/gtests/alembic/abc_export_test.cc | 26 | ||||
-rw-r--r-- | tests/gtests/alembic/abc_matrix_test.cc | 2 | ||||
-rw-r--r-- | tests/gtests/blenlib/BLI_expr_pylike_eval_test.cc | 310 | ||||
-rw-r--r-- | tests/gtests/blenlib/BLI_heap_simple_test.cc | 117 | ||||
-rw-r--r-- | tests/gtests/blenlib/BLI_heap_test.cc | 1 | ||||
-rw-r--r-- | tests/gtests/blenlib/BLI_kdopbvh_test.cc | 24 | ||||
-rw-r--r-- | tests/gtests/blenlib/BLI_memiter_test.cc | 206 | ||||
-rw-r--r-- | tests/gtests/blenlib/CMakeLists.txt | 3 |
9 files changed, 680 insertions, 10 deletions
diff --git a/tests/gtests/alembic/CMakeLists.txt b/tests/gtests/alembic/CMakeLists.txt index 1511024ee51..3e794898ebe 100644 --- a/tests/gtests/alembic/CMakeLists.txt +++ b/tests/gtests/alembic/CMakeLists.txt @@ -28,6 +28,7 @@ set(INC ../../../source/blender/blenkernel ../../../source/blender/alembic ../../../source/blender/makesdna + ../../../source/blender/depsgraph ${ALEMBIC_INCLUDE_DIRS} ${BOOST_INCLUDE_DIR} ${HDF5_INCLUDE_DIRS} diff --git a/tests/gtests/alembic/abc_export_test.cc b/tests/gtests/alembic/abc_export_test.cc index a3eb2c412df..ac7760d1541 100644 --- a/tests/gtests/alembic/abc_export_test.cc +++ b/tests/gtests/alembic/abc_export_test.cc @@ -1,21 +1,25 @@ #include "testing/testing.h" -// Keep first since utildefines defines AT which conflicts with fucking STL +// Keep first since utildefines defines AT which conflicts with STL #include "intern/abc_util.h" #include "intern/abc_exporter.h" extern "C" { #include "BLI_utildefines.h" -#include "BKE_library.h" +#include "BKE_main.h" #include "BLI_math.h" #include "DNA_scene_types.h" } +#include "DEG_depsgraph.h" + class TestableAbcExporter : public AbcExporter { public: - TestableAbcExporter(Main *bmain, Scene *scene, const char *filename, ExportSettings &settings) - : AbcExporter(bmain, scene, filename, settings) - {} + TestableAbcExporter(Main *bmain, + const char *filename, ExportSettings &settings) + : AbcExporter(bmain, filename, settings) + { + } void getShutterSamples(unsigned int nr_of_samples, bool time_relative, @@ -28,7 +32,6 @@ public: std::set<double> &frames) { AbcExporter::getFrameSet(nr_of_samples, frames); } - }; class AlembicExportTest : public testing::Test @@ -36,6 +39,7 @@ class AlembicExportTest : public testing::Test protected: ExportSettings settings; Scene scene; + Depsgraph *depsgraph; TestableAbcExporter *exporter; Main *bmain; @@ -50,19 +54,27 @@ protected: bmain = BKE_main_new(); + /* TODO(sergey): Pass scene layer somehow? */ + ViewLayer *view_layer = (ViewLayer *)scene.view_layers.first; + settings.depsgraph = depsgraph = DEG_graph_new(&scene, view_layer, DAG_EVAL_VIEWPORT); + + settings.scene = &scene; + settings.view_layer = view_layer; + exporter = NULL; } virtual void TearDown() { BKE_main_free(bmain); + DEG_graph_free(depsgraph); delete exporter; } // Call after setting up the settings. void createExporter() { - exporter = new TestableAbcExporter(bmain, &scene, "somefile.abc", settings); + exporter = new TestableAbcExporter(bmain, "somefile.abc", settings); } }; diff --git a/tests/gtests/alembic/abc_matrix_test.cc b/tests/gtests/alembic/abc_matrix_test.cc index 08bce1ed50f..49fb662c934 100644 --- a/tests/gtests/alembic/abc_matrix_test.cc +++ b/tests/gtests/alembic/abc_matrix_test.cc @@ -1,6 +1,6 @@ #include "testing/testing.h" -// Keep first since utildefines defines AT which conflicts with fucking STL +// Keep first since utildefines defines AT which conflicts with STL #include "intern/abc_util.h" extern "C" { diff --git a/tests/gtests/blenlib/BLI_expr_pylike_eval_test.cc b/tests/gtests/blenlib/BLI_expr_pylike_eval_test.cc new file mode 100644 index 00000000000..51e5b02232b --- /dev/null +++ b/tests/gtests/blenlib/BLI_expr_pylike_eval_test.cc @@ -0,0 +1,310 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" + +#include <string.h> + +extern "C" { +#include "BLI_expr_pylike_eval.h" +#include "BLI_math.h" +}; + +#define TRUE_VAL 1.0 +#define FALSE_VAL 0.0 + +static void expr_pylike_parse_fail_test(const char *str) +{ + ExprPyLike_Parsed *expr = BLI_expr_pylike_parse(str, NULL, 0); + + EXPECT_FALSE(BLI_expr_pylike_is_valid(expr)); + + BLI_expr_pylike_free(expr); +} + +static void expr_pylike_const_test(const char *str, double value, bool force_const) +{ + ExprPyLike_Parsed *expr = BLI_expr_pylike_parse(str, NULL, 0); + + if (force_const) { + EXPECT_TRUE(BLI_expr_pylike_is_constant(expr)); + } + else { + EXPECT_TRUE(BLI_expr_pylike_is_valid(expr)); + EXPECT_FALSE(BLI_expr_pylike_is_constant(expr)); + } + + double result; + eExprPyLike_EvalStatus status = BLI_expr_pylike_eval(expr, NULL, 0, &result); + + EXPECT_EQ(status, EXPR_PYLIKE_SUCCESS); + EXPECT_EQ(result, value); + + BLI_expr_pylike_free(expr); +} + +static ExprPyLike_Parsed *parse_for_eval(const char *str, bool nonconst) +{ + const char *names[1] = {"x"}; + ExprPyLike_Parsed *expr = BLI_expr_pylike_parse(str, names, ARRAY_SIZE(names)); + + EXPECT_TRUE(BLI_expr_pylike_is_valid(expr)); + + if (nonconst) { + EXPECT_FALSE(BLI_expr_pylike_is_constant(expr)); + } + + return expr; +} + +static void verify_eval_result(ExprPyLike_Parsed *expr, double x, double value) +{ + double result; + eExprPyLike_EvalStatus status = BLI_expr_pylike_eval(expr, &x, 1, &result); + + EXPECT_EQ(status, EXPR_PYLIKE_SUCCESS); + EXPECT_EQ(result, value); +} + +static void expr_pylike_eval_test(const char *str, double x, double value) +{ + ExprPyLike_Parsed *expr = parse_for_eval(str, true); + verify_eval_result(expr, x, value); + BLI_expr_pylike_free(expr); +} + +static void expr_pylike_error_test(const char *str, double x, eExprPyLike_EvalStatus error) +{ + ExprPyLike_Parsed *expr = parse_for_eval(str, false); + + double result; + eExprPyLike_EvalStatus status = BLI_expr_pylike_eval(expr, &x, 1, &result); + + EXPECT_EQ(status, error); + + BLI_expr_pylike_free(expr); +} + +#define TEST_PARSE_FAIL(name, str) \ + TEST(expr_pylike, ParseFail_##name) { expr_pylike_parse_fail_test(str); } + +TEST_PARSE_FAIL(Empty, "") +TEST_PARSE_FAIL(ConstHex, "0x0") +TEST_PARSE_FAIL(ConstOctal, "01") +TEST_PARSE_FAIL(Tail, "0 0") +TEST_PARSE_FAIL(ConstFloatExp, "0.5e+") +TEST_PARSE_FAIL(BadId, "Pi") +TEST_PARSE_FAIL(BadArgCount0, "sqrt") +TEST_PARSE_FAIL(BadArgCount1, "sqrt()") +TEST_PARSE_FAIL(BadArgCount2, "sqrt(1,2)") +TEST_PARSE_FAIL(BadArgCount3, "pi()") +TEST_PARSE_FAIL(BadArgCount4, "max()") +TEST_PARSE_FAIL(BadArgCount5, "min()") + +TEST_PARSE_FAIL(Truncated1, "(1+2") +TEST_PARSE_FAIL(Truncated2, "1 if 2") +TEST_PARSE_FAIL(Truncated3, "1 if 2 else") +TEST_PARSE_FAIL(Truncated4, "1 < 2 <") +TEST_PARSE_FAIL(Truncated5, "1 +") +TEST_PARSE_FAIL(Truncated6, "1 *") +TEST_PARSE_FAIL(Truncated7, "1 and") +TEST_PARSE_FAIL(Truncated8, "1 or") +TEST_PARSE_FAIL(Truncated9, "sqrt(1") +TEST_PARSE_FAIL(Truncated10, "fmod(1,") + +/* Constant expression with working constant folding */ +#define TEST_CONST(name, str, value) \ + TEST(expr_pylike, Const_##name) { expr_pylike_const_test(str, value, true); } + +/* Constant expression but constant folding is not supported */ +#define TEST_RESULT(name, str, value) \ + TEST(expr_pylike, Result_##name) { expr_pylike_const_test(str, value, false); } + +/* Expression with an argument */ +#define TEST_EVAL(name, str, x, value) \ + TEST(expr_pylike, Eval_##name) { expr_pylike_eval_test(str, x, value); } + +TEST_CONST(Zero, "0", 0.0) +TEST_CONST(Zero2, "00", 0.0) +TEST_CONST(One, "1", 1.0) +TEST_CONST(OneF, "1.0", 1.0) +TEST_CONST(OneF2, "1.", 1.0) +TEST_CONST(OneE, "1e0", 1.0) +TEST_CONST(TenE, "1.e+1", 10.0) +TEST_CONST(Half, ".5", 0.5) + +TEST_CONST(Pi, "pi", M_PI) +TEST_CONST(True, "True", TRUE_VAL) +TEST_CONST(False, "False", FALSE_VAL) + +TEST_CONST(Sqrt, "sqrt(4)", 2.0) +TEST_EVAL(Sqrt, "sqrt(x)", 4.0, 2.0) + +TEST_CONST(FMod, "fmod(3.5, 2)", 1.5) +TEST_EVAL(FMod, "fmod(x, 2)", 3.5, 1.5) + +TEST_CONST(Pow, "pow(4, 0.5)", 2.0) +TEST_EVAL(Pow, "pow(4, x)", 0.5, 2.0) + +TEST_RESULT(Min1, "min(3,1,2)", 1.0) +TEST_RESULT(Max1, "max(3,1,2)", 3.0) +TEST_RESULT(Min2, "min(1,2,3)", 1.0) +TEST_RESULT(Max2, "max(1,2,3)", 3.0) +TEST_RESULT(Min3, "min(2,3,1)", 1.0) +TEST_RESULT(Max3, "max(2,3,1)", 3.0) + +TEST_CONST(UnaryPlus, "+1", 1.0) + +TEST_CONST(UnaryMinus, "-1", -1.0) +TEST_EVAL(UnaryMinus, "-x", 1.0, -1.0) + +TEST_CONST(BinaryPlus, "1+2", 3.0) +TEST_EVAL(BinaryPlus, "x+2", 1, 3.0) + +TEST_CONST(BinaryMinus, "1-2", -1.0) +TEST_EVAL(BinaryMinus, "1-x", 2, -1.0) + +TEST_CONST(BinaryMul, "2*3", 6.0) +TEST_EVAL(BinaryMul, "x*3", 2, 6.0) + +TEST_CONST(BinaryDiv, "3/2", 1.5) +TEST_EVAL(BinaryDiv, "3/x", 2, 1.5) + +TEST_CONST(Arith1, "1 + -2 * 3", -5.0) +TEST_CONST(Arith2, "(1 + -2) * 3", -3.0) +TEST_CONST(Arith3, "-1 + 2 * 3", 5.0) +TEST_CONST(Arith4, "3 * (-2 + 1)", -3.0) + +TEST_EVAL(Arith1, "1 + -x * 3", 2, -5.0) + +TEST_CONST(Eq1, "1 == 1.0", TRUE_VAL) +TEST_CONST(Eq2, "1 == 2.0", FALSE_VAL) +TEST_CONST(Eq3, "True == 1", TRUE_VAL) +TEST_CONST(Eq4, "False == 0", TRUE_VAL) + +TEST_EVAL(Eq1, "1 == x", 1.0, TRUE_VAL) +TEST_EVAL(Eq2, "1 == x", 2.0, FALSE_VAL) + +TEST_CONST(NEq1, "1 != 1.0", FALSE_VAL) +TEST_CONST(NEq2, "1 != 2.0", TRUE_VAL) + +TEST_EVAL(NEq1, "1 != x", 1.0, FALSE_VAL) +TEST_EVAL(NEq2, "1 != x", 2.0, TRUE_VAL) + +TEST_CONST(Lt1, "1 < 1", FALSE_VAL) +TEST_CONST(Lt2, "1 < 2", TRUE_VAL) +TEST_CONST(Lt3, "2 < 1", FALSE_VAL) + +TEST_CONST(Le1, "1 <= 1", TRUE_VAL) +TEST_CONST(Le2, "1 <= 2", TRUE_VAL) +TEST_CONST(Le3, "2 <= 1", FALSE_VAL) + +TEST_CONST(Gt1, "1 > 1", FALSE_VAL) +TEST_CONST(Gt2, "1 > 2", FALSE_VAL) +TEST_CONST(Gt3, "2 > 1", TRUE_VAL) + +TEST_CONST(Ge1, "1 >= 1", TRUE_VAL) +TEST_CONST(Ge2, "1 >= 2", FALSE_VAL) +TEST_CONST(Ge3, "2 >= 1", TRUE_VAL) + +TEST_CONST(Cmp1, "3 == 1 + 2", TRUE_VAL) + +TEST_EVAL(Cmp1, "3 == x + 2", 1, TRUE_VAL) +TEST_EVAL(Cmp1b, "3 == x + 2", 1.5, FALSE_VAL) + +TEST_RESULT(CmpChain1, "1 < 2 < 3", TRUE_VAL) +TEST_RESULT(CmpChain2, "1 < 2 == 2", TRUE_VAL) +TEST_RESULT(CmpChain3, "1 < 2 > -1", TRUE_VAL) +TEST_RESULT(CmpChain4, "1 < 2 < 2 < 3", FALSE_VAL) +TEST_RESULT(CmpChain5, "1 < 2 <= 2 < 3", TRUE_VAL) + +TEST_EVAL(CmpChain1a, "1 < x < 3", 2, TRUE_VAL) +TEST_EVAL(CmpChain1b, "1 < x < 3", 1, FALSE_VAL) +TEST_EVAL(CmpChain1c, "1 < x < 3", 3, FALSE_VAL) + +TEST_CONST(Not1, "not 2", FALSE_VAL) +TEST_CONST(Not2, "not 0", TRUE_VAL) +TEST_CONST(Not3, "not not 2", TRUE_VAL) + +TEST_EVAL(Not1, "not x", 2, FALSE_VAL) +TEST_EVAL(Not2, "not x", 0, TRUE_VAL) + +TEST_RESULT(And1, "2 and 3", 3.0) +TEST_RESULT(And2, "0 and 3", 0.0) + +TEST_RESULT(Or1, "2 or 3", 2.0) +TEST_RESULT(Or2, "0 or 3", 3.0) + +TEST_RESULT(Bool1, "2 or 3 and 4", 2.0) +TEST_RESULT(Bool2, "not 2 or 3 and 4", 4.0) + +TEST(expr_pylike, Eval_Ternary1) +{ + ExprPyLike_Parsed *expr = parse_for_eval("x / 2 if x < 4 else x - 2 if x < 8 else x*2 - 12", true); + + for (int i = 0; i <= 10; i++) { + double x = i; + double v = (x < 4) ? (x / 2) : (x < 8) ? (x - 2) : (x*2 - 12); + + verify_eval_result(expr, x, v); + } + + BLI_expr_pylike_free(expr); +} + +TEST(expr_pylike, MultipleArgs) +{ + const char* names[3] = {"x", "y", "x"}; + double values[3] = {1.0, 2.0, 3.0}; + + ExprPyLike_Parsed *expr = BLI_expr_pylike_parse("x*10 + y", names, ARRAY_SIZE(names)); + + EXPECT_TRUE(BLI_expr_pylike_is_valid(expr)); + + double result; + eExprPyLike_EvalStatus status = BLI_expr_pylike_eval(expr, values, 3, &result); + + EXPECT_EQ(status, EXPR_PYLIKE_SUCCESS); + EXPECT_EQ(result, 32.0); + + BLI_expr_pylike_free(expr); +} + +#define TEST_ERROR(name, str, x, code) \ + TEST(expr_pylike, Error_##name) { expr_pylike_error_test(str, x, code); } + +TEST_ERROR(DivZero1, "0 / 0", 0.0, EXPR_PYLIKE_MATH_ERROR) +TEST_ERROR(DivZero2, "1 / 0", 0.0, EXPR_PYLIKE_DIV_BY_ZERO) +TEST_ERROR(DivZero3, "1 / x", 0.0, EXPR_PYLIKE_DIV_BY_ZERO) +TEST_ERROR(DivZero4, "1 / x", 1.0, EXPR_PYLIKE_SUCCESS) + +TEST_ERROR(SqrtDomain1, "sqrt(-1)", 0.0, EXPR_PYLIKE_MATH_ERROR) +TEST_ERROR(SqrtDomain2, "sqrt(x)", -1.0, EXPR_PYLIKE_MATH_ERROR) +TEST_ERROR(SqrtDomain3, "sqrt(x)", 0.0, EXPR_PYLIKE_SUCCESS) + +TEST_ERROR(PowDomain1, "pow(-1, 0.5)", 0.0, EXPR_PYLIKE_MATH_ERROR) +TEST_ERROR(PowDomain2, "pow(-1, x)", 0.5, EXPR_PYLIKE_MATH_ERROR) +TEST_ERROR(PowDomain3, "pow(-1, x)", 2.0, EXPR_PYLIKE_SUCCESS) + +TEST_ERROR(Mixed1, "sqrt(x) + 1 / max(0, x)", -1.0, EXPR_PYLIKE_MATH_ERROR) +TEST_ERROR(Mixed2, "sqrt(x) + 1 / max(0, x)", 0.0, EXPR_PYLIKE_DIV_BY_ZERO) +TEST_ERROR(Mixed3, "sqrt(x) + 1 / max(0, x)", 1.0, EXPR_PYLIKE_SUCCESS) + +TEST(expr_pylike, Error_Invalid) +{ + ExprPyLike_Parsed *expr = BLI_expr_pylike_parse("", NULL, 0); + double result; + + EXPECT_EQ(BLI_expr_pylike_eval(expr, NULL, 0, &result), EXPR_PYLIKE_INVALID); + + BLI_expr_pylike_free(expr); +} + +TEST(expr_pylike, Error_ArgumentCount) +{ + ExprPyLike_Parsed *expr = parse_for_eval("x", false); + double result; + + EXPECT_EQ(BLI_expr_pylike_eval(expr, NULL, 0, &result), EXPR_PYLIKE_FATAL_ERROR); + + BLI_expr_pylike_free(expr); +} diff --git a/tests/gtests/blenlib/BLI_heap_simple_test.cc b/tests/gtests/blenlib/BLI_heap_simple_test.cc new file mode 100644 index 00000000000..29aa8f23c49 --- /dev/null +++ b/tests/gtests/blenlib/BLI_heap_simple_test.cc @@ -0,0 +1,117 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" +#include <string.h> + +extern "C" { +#include "BLI_compiler_attrs.h" +#include "BLI_heap_simple.h" +#include "BLI_utildefines.h" +#include "BLI_rand.h" + +#include "MEM_guardedalloc.h" +}; + +#define SIZE 1024 + + +static void range_fl(float *array_tar, const int size) +{ + float *array_pt = array_tar + (size - 1); + int i = size; + while (i--) { + *(array_pt--) = (float)i; + } +} + +TEST(heap, SimpleEmpty) +{ + HeapSimple *heap; + + heap = BLI_heapsimple_new(); + EXPECT_TRUE(BLI_heapsimple_is_empty(heap)); + EXPECT_EQ(BLI_heapsimple_len(heap), 0); + BLI_heapsimple_free(heap, NULL); +} + +TEST(heap, SimpleOne) +{ + HeapSimple *heap; + const char *in = "test"; + + heap = BLI_heapsimple_new(); + + BLI_heapsimple_insert(heap, 0.0f, (void *)in); + EXPECT_FALSE(BLI_heapsimple_is_empty(heap)); + EXPECT_EQ(BLI_heapsimple_len(heap), 1); + EXPECT_EQ(in, BLI_heapsimple_pop_min(heap)); + EXPECT_TRUE(BLI_heapsimple_is_empty(heap)); + EXPECT_EQ(BLI_heapsimple_len(heap), 0); + BLI_heapsimple_free(heap, NULL); +} + +TEST(heap, SimpleRange) +{ + const int items_total = SIZE; + HeapSimple *heap = BLI_heapsimple_new(); + for (int in = 0; in < items_total; in++) { + BLI_heapsimple_insert(heap, (float)in, POINTER_FROM_INT(in)); + } + for (int out_test = 0; out_test < items_total; out_test++) { + EXPECT_EQ(out_test, POINTER_AS_INT(BLI_heapsimple_pop_min(heap))); + + } + EXPECT_TRUE(BLI_heapsimple_is_empty(heap)); + BLI_heapsimple_free(heap, NULL); +} + +TEST(heap, SimpleRangeReverse) +{ + const int items_total = SIZE; + HeapSimple *heap = BLI_heapsimple_new(); + for (int in = 0; in < items_total; in++) { + BLI_heapsimple_insert(heap, (float)-in, POINTER_FROM_INT(-in)); + } + for (int out_test = items_total - 1; out_test >= 0; out_test--) { + EXPECT_EQ(-out_test, POINTER_AS_INT(BLI_heapsimple_pop_min(heap))); + } + EXPECT_TRUE(BLI_heapsimple_is_empty(heap)); + BLI_heapsimple_free(heap, NULL); +} + +TEST(heap, SimpleDuplicates) +{ + const int items_total = SIZE; + HeapSimple *heap = BLI_heapsimple_new(); + for (int in = 0; in < items_total; in++) { + BLI_heapsimple_insert(heap, 1.0f, 0); + } + for (int out_test = 0; out_test < items_total; out_test++) { + EXPECT_EQ(0, POINTER_AS_INT(BLI_heapsimple_pop_min(heap))); + } + EXPECT_TRUE(BLI_heapsimple_is_empty(heap)); + BLI_heapsimple_free(heap, NULL); +} + +static void random_heapsimple_helper( + const int items_total, + const int random_seed) +{ + HeapSimple *heap = BLI_heapsimple_new(); + float *values = (float *)MEM_mallocN(sizeof(float) * items_total, __func__); + range_fl(values, items_total); + BLI_array_randomize(values, sizeof(float), items_total, random_seed); + for (int i = 0; i < items_total; i++) { + BLI_heapsimple_insert(heap, values[i], POINTER_FROM_INT((int)values[i])); + } + for (int out_test = 0; out_test < items_total; out_test++) { + EXPECT_EQ(out_test, POINTER_AS_INT(BLI_heapsimple_pop_min(heap))); + } + EXPECT_TRUE(BLI_heapsimple_is_empty(heap)); + BLI_heapsimple_free(heap, NULL); + MEM_freeN(values); +} + +TEST(heap, SimpleRand1) { random_heapsimple_helper(1, 1234); } +TEST(heap, SimpleRand2) { random_heapsimple_helper(2, 1234); } +TEST(heap, SimpleRand100) { random_heapsimple_helper(100, 4321); } diff --git a/tests/gtests/blenlib/BLI_heap_test.cc b/tests/gtests/blenlib/BLI_heap_test.cc index 69566d8dca6..26f3aa19b9f 100644 --- a/tests/gtests/blenlib/BLI_heap_test.cc +++ b/tests/gtests/blenlib/BLI_heap_test.cc @@ -176,6 +176,7 @@ static void random_heap_reinsert_helper( for (int out_test = 0; out_test < items_total; out_test++) { HeapNode *node_top = BLI_heap_top(heap); float out = BLI_heap_node_value(node_top); + EXPECT_EQ(out, BLI_heap_top_value(heap)); EXPECT_EQ((float)out_test, out); BLI_heap_pop_min(heap); } diff --git a/tests/gtests/blenlib/BLI_kdopbvh_test.cc b/tests/gtests/blenlib/BLI_kdopbvh_test.cc index 48f4d7054da..ff4a74b8be8 100644 --- a/tests/gtests/blenlib/BLI_kdopbvh_test.cc +++ b/tests/gtests/blenlib/BLI_kdopbvh_test.cc @@ -52,11 +52,23 @@ TEST(kdopbvh, Single) BLI_bvhtree_free(tree); } +void optimal_check_callback(void *userdata, int index, const float co[3], BVHTreeNearest *nearest) +{ + float (*points)[3] = (float (*)[3])userdata; + + /* BVH_NEAREST_OPTIMAL_ORDER should hit the right node on the first try */ + EXPECT_EQ(nearest->index, -1); + EXPECT_EQ_ARRAY(co, points[index], 3); + + nearest->index = index; + nearest->dist_sq = len_squared_v3v3(co, points[index]); +} + /** * Note that a small epsilon is added to the BVH nodes bounds, even if we pass in zero. * Use rounding to ensure very close nodes don't cause the wrong node to be found as nearest. */ -static void find_nearest_points_test(int points_len, float scale, int round, int random_seed) +static void find_nearest_points_test(int points_len, float scale, int round, int random_seed, bool optimal = false) { struct RNG *rng = BLI_rng_new(random_seed); BVHTree *tree = BLI_bvhtree_new(points_len, 0.0, 8, 8); @@ -69,9 +81,13 @@ static void find_nearest_points_test(int points_len, float scale, int round, int BLI_bvhtree_insert(tree, i, points[i], 1); } BLI_bvhtree_balance(tree); + /* first find each point */ + BVHTree_NearestPointCallback callback = optimal ? optimal_check_callback : NULL; + int flags = optimal ? BVH_NEAREST_OPTIMAL_ORDER : 0; + for (int i = 0; i < points_len; i++) { - const int j = BLI_bvhtree_find_nearest(tree, points[i], NULL, NULL, NULL); + const int j = BLI_bvhtree_find_nearest_ex(tree, points[i], NULL, callback, points, flags); if (j != i) { #if 0 const float dist = len_v3v3(points[i], points[j]); @@ -95,3 +111,7 @@ static void find_nearest_points_test(int points_len, float scale, int round, int TEST(kdopbvh, FindNearest_1) { find_nearest_points_test(1, 1.0, 1000, 1234); } TEST(kdopbvh, FindNearest_2) { find_nearest_points_test(2, 1.0, 1000, 123); } TEST(kdopbvh, FindNearest_500) { find_nearest_points_test(500, 1.0, 1000, 12); } + +TEST(kdopbvh, OptimalFindNearest_1) { find_nearest_points_test(1, 1.0, 1000, 1234, true); } +TEST(kdopbvh, OptimalFindNearest_2) { find_nearest_points_test(2, 1.0, 1000, 123, true); } +TEST(kdopbvh, OptimalFindNearest_500) { find_nearest_points_test(500, 1.0, 1000, 12, true); } diff --git a/tests/gtests/blenlib/BLI_memiter_test.cc b/tests/gtests/blenlib/BLI_memiter_test.cc new file mode 100644 index 00000000000..601eadea267 --- /dev/null +++ b/tests/gtests/blenlib/BLI_memiter_test.cc @@ -0,0 +1,206 @@ +/* Apache License, Version 2.0 */ + +#include "testing/testing.h" + +extern "C" { +#include "BLI_array_utils.h" +#include "BLI_memiter.h" +#include "MEM_guardedalloc.h" + +#include "BLI_string.h" +#include "BLI_ressource_strings.h" +} + +TEST(memiter, Nop) +{ + BLI_memiter *mi = BLI_memiter_create(64); + BLI_memiter_destroy(mi); +} + +void memiter_empty_test(int num_elems, const int chunk_size) +{ + BLI_memiter *mi = BLI_memiter_create(chunk_size); + void *data; + for (int index = 0; index < num_elems; index++) { + data = BLI_memiter_alloc(mi, 0); + } + int index = 0, total_size = 0; + BLI_memiter_handle it; + BLI_memiter_iter_init(mi, &it); + uint elem_size; + while ((data = BLI_memiter_iter_step_size(&it, &elem_size))) { + index += 1; + total_size += elem_size; + } + EXPECT_EQ(0, total_size); + EXPECT_EQ(num_elems, index); + + BLI_memiter_destroy(mi); +} + +#define MEMITER_NUMBER_TEST_FN(fn, number_type) \ +void fn(int num_elems, const int chunk_size) \ +{ \ + BLI_memiter *mi = BLI_memiter_create(chunk_size); \ + number_type *data; \ + for (int index = 0; index < num_elems; index++) { \ + data = (number_type *)BLI_memiter_alloc(mi, sizeof(number_type)); \ + *data = index; \ + } \ + BLI_memiter_handle it; \ + BLI_memiter_iter_init(mi, &it); \ + uint elem_size; \ + int index = 0; \ + while ((data = (number_type *)BLI_memiter_iter_step_size(&it, &elem_size))) { \ + EXPECT_EQ(sizeof(number_type), elem_size); \ + EXPECT_EQ(index, *data); \ + index += 1; \ + } \ + BLI_memiter_destroy(mi); \ +} + +/* generate number functions */ +MEMITER_NUMBER_TEST_FN(memiter_char_test, char) +MEMITER_NUMBER_TEST_FN(memiter_short_test, short) +MEMITER_NUMBER_TEST_FN(memiter_int_test, int) +MEMITER_NUMBER_TEST_FN(memiter_long_test, int64_t) + +void memiter_string_test(const char *strings[], const int chunk_size) +{ + BLI_memiter *mi = BLI_memiter_create(chunk_size); + char *data; + int index = 0; + int total_size_expect = 0; + while (strings[index]) { + const int size = strlen(strings[index]) + 1; + BLI_memiter_alloc_from(mi, size, strings[index]); + total_size_expect += size; + index += 1; + } + const int strings_len = index; + int total_size = 0; + BLI_memiter_handle it; + BLI_memiter_iter_init(mi, &it); + uint elem_size; + index = 0; + while ((data = (char *)BLI_memiter_iter_step_size(&it, &elem_size))) { + EXPECT_EQ(strlen(strings[index]) + 1, elem_size); + EXPECT_STREQ(strings[index], data); + total_size += elem_size; + index += 1; + } + EXPECT_EQ(total_size_expect, total_size); + EXPECT_EQ(strings_len, index); + + BLI_memiter_destroy(mi); +} + +void memiter_words10k_test(const char split_char, const int chunk_size) +{ + const int words_len = sizeof(words10k) - 1; + char *words = BLI_strdupn(words10k, words_len); + BLI_str_replace_char(words, split_char, '\0'); + + BLI_memiter *mi = BLI_memiter_create(chunk_size); + + char *data; + int index; + char *c_end, *c; + c_end = words + words_len; + c = words; + index = 0; + while (c < c_end) { + int elem_size = strlen(c) + 1; + data = (char *)BLI_memiter_alloc(mi, elem_size); + memcpy(data, c, elem_size); + c += elem_size; + index += 1; + } + const int len_expect = index; + c = words; + uint size; + BLI_memiter_handle it; + BLI_memiter_iter_init(mi, &it); + index = 0; + while ((data = (char *)BLI_memiter_iter_step_size(&it, &size))) { + int size_expect = strlen(c) + 1; + EXPECT_EQ(size_expect, size); + EXPECT_STREQ(c, data); + c += size; + index += 1; + } + EXPECT_EQ(len_expect, index); + BLI_memiter_destroy(mi); + MEM_freeN(words); +} + + +#define TEST_EMPTY_AT_CHUNK_SIZE(chunk_size) \ +TEST(memiter, Empty0_##chunk_size) { memiter_empty_test(0, chunk_size); } \ +TEST(memiter, Empty1_##chunk_size) { memiter_empty_test(1, chunk_size); } \ +TEST(memiter, Empty2_##chunk_size) { memiter_empty_test(2, chunk_size); } \ +TEST(memiter, Empty3_##chunk_size) { memiter_empty_test(3, chunk_size); } \ +TEST(memiter, Empty13_##chunk_size) { memiter_empty_test(13, chunk_size); } \ +TEST(memiter, Empty256_##chunk_size) { memiter_empty_test(256, chunk_size); } \ + +TEST_EMPTY_AT_CHUNK_SIZE(1) +TEST_EMPTY_AT_CHUNK_SIZE(2) +TEST_EMPTY_AT_CHUNK_SIZE(3) +TEST_EMPTY_AT_CHUNK_SIZE(13) +TEST_EMPTY_AT_CHUNK_SIZE(256) + +#define TEST_NUMBER_AT_CHUNK_SIZE(chunk_size) \ +TEST(memiter, Char1_##chunk_size) { memiter_char_test(1, chunk_size); } \ +TEST(memiter, Short1_##chunk_size) { memiter_short_test(1, chunk_size); } \ +TEST(memiter, Int1_##chunk_size) { memiter_int_test(1, chunk_size); } \ +TEST(memiter, Long1_##chunk_size) { memiter_long_test(1, chunk_size); } \ +\ +TEST(memiter, Char2_##chunk_size) { memiter_char_test(2, chunk_size); } \ +TEST(memiter, Short2_##chunk_size) { memiter_short_test(2, chunk_size); } \ +TEST(memiter, Int2_##chunk_size) { memiter_int_test(2, chunk_size); } \ +TEST(memiter, Long2_##chunk_size) { memiter_long_test(2, chunk_size); } \ +\ +TEST(memiter, Char3_##chunk_size) { memiter_char_test(3, chunk_size); } \ +TEST(memiter, Short3_##chunk_size) { memiter_short_test(3, chunk_size); } \ +TEST(memiter, Int3_##chunk_size) { memiter_int_test(3, chunk_size); } \ +TEST(memiter, Long3_##chunk_size) { memiter_long_test(3, chunk_size); } \ +\ +TEST(memiter, Char256_##chunk_size) { memiter_char_test(256, chunk_size); } \ +TEST(memiter, Short256_##chunk_size) { memiter_short_test(256, chunk_size); } \ +TEST(memiter, Int256_##chunk_size) { memiter_int_test(256, chunk_size); } \ +TEST(memiter, Long256_##chunk_size) { memiter_long_test(256, chunk_size); } \ + +TEST_NUMBER_AT_CHUNK_SIZE(1) +TEST_NUMBER_AT_CHUNK_SIZE(2) +TEST_NUMBER_AT_CHUNK_SIZE(3) +TEST_NUMBER_AT_CHUNK_SIZE(13) +TEST_NUMBER_AT_CHUNK_SIZE(256) + +#define STRINGS_TEST(chunk_size, ...) { \ + const char *data[] = {__VA_ARGS__, NULL}; \ + memiter_string_test(data, chunk_size); \ +} + +#define TEST_STRINGS_AT_CHUNK_SIZE(chunk_size) \ +TEST(memiter, Strings_##chunk_size) { \ + STRINGS_TEST(chunk_size, ""); \ + STRINGS_TEST(chunk_size, "test", "me"); \ + STRINGS_TEST(chunk_size, "more", "test", "data", "to", "follow"); \ +} + +TEST_STRINGS_AT_CHUNK_SIZE(1) +TEST_STRINGS_AT_CHUNK_SIZE(2) +TEST_STRINGS_AT_CHUNK_SIZE(3) +TEST_STRINGS_AT_CHUNK_SIZE(13) +TEST_STRINGS_AT_CHUNK_SIZE(256) + + +#define TEST_WORDS10K_AT_CHUNK_SIZE(chunk_size) \ +TEST(memiter, Words10kSentence_##chunk_size) { memiter_words10k_test('.', chunk_size); } \ +TEST(memiter, Words10kWords_##chunk_size) { memiter_words10k_test(' ', chunk_size); } \ + +TEST_WORDS10K_AT_CHUNK_SIZE(1) +TEST_WORDS10K_AT_CHUNK_SIZE(2) +TEST_WORDS10K_AT_CHUNK_SIZE(3) +TEST_WORDS10K_AT_CHUNK_SIZE(13) +TEST_WORDS10K_AT_CHUNK_SIZE(256) diff --git a/tests/gtests/blenlib/CMakeLists.txt b/tests/gtests/blenlib/CMakeLists.txt index 43883e83f6e..e399d4651f5 100644 --- a/tests/gtests/blenlib/CMakeLists.txt +++ b/tests/gtests/blenlib/CMakeLists.txt @@ -43,15 +43,18 @@ endif() BLENDER_TEST(BLI_array_store "bf_blenlib") BLENDER_TEST(BLI_array_utils "bf_blenlib") +BLENDER_TEST(BLI_expr_pylike_eval "bf_blenlib") BLENDER_TEST(BLI_ghash "bf_blenlib") BLENDER_TEST(BLI_hash_mm2a "bf_blenlib") BLENDER_TEST(BLI_heap "bf_blenlib") +BLENDER_TEST(BLI_heap_simple "bf_blenlib") BLENDER_TEST(BLI_kdopbvh "bf_blenlib;bf_intern_numaapi") BLENDER_TEST(BLI_linklist_lockfree "bf_blenlib;bf_intern_numaapi") BLENDER_TEST(BLI_listbase "bf_blenlib") BLENDER_TEST(BLI_math_base "bf_blenlib") BLENDER_TEST(BLI_math_color "bf_blenlib") BLENDER_TEST(BLI_math_geom "bf_blenlib") +BLENDER_TEST(BLI_memiter "bf_blenlib") BLENDER_TEST(BLI_path_util "${BLI_path_util_extra_libs}") BLENDER_TEST(BLI_polyfill_2d "bf_blenlib") BLENDER_TEST(BLI_stack "bf_blenlib") |