aboutsummaryrefslogtreecommitdiffstats
path: root/tools/enum_parser/parse_enum/ut
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /tools/enum_parser/parse_enum/ut
downloadydb-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.h7
-rw-r--r--tools/enum_parser/parse_enum/ut/badcode.h10
-rw-r--r--tools/enum_parser/parse_enum/ut/enums.cpp195
-rw-r--r--tools/enum_parser/parse_enum/ut/enums.h195
-rw-r--r--tools/enum_parser/parse_enum/ut/enums_with_header.h8
-rw-r--r--tools/enum_parser/parse_enum/ut/including_header.h9
-rw-r--r--tools/enum_parser/parse_enum/ut/stringlist.cpp1
-rw-r--r--tools/enum_parser/parse_enum/ut/unbalanced.h4
-rw-r--r--tools/enum_parser/parse_enum/ut/ya.make33
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()