Rework yang::LeafDataType

Before this patch, Schema::leafType was used like this: you called the
method, and it would give you an enum value from which you could tell
the type. In case the type was, for example, yang::LeafDataTypes::Enum,
you would call enumValues to get the valid values from the enum.
However, this approach came up as a problem when implementing the union
yang type. Example: if the union consisted of two different enums, there
was no way to differentiate those two enums (so enumValues wouldn't know
which one to return). The new approach encodes everything inside the
return value of Schema::leafType, so no futher method calls are needed.
This also means, that methods like Schema::leafEnumIsValid and others
are unneeded, since you get all the info from Schema::leafType.

Also, I got rid of all the on_success handlers, and moved the code to
inside to impl_LeafData. This means that enum/identityref validity is
checked inside there. If I wanted to keep the on_success handlers I
would have create another member in ParserContext (which would contain
the values), but it doesn't give any advantage, except that it
automatically rolls back the iterator on fail (I have to do that myself
now, but I don't think it's a huge deal).
createSetSuggestions::on_success was also moved to impl_LeafData.

Change-Id: Ie9a30174094b73f2c25af8cfc88d0aa5e9e882b3
diff --git a/tests/cd.cpp b/tests/cd.cpp
index def2bdd..32d7230 100644
--- a/tests/cd.cpp
+++ b/tests/cd.cpp
@@ -24,11 +24,11 @@
     schema->addContainer("/example:a/example:a2", "example:a3");
     schema->addContainer("/example:b/example:b2", "example:b3");
     schema->addList("/", "example:list", {"number"});
-    schema->addLeaf("/example:list", "example:number", yang::LeafDataTypes::Int32);
+    schema->addLeaf("/example:list", "example:number", yang::Int32{});
     schema->addContainer("/example:list", "example:contInList");
     schema->addList("/", "example:twoKeyList", {"number", "name"});
-    schema->addLeaf("/example:twoKeyList", "example:number", yang::LeafDataTypes::Int32);
-    schema->addLeaf("/example:twoKeyList", "example:name", yang::LeafDataTypes::String);
+    schema->addLeaf("/example:twoKeyList", "example:number", yang::Int32{});
+    schema->addLeaf("/example:twoKeyList", "example:name", yang::String{});
     Parser parser(schema);
     std::string input;
     std::ostringstream errorStream;
diff --git a/tests/enum_completion.cpp b/tests/enum_completion.cpp
index 939243f..07ea32c 100644
--- a/tests/enum_completion.cpp
+++ b/tests/enum_completion.cpp
@@ -9,6 +9,7 @@
 
 #include "trompeloeil_doctest.hpp"
 #include "datastoreaccess_mock.hpp"
+#include "leaf_data_helpers.hpp"
 #include "parser.hpp"
 #include "pretty_printers.hpp"
 #include "static_schema.hpp"
@@ -18,11 +19,11 @@
     auto schema = std::make_shared<StaticSchema>();
     schema->addModule("mod");
     schema->addContainer("/", "mod:contA");
-    schema->addLeafEnum("/", "mod:leafEnum", {"lala", "lol", "data", "coze"});
-    schema->addLeafEnum("/mod:contA", "mod:leafInCont", {"abc", "def"});
+    schema->addLeaf("/", "mod:leafEnum", createEnum({"lala", "lol", "data", "coze"}));
+    schema->addLeaf("/mod:contA", "mod:leafInCont", createEnum({"abc", "def"}));
     schema->addList("/", "mod:list", {"number"});
-    schema->addLeaf("/mod:list", "mod:number", yang::LeafDataTypes::Int32);
-    schema->addLeafEnum("/mod:list", "mod:leafInList", {"ano", "anoda", "ne", "katoda"});
+    schema->addLeaf("/mod:list", "mod:number", yang::Int32{});
+    schema->addLeaf("/mod:list", "mod:leafInList", createEnum({"ano", "anoda", "ne", "katoda"}));
     auto mockDatastore = std::make_shared<MockDatastoreAccess>();
     // The parser will use DataQuery for key value completion, but I'm not testing that here, so I don't return anything.
     ALLOW_CALL(*mockDatastore, listInstances("/mod:list"))
