Skip to content

Commit f872d81

Browse files
committed
test: Add test for Database object
Some conditions are difficult to check via the python scripts. Specfically some of the more odd sort orderings. Signed-off-by: Shaun Ruffell <[email protected]>
1 parent 98e313f commit f872d81

File tree

3 files changed

+197
-1
lines changed

3 files changed

+197
-1
lines changed

test/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
all.log
22
AtomicFileTest
33
data.t
4+
Database.t
45
Datafile.t
56
DatetimeParser.t
67
exclusion.t

test/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ include_directories (${CMAKE_SOURCE_DIR}
3434
include_directories (${CMAKE_INSTALL_PREFIX}/include)
3535
link_directories(${CMAKE_INSTALL_PREFIX}/lib)
3636

37-
set (test_SRCS AtomicFileTest data.t Datafile.t DatetimeParser.t exclusion.t helper.t interval.t range.t rules.t util.t TagInfoDatabase.t)
37+
set (test_SRCS AtomicFileTest data.t Database.t Datafile.t DatetimeParser.t
38+
exclusion.t helper.t interval.t range.t rules.t util.t TagInfoDatabase.t)
3839

3940
add_custom_target (test ./run_all --verbose
4041
DEPENDS ${test_SRCS} timew_executable

test/Database.t.cpp

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
////////////////////////////////////////////////////////////////////////////////
2+
//
3+
// Copyright 2020, Shaun Ruffell, Thomas Lauf.
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included
13+
// in all copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18+
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
// SOFTWARE.
22+
//
23+
// https://www.opensource.org/licenses/mit-license.php
24+
//
25+
////////////////////////////////////////////////////////////////////////////////
26+
27+
#include <algorithm>
28+
#include <cassert>
29+
#include <test.h>
30+
#include <vector>
31+
#include <algorithm>
32+
#include <Database.h>
33+
#include <Interval.h>
34+
#include <IntervalFactory.h>
35+
#include <timew.h>
36+
37+
#include <TempDir.h>
38+
39+
const std::vector <Interval>& get_common_inputs ()
40+
{
41+
static std::vector <Interval> inputs;
42+
if (inputs.empty ())
43+
{
44+
inputs.reserve (7);
45+
46+
inputs.emplace_back (Datetime ("2016-06-03T01:00:00"), Datetime ("2016-06-03T02:00:00"));
47+
inputs.emplace_back (Datetime ("2018-06-02T01:00:00"), Datetime ("2018-06-02T02:00:00"));
48+
inputs.emplace_back (Datetime ("2019-06-03T01:00:00"), Datetime ("2019-06-03T02:00:00"));
49+
inputs.emplace_back (Datetime ("2017-06-02T01:00:00"), Datetime ("2017-06-02T02:00:00"));
50+
inputs.emplace_back (Datetime ("2018-06-03T01:00:00"), Datetime ("2018-06-03T02:00:00"));
51+
inputs.emplace_back (Datetime ("2019-06-02T01:00:00"), Datetime ("2019-06-02T02:00:00"));
52+
inputs.emplace_back (Datetime ("2016-06-02T01:00:00"), Datetime ("2016-06-02T02:00:00"));
53+
}
54+
55+
return inputs;
56+
}
57+
58+
bool test_database_remains_sorted ()
59+
{
60+
const bool verbose = true;
61+
62+
TempDir tempDir;
63+
64+
const std::vector <Interval>& inputs = get_common_inputs ();
65+
66+
Database database {tempDir, 0};
67+
68+
for (const auto& interval : inputs)
69+
{
70+
database.addInterval (interval, verbose);
71+
}
72+
73+
database.commit ();
74+
if (!std::is_sorted (database.rbegin (), database.rend ()))
75+
{
76+
return false;
77+
}
78+
79+
database = Database {tempDir, 0};
80+
81+
if (std::distance (database.begin(), database.end()) != static_cast <ssize_t> (inputs.size ()))
82+
{
83+
return false;
84+
}
85+
86+
return true;
87+
}
88+
89+
bool test_database_handles_add_on_reload ()
90+
{
91+
const bool verbose = true;
92+
TempDir tempDir;
93+
94+
const std::vector <Interval>& inputs = get_common_inputs ();
95+
96+
// First, just load the database with the common inputs and commit
97+
Database database {tempDir, 0};
98+
99+
for (const auto& interval : inputs)
100+
{
101+
database.addInterval (interval, verbose);
102+
}
103+
database.commit ();
104+
105+
// Reset the database
106+
database = Database {tempDir, 0};
107+
108+
database.addInterval ({Datetime ("1980-01-01T12:01:01"), Datetime ("1980-01-01T12:01:02")}, verbose);
109+
110+
if (std::distance (database.begin(), database.end()) != static_cast <ssize_t> (inputs.size () + 1))
111+
{
112+
return false;
113+
}
114+
115+
if (!std::is_sorted (database.rbegin (), database.rend ()))
116+
{
117+
return false;
118+
}
119+
120+
return true;
121+
}
122+
123+
bool test_database_forward_and_reverse_iterators_keep_ordering ()
124+
{
125+
const bool verbose = true;
126+
TempDir tempDir;
127+
128+
const std::vector <Interval>& inputs = get_common_inputs ();
129+
130+
// First, just load the database with the common inputs and commit
131+
Database database {tempDir, 0};
132+
133+
for (const auto& interval : inputs)
134+
{
135+
database.addInterval (interval, verbose);
136+
}
137+
138+
database.commit ();
139+
140+
// Now reload database and check forward and reverse iterator
141+
database = Database {tempDir, 0};
142+
143+
std::vector <std::string> forward_vector {database.begin (), database.end ()};
144+
std::reverse (forward_vector.begin (), forward_vector.end ());
145+
146+
return std::equal (database.rbegin (), database.rend (), forward_vector.begin ());
147+
}
148+
149+
bool test_database_throws_on_bad_location ()
150+
{
151+
try
152+
{
153+
Database database {"baddir", 0};
154+
return false;
155+
}
156+
catch (const std::string& error)
157+
{
158+
return true;
159+
}
160+
return true;
161+
}
162+
163+
int main ()
164+
{
165+
enableDebugMode (false);
166+
UnitTest t (5);
167+
bool unexpected_exception = false;
168+
try
169+
{
170+
t.ok (test_database_remains_sorted (), "database stays sorted when intervals are added out of order");
171+
t.ok (test_database_handles_add_on_reload (), "database remains sorted when mixing new intervals with those loaded from files");
172+
t.ok (test_database_forward_and_reverse_iterators_keep_ordering (), "database forward and reverse iterators keep same ordering");
173+
t.ok (test_database_throws_on_bad_location (), "database throws an error when given an invalid location");
174+
}
175+
catch (const std::string& error)
176+
{
177+
unexpected_exception = true;
178+
std::cerr << "Unexpected exception: " << error << '\n';
179+
}
180+
catch (const std::exception& error)
181+
{
182+
unexpected_exception = true;
183+
std::cerr << "Unexpected exception: " << error.what () << '\n';
184+
}
185+
catch (...)
186+
{
187+
unexpected_exception = true;
188+
std::cerr << "Unexpected exception.\n";
189+
}
190+
191+
t.ok (unexpected_exception == false, "No unexpected exceptions");
192+
return 0;
193+
}
194+

0 commit comments

Comments
 (0)