import unittest
import sys
import os
import subprocess
import nbformat
from nbconvert.preprocessors import ClearOutputPreprocessor, ExecutePreprocessor
from nbconvert.preprocessors.execute import CellExecutionError


# Testing for the notebooks - use nbconvert to execute all cells of the
# notebook

# add names of notebooks to ignore here.
py2Ignore = []

TESTDIR = os.path.abspath(__file__)
NBDIR = os.path.sep.join(TESTDIR.split(os.path.sep)[:-3] + ['em_apps/']) # where are the notebooks?


def setUp():
    nbpaths = []  # list of notebooks, with file paths
    nbnames = []  # list of notebook names (for making the tests)

    # walk the test directory and find all notebooks
    for dirname, dirnames, filenames in os.walk(NBDIR):
        for filename in filenames:
            if filename.endswith(".ipynb") and not filename.endswith("-checkpoint.ipynb"):
                nbpaths.append(os.path.abspath(dirname) + os.path.sep + filename) # get abspath of notebook
                nbnames.append("".join(filename[:-6])) # strip off the file extension
    return nbpaths, nbnames


def get(nbname, nbpath):

    # use nbconvert to execute the notebook
    def test_func(self):
        passing = True
        print("\n--------------- Testing {0} ---------------".format(nbname))
        print("   {0}".format(nbpath))

        if nbname in py2Ignore and sys.version_info[0] == 2:
            print(" Skipping {}".format(nbname))
            return

        ep = ClearOutputPreprocessor()

        with open(nbpath) as f:
            nb = nbformat.read(f, as_version=4)

            ep.preprocess(nb, {})

            ex = ExecutePreprocessor(
                timeout=600,
                kernel_name='python{}'.format(sys.version_info[0]),
                allow_errors=True
            )

            out = ex.preprocess(nb, {})

            for cell in out[0]['cells']:
                if 'outputs' in cell.keys():
                    for output in cell['outputs']:
                        if output['output_type'] == 'error':  #in output.keys():
                            passing = False

                            err_msg = []
                            for o in output['traceback']:
                                err_msg += ["{}".format(o)]
                            err_msg = "\n".join(err_msg)

                            msg = """
\n <<<<< {} FAILED  >>>>> \n
{} in cell [{}] \n-----------\n{}\n-----------\n
----------------- >> begin Traceback << ----------------- \n
{}\n
\n----------------- >> end Traceback << -----------------\n
                            """.format(
                                nbname, output['ename'],
                                cell['execution_count'], cell['source'],
                                err_msg
                            )

                            assert passing, msg

            print("\n ..... {0} Passed ..... \n".format(nbname))

        # nbexe = subprocess.Popen(
        #     [
        #         "jupyter", "nbconvert", "{0}".format(nbpath), "--execute",
        #         "--ExecutePreprocessor.timeout=600",
        #         "--ExecutePreprocessor.kernel_name='python{}'".format(sys.version_info[0])
        #     ],
        #     stdin=subprocess.PIPE, stdout=subprocess.PIPE,
        #     stderr=subprocess.PIPE
        # )
        # output, err = nbexe.communicate()
        # check = nbexe.returncode
        # if check == 0:
        #     print("\n ..... {0} Passed ..... \n".format(nbname))
        #     print("   removing {0}.html".format(os.path.splitext(nbpath)[0]))
        #     subprocess.call([
        #         "rm", "{0}.html".format(os.path.splitext(nbpath)[0])
        #     ])
        # else:
        #     print("\n <<<<< {0} FAILED >>>>> \n".format(nbname))
        #     print("Captured Output: \n")
        #     print("{}".format(err))

        # self.assertTrue(check == 0)

    return test_func


attrs = dict()
nbpaths, nbnames = setUp()

# build test for each notebook
for i, nb in enumerate(nbnames):
    attrs["test_"+nb] = get(nb, nbpaths[i])

# create class to unit test notebooks
TestNotebooks = type("TestNotebooks", (unittest.TestCase,), attrs)


if __name__ == "__main__":
    unittest.main()

@@ -348,18 +348,49 @@
 nore = %5B
+'MarineCSEM_LayeredEarth.ipynb'
 %5D%0A
-
 %0ATESTDIR
@@ -443,16 +443,21 @@
 ep.join(
+%0A    
 TESTDIR.
@@ -494,16 +494,17 @@
 _apps/'%5D
+%0A
 ) # wher
@@ -2068,28 +2068,8 @@
 or':
-  #in output.keys():
 %0A   
@@ -2859,16 +2859,16 @@
 g, msg%0A%0A
+
         
@@ -2928,988 +2928,8 @@
 e))%0A
-%0A        # nbexe = subprocess.Popen(%0A        #     %5B%0A        #         %22jupyter%22, %22nbconvert%22, %22%7B0%7D%22.format(nbpath), %22--execute%22,%0A        #         %22--ExecutePreprocessor.timeout=600%22,%0A        #         %22--ExecutePreprocessor.kernel_name='python%7B%7D'%22.format(sys.version_info%5B0%5D)%0A        #     %5D,%0A        #     stdin=subprocess.PIPE, stdout=subprocess.PIPE,%0A        #     stderr=subprocess.PIPE%0A        # )%0A        # output, err = nbexe.communicate()%0A        # check = nbexe.returncode%0A        # if check == 0:%0A        #     print(%22%5Cn ..... %7B0%7D Passed ..... %5Cn%22.format(nbname))%0A        #     print(%22   removing %7B0%7D.html%22.format(os.path.splitext(nbpath)%5B0%5D))%0A        #     subprocess.call(%5B%0A        #         %22rm%22, %22%7B0%7D.html%22.format(os.path.splitext(nbpath)%5B0%5D)%0A        #     %5D)%0A        # else:%0A        #     print(%22%5Cn %3C%3C%3C%3C%3C %7B0%7D FAILED %3E%3E%3E%3E%3E %5Cn%22.format(nbname))%0A        #     print(%22Captured Output: %5Cn%22)%0A        #     print(%22%7B%7D%22.format(err))%0A%0A        # self.assertTrue(check == 0)%0A%0A
     

add marineEM app to the py2Ignore in the tests