From 05c7b0a3aeccccc46c85ee0cbf93987e442d9023 2013-08-12 23:06:18
From: Brian E. Granger <ellisonbg@gmail.com>
Date: 2013-08-12 23:06:18
Subject: [PATCH] Merge pull request #3914 from jdfreder/trans_tests

nbconvert: Transformer tests
---

diff --git a/IPython/nbconvert/exporters/tests/test_exporter.py b/IPython/nbconvert/exporters/tests/test_exporter.py
index c65f150..2858dad 100644
--- a/IPython/nbconvert/exporters/tests/test_exporter.py
+++ b/IPython/nbconvert/exporters/tests/test_exporter.py
@@ -53,7 +53,7 @@ class TestExporter(ExportersTestsBase):
         exporter = self._make_exporter(config=config)
         (output, resources) = exporter.from_filename(self._get_notebook())
         assert resources is not None
-        assert 'outputs' in resources
+        assert isinstance(resources['outputs'], dict)
         assert len(resources['outputs']) > 0
 
 
@@ -65,7 +65,6 @@ class TestExporter(ExportersTestsBase):
         exporter = self._make_exporter(config=config)
         (output, resources) = exporter.from_filename(self._get_notebook())
         assert resources is not None
-        assert 'cheese' in resources
         assert resources['cheese'] == 'real'
 
 
@@ -77,7 +76,6 @@ class TestExporter(ExportersTestsBase):
         exporter = self._make_exporter(config=config)
         (output, resources) = exporter.from_filename(self._get_notebook())
         assert resources is not None
-        assert 'cheese' in resources
         assert resources['cheese'] == 'real'
 
 
@@ -89,7 +87,6 @@ class TestExporter(ExportersTestsBase):
         exporter = self._make_exporter(config=config)
         (output, resources) = exporter.from_filename(self._get_notebook())
         assert resources is not None
-        assert 'cheese' in resources
         assert resources['cheese'] == 'real'
 
 
@@ -101,7 +98,6 @@ class TestExporter(ExportersTestsBase):
         exporter.register_transformer(CheeseTransformer, enabled=True)
         (output, resources) = exporter.from_filename(self._get_notebook())
         assert resources is not None
-        assert 'cheese' in resources
         assert resources['cheese'] == 'real'
 
 
diff --git a/IPython/nbconvert/transformers/extractoutput.py b/IPython/nbconvert/transformers/extractoutput.py
index 5a0297b..d6a83ae 100755
--- a/IPython/nbconvert/transformers/extractoutput.py
+++ b/IPython/nbconvert/transformers/extractoutput.py
@@ -57,7 +57,7 @@ class ExtractOutputTransformer(Transformer):
         output_files_dir = resources.get('output_files_dir', None)
         
         #Make sure outputs key exists
-        if not 'outputs' in resources:
+        if not isinstance(resources['outputs'], dict):
             resources['outputs'] = {}
             
         #Loop through all of the outputs in the cell
@@ -65,11 +65,12 @@ class ExtractOutputTransformer(Transformer):
 
             #Get the output in data formats that the template is interested in.
             for out_type in self.display_data_priority:
-                if out.hasattr(out_type):
+                if out.hasattr(out_type): 
                     data = out[out_type]
 
                     #Binary files are base64-encoded, SVG is already XML
                     if out_type in ('png', 'jpg', 'jpeg', 'pdf'):
+
                         # data is b64-encoded as text (str, unicode)
                         # decodestring only accepts bytes
                         data = py3compat.cast_bytes(data)
diff --git a/IPython/nbconvert/transformers/revealhelp.py b/IPython/nbconvert/transformers/revealhelp.py
index 96d69f1..7e79f1f 100755
--- a/IPython/nbconvert/transformers/revealhelp.py
+++ b/IPython/nbconvert/transformers/revealhelp.py
@@ -54,7 +54,7 @@ class RevealHelpTransformer(Transformer):
                     worksheet.cells[index - 1].metadata.slide_helper = 'subslide_end'
 
 
-        if 'reveal' not in resources:
+        if not isinstance(resources['reveal'], dict):
             resources['reveal'] = {}
         resources['reveal']['url_prefix'] = self.url_prefix
 
