From 31e9b4c315ecd71bb79e83f4eefbfd892da78d8b Mon Sep 17 00:00:00 2001
From: Samuel Gaist <samuel.gaist@idiap.ch>
Date: Thu, 3 Jan 2019 17:16:17 +0100
Subject: [PATCH] [utils] Test refactor to separate data and tests

---
 beat/editor/templates/algorithm.jinja2        | 20 ++--
 beat/editor/templates/database.jinja2         | 15 +--
 beat/editor/templates/library.jinja2          |  5 +-
 .../test/reference_data/empty_algorithm.py    | 43 +++++++++
 .../test/reference_data/empty_database.py     | 27 ++++++
 .../test/reference_data/empty_library.py      |  3 +
 beat/editor/test/test_utils.py                | 92 +++++--------------
 7 files changed, 119 insertions(+), 86 deletions(-)
 create mode 100644 beat/editor/test/reference_data/empty_algorithm.py
 create mode 100644 beat/editor/test/reference_data/empty_database.py
 create mode 100644 beat/editor/test/reference_data/empty_library.py

diff --git a/beat/editor/templates/algorithm.jinja2 b/beat/editor/templates/algorithm.jinja2
index ab9eb1c8..81cae4fe 100644
--- a/beat/editor/templates/algorithm.jinja2
+++ b/beat/editor/templates/algorithm.jinja2
@@ -1,9 +1,11 @@
-# You may import any python packages that will be available in the environment you will run this algorithm in
-# Environments can change based on the experiment's settings
+# You may import any python packages that will be available in the environment
+# you will run this algorithm in Environments can change based on the
+# experiment's settings
 {% for ref, lib in contents.uses.items() %}# Library "{{ lib }}" is available under "{{ ref }}"
 {% endfor %}
 class Algorithm:
-    # initialise fields to store cross-input data (e.g. machines, aggregations, etc.)
+    # initialise fields to store cross-input data (e.g. machines,
+    # aggregations, etc.)
     def __init__(self):
         pass
 {% if contents.parameters %}
@@ -18,7 +20,8 @@ class Algorithm:
         return True
 
 {% endif %}
-    # this will be called each time the sync'd input has more data available to be processed
+    # this will be called each time the sync'd input has more data available to
+    # be processed
     def process(self, inputs, outputs):
         # Groups available:
 {% for group in contents.groups %}        # Group {{ loop.index - 1 }}:
@@ -29,19 +32,22 @@ class Algorithm:
         {% for rName, result in contents.results.items() %}#   Result "{{ rName }}" with type "{{ result.type }}"
         {% endfor %}{% endif %}
         # to check if there is more data waiting in the inputs
-        # (if it is False, you have processed all the inputs and this "process" function won't be called again):
+        # (if it is False, you have processed all the inputs and this "process"
+        # function won't be called again):
         #       if inputs.hasMoreData():
 
         # to check if a specific input is done:
         #       if inputs["input1"].isDataUnitDone():
 
         # to manually fetch the next input of a specific input
-        # (e.g. the block is not sync'd to the input but you want the input immediately)
+        # (e.g. the block is not sync'd to the input but you want the input
+        # immediately)
         #       inputs['input1'].next()
         # you can then access that input value as normal:
         #       self.val1 = inputs['input1'].data
 
-        # to get the data for an input (note that the value will be of the type specified in the metadata!):
+        # to get the data for an input (note that the value will be of the type
+        # specified in the metadata!):
         #       data_value = inputs['input1'].data
 
         # to write to an output:
diff --git a/beat/editor/templates/database.jinja2 b/beat/editor/templates/database.jinja2
index dd148f21..172243aa 100644
--- a/beat/editor/templates/database.jinja2
+++ b/beat/editor/templates/database.jinja2
@@ -1,13 +1,16 @@
-# You may import any python packages that will be available in the environment you will run this database in
-# Environments can change based on the experiment's settings
+# You may import any python packages that will be available in the environment
+# you will run this database in Environments can change based on the
+# experiment's settings
 from beat.backend.python.database import View
 {% for view in views %}
 class {{ view }}(View):
     # build the data for your view
     # split the raw data into (homogenous) bits and return a keyed iterable
     # (something with `.keys()` available to it, like a dict)
-    # the key names must be the same as the output names for sets that use this view
-    #    root_folder: the path to the root folder of the database's files (not always applicable)
+    # the key names must be the same as the output names for sets that use this
+    # view.
+    #    root_folder: the path to the root folder of the database's files (not
+    #                 always applicable)
     #    parameters: parameters passed to the view, defined in the metadata
     def index(self, root_folder, parameters):
         pass
