Fix relative class name functionality

Remove the old implementation of the relative class name functionality
as this has bugs, leading to classes not being loaded.The new
implementation catches relative class names when they are first
encountered and converts them into absolute class names straight away.
Also add some tests for the relative class names.
diff --git a/reclass/core.py b/reclass/core.py
index 66c74f5..75eea54 100644
--- a/reclass/core.py
+++ b/reclass/core.py
@@ -123,10 +123,6 @@
                     except ResolveError as e:
                         raise ClassNameResolveError(klass, nodename, entity.uri)
 
-            # for convenience, first level classes_uri/class.yml can have un-interpolated "."
-            if klass.startswith('.'):
-                klass = klass[1:]
-
             if klass not in seen:
                 try:
                     class_entity = self._storage.get_class(klass, environment, self._settings)
diff --git a/reclass/storage/yaml_fs/__init__.py b/reclass/storage/yaml_fs/__init__.py
index 7540aa4..20e8eec 100644
--- a/reclass/storage/yaml_fs/__init__.py
+++ b/reclass/storage/yaml_fs/__init__.py
@@ -96,7 +96,6 @@
         try:
             relpath = self._nodes[name]
             path = os.path.join(self.nodes_uri, relpath)
-            name = os.path.splitext(relpath)[0]
         except KeyError as e:
             raise reclass.errors.NodeNotFound(self.name, name, self.nodes_uri)
         entity = YamlData.from_file(path).get_entity(name, settings)
@@ -108,13 +107,7 @@
             path = os.path.join(self.classes_uri, self._classes[name])
         except KeyError as e:
             raise reclass.errors.ClassNotFound(self.name, name, self.classes_uri)
-
-        if path.endswith('init{}'.format(FILE_EXTENSION)):
-            parent_class=name
-        else:
-            # for regular class yml file, strip its name
-            parent_class='.'.join(name.split('.')[:-1])
-        entity = YamlData.from_file(path).get_entity(name, settings, parent_class)
+        entity = YamlData.from_file(path).get_entity(name, settings)
         return entity
 
     def enumerate_nodes(self):
diff --git a/reclass/storage/yaml_git/__init__.py b/reclass/storage/yaml_git/__init__.py
index 61c4551..45cb6c0 100644
--- a/reclass/storage/yaml_git/__init__.py
+++ b/reclass/storage/yaml_git/__init__.py
@@ -258,15 +258,7 @@
             raise reclass.errors.NotFoundError("File " + name + " missing from " + uri.repo + " branch " + uri.branch)
         file = self._repos[uri.repo].files[uri.branch][name]
         blob = self._repos[uri.repo].get(file.id)
-
-        if file.name.endswith('init{}'.format(FILE_EXTENSION)):
-            parent_class=name
-        else:
-            # for regular class yml file, strip its name
-            parent_class='.'.join(name.split('.')[:-1])
-
-        entity = YamlData.from_string(blob.data, 'git_fs://{0} {1} {2}'.format(uri.repo, uri.branch,
-            file.path)).get_entity(name, settings, parent_class)
+        entity = YamlData.from_string(blob.data, 'git_fs://{0} {1} {2}'.format(uri.repo, uri.branch, file.path)).get_entity(name, settings)
         return entity
 
     def enumerate_nodes(self):
diff --git a/reclass/storage/yamldata.py b/reclass/storage/yamldata.py
index 52547ac..034832d 100644
--- a/reclass/storage/yamldata.py
+++ b/reclass/storage/yamldata.py
@@ -53,16 +53,26 @@
     def get_data(self):
         return self._data
 
-    def get_entity(self, name, settings, parent_class=None):
+    def set_absolute_names(self, name, names):
+        parent = '.'.join(name.split('.')[0:-1])
+        new_names = []
+        for n in names:
+            if n[0] == '.':
+                if parent == '':
+                    n = n[1:]
+                else:
+                    n = parent + n
+            new_names.append(n)
+        return new_names
+
+    def get_entity(self, name, settings):
         #if name is None:
         #    name = self._uri
 
         classes = self._data.get('classes')
         if classes is None:
             classes = []