diff --git a/IPython/nbconvert/transformers/sphinx.py b/IPython/nbconvert/transformers/sphinx.py
index b585818..12f02d2 100755
--- a/IPython/nbconvert/transformers/sphinx.py
+++ b/IPython/nbconvert/transformers/sphinx.py
@@ -127,7 +127,7 @@ class SphinxTransformer(Transformer):
         # TODO: Add versatile method of additional notebook metadata.  Include
         #       handling of multiple files.  For now use a temporay namespace,
         #       '_draft' to signify that this needs to change.
-        if not "sphinx" in resources:
+        if not isinstance(resources["sphinx"], dict):
             resources["sphinx"] = {}
 
         if self.interactive:
diff --git a/IPython/nbconvert/transformers/tests/__init__.py b/IPython/nbconvert/transformers/tests/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/IPython/nbconvert/transformers/tests/__init__.py
diff --git a/IPython/nbconvert/transformers/tests/base.py b/IPython/nbconvert/transformers/tests/base.py
new file mode 100644
index 0000000..56fb249
--- /dev/null
+++ b/IPython/nbconvert/transformers/tests/base.py
@@ -0,0 +1,53 @@
+"""
+Module with utility functions for transformer tests
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2013, the IPython Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+from IPython.nbformat import current as nbformat
+
+from ...tests.base import TestsBase
+from ...exporters.exporter import ResourcesDict
+
+#-----------------------------------------------------------------------------
+# Class
+#-----------------------------------------------------------------------------
+
+class TransformerTestsBase(TestsBase):
+    """Contains test functions transformer tests"""
+
+
+    def build_notebook(self):
+        """Build a notebook in memory for use with transformer tests"""
+
+        outputs = [nbformat.new_output(output_type="stream", stream="stdout", output_text="a"),
+                   nbformat.new_output(output_type="text", output_text="b"),
+                   nbformat.new_output(output_type="stream", stream="stdout", output_text="c"),
+                   nbformat.new_output(output_type="stream", stream="stdout", output_text="d"),
+                   nbformat.new_output(output_type="stream", stream="stderr", output_text="e"),
+                   nbformat.new_output(output_type="stream", stream="stderr", output_text="f"),
+                   nbformat.new_output(output_type="png", output_png=b'Zw==')] #g
+        
+        cells=[nbformat.new_code_cell(input="$ e $", prompt_number=1,outputs=outputs),
+               nbformat.new_text_cell('markdown', source="$ e $")]
+        worksheets = [nbformat.new_worksheet(name="worksheet1", cells=cells)]
+
+        return nbformat.new_notebook(name="notebook1", worksheets=worksheets)
+
+
+    def build_resources(self):
+        """Build an empty resources dictionary."""
+        
+        res = ResourcesDict()
+        res['metadata'] = ResourcesDict()
+        return res
\ No newline at end of file
diff --git a/IPython/nbconvert/transformers/tests/test_coalescestreams.py b/IPython/nbconvert/transformers/tests/test_coalescestreams.py
new file mode 100644
index 0000000..548d48f
--- /dev/null
+++ b/IPython/nbconvert/transformers/tests/test_coalescestreams.py
@@ -0,0 +1,38 @@
+"""
+Module with tests for the coalescestreams transformer
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2013, the IPython Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+from .base import TransformerTestsBase
+from ..coalescestreams import coalesce_streams
+
+
+#-----------------------------------------------------------------------------
+# Class
+#-----------------------------------------------------------------------------
+
+class TestCoalesceStreams(TransformerTestsBase):
+    """Contains test functions for coalescestreams.py"""
+
+    def test_coalesce_streams(self):
+        """coalesce_streams transformer output test"""
+        nb = self.build_notebook()
+        res = self.build_resources()
+        nb, res = coalesce_streams(nb, res)
+        outputs = nb.worksheets[0].cells[0].outputs
+        self.assertEqual(outputs[0].text, "a")
+        self.assertEqual(outputs[1].output_type, "text")
+        self.assertEqual(outputs[2].text, "cd")
+        self.assertEqual(outputs[3].text, "ef")
+    
\ No newline at end of file
diff --git a/IPython/nbconvert/transformers/tests/test_csshtmlheader.py b/IPython/nbconvert/transformers/tests/test_csshtmlheader.py
new file mode 100644
index 0000000..7b41a5e
--- /dev/null
+++ b/IPython/nbconvert/transformers/tests/test_csshtmlheader.py
@@ -0,0 +1,47 @@
+"""
+Module with tests for the csshtmlheader transformer
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2013, the IPython Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+from .base import TransformerTestsBase
+from ..csshtmlheader import CSSHTMLHeaderTransformer
+
+
+#-----------------------------------------------------------------------------
+# Class
+#-----------------------------------------------------------------------------
+
+class TestCSSHTMLHeader(TransformerTestsBase):
+    """Contains test functions for csshtmlheader.py"""
+
+
+    def build_transformer(self):
+        """Make an instance of a transformer"""
+        transformer = CSSHTMLHeaderTransformer()
+        transformer.enabled = True
+        return transformer
+
+
+    def test_constructor(self):
+        """Can a CSSHTMLHeaderTransformer be constructed?"""
+        self.build_transformer()
+    
+
+    def test_output(self):
+        """Test the output of the CSSHTMLHeaderTransformer"""
+        nb = self.build_notebook()
+        res = self.build_resources()
+        transformer = self.build_transformer()
+        nb, res = transformer(nb, res)
+        assert 'css' in res['inlining'] 
\ No newline at end of file
diff --git a/IPython/nbconvert/transformers/tests/test_extractoutput.py b/IPython/nbconvert/transformers/tests/test_extractoutput.py
new file mode 100644
index 0000000..1da1988
--- /dev/null
+++ b/IPython/nbconvert/transformers/tests/test_extractoutput.py
@@ -0,0 +1,62 @@
+"""
+Module with tests for the extractoutput transformer
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2013, the IPython Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+from .base import TransformerTestsBase
+from ..extractoutput import ExtractOutputTransformer
+
+
+#-----------------------------------------------------------------------------
+# Class
+#-----------------------------------------------------------------------------
+
+class TestExtractOutput(TransformerTestsBase):
+    """Contains test functions for extractoutput.py"""
+
+
+    def build_transformer(self):
+        """Make an instance of a transformer"""
+        transformer = ExtractOutputTransformer()
+        transformer.enabled = True
+        return transformer
+
+
+    def test_constructor(self):
+        """Can a ExtractOutputTransformer be constructed?"""
+        self.build_transformer()
+    
+
+    def test_output(self):
+        """Test the output of the ExtractOutputTransformer"""
+        nb = self.build_notebook()
+        res = self.build_resources()
+        transformer = self.build_transformer()
+        nb, res = transformer(nb, res)
+
+        # Check if text was extracted.
+        assert 'text_filename' in nb.worksheets[0].cells[0].outputs[1]
+        text_filename = nb.worksheets[0].cells[0].outputs[1]['text_filename']
+
+        # Check if png was extracted.
+        assert 'png_filename' in nb.worksheets[0].cells[0].outputs[6]
+        png_filename = nb.worksheets[0].cells[0].outputs[6]['png_filename']
+
+        # Verify text output
+        assert text_filename in res['outputs']
+        self.assertEqual(res['outputs'][text_filename], b'b')
+
+        # Verify png output
+        assert png_filename in res['outputs']
+        self.assertEqual(res['outputs'][png_filename], b'g')
diff --git a/IPython/nbconvert/transformers/tests/test_latex.py b/IPython/nbconvert/transformers/tests/test_latex.py
new file mode 100644
index 0000000..ab0b274
--- /dev/null
+++ b/IPython/nbconvert/transformers/tests/test_latex.py
@@ -0,0 +1,51 @@
+"""
+Module with tests for the latex transformer
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2013, the IPython Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+from .base import TransformerTestsBase
+from ..latex import LatexTransformer
+
+
+#-----------------------------------------------------------------------------
+# Class
+#-----------------------------------------------------------------------------
+
+class TestLatex(TransformerTestsBase):
+    """Contains test functions for latex.py"""
+
+
+    def build_transformer(self):
+        """Make an instance of a transformer"""
+        transformer = LatexTransformer()
+        transformer.enabled = True
+        return transformer
+
+    def test_constructor(self):
+        """Can a LatexTransformer be constructed?"""
+        self.build_transformer()
+        
+
+    def test_output(self):
+        """Test the output of the LatexTransformer"""
+        nb = self.build_notebook()
+        res = self.build_resources()
+        transformer = self.build_transformer()
+        nb, res = transformer(nb, res)
+
+        # Make sure the code cell wasn't modified.
+        self.assertEqual(nb.worksheets[0].cells[0].input, '$ e $')
+
+        # Verify that the markdown cell was processed.
+        self.assertEqual(nb.worksheets[0].cells[1].source, '$e$')
diff --git a/IPython/nbconvert/transformers/tests/test_revealhelp.py b/IPython/nbconvert/transformers/tests/test_revealhelp.py
new file mode 100644
index 0000000..126564e
--- /dev/null
+++ b/IPython/nbconvert/transformers/tests/test_revealhelp.py
@@ -0,0 +1,94 @@
+"""
+Module with tests for the revealhelp transformer
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2013, the IPython Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+from IPython.nbformat import current as nbformat
+
+from .base import TransformerTestsBase
+from ..revealhelp import RevealHelpTransformer
+
+
+#-----------------------------------------------------------------------------
+# Class
+#-----------------------------------------------------------------------------
+
+class Testrevealhelp(TransformerTestsBase):
+    """Contains test functions for revealhelp.py"""
+
+    def build_notebook(self):
+        """Build a reveal slides notebook in memory for use with tests.  
+        Overrides base in TransformerTestsBase"""
+
+        outputs = [nbformat.new_output(output_type="stream", stream="stdout", output_text="a")]
+        
+        slide_metadata = {'slideshow' : {'slide_type': 'slide'}}
+        subslide_metadata = {'slideshow' : {'slide_type': 'subslide'}}
+
+        cells=[nbformat.new_code_cell(input="", prompt_number=1, outputs=outputs),
+               nbformat.new_text_cell('markdown', source="", metadata=slide_metadata),
+               nbformat.new_code_cell(input="", prompt_number=2, outputs=outputs),
+               nbformat.new_text_cell('markdown', source="", metadata=slide_metadata),
+               nbformat.new_text_cell('markdown', source="", metadata=subslide_metadata)]
+        worksheets = [nbformat.new_worksheet(name="worksheet1", cells=cells)]
+
+        return nbformat.new_notebook(name="notebook1", worksheets=worksheets)
+
+
+    def build_transformer(self):
+        """Make an instance of a transformer"""
+        transformer = RevealHelpTransformer()
+        transformer.enabled = True
+        return transformer
+
+
+    def test_constructor(self):
+        """Can a RevealHelpTransformer be constructed?"""
+        self.build_transformer()
+    
+
+    def test_reveal_attribute(self):
+        """Make sure the reveal url_prefix resources is set"""
+        nb = self.build_notebook()
+        res = self.build_resources()
+        transformer = self.build_transformer()
+        nb, res = transformer(nb, res)
+        assert 'reveal' in res
+        assert  'url_prefix' in res['reveal']
+
+
+    def test_reveal_output(self):
+        """Make sure that the reveal transformer """
+        nb = self.build_notebook()
+        res = self.build_resources()
+        transformer = self.build_transformer()
+        nb, res = transformer(nb, res)
+        cells = nb.worksheets[0].cells
+        
+        # Make sure correct metadata tags are available on every cell.
+        for cell in cells:
+            assert 'slide_type' in cell.metadata
+            assert 'align_type' in cell.metadata
+
+        # Make sure slide end is only applied to the cells preceeding slide 
+        # cells.
+        assert 'slide_helper' not in cells[1].metadata
+
+        # Verify 'slide-end'
+        assert 'slide_helper' in cells[0].metadata
+        self.assertEqual(cells[0].metadata['slide_helper'], 'slide_end')
+        assert 'slide_helper' in cells[2].metadata
+        self.assertEqual(cells[2].metadata['slide_helper'], 'slide_end')
+        assert 'slide_helper' in cells[3].metadata
+        self.assertEqual(cells[3].metadata['slide_helper'], 'subslide_end')
diff --git a/IPython/nbconvert/transformers/tests/test_sphinx.py b/IPython/nbconvert/transformers/tests/test_sphinx.py
new file mode 100644
index 0000000..6c65578
--- /dev/null
+++ b/IPython/nbconvert/transformers/tests/test_sphinx.py
@@ -0,0 +1,57 @@
+"""
+Module with tests for the sphinx transformer
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2013, the IPython Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+from .base import TransformerTestsBase
+from ..sphinx import SphinxTransformer
+
+
+#-----------------------------------------------------------------------------
+# Class
+#-----------------------------------------------------------------------------
+
+class TestSphinx(TransformerTestsBase):
+    """Contains test functions for sphinx.py"""
+
+
+    def build_transformer(self):
+        """Make an instance of a transformer"""
+        transformer = SphinxTransformer()
+        transformer.enabled = True
+        return transformer
+
+
+    def test_constructor(self):
+        """Can a SphinxTransformer be constructed?"""
+        self.build_transformer()
+    
+
+    def test_resources(self):
+        """Make sure the SphinxTransformer adds the appropriate resources to the
+        resources dict."""
+        nb = self.build_notebook()
+        res = self.build_resources()
+        transformer = self.build_transformer()
+        nb, res = transformer(nb, res)
+        assert "author" in res['sphinx']
+        assert "version" in res['sphinx']
+        assert "release" in res['sphinx']
+        assert "date" in res['sphinx']
+        assert "chapterstyle" in res['sphinx']
+        assert "outputstyle" in res['sphinx']
+        assert "centeroutput" in res['sphinx']
+        assert "header" in res['sphinx']
+        assert "texinputs" in res['sphinx']
+        assert "pygment_definitions" in res['sphinx']
diff --git a/IPython/nbconvert/transformers/tests/test_svg2pdf.py b/IPython/nbconvert/transformers/tests/test_svg2pdf.py
new file mode 100644
index 0000000..3914b54
--- /dev/null
+++ b/IPython/nbconvert/transformers/tests/test_svg2pdf.py
@@ -0,0 +1,90 @@
+"""
+Module with tests for the svg2pdf transformer
+"""
+
+#-----------------------------------------------------------------------------
+# Copyright (c) 2013, the IPython Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+from IPython.testing import decorators as dec
+from IPython.nbformat import current as nbformat
+
+from .base import TransformerTestsBase
+from ..svg2pdf import SVG2PDFTransformer
+
+
+#-----------------------------------------------------------------------------
+# Class
+#-----------------------------------------------------------------------------
+
+class Testsvg2pdf(TransformerTestsBase):
+    """Contains test functions for svg2pdf.py"""
+
+    simple_svg = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   version="1.0"
+   x="0.00000000"
+   y="0.00000000"
+   width="500.00000"
+   height="500.00000"
+   id="svg2">
+  <defs
+     id="defs4" />
+  <g
+     id="layer1">
+    <rect
+       width="300.00000"
+       height="300.00000"
+       x="100.00000"
+       y="100.00000"
+       style="opacity:1.0000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:8.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000"
+       id="rect5719" />
+  </g>
+</svg>"""
+
+    def build_notebook(self):
+        """Build a reveal slides notebook in memory for use with tests.  
+        Overrides base in TransformerTestsBase"""
+
+        outputs = [nbformat.new_output(output_type="svg", output_svg=self.simple_svg)]
+        
+        slide_metadata = {'slideshow' : {'slide_type': 'slide'}}
+        subslide_metadata = {'slideshow' : {'slide_type': 'subslide'}}
+
+        cells=[nbformat.new_code_cell(input="", prompt_number=1, outputs=outputs)]
+        worksheets = [nbformat.new_worksheet(name="worksheet1", cells=cells)]
+
+        return nbformat.new_notebook(name="notebook1", worksheets=worksheets)
+
+
+    def build_transformer(self):
+        """Make an instance of a transformer"""
+        transformer = SVG2PDFTransformer()
+        transformer.enabled = True
+        return transformer
+
+
+    def test_constructor(self):
+        """Can a SVG2PDFTransformer be constructed?"""
+        self.build_transformer()
+
+
+    @dec.onlyif_cmds_exist('inkscape')
+    def test_output(self):
+        """Test the output of the SVG2PDFTransformer"""
+        nb = self.build_notebook()
+        res = self.build_resources()
+        transformer = self.build_transformer()
+        nb, res = transformer(nb, res)
+        assert 'svg' in nb.worksheets[0].cells[0].outputs[0]
diff --git a/IPython/nbconvert/writers/debug.py b/IPython/nbconvert/writers/debug.py
index 7a93ace..5c5ea43 100644
--- a/IPython/nbconvert/writers/debug.py
+++ b/IPython/nbconvert/writers/debug.py
@@ -33,7 +33,7 @@ class DebugWriter(WriterBase):
         See base for more...
         """
 
-        if 'outputs' in resources:
+        if isinstance(resources['outputs'], dict):
             print("outputs extracted from %s" % notebook_name)
             print('-' * 80)
             pprint(resources['outputs'], indent=2, width=70)