diff --git a/tests/keyvalue_completion.cpp b/tests/keyvalue_completion.cpp
index c6a2350..61e90cd 100644
--- a/tests/keyvalue_completion.cpp
+++ b/tests/keyvalue_completion.cpp
@@ -30,10 +30,10 @@
     schema->addContainer("/", "example:a");
     schema->addContainer("/", "example:b");
     schema->addList("/", "example:list", {"number"});
-    schema->addLeaf("/example:list", "example:number", yang::LeafDataTypes::Int32);
+    schema->addLeaf("/example:list", "example:number", yang::Int32{});
     schema->addList("/", "example:twoKeyList", {"number", "name"});
-    schema->addLeaf("/example:twoKeyList", "example:number", yang::LeafDataTypes::Int32);
-    schema->addLeaf("/example:twoKeyList", "example:name", yang::LeafDataTypes::String);
+    schema->addLeaf("/example:twoKeyList", "example:number", yang::Int32{});
+    schema->addLeaf("/example:twoKeyList", "example:name", yang::String{});
     auto mockDatastore = std::make_shared<MockDatastoreAccess>();
 
     // DataQuery gets the schema from DatastoreAccess once
diff --git a/tests/leaf_data_helpers.hpp b/tests/leaf_data_helpers.hpp
new file mode 100644
index 0000000..0a28ae3
--- /dev/null
+++ b/tests/leaf_data_helpers.hpp
@@ -0,0 +1,10 @@
+#include <algorithm>
+#include "leaf_data_type.hpp"
+yang::Enum createEnum(const std::initializer_list<const char*>& list)
+{
+    std::set<enum_> enums;
+    std::transform(list.begin(), list.end(), std::inserter(enums, enums.end()), [](const auto& value) {
+        return enum_{value};
+    });
+    return yang::Enum(std::move(enums));
+}
diff --git a/tests/leaf_editing.cpp b/tests/leaf_editing.cpp
index 655f269..ca720c5 100644
--- a/tests/leaf_editing.cpp
+++ b/tests/leaf_editing.cpp
@@ -9,6 +9,7 @@
 #include "trompeloeil_doctest.hpp"
 #include <boost/core/demangle.hpp>
 #include "ast_commands.hpp"
+#include "leaf_data_helpers.hpp"
 #include "parser.hpp"
 #include "static_schema.hpp"
 #include "utils.hpp"
@@ -24,33 +25,33 @@
     schema->addModule("mod");
     schema->addModule("pizza-module");
     schema->addContainer("/", "mod:contA");
-    schema->addLeaf("/", "mod:leafString", yang::LeafDataTypes::String);
-    schema->addLeaf("/", "mod:leafDecimal", yang::LeafDataTypes::Decimal);
-    schema->addLeaf("/", "mod:leafBool", yang::LeafDataTypes::Bool);
-    schema->addLeaf("/", "mod:leafInt8", yang::LeafDataTypes::Int8);
-    schema->addLeaf("/", "mod:leafInt16", yang::LeafDataTypes::Int16);
-    schema->addLeaf("/", "mod:leafInt32", yang::LeafDataTypes::Int32);
-    schema->addLeaf("/", "mod:leafInt64", yang::LeafDataTypes::Int64);
-    schema->addLeaf("/", "mod:leafUint8", yang::LeafDataTypes::Uint8);
-    schema->addLeaf("/", "mod:leafUint16", yang::LeafDataTypes::Uint16);
-    schema->addLeaf("/", "mod:leafUint32", yang::LeafDataTypes::Uint32);
-    schema->addLeaf("/", "mod:leafUint64", yang::LeafDataTypes::Uint64);
-    schema->addLeaf("/", "mod:leafBinary", yang::LeafDataTypes::Binary);
+    schema->addLeaf("/", "mod:leafString", yang::String{});
+    schema->addLeaf("/", "mod:leafDecimal", yang::Decimal{});
+    schema->addLeaf("/", "mod:leafBool", yang::Bool{});
+    schema->addLeaf("/", "mod:leafInt8", yang::Int8{});
+    schema->addLeaf("/", "mod:leafInt16", yang::Int16{});
+    schema->addLeaf("/", "mod:leafInt32", yang::Int32{});
+    schema->addLeaf("/", "mod:leafInt64", yang::Int64{});
+    schema->addLeaf("/", "mod:leafUint8", yang::Uint8{});
+    schema->addLeaf("/", "mod:leafUint16", yang::Uint16{});
+    schema->addLeaf("/", "mod:leafUint32", yang::Uint32{});
+    schema->addLeaf("/", "mod:leafUint64", yang::Uint64{});
+    schema->addLeaf("/", "mod:leafBinary", yang::Binary{});
     schema->addIdentity(std::nullopt, ModuleValuePair{"mod", "food"});
     schema->addIdentity(std::nullopt, ModuleValuePair{"mod", "vehicle"});
     schema->addIdentity(ModuleValuePair{"mod", "food"}, ModuleValuePair{"mod", "pizza"});
     schema->addIdentity(ModuleValuePair{"mod", "food"}, ModuleValuePair{"mod", "spaghetti"});
     schema->addIdentity(ModuleValuePair{"mod", "pizza"}, ModuleValuePair{"pizza-module", "hawaii"});
