diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /tools/enum_parser/parse_enum/ut | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'tools/enum_parser/parse_enum/ut')
-rw-r--r-- | tools/enum_parser/parse_enum/ut/alias_before_name.h | 7 | ||||
-rw-r--r-- | tools/enum_parser/parse_enum/ut/badcode.h | 10 | ||||
-rw-r--r-- | tools/enum_parser/parse_enum/ut/enums.cpp | 195 | ||||
-rw-r--r-- | tools/enum_parser/parse_enum/ut/enums.h | 195 | ||||
-rw-r--r-- | tools/enum_parser/parse_enum/ut/enums_with_header.h | 8 | ||||
-rw-r--r-- | tools/enum_parser/parse_enum/ut/including_header.h | 9 | ||||
-rw-r--r-- | tools/enum_parser/parse_enum/ut/stringlist.cpp | 1 | ||||
-rw-r--r-- | tools/enum_parser/parse_enum/ut/unbalanced.h | 4 | ||||
-rw-r--r-- | tools/enum_parser/parse_enum/ut/ya.make | 33 |
9 files changed, 462 insertions, 0 deletions
diff --git a/tools/enum_parser/parse_enum/ut/alias_before_name.h b/tools/enum_parser/parse_enum/ut/alias_before_name.h new file mode 100644 index 0000000000..64015c1db6 --- /dev/null +++ b/tools/enum_parser/parse_enum/ut/alias_before_name.h @@ -0,0 +1,7 @@ +#pragma once + +// https://clubs.at.yandex-team.ru/stackoverflow/2603 bad example +enum EStrange { + One, /* "one" */ + Two, /* "two" */ +}; diff --git a/tools/enum_parser/parse_enum/ut/badcode.h b/tools/enum_parser/parse_enum/ut/badcode.h new file mode 100644 index 0000000000..88448c8eae --- /dev/null +++ b/tools/enum_parser/parse_enum/ut/badcode.h @@ -0,0 +1,10 @@ +#pragma once + +// Anonymous namespaces are meaningless, but should not break our parser +namespace { + enum ETest { + Http = 9 /* "http://" "secondary" "old\nvalue" */, + Https = 1 /* "https://" */, + ETestItemCount, + }; +} diff --git a/tools/enum_parser/parse_enum/ut/enums.cpp b/tools/enum_parser/parse_enum/ut/enums.cpp new file mode 100644 index 0000000000..a03045855e --- /dev/null +++ b/tools/enum_parser/parse_enum/ut/enums.cpp @@ -0,0 +1,195 @@ +#include "enums.h" +#include "enums_with_header.h" +#include <tools/enum_parser/parse_enum/ut/enums_with_header.h_serialized.h> + +#include "including_header.h" + +// just to test that generated stuff works +#include <util/generic/serialized_enum.h> +#include <library/cpp/testing/unittest/registar.h> + +#include <util/generic/ptr.h> +#include <util/generic/singleton.h> + + +void FunctionUsingEFwdEnum(EFwdEnum) { +} + +class TEnumSerializationInitializer { +public: + TEnumSerializationInitializer() { + UNIT_ASSERT_VALUES_EQUAL(ToString(EDestructionPriorityTest::first), "first"); + } + ~TEnumSerializationInitializer() { + UNIT_ASSERT_VALUES_EQUAL(ToString(EDestructionPriorityTest::second), "second"); + } +}; + +class TEnumSerializationInitializerHolder { +public: + TEnumSerializationInitializerHolder() { + } + + ~TEnumSerializationInitializerHolder() { + } + + void Init() { Ptr.Reset(new TEnumSerializationInitializer); } +private: + THolder<TEnumSerializationInitializer> Ptr; +}; + + +Y_UNIT_TEST_SUITE(TEnumGeneratorTest) { + + template<typename T> + void CheckToString(const T& value, const TString& strValue) { + UNIT_ASSERT_VALUES_EQUAL(ToString(value), strValue); + } + + Y_UNIT_TEST(ToStringTest) { + // ESimple + CheckToString(Http, "Http"); + CheckToString(Https, "Https"); + CheckToString(ItemCount, "ItemCount"); + + // ESimpleWithComma + CheckToString(ESimpleWithComma::Http, "Http"); + CheckToString(ESimpleWithComma::Https, "Https"); + CheckToString(ESimpleWithComma::Http2, "Http"); // Http2 is an alias for Http + CheckToString(ESimpleWithComma::ItemCount, "ItemCount"); + + // ECustomAliases + CheckToString(CAHttp, "http"); + CheckToString(CAHttps, "https"); + CheckToString(CAItemCount, "CAItemCount"); + + // EMultipleAliases + CheckToString(MAHttp, "http://"); + CheckToString(MAHttps, "https://"); + CheckToString(MAItemCount, "MAItemCount"); + + // EDuplicateKeys + CheckToString(Key0, "Key0"); + CheckToString(Key0Second, "Key0"); // obtain FIRST encountered value with such integer key + CheckToString(Key1, "Key1"); + CheckToString(Key2, "k2"); + CheckToString(Key3, "k2"); // we CANNOT obtain "k3" here (as Key3 == Key2) + } + + template<typename T> + void CheckFromString(const TString& strValue, const T& value) { + UNIT_ASSERT_VALUES_EQUAL(static_cast<int>(FromString<T>(TStringBuf(strValue))), static_cast<int>(value)); + } + + template<typename T> + void CheckFromStringFail(const TString& strValue) { + UNIT_ASSERT_EXCEPTION(FromString<T>(TStringBuf(strValue)), yexception); + } + + template<typename T> + void CheckTryFromString(const TString& strValue, const T& value) { + T x; + UNIT_ASSERT_VALUES_EQUAL(TryFromString(TStringBuf(strValue), x), true); + UNIT_ASSERT_VALUES_EQUAL(x, value); + } + + template<typename T> + void CheckTryFromStringFail(const TString& strValue) { + T x = T(-666); + UNIT_ASSERT_VALUES_EQUAL(TryFromString(TStringBuf(strValue), x), false); + UNIT_ASSERT_VALUES_EQUAL(int(x), -666); + } + + Y_UNIT_TEST(TryFromStringTest) { + // ESimple + CheckFromString("Http", Http); + CheckFromString("Https", Https); + CheckFromString("ItemCount", ItemCount); + CheckFromStringFail<ESimple>("ItemC0unt"); + + CheckTryFromString("Http", Http); + CheckTryFromString("Https", Https); + CheckTryFromString("ItemCount", ItemCount); + CheckTryFromStringFail<ESimple>("ItemC0unt"); + + // ESimpleWithComma + CheckTryFromString("Http", ESimpleWithComma::Http); + CheckTryFromString("Https", ESimpleWithComma::Https); + CheckTryFromString("ItemCount", ESimpleWithComma::ItemCount); + CheckTryFromStringFail<ESimpleWithComma>(""); + + // ECustomAliases + CheckTryFromString("http", CAHttp); + CheckTryFromString("https", CAHttps); + CheckTryFromString("CAItemCount", CAItemCount); + + // EDuplicateKeys + CheckTryFromString("Key0", Key0); + CheckTryFromString("Key0Second", Key0Second); + CheckTryFromString("Key1", Key1); + CheckTryFromString("k2", Key2); + CheckTryFromString("k2.1", Key2); + CheckTryFromString("k3", Key3); + } + + Y_UNIT_TEST(AllNamesValuesTest) { + { + auto allNames = GetEnumAllCppNames<EDuplicateKeys>(); + UNIT_ASSERT(!!allNames); + UNIT_ASSERT_VALUES_EQUAL(allNames.size(), 5u); + UNIT_ASSERT_VALUES_EQUAL(allNames[4], "Key3"); + } + { + auto allNames = GetEnumAllCppNames<ESimpleWithComma>(); + UNIT_ASSERT(!!allNames); + UNIT_ASSERT_VALUES_EQUAL(allNames.size(), 4u); + UNIT_ASSERT_VALUES_EQUAL(allNames[1], "ESimpleWithComma::Http2"); + } + } + + Y_UNIT_TEST(EnumWithHeaderTest) { + UNIT_ASSERT_VALUES_EQUAL(GetEnumItemsCount<EWithHeader>(), 3); + } + + Y_UNIT_TEST(AllNamesValuesWithHeaderTest) { + { + auto allNames = GetEnumAllCppNames<EWithHeader>(); + UNIT_ASSERT_VALUES_EQUAL(allNames.size(), 3u); + UNIT_ASSERT_VALUES_EQUAL(allNames.at(2), "HThree"); + } + { + UNIT_ASSERT_VALUES_EQUAL(GetEnumAllNames<EWithHeader>(), "'one', 'HTwo', 'HThree'"); + } + } + + Y_UNIT_TEST(AllValuesTest) { + const auto& allNames = GetEnumNames<EWithHeader>(); + const auto& allValues = GetEnumAllValues<EWithHeader>(); + UNIT_ASSERT_VALUES_EQUAL(allValues.size(), 3u); + UNIT_ASSERT_VALUES_EQUAL(allValues[2], HThree); + size_t size = 0; + for (const EWithHeader value : GetEnumAllValues<EWithHeader>()) { + size += 1; + UNIT_ASSERT_VALUES_EQUAL(allNames.contains(value), true); + } + UNIT_ASSERT_VALUES_EQUAL(size, 3u); + } + + Y_UNIT_TEST(EnumNamesTest) { + const auto& names = GetEnumNames<EWithHeader>(); + UNIT_ASSERT_VALUES_EQUAL(names.size(), 3u); + + UNIT_ASSERT(names.contains(HOne)); + UNIT_ASSERT_VALUES_EQUAL(names.at(HOne), "one"); + + UNIT_ASSERT(names.contains(HTwo)); + UNIT_ASSERT_VALUES_EQUAL(names.at(HTwo), "HTwo"); + + UNIT_ASSERT(names.contains(HThree)); + UNIT_ASSERT_VALUES_EQUAL(names.at(HThree), "HThree"); + } + + Y_UNIT_TEST(EnumSerializerDestructionPriority) { + Singleton<TEnumSerializationInitializerHolder>()->Init(); + } +}; diff --git a/tools/enum_parser/parse_enum/ut/enums.h b/tools/enum_parser/parse_enum/ut/enums.h new file mode 100644 index 0000000000..93d835c78d --- /dev/null +++ b/tools/enum_parser/parse_enum/ut/enums.h @@ -0,0 +1,195 @@ +#pragma once +// Sample file for parse_enum unittests + +#include <util/generic/fwd.h> +#include <util/system/compiler.h> + +// Test template declarations +template<class T> +void Func(T&); + +template<> +void Func(struct ENonDeclared&); + +template<class TClass> class TFwdDecl; + +// Test in-function class declarations +void InexistentFunction(struct TFwdStructDecl); +void InexistentFunction2(struct TFwdStructDecl, class TMegaClass); + + +static inline void Func() { + class TLocal { + int M; + public: + void F() { + // to shut up clang + Y_UNUSED(M); + } + }; + + { + // unnamed block + } +} + +// Test forward declarations, pt 2 +namespace NTestContainer { + struct TStruct; +} + +// Enums +enum ESimple { + Http, + Https, + ItemCount +}; + +enum class ESimpleWithComma { + Http = 3, + Http2 = Http, + Https, // 4 + ItemCount, // 5 +}; + +enum ECustomAliases { + CAHttp = 3 /* "http" */, + CAHttps /* "https" */, + CAItemCount, +}; + +enum EMultipleAliases { + MAHttp = 9 /* "http://" "secondary" "old\nvalue" */, + MAHttps = 1 /* "https://" */, + MAItemCount, +}; + +namespace NEnumNamespace { + enum EInNamespace { + Http = 9 /* "http://" "secondary" "old\nvalue" */, + Https = 1 /* "https://" */, + ItemCount /* "real value" */, + }; +}; + +struct TStruct { + int M; +}; + +namespace NEnumNamespace { + class TEnumClass: public TStruct { + public: + enum EInClass { + Http = 9 /* "http://" "secondary" "old\nvalue" */, + Https1 = NEnumNamespace::Https /* "https://" */, + // holy crap, this will work too: + Https3 = 1 /* "https://" */ + 2, + }; + }; +} + +enum { + One, + Two, + Three, +}; + +struct { + int M; +} SomeStruct; + +static inline void f() { + (void)(SomeStruct); + (void)(f); +} + +// buggy case taken from library/cpp/html/face/parstypes.h +enum TEXT_WEIGHT { + WEIGHT_ZERO=-1,// NOINDEX_RELEV + WEIGHT_LOW, // LOW_RELEV + WEIGHT_NORMAL, // NORMAL_RELEV + WEIGHT_HIGH, // HIGH_RELEV (H1,H2,H3,ADDRESS,CAPTION) + WEIGHT_BEST // BEST_RELEV (TITLE) +}; + +// enum with duplicate keys +enum EDuplicateKeys { + Key0 = 0, + Key0Second = Key0, + Key1, + Key2 = 3 /* "k2" "k2.1" */, + Key3 = 3 /* "k3" */, +}; + +enum class EFwdEnum; +void FunctionUsingEFwdEnum(EFwdEnum); +enum class EFwdEnum { + One, + Two +}; + +// empty enum (bug found by sankear@) +enum EEmpty { +}; + +namespace NComposite::NInner { + enum EInCompositeNamespaceSimple { + one, + two = 2, + three, + }; +} + +namespace NOuterSimple { + namespace NComposite::NMiddle::NInner { + namespace NInnerSimple { + class TEnumClass { + public: + enum EVeryDeep { + Key0 = 0, + Key1 = 1, + }; + }; + } + } +} + + +constexpr int func(int value) { + return value; +} + +#define MACRO(x, y) x + +// enum with nonliteral values +enum ENonLiteralValues { + one = MACRO(1, 2), + two = 2, + three = func(3), + four, + five = MACRO(MACRO(1, 2), 2), +}; + +#undef MACRO + + +enum EDestructionPriorityTest { + first, + second +}; + + +enum class NotifyingStatus +{ + NEW = 0, + FAILED_WILL_RETRY = 1, + FAILED_NO_MORE_TRIALS = 2, + SENT = 3 +}; + +/* + * Still unsupported features: + * + * a) Anonymous namespaces (it is parsed correctly, though) + * b) Enums inside template classes (impossible by design) + **/ diff --git a/tools/enum_parser/parse_enum/ut/enums_with_header.h b/tools/enum_parser/parse_enum/ut/enums_with_header.h new file mode 100644 index 0000000000..26fe5565a9 --- /dev/null +++ b/tools/enum_parser/parse_enum/ut/enums_with_header.h @@ -0,0 +1,8 @@ +#pragma once + +enum EWithHeader { + HOne /* "one" */, + HTwo, + HThree, +}; + diff --git a/tools/enum_parser/parse_enum/ut/including_header.h b/tools/enum_parser/parse_enum/ut/including_header.h new file mode 100644 index 0000000000..b3b2a2129f --- /dev/null +++ b/tools/enum_parser/parse_enum/ut/including_header.h @@ -0,0 +1,9 @@ +#pragma once + +#include <util/generic/serialized_enum.h> +#include <tools/enum_parser/parse_enum/ut/enums_with_header.h_serialized.h> + +int TestEnumWithHeader() { + return GetEnumItemsCount<EWithHeader>(); +} + diff --git a/tools/enum_parser/parse_enum/ut/stringlist.cpp b/tools/enum_parser/parse_enum/ut/stringlist.cpp new file mode 100644 index 0000000000..f69d0fc08d --- /dev/null +++ b/tools/enum_parser/parse_enum/ut/stringlist.cpp @@ -0,0 +1 @@ +"qqqq\nqqqqqq", "test:\\string" diff --git a/tools/enum_parser/parse_enum/ut/unbalanced.h b/tools/enum_parser/parse_enum/ut/unbalanced.h new file mode 100644 index 0000000000..9caf54044c --- /dev/null +++ b/tools/enum_parser/parse_enum/ut/unbalanced.h @@ -0,0 +1,4 @@ +#pragma once + +} + diff --git a/tools/enum_parser/parse_enum/ut/ya.make b/tools/enum_parser/parse_enum/ut/ya.make new file mode 100644 index 0000000000..03ace866d4 --- /dev/null +++ b/tools/enum_parser/parse_enum/ut/ya.make @@ -0,0 +1,33 @@ +UNITTEST() + +OWNER( + g:util + mvel +) + +PEERDIR( + ADDINCL tools/enum_parser/parse_enum + library/cpp/resource +) + +SRCDIR(tools/enum_parser/parse_enum) + +RESOURCE( + enums.h /enums + badcode.h /badcode + unbalanced.h /unbalanced + alias_before_name.h /alias_before_name +) + +# self-test +GENERATE_ENUM_SERIALIZATION(enums.h) + +# test GENERATE_ENUM_SERIALIZATION_WITH_HEADER macro +GENERATE_ENUM_SERIALIZATION_WITH_HEADER(enums_with_header.h) + +SRCS( + parse_enum_ut.cpp + enums.cpp +) + +END() |