generated from cpp-best-practices/cmake_template
/
tests.cpp
117 lines (88 loc) · 3.11 KB
/
tests.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <catch2/catch_test_macros.hpp>
#include <iostream>
#include <cons_expr/cons_expr.hpp>
void display(long long i) { std::cout << i << '\n'; }
auto evaluate(std::string_view input)
{
lefticus::cons_expr<> evaluator;
evaluator.add<display>("display");
auto parse_result = evaluator.parse(input);
auto list = std::get<typename lefticus::cons_expr<>::list_type>(parse_result.first.value);
return evaluator.sequence(evaluator.global_scope, list);
}
template<typename Result> Result evaluate_to(std::string_view input)
{
return std::get<Result>(std::get<lefticus::cons_expr<>::Atom>(evaluate(input).value));
}
TEST_CASE("basic callable usage", "[c++ api]")
{
lefticus::cons_expr<> evaluator;
auto func = evaluator.make_callable<long long(long long, long long, long long)>("+");
CHECK(func(evaluator, 1, 2, 3) == 6);
auto func2 = evaluator.make_callable<long long(long long)>("(lambda (x) (* x x))");
CHECK(func2(evaluator, 10) == 100);
}
TEST_CASE("GPT Generated Tests", "[integration tests]")
{
CHECK(evaluate_to<long long>(R"(
(define make-adder-multiplier
(lambda (a)
(lambda (b)
(do ((i 0 (+ i 1))
(sum 0 (+ sum (let ((x (+ a i)))
(if (>= x b)
(define y (* x 2))
(define y (* x 3)))
(do ((j 0 (+ j 1))
(inner-sum 0 (+ inner-sum y)))
((>= j i) inner-sum))))))
((>= i 5) sum)))))
((make-adder-multiplier 2) 3)
)") == 100);
}
TEST_CASE("member functions", "[function]")
{
struct Test
{
void set(int i) { m_i = i; }
int get() const { return m_i; }
int m_i{ 0 };
};
lefticus::cons_expr<std::uint16_t, char, int, float, 100, 100, 100, Test *> evaluator;
evaluator.add<&Test::set>("set");
evaluator.add<&Test::get>("get");
auto eval = [&](const std::string_view input) {
return evaluator.sequence(
evaluator.global_scope, std::get<decltype(evaluator)::list_type>(evaluator.parse(input).first.value));
};
Test myobj;
myobj.m_i = 42;
evaluator.add("myobj", &myobj);
CHECK(myobj.m_i == 42);
eval("(set myobj 10)");
CHECK(myobj.m_i == 10);
eval("(set myobj (+ (get myobj) 12)");
CHECK(myobj.m_i == 22);
CHECK(evaluator.template eval_to<int>(evaluator.global_scope, eval("(get myobj)")) == 22);
}
TEST_CASE("basic for-each usage", "[builtins]")
{
CHECK_NOTHROW(evaluate_to<std::monostate>("(for-each display '(1 2 3 4))"));
}
/*
struct UDT
{
};
template<typename Result> Result evaluate_to_with_UDT(std::string_view input)
{
lefticus::cons_expr<UDT> evaluator;
lefticus::cons_expr<UDT>::Context context;
auto parsed = evaluator.parse(input);
const auto &items = std::get<lefticus::cons_expr<UDT>::List>(parsed.first.value);
if (!items.empty()) {
for (std::size_t idx = 0; idx < items.size() - 1; ++idx) { evaluator.eval(context, items[idx]); }
}
return evaluator.eval(context, std::get<lefticus::cons_expr<UDT>::List>(parsed.first.value).front());
return std::get<Result>(std::get<lefticus::cons_expr<>::Atom>(evaluate(input).value));
}
*/