Reimplement SchemaContextUtil.getBaseTypeForLeafRef()
[yangtools.git] / yang / yang-model-util / src / test / java / org / opendaylight / yangtools / yang / model / util / LeafrefStaticAnalysisTest.java
index b651a5237abaf68a5f905dab7f0036e1ace8bfd0..65da97f894c78b24121367e26200d2265c7d9572 100644 (file)
@@ -7,10 +7,12 @@
  */
 package org.opendaylight.yangtools.yang.model.util;
 
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.startsWith;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.isA;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -22,7 +24,6 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
 
@@ -49,35 +50,43 @@ public class LeafrefStaticAnalysisTest {
     public void testGrpOuterId() {
         final LeafSchemaNode leaf = (LeafSchemaNode) grp.findDataChildByName(QName.create(FOO, "outer-id")).get();
         // Cannot be found as the reference goes outside of the grouping
-        assertNull(SchemaContextUtil.findDataSchemaNodeForRelativeXPath(context, module, leaf,
-            ((LeafrefTypeDefinition) leaf.getType()).getPathStatement()));
+        final SchemaInferenceStack stack = SchemaInferenceStack.of(context);
+        stack.enterGrouping(grp.getQName());
+        stack.enterSchemaTree(QName.create(FOO, "outer-id"));
+        assertThrowsInvalidPath(stack, leaf);
     }
 
     @Test
     public void testFooOuterId() {
         final LeafSchemaNode leaf = (LeafSchemaNode) bar.findDataChildByName(QName.create(FOO, "outer-id")).get();
-        final SchemaNode found = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(context, module, leaf,
-            ((LeafrefTypeDefinition) leaf.getType()).getPathStatement());
+        final SchemaInferenceStack stack = SchemaInferenceStack.ofDataTreePath(context, foo.getQName(), bar.getQName());
+        stack.enterSchemaTree(QName.create(FOO, "outer-id"));
+        final SchemaNode found = (SchemaNode) stack.resolvePathExpression(((LeafrefTypeDefinition) leaf.getType())
+                .getPathStatement());
 
         assertThat(found, isA(LeafSchemaNode.class));
-        assertEquals(SchemaPath.create(true, FOO, QName.create(FOO, "id")), found.getPath());
+        assertEquals(QName.create(FOO, "id"), found.getQName());
     }
 
     @Test
     public void testGrpOuterIndirectProp() {
         final LeafSchemaNode leaf = (LeafSchemaNode) grp.findDataChildByName(
             QName.create(FOO, "outer-indirect-prop")).get();
+        final SchemaInferenceStack stack = SchemaInferenceStack.of(context);
+        stack.enterGrouping(grp.getQName());
+        stack.enterSchemaTree(QName.create(FOO, "outer-indirect-prop"));
         // Cannot resolve deref outer-id
-        assertNull(SchemaContextUtil.findDataSchemaNodeForRelativeXPath(context, module, leaf,
-            ((LeafrefTypeDefinition) leaf.getType()).getPathStatement()));
+        assertThrowsInvalidPath(stack, leaf);
     }
 
     @Test
     public void testFooOuterIndirectProp() {
         final LeafSchemaNode leaf = (LeafSchemaNode) bar.findDataChildByName(
             QName.create(FOO, "outer-indirect-prop")).get();
-        final SchemaNode found = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(context, module, leaf,
-            ((LeafrefTypeDefinition) leaf.getType()).getPathStatement());
+        final SchemaInferenceStack stack = SchemaInferenceStack.ofDataTreePath(context, foo.getQName(), bar.getQName());
+        stack.enterSchemaTree(QName.create(FOO, "outer-indirect-prop"));
+        final SchemaNode found = (SchemaNode) stack.resolvePathExpression(((LeafrefTypeDefinition) leaf.getType())
+                .getPathStatement());
 
         assertThat(found, isA(LeafSchemaNode.class));
         assertEquals(QName.create(FOO, "prop"), found.getQName());
@@ -86,8 +95,11 @@ public class LeafrefStaticAnalysisTest {
     @Test
     public void testGrpIndirect() {
         final LeafSchemaNode leaf = (LeafSchemaNode) grp.findDataChildByName(QName.create(FOO, "indirect")).get();
-        final SchemaNode found = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(context, module, leaf,
-            ((LeafrefTypeDefinition) leaf.getType()).getPathStatement());
+        final SchemaInferenceStack stack = SchemaInferenceStack.of(context);
+        stack.enterGrouping(grp.getQName());
+        stack.enterSchemaTree(QName.create(FOO, "indirect"));
+        final SchemaNode found = (SchemaNode) stack.resolvePathExpression(((LeafrefTypeDefinition) leaf.getType())
+                .getPathStatement());
 
         assertThat(found, isA(LeafSchemaNode.class));
         assertEquals(QName.create(FOO, "prop"), found.getQName());
@@ -96,8 +108,10 @@ public class LeafrefStaticAnalysisTest {
     @Test
     public void testFooIndirect() {
         final LeafSchemaNode leaf = (LeafSchemaNode) bar.findDataChildByName(QName.create(FOO, "indirect")).get();
-        final SchemaNode found = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(context, module, leaf,
-            ((LeafrefTypeDefinition) leaf.getType()).getPathStatement());
+        final SchemaInferenceStack stack = SchemaInferenceStack.ofDataTreePath(context, foo.getQName(), bar.getQName());
+        stack.enterSchemaTree(QName.create(FOO, "indirect"));
+        final SchemaNode found = (SchemaNode) stack.resolvePathExpression(((LeafrefTypeDefinition) leaf.getType())
+                .getPathStatement());
 
         assertThat(found, isA(LeafSchemaNode.class));
         assertEquals(QName.create(FOO, "prop"), found.getQName());
@@ -107,39 +121,69 @@ public class LeafrefStaticAnalysisTest {
     public void testGrpDerefNonExistent() {
         final LeafSchemaNode leaf = (LeafSchemaNode) grp.findDataChildByName(
             QName.create(FOO, "deref-non-existent")).get();
-        assertNull(SchemaContextUtil.findDataSchemaNodeForRelativeXPath(context, module, leaf,
-            ((LeafrefTypeDefinition) leaf.getType()).getPathStatement()));
+        final SchemaInferenceStack stack = SchemaInferenceStack.of(context);
+        stack.enterGrouping(grp.getQName());
+        stack.enterSchemaTree(QName.create(FOO, "deref-non-existent"));
+        assertThrowsMissingXyzzy(stack, leaf);
     }
 
     @Test
     public void testFooDerefNonExistent() {
         final LeafSchemaNode leaf = (LeafSchemaNode) bar.findDataChildByName(
             QName.create(FOO, "deref-non-existent")).get();
-        assertNull(SchemaContextUtil.findDataSchemaNodeForRelativeXPath(context, module, leaf,
-            ((LeafrefTypeDefinition) leaf.getType()).getPathStatement()));
+        final SchemaInferenceStack stack = SchemaInferenceStack.ofDataTreePath(context, foo.getQName(), bar.getQName());
+        stack.enterSchemaTree(QName.create(FOO, "deref-non-existent"));
+        assertThrowsMissingXyzzy(stack, leaf);
     }
 
     @Test
     public void testGrpNonExistentDeref() {
         final LeafSchemaNode leaf = (LeafSchemaNode) grp.findDataChildByName(
             QName.create(FOO, "non-existent-deref")).get();
-        assertNull(SchemaContextUtil.findDataSchemaNodeForRelativeXPath(context, module, leaf,
-            ((LeafrefTypeDefinition) leaf.getType()).getPathStatement()));
+        final SchemaInferenceStack stack = SchemaInferenceStack.of(context);
+        stack.enterGrouping(grp.getQName());
+        stack.enterSchemaTree(QName.create(FOO, "non-existent-deref"));
+        assertThrowsMissingXyzzy(stack, leaf);
     }
 
     @Test
     public void testFooNonExistentDeref() {
         final LeafSchemaNode leaf = (LeafSchemaNode) bar.findDataChildByName(
             QName.create(FOO, "non-existent-deref")).get();
-        assertNull(SchemaContextUtil.findDataSchemaNodeForRelativeXPath(context, module, leaf,
-            ((LeafrefTypeDefinition) leaf.getType()).getPathStatement()));
+        final SchemaInferenceStack stack = SchemaInferenceStack.ofDataTreePath(context, foo.getQName(), bar.getQName());
+        stack.enterSchemaTree(QName.create(FOO, "non-existent-deref"));
+        assertThrowsMissingXyzzy(stack, leaf);
     }
 
     @Test
     public void testNonExistentRelativeXpath() {
         final LeafSchemaNode leaf = (LeafSchemaNode) bar.findDataChildByName(
                 QName.create(FOO, "indirect-with-current")).get();
-        assertNull(SchemaContextUtil.findDataSchemaNodeForRelativeXPath(context, module, leaf,
-                ((LeafrefTypeDefinition) leaf.getType()).getPathStatement()));
+        final SchemaInferenceStack stack = SchemaInferenceStack.ofDataTreePath(context,
+            foo.getQName(), bar.getQName(), QName.create(FOO, "indirect-with-current"));
+        assertThrowsMissingChild(stack, leaf, "(leafrefs)n");
+    }
+
+    private static void assertThrowsInvalidPath(final SchemaInferenceStack stack, final LeafSchemaNode leaf) {
+        final IllegalArgumentException ex = assertThrowsIAE(stack, leaf);
+        assertThat(ex.getMessage(), startsWith("Illegal parent access in "));
+        final Throwable cause = ex.getCause();
+        assertThat(cause, instanceOf(IllegalStateException.class));
+        assertEquals("Unexpected current GroupingEffectiveStatementImpl[qname=(leafrefs)grp]", cause.getMessage());
+    }
+
+    private static void assertThrowsMissingXyzzy(final SchemaInferenceStack stack, final LeafSchemaNode leaf) {
+        assertThrowsMissingChild(stack, leaf, "(leafrefs)xyzzy");
+    }
+
+    private static void assertThrowsMissingChild(final SchemaInferenceStack stack, final LeafSchemaNode leaf,
+            final String childName) {
+        assertEquals("Data tree child " + childName + " not present", assertThrowsIAE(stack, leaf).getMessage());
+    }
+
+    private static IllegalArgumentException assertThrowsIAE(final SchemaInferenceStack stack,
+            final LeafSchemaNode leaf) {
+        return assertThrows(IllegalArgumentException.class,
+            () -> stack.resolvePathExpression(((LeafrefTypeDefinition) leaf.getType()).getPathStatement()));
     }
 }