-
Notifications
You must be signed in to change notification settings - Fork 0
/
tester.cc
145 lines (119 loc) · 3.81 KB
/
tester.cc
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <cassert>
#include <cmath>
#include <cstddef>
#include <cstring>
#include <optional>
#include <string>
#include <string_view>
#include <variant>
#include <unistd.h>
#include <fmt/format.h>
#include "oicompare.hh"
#include "tests.hh"
using namespace oicompare::tests;
namespace
{
constexpr bool
test_constexpr ()
{
for (const auto &test_case : test_cases)
{
{
auto result = oicompare::compare (test_case.first, test_case.second);
if (!compare_result (test_case.first.begin (),
test_case.second.begin (),
test_case.expected_result, result))
return false;
}
// Test symmetry
{
auto result = oicompare::compare (test_case.second, test_case.first);
auto expected = test_case.expected_result;
expected.swap ();
if (!compare_result (test_case.second.begin (),
test_case.first.begin (), expected, result))
return false;
}
}
return true;
}
// Run tests in compile time.
static_assert (test_constexpr ());
}
int
main ()
{
std::size_t index = 0;
for (const auto &test_case : test_cases)
{
// Prevent the compiler from optimizing the test
std::string first_copy (test_case.first.size (), '\0');
std::memcpy (first_copy.data (), test_case.first.data (),
test_case.first.size ());
std::string second_copy (test_case.second.size (), '\0');
std::memcpy (second_copy.data (), test_case.second.data (),
test_case.second.size ());
{
auto result = oicompare::compare (first_copy, second_copy);
if (!compare_result (first_copy.begin (), second_copy.begin (),
test_case.expected_result, result))
{
fmt::println ("Test {} failed\n", index);
return 1;
}
}
// Test symmetry
{
auto result = oicompare::compare (second_copy, first_copy);
auto expected = test_case.expected_result;
expected.swap ();
if (!compare_result (second_copy.begin (), first_copy.begin (),
expected, result))
{
fmt::println ("Test {} failed symmetry check!\n", index);
return 99;
}
}
++index;
}
index = 0;
for (const auto &test_case : test_translation_cases)
{
// Prevent the compiler from optimizing the test
std::string first_copy (test_case.first.size (), '\0');
std::memcpy (first_copy.data (), test_case.first.data (),
test_case.first.size ());
std::string second_copy (test_case.second.size (), '\0');
std::memcpy (second_copy.data (), test_case.second.data (),
test_case.second.size ());
auto result = oicompare::compare (
first_copy.c_str (), first_copy.c_str () + first_copy.size (),
second_copy.c_str (), second_copy.c_str () + second_copy.size ());
// Replace stdout.
fflush (stdout);
int stdout_fd = dup (fileno (stdout));
std::FILE *capture_file = tmpfile ();
dup2 (fileno (capture_file), fileno (stdout));
// Print the result.
test_case.translator (result);
// Restore stdout.
fflush (stdout);
dup2 (stdout_fd, fileno (stdout));
close (stdout_fd);
char buffer[1024];
std::string result_str;
rewind (capture_file);
while (fgets (buffer, sizeof (buffer), capture_file) != nullptr)
result_str += buffer;
fclose (capture_file);
if (result_str != test_case.result)
{
fmt::println ("Test {} failed", index);
fmt::println ("Expected: {}", test_case.result);
fmt::println ("Got: {}", result_str);
return 1;
}
++index;
}
return 0;
}