| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- //
- // properties_test.cpp
- // logger-test
- //
- // Created by Sam Jaffe on 8/12/20.
- //
- #include "logger/properties.h"
- #include <gmock/gmock.h>
- #include "logger/exception.h"
- namespace logging {
- void indent(int i, std::ostream * os) {
- while (i-- > 0) {
- (*os) << ' ' << ' ';
- }
- }
- void PrintTo(properties const & props, std::ostream * os, int level = 1) {
- switch (props.data.index()) {
- case 0:
- (*os) << '{' << '\n';
- for (auto & [k, v] : props.object()) {
- indent(level + 1, os);
- (*os) << k << ':' << ' ';
- PrintTo(v, os, level + 1);
- }
- (*os) << '\n';
- indent(level, os);
- (*os) << '}' << '\n';
- break;
- case 1:
- (*os) << '[' << '\n';
- for (auto & v : props.array()) {
- indent(level + 1, os);
- PrintTo(v, os, level + 1);
- }
- (*os) << '\n';
- indent(level, os);
- (*os) << ']' << '\n';
- break;
- case 2:
- (*os) << props.str();
- break;
- case 3:
- (*os) << int(props);
- break;
- case 4:
- (*os) << std::boolalpha << bool(props);
- break;
- default:
- (*os) << "null";
- break;
- }
- }
- }
- MATCHER(Valid, "") { return arg.data.valid(); }
- MATCHER_P(Contains, key, "") { return arg.contains(key); }
- MATCHER_P(IsOfType, type, "") { return arg.data.template is<decltype(type)>(); }
- MATCHER_P(ArraySizeIs, size, "") {
- return arg.data.template is<logging::array_t>() && arg.array().size() == size;
- }
- template <typename T> auto IsOfType() { return IsOfType(T()); }
- using namespace logging;
- using namespace ::logging::property;
- TEST(PropertiesTest, DefaultPropertyIsInvalidType) {
- EXPECT_THAT(properties(), testing::Not(Valid()));
- }
- TEST(PropertiesTest, CanStoreBoolean) {
- EXPECT_THAT(_v(true), IsOfType<bool>());
- EXPECT_THAT(_v(true), Valid());
- }
- TEST(PropertiesTest, CanStoreInteger) {
- EXPECT_THAT(_v(0), IsOfType<int>());
- EXPECT_THAT(_v(0), Valid());
- }
- TEST(PropertiesTest, CanStoreString) {
- EXPECT_THAT(_v("hello"), IsOfType<std::string>());
- EXPECT_THAT(_v("hello"), Valid());
- }
- TEST(PropertiesTest, CanStoreArray) {
- EXPECT_THAT(_arr({}), IsOfType<array_t>());
- EXPECT_THAT(_arr({}), Valid());
- }
- TEST(PropertiesTest, CanStoreObject) {
- EXPECT_THAT(_obj({}), IsOfType<object_t>());
- EXPECT_THAT(_obj({}), Valid());
- }
- TEST(PropertiesTest, ArrContainsReturnsTrueEvenWhenUnderlyingIsInvalid) {
- properties const props = _arr({{}});
- EXPECT_THAT(props, Contains(0));
- EXPECT_THAT(props[0ul], testing::Not(Valid()));
- }
- TEST(PropertiesTest, ObjContainsReturnsTrueEvenWhenUnderlyingIsInvalid) {
- properties const props = _obj({{"data", {}}});
- EXPECT_THAT(props, Contains("data"));
- EXPECT_THAT(props["data"], testing::Not(Valid()));
- }
- TEST(PropertiesTest, ContainsAlwaysFalseForNonContainer) {
- EXPECT_THAT(_v(true), testing::Not(Contains(0)));
- EXPECT_THAT(_v(true), testing::Not(Contains("")));
- EXPECT_THAT(_v(0), testing::Not(Contains(0)));
- EXPECT_THAT(_v(0), testing::Not(Contains("")));
- EXPECT_THAT(_v(""), testing::Not(Contains(0)));
- EXPECT_THAT(_v(""), testing::Not(Contains("")));
- }
- TEST(PropertiesTest, ArrayCannotContainKey) {
- properties const props = _arr({{}});
- EXPECT_THAT(props, testing::Not(Contains("")));
- }
- TEST(PropertiesTest, ObjectCannotContainIndex) {
- properties const props = _obj({{"data", {}}});
- EXPECT_THAT(props, testing::Not(Contains(0)));
- }
- TEST(PropertiesTest, MistypingWillThrow) {
- properties prop;
- // Avoid most vexing parse/unused variable
- EXPECT_THROW((void)bool(prop), invalid_property_type);
- EXPECT_THROW((void)int(prop), invalid_property_type);
- EXPECT_THROW(prop.str(), invalid_property_type);
- EXPECT_THROW(prop.array(), invalid_property_type);
- EXPECT_THROW(prop.object(), invalid_property_type);
- }
- TEST(PropertiesTest, IndexingNonContainerWillThrow) {
- properties prop;
- EXPECT_THROW(prop[0ul], invalid_property_type);
- EXPECT_THROW(prop[""], invalid_property_type);
- }
- TEST(PropertiesTest, IndexingContainerWithWrongTypeWillThrow) {
- EXPECT_THROW(_obj({{"", {}}})[0ul], invalid_property_type);
- EXPECT_THROW(_arr({{}})[""], invalid_property_type);
- }
- TEST(PropertiesTest, IndexingNonExistantPathWillThrouw) {
- EXPECT_THROW(_obj({{"", {}}})["data"], missing_property);
- EXPECT_THROW(_arr({{}})[1], missing_property);
- }
- properties const EXAMPLE_PROPERTIES =
- _obj({{"data", _obj({{"files", _arr({_v("a.txt")})},
- {"config", _obj({{"append", _v(false)}})}})}});
- TEST(PropertiesTest, MergeWithWillNotAddNewProperties) {
- properties const input =
- _obj({{"data", _obj({{"config", _obj({{"compact", _v(true)}})}})}});
- properties const output = EXAMPLE_PROPERTIES.mergedWith(input);
- EXPECT_THAT(output, Contains("data"));
- EXPECT_THAT(output["data"], Contains("files"));
- EXPECT_THAT(output["data"]["files"], ArraySizeIs(1));
- EXPECT_THAT(output["data"], Contains("config"));
- EXPECT_THAT(output["data"]["config"], Contains("append"));
- EXPECT_THAT(output["data"]["config"], testing::Not(Contains("compact")));
- }
- TEST(PropertiesTest, MergeWithWillOverwriteProperties) {
- properties const input =
- _obj({{"data", _obj({{"config", _obj({{"append", _v(true)}})}})}});
- properties const output = EXAMPLE_PROPERTIES.mergedWith(input);
- EXPECT_THAT(output, Contains("data"));
- EXPECT_THAT(output["data"], Contains("files"));
- EXPECT_THAT(output["data"]["files"], ArraySizeIs(1));
- EXPECT_THAT(output["data"], Contains("config"));
- EXPECT_THAT(output["data"]["config"], Contains("append"));
- EXPECT_TRUE(output["data"]["config"]["append"]);
- }
- TEST(PropertiesTest, ArraysWillBeOverwritten) {
- properties const input =
- _obj({{"data", _obj({{"files", _arr({_v("b.txt"), _v("c.txt")})}})}});
- properties const output = EXAMPLE_PROPERTIES.mergedWith(input);
- EXPECT_THAT(output, Contains("data"));
- EXPECT_THAT(output["data"], Contains("files"));
- EXPECT_THAT(output["data"]["files"], ArraySizeIs(2));
- EXPECT_THAT(output["data"]["files"][0ul].str(), "b.txt");
- EXPECT_THAT(output["data"]["files"][1ul].str(), "c.txt");
- }
|