diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/Jamfile.jam | 11 | ||||
-rw-r--r-- | test/helpers.h | 44 | ||||
-rw-r--r-- | test/test-bitset.cpp | 31 | ||||
-rw-r--r-- | test/test-rawDataReader.cpp | 163 | ||||
-rw-r--r-- | test/test-streams.cpp | 92 |
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(); |