-    schema->addLeafIdentityRef("/", "mod:foodIdentRef", ModuleValuePair{"mod", "food"});
-    schema->addLeafIdentityRef("/", "mod:pizzaIdentRef", ModuleValuePair{"mod", "pizza"});
-    schema->addLeafIdentityRef("/mod:contA", "mod:identInCont", ModuleValuePair{"mod", "pizza"});
-    schema->addLeafEnum("/", "mod:leafEnum", {"lol", "data", "coze"});
-    schema->addLeaf("/mod:contA", "mod:leafInCont", yang::LeafDataTypes::String);
+    schema->addLeaf("/", "mod:foodIdentRef", yang::IdentityRef{schema->validIdentities("mod", "food")});
+    schema->addLeaf("/", "mod:pizzaIdentRef", yang::IdentityRef{schema->validIdentities("mod", "pizza")});
+    schema->addLeaf("/mod:contA", "mod:identInCont", yang::IdentityRef{schema->validIdentities("mod", "pizza")});
+    schema->addLeaf("/", "mod:leafEnum", createEnum({"lol", "data", "coze"}));
+    schema->addLeaf("/mod:contA", "mod:leafInCont", yang::String{});
     schema->addList("/", "mod:list", {"number"});
-    schema->addLeaf("/mod:list", "mod:number", yang::LeafDataTypes::Int32);
-    schema->addLeaf("/mod:list", "mod:leafInList", yang::LeafDataTypes::String);
-    schema->addLeafRef("/", "mod:refToString", "/mod:leafString");
-    schema->addLeafRef("/", "mod:refToInt8", "/mod:leafInt8");
+    schema->addLeaf("/mod:list", "mod:number", yang::Int32{});
+    schema->addLeaf("/mod:list", "mod:leafInList", yang::String{});
+    schema->addLeaf("/", "mod:refToString", yang::LeafRef{"/mod:leafString", std::make_unique<yang::LeafDataType>(schema->leafType("/mod:leafString"))});
+    schema->addLeaf("/", "mod:refToInt8", yang::LeafRef{"/mod:leafInt8", std::make_unique<yang::LeafDataType>(schema->leafType("/mod:leafInt8"))});
     Parser parser(schema);
     std::string input;
     std::ostringstream errorStream;
diff --git a/tests/list_manipulation.cpp b/tests/list_manipulation.cpp
index b71ee7b..15f2f04 100644
--- a/tests/list_manipulation.cpp
+++ b/tests/list_manipulation.cpp
@@ -14,8 +14,8 @@
     auto schema = std::make_shared<StaticSchema>();
     schema->addModule("mod");
     schema->addList("/", "mod:list", {"number"});
-    schema->addLeaf("/mod:list", "mod:number", yang::LeafDataTypes::Int32);
-    schema->addLeaf("/mod:list", "mod:leafInList", yang::LeafDataTypes::String);
+    schema->addLeaf("/mod:list", "mod:number", yang::Int32{});
+    schema->addLeaf("/mod:list", "mod:leafInList", yang::String{});
     Parser parser(schema);
     std::string input;
     std::ostringstream errorStream;
diff --git a/tests/ls.cpp b/tests/ls.cpp
index 2c72041..66c2aaa 100644
--- a/tests/ls.cpp
+++ b/tests/ls.cpp
@@ -25,11 +25,11 @@
     schema->addContainer("/example:a/example:a2", "example:a3");
     schema->addContainer("/example:b/example:b2", "example:b3");
     schema->addList("/", "example:list", {"number"});
