Drop the AGPL license in favor of a source-available license. See the blog post [1] for details. [1] https://www.scylladb.com/2024/12/18/why-were-moving-to-a-source-available-license/
162 lines
5.5 KiB
C++
162 lines
5.5 KiB
C++
/*
|
|
* Copyright (C) 2019-present ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0
|
|
*/
|
|
|
|
#define BOOST_TEST_MODULE core
|
|
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
#include <boost/program_options.hpp>
|
|
#include <map>
|
|
#include <set>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
|
|
#include "utils/enum_option.hh"
|
|
|
|
namespace po = boost::program_options;
|
|
|
|
namespace {
|
|
|
|
struct days {
|
|
enum enumeration : uint8_t { Mo, Tu, We, Th, Fr, Sa, Su };
|
|
static std::unordered_map<std::string, enumeration> map() {
|
|
return {{"Mon", Mo}, {"Tue", Tu}, {"Wed", We}, {"Thu", Th}, {"Fri", Fr}, {"Sat", Sa}, {"Sun", Su}};
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
enum_option<T> parse(const char* value) {
|
|
po::options_description desc("Allowed options");
|
|
desc.add_options()("opt", po::value<enum_option<T>>(), "Option");
|
|
po::variables_map vm;
|
|
const char* argv[] = {"$0", "--opt", value};
|
|
po::store(po::parse_command_line(3, argv, desc), vm);
|
|
return vm["opt"].as<enum_option<T>>();
|
|
}
|
|
|
|
template <typename T>
|
|
std::string format(typename T::enumeration d) {
|
|
std::ostringstream os;
|
|
os << enum_option<T>(d);
|
|
return os.str();
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
BOOST_AUTO_TEST_CASE(test_parsing) {
|
|
BOOST_CHECK_EQUAL(parse<days>("Sun"), days::Su);
|
|
BOOST_CHECK_EQUAL(parse<days>("Mon"), days::Mo);
|
|
BOOST_CHECK_EQUAL(parse<days>("Tue"), days::Tu);
|
|
BOOST_CHECK_EQUAL(parse<days>("Wed"), days::We);
|
|
BOOST_CHECK_EQUAL(parse<days>("Thu"), days::Th);
|
|
BOOST_CHECK_EQUAL(parse<days>("Fri"), days::Fr);
|
|
BOOST_CHECK_EQUAL(parse<days>("Sat"), days::Sa);
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(test_parsing_error) {
|
|
BOOST_REQUIRE_THROW(parse<days>("Sunday"), po::invalid_option_value);
|
|
BOOST_REQUIRE_THROW(parse<days>(""), po::invalid_option_value);
|
|
BOOST_REQUIRE_THROW(parse<days>(" "), po::invalid_option_value);
|
|
BOOST_REQUIRE_THROW(parse<days>(" Sun"), po::invalid_option_value);
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(test_formatting) {
|
|
BOOST_CHECK_EQUAL(format<days>(days::Mo), "Mon");
|
|
BOOST_CHECK_EQUAL(format<days>(days::Tu), "Tue");
|
|
BOOST_CHECK_EQUAL(format<days>(days::We), "Wed");
|
|
BOOST_CHECK_EQUAL(format<days>(days::Th), "Thu");
|
|
BOOST_CHECK_EQUAL(format<days>(days::Fr), "Fri");
|
|
BOOST_CHECK_EQUAL(format<days>(days::Sa), "Sat");
|
|
BOOST_CHECK_EQUAL(format<days>(days::Su), "Sun");
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(test_formatting_unknown) {
|
|
BOOST_CHECK_EQUAL(format<days>(static_cast<days::enumeration>(77)), "?unknown");
|
|
}
|
|
|
|
namespace {
|
|
|
|
struct names {
|
|
enum enumeration : uint8_t { John, Jane, Jim };
|
|
static std::map<std::string, enumeration> map() {
|
|
return {{"John", John}, {"Jane", Jane}, {"James", Jim}};
|
|
}
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
BOOST_AUTO_TEST_CASE(test_ordered_map) {
|
|
BOOST_CHECK_EQUAL(parse<names>("James"), names::Jim);
|
|
BOOST_CHECK_EQUAL(format<names>(names::Jim), "James");
|
|
BOOST_CHECK_EQUAL(parse<names>("John"), names::John);
|
|
BOOST_CHECK_EQUAL(format<names>(names::John), "John");
|
|
BOOST_CHECK_EQUAL(parse<names>("Jane"), names::Jane);
|
|
BOOST_CHECK_EQUAL(format<names>(names::Jane), "Jane");
|
|
BOOST_CHECK_THROW(parse<names>("Jimbo"), po::invalid_option_value);
|
|
BOOST_CHECK_EQUAL(format<names>(static_cast<names::enumeration>(77)), "?unknown");
|
|
}
|
|
|
|
namespace {
|
|
|
|
struct cities {
|
|
enum enumeration { SF, TO, NY };
|
|
static std::unordered_map<std::string, enumeration> map() {
|
|
return {
|
|
{"SanFrancisco", SF}, {"SF", SF}, {"SFO", SF}, {"Frisco", SF},
|
|
{"Toronto", TO}, {"TO", TO}, {"YYZ", TO}, {"TheSix", TO},
|
|
{"NewYork", NY}, {"NY", NY}, {"NYC", NY}, {"BigApple", NY},
|
|
};
|
|
}
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
BOOST_AUTO_TEST_CASE(test_multiple_parse) {
|
|
BOOST_CHECK_EQUAL(parse<cities>("SanFrancisco"), cities::SF);
|
|
BOOST_CHECK_EQUAL(parse<cities>("SF"), cities::SF);
|
|
BOOST_CHECK_EQUAL(parse<cities>("SFO"), cities::SF);
|
|
BOOST_CHECK_EQUAL(parse<cities>("Frisco"), cities::SF);
|
|
BOOST_CHECK_EQUAL(parse<cities>("Toronto"), cities::TO);
|
|
BOOST_CHECK_EQUAL(parse<cities>("TO"), cities::TO);
|
|
BOOST_CHECK_EQUAL(parse<cities>("YYZ"), cities::TO);
|
|
BOOST_CHECK_EQUAL(parse<cities>("TheSix"), cities::TO);
|
|
BOOST_CHECK_EQUAL(parse<cities>("NewYork"), cities::NY);
|
|
BOOST_CHECK_EQUAL(parse<cities>("NY"), cities::NY);
|
|
BOOST_CHECK_EQUAL(parse<cities>("NYC"), cities::NY);
|
|
BOOST_CHECK_EQUAL(parse<cities>("BigApple"), cities::NY);
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(test_multiple_format) {
|
|
BOOST_CHECK((std::set<std::string>{"SanFrancisco", "SF", "SFO", "Frisco"}).contains(format<cities>(cities::SF)));
|
|
BOOST_CHECK((std::set<std::string>{"Toronto", "TO", "YYZ", "TheSix"}).contains(format<cities>(cities::TO)));
|
|
BOOST_CHECK((std::set<std::string>{"NewYork", "NY", "NYC", "BigApple"}).contains(format<cities>(cities::NY)));
|
|
}
|
|
|
|
namespace {
|
|
|
|
struct numbers {
|
|
enum enumeration : uint8_t { ONE, TWO };
|
|
static std::unordered_map<int, enumeration> map() {
|
|
return {{1, ONE}, {2, TWO}};
|
|
}
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
BOOST_AUTO_TEST_CASE(test_non_string) {
|
|
BOOST_CHECK_EQUAL(parse<numbers>("1"), numbers::ONE);
|
|
BOOST_CHECK_EQUAL(parse<numbers>("2"), numbers::TWO);
|
|
BOOST_CHECK_THROW(parse<numbers>("3"), po::invalid_option_value);
|
|
BOOST_CHECK_THROW(parse<numbers>("xx"), po::invalid_option_value);
|
|
BOOST_CHECK_THROW(parse<numbers>(""), po::invalid_option_value);
|
|
BOOST_CHECK_EQUAL(format<numbers>(numbers::ONE), "1");
|
|
BOOST_CHECK_EQUAL(format<numbers>(numbers::TWO), "2");
|
|
BOOST_CHECK_EQUAL(format<numbers>(static_cast<numbers::enumeration>(77)), "?unknown");
|
|
}
|