15 #include "eckit/testing/Test.h"
20 using namespace eckit::testing;
25 CASE(
"Read columnar data from CSV") {
30 std::stringstream data;
31 data <<
"col1:INTEGER,col2:REAL,col3:DOUBLE,col4:STRING,col5:BITFIELD[a:1;b:2;c:5]\n";
32 data <<
"1,1.001,0,a-string,0\n";
33 data <<
"1234,0,88,b-string,2\n";
34 data <<
"-5432,-6.543210,99.999,string-c,4\n";
35 data <<
"-2147483648,6.543210,11.63e-37,testing,7\n";
36 data <<
"2147483647,NaN,Nan,12345678,8\n";
37 data <<
"0,+inf,-inf,this-is-a-longer-string,11\n";
38 data <<
"0,-inf,0,short,0\n";
43 std::vector<long> INTEGERS {1, 1234, -5432, -2147483648, 2147483647, 0, 0};
44 std::vector<float> REALS {1.001, 0.0, -6.543210, 6.543210, std::numeric_limits<float>::quiet_NaN(),
45 std::numeric_limits<float>::infinity(), -std::numeric_limits<float>::infinity()};
46 std::vector<double> DOUBLES {0, 88, 99.999, 11.63e-37, std::numeric_limits<double>::quiet_NaN(),
47 -std::numeric_limits<double>::infinity(), 0};
48 std::vector<std::string> STRINGS {
"a-string",
"b-string",
"string-c",
"testing",
"12345678",
"this-is-a-longer-string",
"short"};
49 std::vector<long> BITFIELDS {0, 2, 4, 7, 8, 11, 0};
51 EXPECT(it->
columns().size() == 5);
53 EXPECT(it->
columns()[0]->name() ==
"col1");
54 EXPECT(it->
columns()[1]->name() ==
"col2");
55 EXPECT(it->
columns()[2]->name() ==
"col3");
56 EXPECT(it->
columns()[3]->name() ==
"col4");
57 EXPECT(it->
columns()[4]->name() ==
"col5");
66 for (; it != reader.
end(); ++it) {
73 EXPECT(it->
data(1) ==
double(REALS[
count-1]) || (std::isnan(it->
data(1)) && std::isnan(REALS[
count-1])));
74 EXPECT(it->
data(2) == DOUBLES[
count-1] || (std::isnan(it->
data(2)) && std::isnan(DOUBLES[
count-1])));
77 EXPECT(it->
data(4) == BITFIELDS[
count-1]);
79 for (
const auto& col : it->
columns()) {
80 EXPECT(!col->hasMissing());
87 CASE(
"Starting with long strings") {
92 std::stringstream data;
93 data <<
"col4:STRING\n";
94 data <<
"a-string-is-long\n";
95 data <<
"b-string-is-very-long-indeed-whoah\n";
100 std::vector<std::string> STRINGS {
"a-string-is-long",
"b-string-is-very-long-indeed-whoah"};
102 EXPECT(it->
columns().size() == 1);
103 EXPECT(it->
columns()[0]->name() ==
"col4");
107 for (; it != reader.
end(); ++it) {
115 for (
const auto& col : it->
columns()) {
116 EXPECT(!col->hasMissing());
123 CASE(
"Test parsing bitfields") {
125 std::string bitfieldDefinition =
"en4_level_flag@hdr:bitfield[TempLevelReject:1;SaltLevelReject:1;LevelVertStability:1;IncreasingDepthCheck:1;NotUsed1:1;NotUsed2:1;NotUsed3:1;NotUsed4:1;NotUsed5:1;TempLevelStatList:1;TempLevelArgoQC:1;TempLevelOutOfRangeSetToMDI:1;TempLevelEN3List:1;TempLevelVertCheck:1;TempLevelNoBckgrnd:1;TempLevelBays:1;TempLevelBaysBud:1;TempLevelBaysBudReinstate:1;TempLevelWaterfallCheck:1;NotUsed6:1;NotUsed7:1;SaltLevelStatList:1;SaltLevelArgoQC:1;SaltLevelOutOfRangeSetToMDI:1;SaltLevelEN3List:1;SaltLevelVertCheck:1;SaltLevelNoBckgrnd:1;SaltLevelBays:1;SaltLevelBaysBud:1;SaltLevelBaysBudReinstate:1;SaltLevelWaterfallCheck:1]";
128 eckit::sql::FieldNames names(def.first);
129 eckit::sql::Sizes sizes(def.second);
131 std::vector<std::string> FIELD_NAMES {
132 "TempLevelReject",
"SaltLevelReject",
"LevelVertStability",
"IncreasingDepthCheck",
133 "NotUsed1",
"NotUsed2",
"NotUsed3",
"NotUsed4",
"NotUsed5",
"TempLevelStatList",
134 "TempLevelArgoQC",
"TempLevelOutOfRangeSetToMDI",
"TempLevelEN3List",
135 "TempLevelVertCheck",
"TempLevelNoBckgrnd",
"TempLevelBays",
"TempLevelBaysBud",
136 "TempLevelBaysBudReinstate",
"TempLevelWaterfallCheck",
"NotUsed6",
"NotUsed7",
137 "SaltLevelStatList",
"SaltLevelArgoQC",
"SaltLevelOutOfRangeSetToMDI",
138 "SaltLevelEN3List",
"SaltLevelVertCheck",
"SaltLevelNoBckgrnd",
"SaltLevelBays",
139 "SaltLevelBaysBud",
"SaltLevelBaysBudReinstate",
"SaltLevelWaterfallCheck" };
141 ASSERT(names.size() == 31);
142 ASSERT(sizes.size() == 31);
144 EXPECT(names == FIELD_NAMES);
145 EXPECT(std::all_of(sizes.begin(), sizes.end(), [](
int x){return x == 1;}));
149 CASE(
"Test parsing bitfields - 32bit limit") {
150 std::string bitfieldDefinition =
"en4_level_flag@hdr:bitfield[TempLevelReject:1;SaltLevelReject:1;LevelVertStability:1;IncreasingDepthCheck:1;NotUsed1:1;NotUsed2:1;NotUsed3:1;NotUsed4:1;NotUsed5:1;TempLevelStatList:1;TempLevelArgoQC:1;TempLevelOutOfRangeSetToMDI:1;TempLevelEN3List:1;TempLevelVertCheck:1;TempLevelNoBckgrnd:1;TempLevelBays:1;TempLevelBaysBud:1;TempLevelBaysBudReinstate:1;TempLevelWaterfallCheck:1;NotUsed6:1;NotUsed7:1;SaltLevelStatList:1;SaltLevelArgoQC:1;SaltLevelOutOfRangeSetToMDI:1;SaltLevelEN3List:1;SaltLevelVertCheck:1;SaltLevelNoBckgrnd:1;SaltLevelBays:1;SaltLevelBaysBud:1;SaltLevelBaysBudReinstate:1;SaltLevelWaterfallCheck:1;NotUsed8:1;NotUsed9:1]";
156 int main(
int argc,
char* argv[]) {
157 return run_tests(argc, argv);
static void count(void *counter, const double *data, size_t n)
size_t dataSizeDoubles(size_t i) const
const core::MetaData & columns() const
static eckit::sql::BitfieldDef parseBitfields(const std::string &)
int main(int argc, char *argv[])
CASE("Read columnar data from CSV")