-    schema->addLeaf("/example:list", "example:number", yang::LeafDataTypes::Int32);
+    schema->addLeaf("/example:list", "example:number", yang::Int32{});
     schema->addContainer("/example:list", "example:contInList");
     schema->addList("/", "example:twoKeyList", {"number", "name"});
-    schema->addLeaf("/example:twoKeyList", "example:number", yang::LeafDataTypes::Int32);
-    schema->addLeaf("/example:twoKeyList", "example:name", yang::LeafDataTypes::String);
+    schema->addLeaf("/example:twoKeyList", "example:number", yang::Int32{});
+    schema->addLeaf("/example:twoKeyList", "example:name", yang::String{});
     Parser parser(schema);
     std::string input;
     std::ostringstream errorStream;
diff --git a/tests/path_completion.cpp b/tests/path_completion.cpp
index 2403f9d..c00a26c 100644
--- a/tests/path_completion.cpp
+++ b/tests/path_completion.cpp
@@ -27,16 +27,16 @@
     schema->addContainer("/example:ano/example:a2", "example:a3");
     schema->addContainer("/example:bota/example:b2", "example:b3");
     schema->addList("/", "example:list", {"number"});
-    schema->addLeaf("/example:list", "example:number", yang::LeafDataTypes::Int32);
+    schema->addLeaf("/example:list", "example:number", yang::Int32{});
     schema->addContainer("/example:list", "example:contInList");
     schema->addList("/", "example:ovoce", {"name"});
-    schema->addLeaf("/example:ovoce", "example:name", yang::LeafDataTypes::String);
+    schema->addLeaf("/example:ovoce", "example:name", yang::String{});
     schema->addList("/", "example:ovocezelenina", {"name"});
-    schema->addLeaf("/example:ovocezelenina", "example:name", yang::LeafDataTypes::String);
+    schema->addLeaf("/example:ovocezelenina", "example:name", yang::String{});
     schema->addList("/", "example:twoKeyList", {"number", "name"});
-    schema->addLeaf("/example:twoKeyList", "example:name", yang::LeafDataTypes::String);
-    schema->addLeaf("/example:twoKeyList", "example:number", yang::LeafDataTypes::Int32);
-    schema->addLeaf("/", "example:leafInt", yang::LeafDataTypes::Int32);
+    schema->addLeaf("/example:twoKeyList", "example:name", yang::String{});
+    schema->addLeaf("/example:twoKeyList", "example:number", yang::Int32{});
+    schema->addLeaf("/", "example:leafInt", yang::Int32{});
     auto mockDatastore = std::make_shared<MockDatastoreAccess>();
 
     // The parser will use DataQuery for key value completion, but I'm not testing that here, so I don't return anything.
diff --git a/tests/presence_containers.cpp b/tests/presence_containers.cpp
index af79d00..7c6397d 100644
--- a/tests/presence_containers.cpp
+++ b/tests/presence_containers.cpp
@@ -22,7 +22,7 @@
     schema->addContainer("/mod:a/mod:a2", "mod:a3", yang::ContainerTraits::Presence);
     schema->addContainer("/mod:b", "mod:b2", yang::ContainerTraits::Presence);
     schema->addList("/", "mod:list", {"quote"});
-    schema->addLeaf("/mod:list", "mod:quote", yang::LeafDataTypes::String);
+    schema->addLeaf("/mod:list", "mod:quote", yang::String{});
     schema->addContainer("/mod:list", "mod:contInList", yang::ContainerTraits::Presence);
     Parser parser(schema);
     std::string input;
diff --git a/tests/pretty_printers.hpp b/tests/pretty_printers.hpp
index 86bd20d..3f592a5 100644
--- a/tests/pretty_printers.hpp
+++ b/tests/pretty_printers.hpp
@@ -36,4 +36,34 @@
     s << "}" << std::endl;
     return s;
 }
