66 using error::LUMIERA_ERROR_STATE;
97 CHECK (not isnil (tab));
98 CHECK (1 == tab.size());
99 CHECK (
"" ==
string{tab.id});
100 CHECK (0.0 == tab.val);
101 CHECK ( 0 == tab.off);
106 CHECK (2 == tab.size());
107 CHECK (
"one" ==
string{tab.id});
108 CHECK ( 1.0 == tab.val);
109 CHECK ( 0 == tab.off);
114 CHECK (
"two" ==
string{tab.id});
115 CHECK ( 5.0 == tab.val);
116 CHECK ( -23 == tab.off);
118 CHECK (tab.off.header ==
"Offset");
119 CHECK (tab.off.data == vector({0,-23}));
129 CHECK (3 == tab.columnCnt);
132 CHECK (0 == tab.size());
133 CHECK (0 == tab.id.data.size());
134 CHECK (0 == tab.val.data.size());
135 CHECK (0 == tab.off.data.size());
136 CHECK (
"ID" == tab.id.header);
137 CHECK (
"Value" == tab.val.header);
138 CHECK (
"Offset" == tab.off.header);
147 tab.val.data.push_back (5.5);
148 CHECK (tab.val == 5.5);
150 CHECK (1 == tab.val.data.size());
151 CHECK (0 == tab.off.data.size());
152 CHECK (0 == tab.id.data.size());
153 CHECK (0 == tab.size());
157 CHECK (
"" ==
string{tab.id});
158 CHECK (5.5 == tab.val);
159 CHECK ( 0 == tab.off);
160 CHECK (1 == tab.val.data.size());
161 CHECK (1 == tab.off.data.size());
162 CHECK (1 == tab.id.data.size());
163 CHECK (1 == tab.size());
164 CHECK (not isnil (tab));
165 CHECK (tab.off.data == vector({0}));
166 CHECK (tab.val.data == vector({5.5}));
168 tab.allColumns() = make_tuple(
"●", 2.3, -11);
169 CHECK (
"●" ==
string{tab.id});
170 CHECK (2.3 == tab.val);
171 CHECK (-11 == tab.off);
176 CHECK (tab.off.data == vector({-11,-11}));
177 CHECK (tab.val.data == vector({2.3,42.0}));
178 CHECK (tab.id.data == vector<string>({
"●",
"◆"}));
181 CHECK (tab.id.data.capacity() >= 100);
182 CHECK (tab.val.data.capacity() >= 100);
183 CHECK (tab.off.data.capacity() >= 100);
184 CHECK (tab.id.data.size() == 2);
185 CHECK (tab.val.data.size() == 2);
186 CHECK (tab.off.data.size() == 2);
187 CHECK (2 == tab.size());
188 CHECK (
"◆" ==
string{tab.id});
189 CHECK ( 42 == tab.val);
190 CHECK (-11 == tab.off);
193 ,[](
auto& col){ col.data.resize(2); }
195 CHECK (2 == tab.size());
196 CHECK (
"◆" ==
string{tab.id});
197 CHECK ( 42 == tab.val);
198 CHECK (-11 == tab.off);
201 CHECK (1 == tab.size());
202 CHECK (
"●" ==
string{tab.id});
203 CHECK (2.3 == tab.val);
204 CHECK (-11 == tab.off);
205 CHECK (tab.val.data.size() == 1);
206 CHECK (tab.val.data.capacity() >= 100);
210 CHECK (tab.val.data.size() == 0);
211 CHECK (tab.val.data.capacity() >= 100);
219 double val = 1.0 / 3;
223 CHECK (boost::lexical_cast<string>(val) ==
"0.33333333333333331"_expect);
225 CHECK (format4Csv(
double(1) / 3) ==
"0.333333333333333"_expect );
226 CHECK (format4Csv(
float(1) / 3) ==
"0.333333"_expect );
227 CHECK (format4Csv(
f128(1) / 3) ==
"0.333333333333333333"_expect);
228 CHECK (format4Csv(
bool(1)) ==
"true"_expect );
229 CHECK (format4Csv(
bool(0)) ==
"false"_expect);
230 CHECK (format4Csv(
"Starship-3") ==
"\"Starship-3\""_expect );
231 CHECK (format4Csv(
Time(1,2,25,13)) ==
"\"13:25:02.001\""_expect);
235 int64_t ii = -100000;
239 CHECK (line ==
"-100000"_expect);
241 CHECK (line ==
"-100000,0.333333333333333"_expect);
243 CHECK (line ==
"-100000,0.333333333333333,true"_expect);
245 CHECK (line ==
"-100000,0.333333333333333,true,\"Raptor\""_expect);
249 CHECK (parse.isValid());
250 CHECK (*parse ==
"-100000"_expect);
251 CHECK (-100000 == parseAs<int>(*parse));
253 CHECK (parse.isValid());
254 CHECK (*parse ==
"0.333333333333333"_expect);
255 CHECK (0.333333343f == parseAs<float>(*parse));
257 CHECK (parse.isValid());
259 CHECK (*parse ==
"true"_expect);
260 CHECK (
true == parseAs<bool>(*parse));
262 CHECK (parse.isValid());
263 CHECK (*parse ==
"Raptor"_expect);
264 CHECK (
"Raptor" == parseAs<string>(*parse));
266 CHECK (not parse.isValid());
268 line =
" ◐0◑. ; \t \"' \" \n ,oh my ;";
270 CHECK (
"◐0◑." == *horror);
271 CHECK (0 == horror.getParsedFieldCnt());
273 CHECK (1 == horror.getParsedFieldCnt());
274 CHECK (
"' " == *horror);
276 CHECK (
"oh" == *horror);
277 CHECK (2 == horror.getParsedFieldCnt());
282 CHECK (not horror.isValid());
283 CHECK (horror.isParseFail());
296 fs::path f = temp.
makeFile(
"dataz.csv");
297 std::ofstream content{f};
298 content << R
"("ID", "Value", "Offset")"<<endl
299 << R"( "one" , 5.5 ; +1 )"<<endl
300 << R"(;" 0 ";0)" <<endl;
304 CHECK (2 == dat.size());
305 CHECK (
"ID" == dat.id.header);
306 CHECK (
"Value" == dat.val.header);
307 CHECK (
"Offset" == dat.off.header);
309 CHECK (
"one" ==
string{dat.id});
310 CHECK ( 5.5 == dat.val);
311 CHECK ( 1 == dat.off);
312 CHECK (dat.id.data == vector<string>({
"",
"one"}));
313 CHECK (dat.val.data == vector<double>({0 ,5.5 }));
314 CHECK (dat.off.data == vector<int> ({0 ,1 }));
322 CHECK (dat.renderCSV() ==
323R
"("ID","Value","Offset"
333 std::ifstream readback{f};
334 std::ostringstream inBuff;
335 inBuff << readback.rdbuf();
336 CHECK (inBuff.str() ==
337R
"("ID","Value","Offset"
351 CHECK (
CSVLine(1,
"2",3.4,5555/55) ==
"1,\"2\",3.4,101"_expect);
352 CHECK (
CSVLine(
string{
"himself"}) ==
"\"himself\""_expect);
354 CHECK (CSVLine{} ==
""_expect);
356 auto appended = (CSVLine{} += 5.5) += Symbol();
357 CHECK (appended ==
"5.5,\"⟂\""_expect);
359 CHECK (CSVData({
"eeny",
"meeny",
"miny",
"moe"}) ==
"\"eeny\",\"meeny\",\"miny\",\"moe\"\n"_expect);
360 CHECK (CSVData({
"eeny , meeny",
"miny",
"moe"}) ==
"\"eeny , meeny\"\n\"miny\"\n\"moe\"\n"_expect);
362 auto csv = CSVData{{
"la",
"la",
"schland"}
364 ,{
"mit",
string{
"mia"}, Literal(
"ned")}
365 ,CSVLine(
string(
";"))
369 CHECK (csv.size() == 6);
370 CHECK (
string(csv) ==
371R
"("la","la","schland"
379 VERIFY_FAIL ("Header mismatch in CSV file", TestTab{csv} );
381 csv = CSVData{{
"ID",
"Value",
"Offset"}
384 VERIFY_FAIL (
"unable to parse \"toe\"", TestTab{csv} );
386 csv = CSVData{{
"ID",
"Value",
"Offset"}
391 CHECK (dat.val == 1.0101e4);
392 CHECK (dat.renderCSV() ==
string(csv));
Parser to split one line of CSV data into fields.
Table with data values, stored persistently as CSV file.
void verify_rowHandling()
void verify_persistentDataFile()
void demonnstrate_CSV_Notation()
A RAII style temporary directory.
fs::path makeFile(string name="")
Lumiera's internal time value datatype.
Manage a table with data records, stored persistently as CSV.
DataTable< TableForm > TestTab
void appendCsvField(string &csv, VAL const &val)
Format and append a data value to a CSV string representation.
Implementation namespace for support and library code.
Test runner and basic definitions for tests.
string showComplete(double val) noexcept
show enough decimal digits to represent every distinct value
string showDecimal(double val) noexcept
show maximum reproducible decimal representation
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
bool isnil(lib::time::Duration const &dur)
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
A string with the ability to construct or append the CSV-rendering of data fields.
Descriptor and Accessor for a data column within a DataTable table.
Manage a temporary directory for storage, with automated clean-up.
A collection of frequently used helper functions to support unit testing.
#define VERIFY_FAIL(FAILURE_MSG, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises a std::exception, which additionally contains some FAI...
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
a family of time value like entities and their relationships.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...