@@ -18,7 +21,7 @@ class {{ view }}(View):
     def get(self, output, index):
         # to get the current object referenced by the given index:
         #       obj = self.objs[index]
-        # note that this object is a named tuple, with fields equivalent to your keys from
-        # the objects returned from the index function
+        # note that this object is a named tuple, with fields equivalent to
+        # your keys from the objects returned from the index function
         pass
 {% endfor %}
diff --git a/beat/editor/templates/library.jinja2 b/beat/editor/templates/library.jinja2
index 9cb365df..172ecd83 100644
--- a/beat/editor/templates/library.jinja2
+++ b/beat/editor/templates/library.jinja2
@@ -1,4 +1,5 @@
-# You may import any python packages that will be available in the environment you will run this library in
-# Environments can change based on the experiment's settings
+# You may import any python packages that will be available in the environment
+# you will run this library in Environments can change based on the
+# experiment's settings
 {% for ref, lib in uses.items() %}# Library "{{ lib }}" is available under "{{ ref }}"
 {% endfor %}
diff --git a/beat/editor/test/reference_data/empty_algorithm.py b/beat/editor/test/reference_data/empty_algorithm.py
new file mode 100644
index 00000000..79dfaf4a
--- /dev/null
+++ b/beat/editor/test/reference_data/empty_algorithm.py
@@ -0,0 +1,43 @@
+# You may import any python packages that will be available in the environment
+# you will run this algorithm in Environments can change based on the
+# experiment's settings
+
+
+class Algorithm:
+    # initialise fields to store cross-input data (e.g. machines,
+    # aggregations, etc.)
+    def __init__(self):
+        pass
+
+    # this will be called each time the sync'd input has more data available to
+    # be processed
+    def process(self, inputs, outputs):
+        # Groups available:
+
+        # to check if there is more data waiting in the inputs
+        # (if it is False, you have processed all the inputs and this "process"
+        # function won't be called again):
+        #       if inputs.hasMoreData():
+
+        # to check if a specific input is done:
+        #       if inputs["input1"].isDataUnitDone():
+
+        # to manually fetch the next input of a specific input
+        # (e.g. the block is not sync'd to the input but you want the input
+        # immediately)
+        #       inputs['input1'].next()
+        # you can then access that input value as normal:
+        #       self.val1 = inputs['input1'].data
+
+        # to get the data for an input (note that the value will be of the type
+        # specified in the metadata!):
+        #       data_value = inputs['input1'].data
+
+        # to write to an output:
+        #       outputs['output1'].write({
+        #           'output_field_1': 1,
+        #           'output_field_2': 'output'
+        #       })
+
+        # always return True, it signals BEAT to continue processing
+        return True
diff --git a/beat/editor/test/reference_data/empty_database.py b/beat/editor/test/reference_data/empty_database.py
new file mode 100644
index 00000000..4f7565f8
--- /dev/null
+++ b/beat/editor/test/reference_data/empty_database.py
@@ -0,0 +1,27 @@
+# You may import any python packages that will be available in the environment
+# you will run this database in Environments can change based on the
+# experiment's settings
+from beat.backend.python.database import View
+
+
+class View(View):
+    # build the data for your view
+    # split the raw data into (homogenous) bits and return a keyed iterable
+    # (something with `.keys()` available to it, like a dict)
+    # the key names must be the same as the output names for sets that use this
+    # view.
+    #    root_folder: the path to the root folder of the database's files (not
+    #                 always applicable)
+    #    parameters: parameters passed to the view, defined in the metadata
+    def index(self, root_folder, parameters):
+        pass
+
+    # returns a value at a specific index in the iterable for this view
+    #   output: the specific output value requested
+    #   index: the current index of the iterable
+    def get(self, output, index):
+        # to get the current object referenced by the given index:
+        #       obj = self.objs[index]
+        # note that this object is a named tuple, with fields equivalent to
+        # your keys from the objects returned from the index function
+        pass
diff --git a/beat/editor/test/reference_data/empty_library.py b/beat/editor/test/reference_data/empty_library.py
new file mode 100644
index 00000000..83be71c4
--- /dev/null
+++ b/beat/editor/test/reference_data/empty_library.py
@@ -0,0 +1,3 @@
+# You may import any python packages that will be available in the environment
+# you will run this library in Environments can change based on the
+# experiment's settings
diff --git a/beat/editor/test/test_utils.py b/beat/editor/test/test_utils.py
index 100e17f3..6bc75618 100644
--- a/beat/editor/test/test_utils.py
+++ b/beat/editor/test/test_utils.py
@@ -27,86 +27,36 @@
 
 # test the utils.py file
 # (mostly python file generation via jinja2 templates)