+
+std::ostream& operator<<(std::ostream& s, const yang::LeafDataType& type)
+{
+    s << std::endl
+      << leafDataTypeToString(type);
+    if (std::holds_alternative<yang::Enum>(type)) {
+        s << "{";
+        auto values = std::get<yang::Enum>(type).m_allowedValues;
+        std::transform(values.begin(), values.end(), std::experimental::make_ostream_joiner(s, ", "), [](const auto& value) {
+            return value.m_value;
+        });
+        s << "}";
+    }
+    if (std::holds_alternative<yang::IdentityRef>(type)) {
+        s << "{";
+        auto values = std::get<yang::IdentityRef>(type).m_allowedValues;
+        std::transform(values.begin(), values.end(), std::experimental::make_ostream_joiner(s, ", "), [](const auto& value) {
+            std::string res;
+            if (value.m_prefix) {
+                res += value.m_prefix->m_name;
+                res += ":";
+            }
+            res += value.m_value;
+            return res;
+        });
+        s << "}";
+    }
+    s << std::endl;
+    return s;
+}
 }
diff --git a/tests/yang.cpp b/tests/yang.cpp
index fc57d3f..dcf4354 100644
--- a/tests/yang.cpp
+++ b/tests/yang.cpp
@@ -7,6 +7,7 @@
 */
 
 #include <experimental/iterator>
+#include "leaf_data_helpers.hpp"
 #include "pretty_printers.hpp"
 #include "trompeloeil_doctest.hpp"
 #include "yang_schema.hpp"
@@ -425,189 +426,6 @@
 
             REQUIRE(ys.isPresenceContainer(path, node));
         }
