add basic types and fix cmake
This commit is contained in:
75
src/test/FormulaTest.cpp
Normal file
75
src/test/FormulaTest.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "Formula.h"
|
||||
|
||||
TEST_CASE("Formula compiles a constant expression", "[formula]")
|
||||
{
|
||||
const Formula f = Formula::compile("42");
|
||||
|
||||
REQUIRE(f.isValid());
|
||||
REQUIRE(f.evaluate(0.0) == Approx(42.0));
|
||||
REQUIRE(f.evaluate(100.0) == Approx(42.0));
|
||||
}
|
||||
|
||||
TEST_CASE("Formula evaluates a linear expression in x", "[formula]")
|
||||
{
|
||||
// Matches world.toml [waves].threat_rate_formula default.
|
||||
const Formula f = Formula::compile("1*x - 30");
|
||||
|
||||
REQUIRE(f.evaluate(0.0) == Approx(-30.0));
|
||||
REQUIRE(f.evaluate(30.0) == Approx(0.0));
|
||||
REQUIRE(f.evaluate(60.0) == Approx(30.0));
|
||||
}
|
||||
|
||||
TEST_CASE("Formula evaluates a polynomial in x", "[formula]")
|
||||
{
|
||||
const Formula f = Formula::compile("2 + 3*x*x");
|
||||
|
||||
REQUIRE(f.evaluate(0.0) == Approx(2.0));
|
||||
REQUIRE(f.evaluate(2.0) == Approx(14.0));
|
||||
REQUIRE(f.evaluate(4.0) == Approx(50.0));
|
||||
}
|
||||
|
||||
TEST_CASE("Formula retains its source string", "[formula]")
|
||||
{
|
||||
const std::string source = "10 + x / 5";
|
||||
const Formula f = Formula::compile(source);
|
||||
|
||||
REQUIRE(f.source() == source);
|
||||
}
|
||||
|
||||
TEST_CASE("Formula throws on malformed source", "[formula]")
|
||||
{
|
||||
REQUIRE_THROWS_AS(Formula::compile("1 * + x"), std::runtime_error);
|
||||
REQUIRE_THROWS_AS(Formula::compile(""), std::runtime_error);
|
||||
REQUIRE_THROWS_AS(Formula::compile("unknown_var"), std::runtime_error);
|
||||
}
|
||||
|
||||
TEST_CASE("Formula survives move construction", "[formula]")
|
||||
{
|
||||
// tinyexpr bakes the bound variable's address into the compiled tree.
|
||||
// Formula keeps x on the heap so that address stays valid across moves.
|
||||
Formula original = Formula::compile("x * 2");
|
||||
Formula moved(std::move(original));
|
||||
|
||||
REQUIRE(moved.evaluate(21.0) == Approx(42.0));
|
||||
}
|
||||
|
||||
TEST_CASE("Formula survives move assignment", "[formula]")
|
||||
{
|
||||
Formula a = Formula::compile("x + 1");
|
||||
Formula b = Formula::compile("x + 100");
|
||||
|
||||
b = std::move(a);
|
||||
|
||||
REQUIRE(b.evaluate(5.0) == Approx(6.0));
|
||||
}
|
||||
|
||||
TEST_CASE("Default-constructed Formula is invalid and throws on evaluate", "[formula]")
|
||||
{
|
||||
const Formula f;
|
||||
REQUIRE_FALSE(f.isValid());
|
||||
REQUIRE_THROWS_AS(f.evaluate(0.0), std::runtime_error);
|
||||
}
|
||||
Reference in New Issue
Block a user