-
-import nose.tools
 import os
 
+import nose.tools
+import pkg_resources
 from .. import utils
 
-def test_generate_empty_database():
-    empty_db = """# You may import any python packages that will be available in the environment you will run this database in
-# Environments can change based on the experiment's settings
-from beat.backend.python.database import View
-
-class View(View):
-    # build the data for your view
-    # split the raw data into (homogenous) bits and return a keyed iterable
-    # (something with `.keys()` available to it, like a dict)
-    # the key names must be the same as the output names for sets that use this view
-    #    root_folder: the path to the root folder of the database's files (not always applicable)
-    #    parameters: parameters passed to the view, defined in the metadata
-    def index(self, root_folder, parameters):
-        pass
-
-    # returns a value at a specific index in the iterable for this view
-    #   output: the specific output value requested
-    #   index: the current index of the iterable
-    def get(self, output, index):
-        # to get the current object referenced by the given index:
-        #       obj = self.objs[index]
-        # note that this object is a named tuple, with fields equivalent to your keys from
-        # the objects returned from the index function
-        pass
-"""
-    str = utils.generate_database()
-    nose.tools.eq_(str, empty_db)
-
-def test_generate_empty_algorithm():
-    empty_alg = """# You may import any python packages that will be available in the environment you will run this algorithm in
-# Environments can change based on the experiment's settings
-
-class Algorithm:
-    # initialise fields to store cross-input data (e.g. machines, aggregations, etc.)
-    def __init__(self):
-        pass
-
-    # this will be called each time the sync'd input has more data available to be processed
-    def process(self, inputs, outputs):
-        # Groups available:
-
-        # to check if there is more data waiting in the inputs
-        # (if it is False, you have processed all the inputs and this "process" function won't be called again):
-        #       if inputs.hasMoreData():
 
-        # to check if a specific input is done:
-        #       if inputs["input1"].isDataUnitDone():
+DATA_PATH = pkg_resources.resource_filename("beat.editor.test", "reference_data")
 
-        # to manually fetch the next input of a specific input
-        # (e.g. the block is not sync'd to the input but you want the input immediately)
-        #       inputs['input1'].next()
-        # you can then access that input value as normal:
-        #       self.val1 = inputs['input1'].data
 
-        # to get the data for an input (note that the value will be of the type specified in the metadata!):
-        #       data_value = inputs['input1'].data
+def test_generate_empty_database():
+    database = utils.generate_database()
+    with open(os.path.join(DATA_PATH, "empty_database.py")) as db_file:
+        empty_db = db_file.read()
+        nose.tools.eq_(database, empty_db)
 
-        # to write to an output:
-        #       outputs['output1'].write({
-        #           'output_field_1': 1,
-        #           'output_field_2': 'output'
-        #       })
 
-        # always return True, it signals BEAT to continue processing
-        return True"""
+def test_generate_empty_algorithm():
+    alg = {
+        "name": "user/alg/1",
+        "contents": {"splittable": True, "groups": [], "uses": {}},
+    }
+    algorithm = utils.generate_algorithm(alg["contents"])
+    with open(os.path.join(DATA_PATH, "empty_algorithm.py")) as db_file:
+        empty_alg = db_file.read()
+        nose.tools.eq_(algorithm, empty_alg)
 
-    alg = { 'name': 'user/alg/1', 'contents': { 'splittable': True, 'groups': [], 'uses': {} }}
-    str = utils.generate_algorithm(alg['contents'])
-    nose.tools.eq_(str, empty_alg)
 
 def test_generate_empty_library():
-    empty_lib = """# You may import any python packages that will be available in the environment you will run this library in
-# Environments can change based on the experiment's settings
-"""
-
-    str = utils.generate_library()
-    nose.tools.eq_(str, empty_lib)
+    library = utils.generate_library()
+    with open(os.path.join(DATA_PATH, "empty_library.py")) as db_file:
+        empty_lib = db_file.read()
+        nose.tools.eq_(library, empty_lib)
-- 
GitLab