-        SECTION("leafEnumHasValue")
-        {
-            std::string value;
-            SECTION("leafEnum")
-            {
-                node.first = "example-schema";
-                node.second = "leafEnum";
-
-                SECTION("lol")
-                    value = "lol";
-
-                SECTION("data")
-                    value = "data";
-
-                SECTION("coze")
-                    value = "coze";
-            }
-
-            SECTION("leafEnumTypedef")
-            {
-                node.first = "example-schema";
-                node.second = "leafEnumTypedef";
-
-                SECTION("lol")
-                    value = "lol";
-
-                SECTION("data")
-                    value = "data";
-
-                SECTION("coze")
-                    value = "coze";
-            }
-
-            SECTION("leafEnumTypedefRestricted")
-            {
-                node.first = "example-schema";
-                node.second = "leafEnumTypedefRestricted";
-
-                SECTION("data")
-                    value = "data";
-
-                SECTION("coze")
-                    value = "coze";
-            }
-
-            SECTION("leafEnumTypedefRestricted2")
-            {
-                node.first = "example-schema";
-                node.second = "leafEnumTypedefRestricted2";
-
-                SECTION("lol")
-                    value = "lol";
-
-                SECTION("data")
-                    value = "data";
-            }
-
-            SECTION("pizzaSize")
-            {
-                node.first = "example-schema";
-                node.second = "pizzaSize";
-
-                SECTION("small")
-                {
-                    value = "small";
-                }
-                SECTION("medium")
-                {
-                    value = "medium";
-                }
-
-                SECTION("large")
-                {
-                    ys.enableFeature("example-schema", "bigPizzas");
-                    value = "large";
-                }
-            }
-
-            REQUIRE(ys.leafEnumHasValue(path, node, value));
-        }
-        SECTION("leafIdentityIsValid")
-        {
-            ModuleValuePair value;
-
-            SECTION("foodIdentLeaf")
-            {
-                node.first = "example-schema";
-                node.second = "foodIdentLeaf";
-
-                SECTION("food")
-                {
-                    value.second = "food";
-                }
-                SECTION("example-schema:food")
-                {
-                    value.first = "example-schema";
-                    value.second = "food";
-                }
-                SECTION("pizza")
-                {
-                    value.second = "pizza";
-                }
-                SECTION("example-schema:pizza")
-                {
-                    value.first = "example-schema";
-                    value.second = "pizza";
-                }
-                SECTION("hawaii")
-                {
-                    value.second = "hawaii";
-                }
-                SECTION("example-schema:hawaii")
-                {
-                    value.first = "example-schema";
-                    value.second = "hawaii";
-                }
-                SECTION("fruit")
-                {
-                    value.second = "fruit";
-                }
-                SECTION("example-schema:fruit")
-                {
-                    value.first = "example-schema";
-                    value.second = "fruit";
-                }
-                SECTION("second-schema:pineapple")
-                {
-                    value.first = "second-schema";
-                    value.second = "pineapple";
-                }
-            }
-
-            SECTION("pizzaIdentLeaf")
-            {
-                node.first = "example-schema";
-                node.second = "pizzaIdentLeaf";
-
-                SECTION("pizza")
-                {
-                    value.second = "pizza";
-                }
-                SECTION("example-schema:pizza")
-                {
-                    value.first = "example-schema";
-                    value.second = "pizza";
-                }
-                SECTION("hawaii")
-                {
-                    value.second = "hawaii";
-                }
-                SECTION("example-schema:hawaii")
-                {
-                    value.first = "example-schema";
-                    value.second = "hawaii";
-                }
-            }
-
-            SECTION("foodDrinkIdentLeaf")
-            {
-                node.first = "example-schema";
-                node.second = "foodDrinkIdentLeaf";
-
-                SECTION("food")
-                {
-                    value.second = "food";
-                }
-                SECTION("example-schema:food")
-                {
-                    value.first = "example-schema";
-                    value.second = "food";
-                }
-                SECTION("drink")
-                {
-                    value.second = "drink";
-                }
-                SECTION("example-schema:drink")
-                {
-                    value.first = "example-schema";
-                    value.second = "drink";
-                }
-            }
-            REQUIRE(ys.leafIdentityIsValid(path, node, value));
-        }
 
         SECTION("listHasKey")
         {
@@ -655,97 +473,175 @@
         }
         SECTION("leafType")
         {
-            yang::LeafDataTypes type;
+            yang::LeafDataType type;
 
             SECTION("leafString")
             {
                 node.first = "example-schema";
                 node.second = "leafString";
-                type = yang::LeafDataTypes::String;
+                type = yang::String{};
             }
 
             SECTION("leafDecimal")
             {
                 node.first = "example-schema";
                 node.second = "leafDecimal";
-                type = yang::LeafDataTypes::Decimal;
+                type = yang::Decimal{};
             }
 
             SECTION("leafBool")
             {
                 node.first = "example-schema";
                 node.second = "leafBool";
-                type = yang::LeafDataTypes::Bool;
+                type = yang::Bool{};
             }
 
             SECTION("leafInt8")
             {
                 node.first = "example-schema";
                 node.second = "leafInt8";
-                type = yang::LeafDataTypes::Int8;
+                type = yang::Int8{};
             }
 
             SECTION("leafUint8")
             {
                 node.first = "example-schema";
                 node.second = "leafUint8";
-                type = yang::LeafDataTypes::Uint8;
+                type = yang::Uint8{};
             }
 
             SECTION("leafInt16")
             {
                 node.first = "example-schema";
                 node.second = "leafInt16";
-                type = yang::LeafDataTypes::Int16;
+                type = yang::Int16{};
             }
 
             SECTION("leafUint16")
             {
                 node.first = "example-schema";
                 node.second = "leafUint16";
-                type = yang::LeafDataTypes::Uint16;
+                type = yang::Uint16{};
             }
 
             SECTION("leafInt32")
             {
                 node.first = "example-schema";
                 node.second = "leafInt32";
-                type = yang::LeafDataTypes::Int32;
+                type = yang::Int32{};
             }
 
             SECTION("leafUint32")
             {
                 node.first = "example-schema";
                 node.second = "leafUint32";
-                type = yang::LeafDataTypes::Uint32;
+                type = yang::Uint32{};
             }
 
             SECTION("leafInt64")
             {
                 node.first = "example-schema";
                 node.second = "leafInt64";
-                type = yang::LeafDataTypes::Int64;
+                type = yang::Int64{};
             }
 
             SECTION("leafUint64")
             {
                 node.first = "example-schema";
                 node.second = "leafUint64";
-                type = yang::LeafDataTypes::Uint64;
+                type = yang::Uint64{};
             }
 
             SECTION("leafEnum")
             {
                 node.first = "example-schema";
                 node.second = "leafEnum";
-                type = yang::LeafDataTypes::Enum;
+                type = createEnum({"lol", "data", "coze"});
+            }
+
+            SECTION("leafEnumTypedef")
+            {
+                node.first = "example-schema";
+                node.second = "leafEnumTypedef";
+                type = createEnum({"lol", "data", "coze"});
+            }
+
+            SECTION("leafEnumTypedefRestricted")
+            {
+                node.first = "example-schema";
+                node.second = "leafEnumTypedefRestricted";
+                type = createEnum({"data", "coze"});
+            }
+
+            SECTION("leafEnumTypedefRestricted2")
+            {
+                node.first = "example-schema";
+                node.second = "leafEnumTypedefRestricted2";
+                type = createEnum({"lol", "data"});
+            }
+
+            SECTION("pizzaSize")
+            {
+                node.first = "example-schema";
+                node.second = "pizzaSize";
+
+                SECTION("bigPizzas disabled")
+                {
+                    type = createEnum({"small", "medium"});
+                }
+                SECTION("bigPizzas enabled")
+                {
+                    ys.enableFeature("example-schema", "bigPizzas");
+                    type = createEnum({"small", "medium", "large"});
+                }
+            }
+
+            SECTION("foodIdentLeaf")
+            {
+                node.first = "example-schema";
+                node.second = "foodIdentLeaf";
+                type = yang::IdentityRef{{{"second-schema", "pineapple"},
+                                          {"example-schema", "food"},
+                                          {"example-schema", "pizza"},
+                                          {"example-schema", "hawaii"},
+                                          {"example-schema", "fruit"}}};
+            }
+
+            SECTION("pizzaIdentLeaf")
+            {
+                node.first = "example-schema";
+                node.second = "pizzaIdentLeaf";
+
+                type = yang::IdentityRef{{
+                    {"example-schema", "pizza"},
+                    {"example-schema", "hawaii"},
+                }};
+            }
+
+            SECTION("foodDrinkIdentLeaf")
+            {
+                node.first = "example-schema";
+                node.second = "foodDrinkIdentLeaf";
+
+                type = yang::IdentityRef{{
+                    {"example-schema", "food"},
+                    {"example-schema", "drink"},
+                    {"example-schema", "fruit"},
+                    {"example-schema", "hawaii"},
+                    {"example-schema", "pizza"},
+                    {"example-schema", "voda"},
+                    {"second-schema", "pineapple"},
+                }};
             }
 
             SECTION("activeNumber")
             {
                 node.first = "example-schema";
                 node.second = "activeNumber";
-                type = yang::LeafDataTypes::LeafRef;
+                type.emplace<yang::LeafRef>(
+                    "/example-schema:_list/number",
+                    std::make_unique<yang::LeafDataType>(ys.leafType("/example-schema:_list/number"))
+                );
             }
 
             REQUIRE(ys.leafType(path, node) == type);
@@ -969,7 +865,6 @@
             path.m_nodes.push_back(schemaNode_(module_{"example-schema"}, container_("a")));
             node.second = "a2";
 
-            REQUIRE(!ys.leafEnumHasValue(path, node, "haha"));
             REQUIRE(!ys.listHasKey(path, node, "chacha"));
         }
 
