summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Jamfile.jam11
-rw-r--r--test/helpers.h44
-rw-r--r--test/test-bitset.cpp31
-rw-r--r--test/test-rawDataReader.cpp163
-rw-r--r--test/test-streams.cpp92
5 files changed, 341 insertions, 0 deletions
diff --git a/test/Jamfile.jam b/test/Jamfile.jam
new file mode 100644
index 0000000..e6a833a
--- /dev/null
+++ b/test/Jamfile.jam
@@ -0,0 +1,11 @@
+lib boost_unit_test_framework ;
+
+project : requirements
+ <library>../lib//mygrate
+ <library>boost_unit_test_framework
+ <define>BOOST_TEST_DYN_LINK
+ ;
+
+run test-rawDataReader.cpp ;
+run test-bitset.cpp ;
+run test-streams.cpp ;
diff --git a/test/helpers.h b/test/helpers.h
new file mode 100644
index 0000000..107eda5
--- /dev/null
+++ b/test/helpers.h
@@ -0,0 +1,44 @@
+#ifndef MYGRATE_TEST_HELPERS_H
+#define MYGRATE_TEST_HELPERS_H
+
+#include <concepts>
+#include <cstddef>
+#include <ctime>
+
+inline constexpr std::byte operator""_b(const unsigned long long hex)
+{
+ return std::byte(hex);
+}
+
+inline constexpr bool
+operator==(const struct tm & a, const struct tm & b)
+{
+ return (a.tm_year == b.tm_year) && (a.tm_mon == b.tm_mon) && (a.tm_mday == b.tm_mday) && (a.tm_hour == b.tm_hour)
+ && (a.tm_min == b.tm_min) && (a.tm_sec == b.tm_sec);
+}
+
+namespace std {
+ template<integral T>
+ inline constexpr bool
+ operator!=(const byte b, const T i)
+ {
+ return to_integer<T>(b) != i;
+ }
+}
+
+inline struct tm
+make_tm(int year, int mon, int day, int hr, int min, int sec)
+{
+ struct tm tm {
+ };
+ tm.tm_year = year - 1900;
+ tm.tm_mon = mon - 1;
+ tm.tm_mday = day;
+ tm.tm_hour = hr;
+ tm.tm_min = min;
+ tm.tm_sec = sec;
+ mktime(&tm);
+ return tm;
+}
+
+#endif
diff --git a/test/test-bitset.cpp b/test/test-bitset.cpp
new file mode 100644
index 0000000..83e136c
--- /dev/null
+++ b/test/test-bitset.cpp
@@ -0,0 +1,31 @@
+#define BOOST_TEST_MODULE BitSet
+#include <boost/test/data/test_case.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include "helpers.h"
+#include <bitset.h>
+#include <bitset>
+
+using namespace MyGrate;
+
+BOOST_TEST_DONT_PRINT_LOG_VALUE(BitSet::Iterator);
+
+BOOST_AUTO_TEST_CASE(bitset)
+{
+ std::byte bytes[3] {0x00_b, 0xFF_b, 0xa1_b};
+ BitSet bs {bytes};
+
+ BOOST_REQUIRE_EQUAL(bs.size(), 24);
+
+ std::bitset<24> exp {0xa1ff00};
+
+ auto iter {bs.begin()};
+
+ for (auto x {0U}; x < 24 && iter != bs.end(); x++) {
+ BOOST_TEST_INFO(x);
+ BOOST_CHECK_EQUAL(*iter, exp.test(x));
+ iter++;
+ }
+
+ BOOST_CHECK_EQUAL(iter, bs.end());
+}
diff --git a/test/test-rawDataReader.cpp b/test/test-rawDataReader.cpp
new file mode 100644
index 0000000..4ac0a8a
--- /dev/null
+++ b/test/test-rawDataReader.cpp
@@ -0,0 +1,163 @@
+#define BOOST_TEST_MODULE RawDataReader
+#include <boost/mpl/list.hpp>
+#include <boost/test/data/test_case.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include "helpers.h"
+#include <mysql_types.h>
+#include <rawDataReader.h>
+#include <streamSupport.h>
+
+using namespace MyGrate;
+
+using Bytes = std::vector<uint8_t>;
+template<typename T> using BytesTo = std::tuple<Bytes, T>;
+
+BOOST_DATA_TEST_CASE(read_packedinteger,
+ boost::unit_test::data::make<BytesTo<uint64_t>>({
+ {{0x00, 0xb2, 0x2, 0}, 0},
+ {{0x01, 0xb2, 0x2, 0}, 1},
+ {{0xfa, 0xb2, 0x2, 0}, 0xfa},
+ {{0xfc, 0xb2, 0x2, 0}, 0x02b2},
+ {{0xfd, 0xb2, 0x2, 0}, 690},
+ {{0xfe, 0xb2, 0x2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 690},
+ }),
+ bytes, out)
+{
+ RawDataReader rdr {bytes.data(), bytes.size()};
+ BOOST_CHECK_EQUAL((rdr.readValue<PackedInteger>()), out);
+}
+
+BOOST_DATA_TEST_CASE(invalid_packed_ints,
+ boost::unit_test::data::make<Bytes>({
+ {0xFF, 0x78, 0x38, 0x1a, 0x0b},
+ {0xFB, 0x78, 0x38, 0x1a, 0x0b},
+ }),
+ bytes)
+{
+ RawDataReader rdr {bytes.data(), bytes.size()};
+ BOOST_CHECK_THROW(rdr.readValue<PackedInteger>(), std::domain_error);
+}
+
+BOOST_DATA_TEST_CASE(read_overflow,
+ boost::unit_test::data::make<Bytes>({
+ {0x00, 0xFB, 0x12, 0x00},
+ }),
+ bytes)
+{
+ RawDataReader rdr {bytes.data(), bytes.size()};
+ rdr.discard(1);
+ BOOST_CHECK_EQUAL(rdr.readValue<uint16_t>(), 0x12FB);
+ BOOST_CHECK_THROW(rdr.readValue<uint16_t>(), std::range_error);
+}
+
+/*
+BOOST_DATA_TEST_CASE(read_overflow_string,
+ boost::unit_test::data::make<Bytes>({
+ {0x04, 'a', 'b', 'c'},
+ }),
+ bytes)
+{
+ RawDataReader rdr {bytes.data(), bytes.size()};
+ // BOOST_CHECK_THROW(rdr.readValue<VarChar<1>>(), std::range_error);
+}
+
+BOOST_DATA_TEST_CASE(read_datetime2,
+ boost::unit_test::data::make<BytesTo<struct tm>>({
+ {{0x99, 0x78, 0x38, 0x1a, 0x0b}, make_tm(2006, 2, 28, 1, 40, 11)},
+ }),
+ bytes, exp)
+{
+ RawDataReader rdr {bytes.data(), bytes.size()};
+ (void)exp;
+ // BOOST_CHECK_EQUAL((rdr.readValue<DateTime2>()), out);
+}
+
+BOOST_DATA_TEST_CASE(read_varchars1,
+ boost::unit_test::data::make<BytesTo<std::string_view>>({
+ {{0x00}, ""},
+ {{0x01, 'A'}, "A"},
+ {{0x03, 'a', 'b', 'c'}, "abc"},
+ {{0x10, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'},
+ "0123456789abcdef"},
+ }),
+ bytes, exp)
+{
+ RawDataReader rdr {bytes.data(), bytes.size()};
+ (void)exp;
+ // BOOST_CHECK_EQUAL((rdr.readValue<VarChar<1>>()), exp);
+}
+
+BOOST_DATA_TEST_CASE(read_varchars2,
+ boost::unit_test::data::make<BytesTo<std::string_view>>({
+ {{0x00, 0x00}, ""},
+ {{0x01, 0x00, 'A'}, "A"},
+ {{0x03, 0x00, 'a', 'b', 'c'}, "abc"},
+ {{0x10, 0x00, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'},
+ "0123456789abcdef"},
+ }),
+ bytes, exp)
+{
+ RawDataReader rdr {bytes.data(), bytes.size()};
+ (void)exp;
+ // BOOST_CHECK_EQUAL((rdr.readValue<VarChar<2>>()), exp);
+}
+*/
+
+BOOST_DATA_TEST_CASE(read_bytes,
+ boost::unit_test::data::make<Bytes>({
+ {},
+ {0x01},
+ {0x00, 0x01, 0x02},
+ {0xFF, 0xFE, 0xFD},
+ {0xFF, 0xFE, 0xFD, 0x00, 0x01, 0x02},
+ }),
+ bytes)
+{
+ RawDataReader rdr {bytes.data(), bytes.size()};
+ const auto out {rdr.viewValue<MyGrate::MySQL::Blob>(bytes.size())};
+ BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(), bytes.begin(), bytes.end());
+}
+
+BOOST_DATA_TEST_CASE(read_bytes_overflow,
+ boost::unit_test::data::make<Bytes>({
+ {},
+ {0x01},
+ {0x00, 0x01, 0x02},
+ {0xFF, 0xFE, 0xFD},
+ {0xFF, 0xFE, 0xFD, 0x00, 0x01, 0x02},
+ }),
+ bytes)
+{
+ RawDataReader rdr {bytes.data(), bytes.size()};
+ BOOST_CHECK_THROW(rdr.viewValue<MyGrate::MySQL::Blob>(bytes.size() + 1), std::range_error);
+}
+
+BOOST_DATA_TEST_CASE(read_field_type,
+ boost::unit_test::data::make<BytesTo<enum_field_types>>({
+ {{0x00}, MYSQL_TYPE_DECIMAL},
+ {{0x04}, MYSQL_TYPE_FLOAT},
+ {{0xFF}, MYSQL_TYPE_GEOMETRY},
+ }),
+ bytes, exp)
+{
+ RawDataReader rdr {bytes.data(), bytes.size()};
+ BOOST_CHECK_EQUAL(rdr.readValue<enum_field_types>(1), exp);
+}
+
+BOOST_AUTO_TEST_CASE(rdr_from_MARIADB_STRING)
+{
+ char buf[5] = "test";
+ MARIADB_STRING str {buf, strlen(buf)};
+ RawDataReader rdr {str};
+ BOOST_CHECK_EQUAL(rdr.viewValue<std::string_view>(4), "test");
+}
+
+using SimpleTypes = boost::mpl::list<std::byte, int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t,
+ uint64_t, float, double>;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(rdr_read_simple, T, SimpleTypes)
+{
+ RawDataReader rdr {"don't care, some bytes", 20};
+ rdr.readValue<T>();
+}
diff --git a/test/test-streams.cpp b/test/test-streams.cpp
new file mode 100644
index 0000000..9e79bd6
--- /dev/null
+++ b/test/test-streams.cpp
@@ -0,0 +1,92 @@
+#define BOOST_TEST_MODULE StreamSupport
+#include <boost/test/data/test_case.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include "helpers.h"
+#include <streamSupport.h>
+
+BOOST_FIXTURE_TEST_SUITE(stream, std::stringstream);
+
+template<typename In> using ToStream = std::tuple<In, std::string_view>;
+BOOST_DATA_TEST_CASE(bytes,
+ boost::unit_test::data::make<ToStream<std::byte>>({
+ //{0x00_b, "0x00"},
+ {0x10_b, "0x10"},
+ {0xFE_b, "0xfe"},
+ {0xff_b, "0xff"},
+ }),
+ in, exp)
+{
+ *this << in;
+ BOOST_CHECK_EQUAL(this->str(), exp);
+}
+
+BOOST_DATA_TEST_CASE(tms,
+ boost::unit_test::data::make<ToStream<tm>>({
+ {make_tm(2016, 1, 4, 12, 13, 14), "2016-01-04 12:13:14"},
+ {make_tm(2016, 12, 31, 0, 0, 1), "2016-12-31 00:00:01"},
+ }),
+ in, exp)
+{
+ *this << in;
+ BOOST_CHECK_EQUAL(this->str(), exp);
+}
+
+BOOST_DATA_TEST_CASE(rts,
+ boost::unit_test::data::make<ToStream<MyGrate::MySQL::DateTime>>({
+ {{{2016, 1, 4}, {12, 13, 14}}, "2016-01-04 12:13:14"},
+ {{{2016, 12, 31}, {0, 0, 1}}, "2016-12-31 00:00:01"},
+ }),
+ in, exp)
+{
+ *this << in;
+ BOOST_CHECK_EQUAL(this->str(), exp);
+}
+
+BOOST_DATA_TEST_CASE(tss,
+ boost::unit_test::data::make<ToStream<timespec>>({
+ {{0, 0}, "0.000000000"},
+ {{0, 1}, "0.000000001"},
+ {{1, 0}, "1.000000000"},
+ {{123, 0}, "123.000000000"},
+ {{123, 999999999}, "123.999999999"},
+ }),
+ in, exp)
+{
+ *this << in;
+ BOOST_CHECK_EQUAL(this->str(), exp);
+}
+constexpr std::byte somebits[3] {0x00_b, 0xFF_b, 0xa1_b};
+BOOST_DATA_TEST_CASE(bss,
+ boost::unit_test::data::make<ToStream<MyGrate::BitSet>>({
+ {{MyGrate::BitSet {somebits}}, "[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,1]"},
+ }),
+ in, exp)
+{
+ *this << in;
+ BOOST_CHECK_EQUAL(this->str(), exp);
+}
+
+BOOST_AUTO_TEST_CASE(mariadb_string)
+{
+ char buf[5] = "test";
+ MARIADB_STRING str {buf, strlen(buf)};
+ *this << str;
+ BOOST_CHECK_EQUAL(this->str(), buf);
+}
+
+BOOST_AUTO_TEST_CASE(array)
+{
+ std::array<int, 3> arr {1, 123456, -78910};
+ *this << arr;
+ BOOST_CHECK_EQUAL(this->str(), "[1,123456,-78910]");
+}
+
+BOOST_AUTO_TEST_CASE(vector)
+{
+ std::vector<int> arr {1, 123456, -78910};
+ *this << arr;
+ BOOST_CHECK_EQUAL(this->str(), "[1,123456,-78910]");
+}
+
+BOOST_AUTO_TEST_SUITE_END();