-        if parent_class:
-            classes = \
-                [parent_class + c for c in classes if c.startswith('.')]
+        classes = self.set_absolute_names(name, classes)
         classes = datatypes.Classes(classes)
 
         applications = self._data.get('applications')
diff --git a/reclass/tests/data/02/classes/one/alpha.yml b/reclass/tests/data/02/classes/one/alpha.yml
new file mode 100644
index 0000000..a13cc5c
--- /dev/null
+++ b/reclass/tests/data/02/classes/one/alpha.yml
@@ -0,0 +1,7 @@
+classes:
+- .beta
+- two.beta
+
+parameters:
+  test1: ${one_beta}
+  test2: ${two_beta}
diff --git a/reclass/tests/data/02/classes/one/beta.yml b/reclass/tests/data/02/classes/one/beta.yml
new file mode 100644
index 0000000..f754252
--- /dev/null
+++ b/reclass/tests/data/02/classes/one/beta.yml
@@ -0,0 +1,2 @@
+parameters:
+  one_beta: 1
diff --git a/reclass/tests/data/02/classes/three.yml b/reclass/tests/data/02/classes/three.yml
new file mode 100644
index 0000000..987fde0
--- /dev/null
+++ b/reclass/tests/data/02/classes/three.yml
@@ -0,0 +1,2 @@
+classes:
+- .one.alpha
diff --git a/reclass/tests/data/02/classes/two/beta.yml b/reclass/tests/data/02/classes/two/beta.yml
new file mode 100644
index 0000000..1f578b2
--- /dev/null
+++ b/reclass/tests/data/02/classes/two/beta.yml
@@ -0,0 +1,2 @@
+parameters:
+  two_beta: 2
diff --git a/reclass/tests/data/02/nodes/relative.yml b/reclass/tests/data/02/nodes/relative.yml
new file mode 100644
index 0000000..1f2bbdc
--- /dev/null
+++ b/reclass/tests/data/02/nodes/relative.yml
@@ -0,0 +1,2 @@
+classes:
+  - one.alpha
diff --git a/reclass/tests/data/02/nodes/top_relative.yml b/reclass/tests/data/02/nodes/top_relative.yml
new file mode 100644
index 0000000..5dae5be
--- /dev/null
+++ b/reclass/tests/data/02/nodes/top_relative.yml
@@ -0,0 +1,2 @@
+classes:
+  - three
diff --git a/reclass/tests/test_core.py b/reclass/tests/test_core.py
index 047bf24..b20b268 100644
--- a/reclass/tests/test_core.py
+++ b/reclass/tests/test_core.py
@@ -59,6 +59,18 @@
         params = { 'node_test': 'class not found', '_reclass_': { 'environment': 'base', 'name': {'full': 'class_notfound', 'short': 'class_notfound' } } }
         self.assertEqual(node['parameters'], params)
 
+    def test_relative_class_names(self):
+        reclass = self._core('02')
+        node = reclass.nodeinfo('relative')
+        params = { 'test1': 1, 'test2': 2, 'one_beta': 1, 'two_beta': 2, '_reclass_': { 'environment': 'base', 'name': { 'full': 'relative', 'short': 'relative' } } }
+        self.assertEqual(node['parameters'], params)
+
+    def test_top_relative_class_names(self):
+        reclass = self._core('02')
+        node = reclass.nodeinfo('top_relative')
+        params = { 'test1': 1, 'test2': 2, 'one_beta': 1, 'two_beta': 2, '_reclass_': { 'environment': 'base', 'name': { 'full': 'top_relative', 'short': 'top_relative' } } }
+        self.assertEqual(node['parameters'], params)
+
 
 if __name__ == '__main__':
     unittest.main()