-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmath_test.cpp
86 lines (74 loc) · 3.15 KB
/
math_test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <gtest/gtest.h>
#include <iostream>
#include <tao/pegtl.hpp>
#include <tao/pegtl/contrib/analyze.hpp>
#include <tuple>
#include <vector>
#include "flexi_cfg/config/parser-internal.h"
#include "flexi_cfg/math/actions.h"
#include "flexi_cfg/math/grammar.h"
namespace peg = TAO_PEGTL_NAMESPACE;
namespace {
using RefMap = std::map<std::string, double>;
}
class MathExpressionTest : public ::testing::Test {
protected:
const std::vector<std::pair<std::string, double>> test_strings = {
// Inject some whitespace to test robustness to it.
{" 3.14159 * 1e3", 3141.5899999999997},
{"0.5 * (0.7 + 1.2 ) ", 0.95},
{"0.5 + 0.7 * 1.2 ", 1.3399999999999999},
{"3*0.27 - 2.3**0.5 - 5 * 4", -20.70657508881031},
{" 3 ^ 2.4 * 12.2 + 0.1 + 4.3 ", 174.79264401590646},
{"-4.7 * -(3.72 + -pi ) ", 2.7185145281279732},
{" 1/3 * -( 5 + 4 ) ", -3.0},
{"\t3.4 * -(1.9**2 * (1/3.1 - 6) * (2.54- 17.0)\t)", -1007.6399690322581}};
const std::vector<std::tuple<std::string, double, RefMap>> test_w_var_ref = {
{"0.5 * ($(test1.key) - 0.234)", 0.503, {{"test1.key", 1.24}}},
{"3*$(var_ref1) - 2.3**$(exponent) - 5 * 4",
-20.70657508881031,
{{"var_ref1", 0.27}, {"exponent", 0.5}}},
{" $(its.a.three) ^ 2.4 * $(another.var) + $(one.more.value) + 4.3 ",
174.79264401590646,
{{"its.a.three", 3}, {"another.var", 12.2}, {"one.more.value", 0.1}}}};
};
// NOLINTNEXTLINE
TEST(MathExpressionGrammar, analyze) { ASSERT_EQ(peg::analyze<flexi_cfg::math::expression>(), 0); }
// NOLINTNEXTLINE
TEST_F(MathExpressionTest, evaluate) {
auto test_input = [](const std::string& input) -> double {
peg::memory_input in(input, "from content");
flexi_cfg::math::ActionData out;
const auto result = flexi_cfg::config::internal::parseCore<flexi_cfg::math::expression,
flexi_cfg::math::action>(in, out);
return out.res;
};
for (const auto& input : test_strings) {
std::cout << "Input: " << input.first << std::endl;
double result{0};
EXPECT_NO_THROW(result = test_input(input.first));
EXPECT_FLOAT_EQ(result, input.second);
}
// We'll intentionally omit the var_ref_map here to ensure a failure occurs
for (const auto& input : test_w_var_ref) {
std::cout << "Input: " << std::get<0>(input) << std::endl;
EXPECT_THROW(test_input(std::get<0>(input)), std::runtime_error);
}
}
// NOLINTNEXTLINE
TEST_F(MathExpressionTest, evaluate_var_ref) {
auto test_input = [](const std::string& input, const RefMap& ref_map) -> double {
peg::memory_input in(input, "from content");
flexi_cfg::math::ActionData out;
out.var_ref_map = ref_map;
const auto result = flexi_cfg::config::internal::parseCore<flexi_cfg::math::expression,
flexi_cfg::math::action>(in, out);
return out.res;
};
for (const auto& input : test_w_var_ref) {
std::cout << "Input: " << std::get<0>(input) << std::endl;
double result{0};
EXPECT_NO_THROW(result = test_input(std::get<0>(input), std::get<2>(input)));
EXPECT_FLOAT_EQ(result, std::get<1>(input));
}
}