This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/blenlib/tests/BLI_function_ref_test.cc
Jacques Lucke 328b39335e BLI: add call_safe method for FunctionRef
This is useful to avoid nullity checks in some places.
2021-04-01 12:38:14 +02:00

128 lines
2.6 KiB
C++

/* Apache License, Version 2.0 */
#include "BLI_function_ref.hh"
#include "testing/testing.h"
namespace blender::tests {
static int perform_binary_operation(int a, int b, FunctionRef<int(int, int)> operation)
{
return operation(a, b);
}
TEST(function_ref, StatelessLambda)
{
const int result = perform_binary_operation(4, 6, [](int a, int b) { return a - b; });
EXPECT_EQ(result, -2);
}
TEST(function_ref, StatefullLambda)
{
const int factor = 10;
const int result = perform_binary_operation(
2, 3, [&](int a, int b) { return factor * (a + b); });
EXPECT_EQ(result, 50);
}
static int add_two_numbers(int a, int b)
{
return a + b;
}
TEST(function_ref, StandaloneFunction)
{
const int result = perform_binary_operation(10, 5, add_two_numbers);
EXPECT_EQ(result, 15);
}
TEST(function_ref, ConstantFunction)
{
auto f = []() { return 42; };
FunctionRef<int()> ref = f;
EXPECT_EQ(ref(), 42);
}
TEST(function_ref, MutableStatefullLambda)
{
int counter = 0;
auto f = [&]() mutable { return counter++; };
FunctionRef<int()> ref = f;
EXPECT_EQ(ref(), 0);
EXPECT_EQ(ref(), 1);
EXPECT_EQ(ref(), 2);
}
TEST(function_ref, Null)
{
FunctionRef<int()> ref;
EXPECT_FALSE(ref);
auto f = []() { return 1; };
ref = f;
EXPECT_TRUE(ref);
ref = {};
EXPECT_FALSE(ref);
}
TEST(function_ref, CopyDoesNotReferenceFunctionRef)
{
auto f1 = []() { return 1; };
auto f2 = []() { return 2; };
FunctionRef<int()> x = f1;
FunctionRef<int()> y = x;
x = f2;
EXPECT_EQ(y(), 1);
}
TEST(function_ref, CopyDoesNotReferenceFunctionRef2)
{
auto f = []() { return 1; };
FunctionRef<int()> x;
FunctionRef<int()> y = f;
FunctionRef<int()> z = static_cast<const FunctionRef<int()> &&>(y);
x = z;
y = {};
EXPECT_EQ(x(), 1);
}
TEST(function_ref, ReferenceAnotherFunctionRef)
{
auto f1 = []() { return 1; };
auto f2 = []() { return 2; };
FunctionRef<int()> x = f1;
auto f3 = [&]() { return x(); };
FunctionRef<int()> y = f3;
EXPECT_EQ(y(), 1);
x = f2;
EXPECT_EQ(y(), 2);
}
TEST(function_ref, CallSafe)
{
FunctionRef<int()> f;
EXPECT_FALSE(f.call_safe().has_value());
auto func = []() { return 10; };
f = func;
EXPECT_TRUE(f.call_safe().has_value());
EXPECT_EQ(*f.call_safe(), 10);
f = {};
EXPECT_FALSE(f.call_safe().has_value());
BLI_STATIC_ASSERT((std::is_same_v<decltype(f.call_safe()), std::optional<int>>), "");
}
TEST(function_ref, CallSafeVoid)
{
FunctionRef<void()> f;
BLI_STATIC_ASSERT((std::is_same_v<decltype(f.call_safe()), void>), "");
f.call_safe();
int value = 0;
auto func = [&]() { value++; };
f = func;
f.call_safe();
EXPECT_EQ(value, 1);
}
} // namespace blender::tests