@@ -978,44 +873,6 @@
             REQUIRE(!ys.isModule("notAModule"));
         }
 
-        SECTION("leafIdentityIsValid")
-        {
-            ModuleValuePair value;
-            SECTION("pizzaIdentLeaf")
-            {
-                node.first = "example-schema";
-                node.second = "pizzaIdentLeaf";
-
-                SECTION("wrong base ident")
-                {
-                    SECTION("food")
-                    {
-                        value.second = "food";
-                    }
-                    SECTION("fruit")
-                    {
-                        value.second = "fruit";
-                    }
-                }
-                SECTION("non-existent identity")
-                {
-                    value.second = "nonexistent";
-                }
-                SECTION("weird module")
-                {
-                    value.first = "ahahaha";
-                    value.second = "pizza";
-                }
-            }
-            SECTION("different module identity, but withotu prefix")
-            {
-                node.first = "example-schema";
-                node.second = "foodIdentLeaf";
-                value.second = "pineapple";
-            }
-            REQUIRE_FALSE(ys.leafIdentityIsValid(path, node, value));
-        }
-
         SECTION("grouping is not a node")
         {
             SECTION("example-schema:arithmeticFlags")
@@ -1069,15 +926,5 @@
             REQUIRE(!ys.isLeaf(path, node));
             REQUIRE(!ys.isContainer(path, node));
         }
-
-        SECTION("enum is disabled by if-feature if feature is not enabled")
-        {
-            node.first = "example-schema";
-            node.second = "pizzaSize";
-
-            std::string value = "large";
-
-            REQUIRE(!ys.leafEnumHasValue(path, node, value));
-        }
     }
 }