2 new revisions:

Revision: 6b6bc12b552e
Author:   Robot Framework Developers <[email protected]>
Date:     Tue Jan 24 20:55:20 2012
Log:      datafilewriter: cleanup based on code review...
http://code.google.com/p/robotframework/source/detail?r=6b6bc12b552e

Revision: 4e31ecbd8594
Author:   Robot Framework Developers <[email protected]>
Date:     Tue Jan 24 20:55:42 2012
Log:      filewriters: cleanup
http://code.google.com/p/robotframework/source/detail?r=4e31ecbd8594

==============================================================================
Revision: 6b6bc12b552e
Author:   Robot Framework Developers <[email protected]>
Date:     Tue Jan 24 20:55:20 2012
Log:      datafilewriter: cleanup based on code review

1) Rename WriteConfiguraition -> WritingContext
2) Remove unnecessary path argument from WritingContext
3) Make WritingContext a context manager
4) Validate given format, raise DataError if not valid
5) Added valid formats as attributes to WritingContext
http://code.google.com/p/robotframework/source/detail?r=6b6bc12b552e

Modified:
 /src/robot/parsing/model.py
 /src/robot/writer/datafilewriter.py
 /utest/writer/test_write_configuration.py

=======================================
--- /src/robot/parsing/model.py Wed Jan 18 22:55:12 2012
+++ /src/robot/parsing/model.py Tue Jan 24 20:55:20 2012
@@ -102,7 +102,7 @@

See also :py:meth:`robot.writer.datafilewriter.DataFileWriter.write`
         """
-        return DataFileWriter().write(self, **options)
+        return DataFileWriter(**options).write(self)


 class TestCaseFile(_TestData):
=======================================
--- /src/robot/writer/datafilewriter.py Fri Jan 20 03:06:10 2012
+++ /src/robot/writer/datafilewriter.py Tue Jan 24 20:55:20 2012
@@ -12,43 +12,44 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.

+from __future__ import with_statement
 import os

+from robot.errors import DataError
 from .filewriters import FileWriter


 class DataFileWriter(object):
- """The DataFileWriter object. It is used to write parsed Robot Framework
-    test data file objects back to disk.
-    """
-
-    def write(self, datafile, **options):
+ """Writes parsed Robot Framework test data file objects back to disk."""
+
+    def __init__(self, **options):
+ """:param options: used to create a :py:class:`.WriteConfiguration`."""
+        self._options = options
+
+    def write(self, datafile):
         """Writes given `datafile` using `**options`.

:param datafile: A robot.parsing.model.DataFile object to be written - :param options: A :py:class:`.WriteConfiguration` is created with these
         """
-        configuration = WriteConfiguration(datafile, **options)
-        FileWriter(configuration).write(datafile)
-        configuration.finish()
+        with WritingContext(datafile, **self._options) as ctx:
+            FileWriter(ctx).write(datafile)


-class WriteConfiguration(object):
-    """The WriteConfiguration object. It contains configuration used in
-    writing a test data file to disk.
-    """
-
-    def __init__(self, datafile, path=None, format=None, output=None,
-                 recursive=False, pipe_separated=False,
-                 line_separator=os.linesep):
+class WritingContext(object):
+    """Contains configuration used in writing a test data file to disk."""
+    encoding = 'UTF-8'
+    txt_format = 'txt'
+    html_format = 'html'
+    tsv_format = 'tsv'
+    _formats = [txt_format, html_format, tsv_format]
+
+    def __init__(self, datafile, format='', output=None,
+                 pipe_separated=False, line_separator=os.linesep):
         """
         :param datafile: The datafile to be written.
         :type datafile: :py:class:`~robot.parsing.model.TestCaseFile`,
             :py:class:`~robot.parsing.model.ResourceFile`,
             :py:class:`~robot.parsing.model.TestDataDirectory`
- :param str path: Output file name. If omitted, basename of the `source`
-            attribute of the given `datafile` is used. If `path` contains
-            extension, it overrides the value of `format` option.
         :param str format: Output file format. If omitted, read from the
             extension of the `source` attribute of the given `datafile`.
         :param output: An open, file-like object used in writing. If
@@ -57,46 +58,50 @@
         :param bool pipe_separated: Whether to use pipes as separator when
             output file format is txt.
         :param str line_separator: Line separator used in output files.
+
+ If `output` is not given, an output file is created based on the source
+        of the given datafile and value of `format`. Examples:
+
+            WriteConfiguration(datafile, output=StringIO) ->
+               Output written in the StringIO instance using format of
+              `datafile.source`
+            WriteConfiguration(datafile, format='html') ->
+               Output file is created from `datafile.source` by stripping
+               extension and replacing it with `html`.
         """
         self.datafile = datafile
-        self.recursive = recursive
         self.pipe_separated = pipe_separated
         self.line_separator = line_separator
         self._given_output = output
-        self._path = path
-        self._format = format
-        self._output = output
-
-    @property
-    def output(self):
-        if not self._output:
-            self._output = open(self._get_source(), 'wb')
-        return self._output
-
-    @property
-    def format(self):
- return self._format_from_path() or self._format or self._format_from_file()
-
-    def finish(self):
+ self.format = self._validate_format(format) or self._format_from_file()
+        self.output = output
+
+    def __enter__(self):
+        if not self.output:
+            self.output = open(self._output_path(), 'wb')
+        return self
+
+    def __exit__(self, *exc_info):
         if self._given_output is None:
-            self._output.close()
-
-    def _get_source(self):
-        return self._path or '%s.%s' % (self._basename(), self.format)
-
-    def _basename(self):
-        return os.path.splitext(self._source_from_file())[0]
-
-    def _source_from_file(self):
-        return getattr(self.datafile, 'initfile', self.datafile.source)
-
-    def _format_from_path(self):
-        if not self._path:
-            return ''
-        return self._format_from_extension(self._path)
+            self.output.close()
+
+    def _validate_format(self, format):
+        format = format.lower()
+        if format and format not in self._formats:
+            raise DataError('Invalid format: %s' % format)
+        return format

     def _format_from_file(self):
         return self._format_from_extension(self._source_from_file())

     def _format_from_extension(self, path):
         return os.path.splitext(path)[1][1:].lower()
+
+    def _output_path(self):
+        return  '%s.%s' % (self._base_name(), self.format)
+
+    def _base_name(self):
+        return os.path.splitext(self._source_from_file())[0]
+
+    def _source_from_file(self):
+        return getattr(self.datafile, 'initfile', self.datafile.source)
=======================================
--- /utest/writer/test_write_configuration.py   Wed Jan 18 22:55:12 2012
+++ /utest/writer/test_write_configuration.py   Tue Jan 24 20:55:20 2012
@@ -1,28 +1,26 @@
 import unittest
 import os

-from robot.writer.datafilewriter import WriteConfiguration
+from robot import DataError
+from robot.writer.datafilewriter import WritingContext
 from robot.parsing.model import TestCaseFile
-from robot.utils.asserts import assert_equals
+from robot.utils.asserts import assert_equals, assert_raises

 HTML_SOURCE = os.path.abspath('foo.html')
 TXT_SOURCE= os.path.abspath('foo.txt')


-class TestOutput(unittest.TestCase):
+class TestOutputFile(unittest.TestCase):

     def test_source_file_is_used_by_default(self):
-        self._assert_source(HTML_SOURCE, source=HTML_SOURCE)
-
-    def test_given_path_override_source(self):
- self._assert_source(TXT_SOURCE, source=HTML_SOURCE, path=TXT_SOURCE)
+        self._assert_output_file(HTML_SOURCE, source=HTML_SOURCE)

     def test_given_format_overrides_source_extension(self):
-        self._assert_source(TXT_SOURCE, HTML_SOURCE, format='txt')
-
- def _assert_source(self, expected, source=None, path=None, format=None): - ctx = WriteConfiguration(TestCaseFile(source=source), path=path, format=format)
-        assert_equals(ctx._get_source(), expected)
+        self._assert_output_file(TXT_SOURCE, HTML_SOURCE, format='txt')
+
+    def _assert_output_file(self, expected, source=None, format=''):
+        ctx = WritingContext(TestCaseFile(source=source), format=format)
+        assert_equals(ctx._output_path()  , expected)


 class TestFormat(unittest.TestCase):
@@ -30,13 +28,13 @@
     def test_format_from_source_file_is_used_by_default(self):
         self._assert_format('html', source=HTML_SOURCE)

-    def test_extension_in_path_override_format(self):
-        self._assert_format('txt', format='html', path=TXT_SOURCE)
-
-    def test_extension_in_given_path_override_extension_in_source(self):
-        self._assert_format('txt', source=HTML_SOURCE, path=TXT_SOURCE)
-
- def _assert_format(self, expected, source=None, format=None, path=None):
+    def test_explicit_format_overrides_default(self):
+        self._assert_format('txt', source=HTML_SOURCE, format='txt')
+
+    def test_creating_with_invalid_format_fails(self):
+ assert_raises(DataError, WritingContext, datafile=None, format='inv')
+
+    def _assert_format(self, expected, source, format=''):
         data = TestCaseFile(source=source)
-        ctx = WriteConfiguration(data, format=format, path=path)
+        ctx = WritingContext(data, format=format)
         assert_equals(ctx.format, expected)

==============================================================================
Revision: 4e31ecbd8594
Author:   Robot Framework Developers <[email protected]>
Date:     Tue Jan 24 20:55:42 2012
Log:      filewriters: cleanup
http://code.google.com/p/robotframework/source/detail?r=4e31ecbd8594

Modified:
 /src/robot/writer/filewriters.py

=======================================
--- /src/robot/writer/filewriters.py    Fri Jan 20 04:29:42 2012
+++ /src/robot/writer/filewriters.py    Tue Jan 24 20:55:42 2012
@@ -11,7 +11,6 @@
 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
-from robot.writer.htmlformatter import HtmlFormatter

 try:
     import csv
@@ -22,35 +21,34 @@
 from robot import utils

 from .formatters import TsvFormatter, TxtFormatter, PipeFormatter
+from .htmlformatter import HtmlFormatter
 from .htmltemplate import TEMPLATE_START, TEMPLATE_END


-def FileWriter(configuration):
+def FileWriter(context):
     """Creates and returns a FileWriter object.

- :param configuration: Type of returned FileWriter is determined based on
-        `configuration.format`. `configuration` is also passed to created
-        writer.
-    :type configuration: :py:class:`WriteConfiguration`
+    :param context: Type of returned FileWriter is determined based on
+        `context.format`. `context` is also passed to created writer.
+    :type context: :py:class:`WritingContext`
     """
-    writer_class = {'tsv': TsvFileWriter,
-                    'txt': TxtFileWriter,
-                    'html': HtmlFileWriter}[configuration.format]
-    return writer_class(configuration)
-
-
-def TxtFileWriter(configuration):
-    writer_class = PipeSeparatedTxtWriter if configuration.pipe_separated \
-            else SpaceSeparatedTxtWriter
-    return writer_class(configuration)
+    if context.format == context.html_format:
+        return HtmlFileWriter(context)
+    if context.format == context.tsv_format:
+        return TsvFileWriter(context)
+    if context.pipe_separated:
+        return PipeSeparatedTxtWriter(context)
+    return SpaceSeparatedTxtWriter(context)


 class _DataFileWriter(object):
     _formatter = None
+    _write_row = NotImplemented

     def __init__(self, configuration):
         self._output = configuration.output
         self._line_separator = configuration.line_separator
+        self._encoding = configuration.encoding

     def write(self, datafile):
         for table in datafile:
@@ -80,7 +78,7 @@
             self._write_row(row)

     def _encode(self, row):
-        return row.encode('UTF-8')
+        return row.encode(self._encoding)


 class SpaceSeparatedTxtWriter(_DataFileWriter):
@@ -115,10 +113,7 @@
lineterminator=configuration.line_separator)

     def _write_row(self, row):
-        self._writer.writerow(self._encode(row))
-
-    def _encode(self, row):
-        return [c.encode('UTF-8') for c in row]
+        self._writer.writerow([self._encode(c) for c in row])


 class HtmlFileWriter(_DataFileWriter):
@@ -129,7 +124,7 @@
         self._name = configuration.datafile.name
         self._writer = utils.HtmlWriter(configuration.output,
                                         configuration.line_separator,
-                                        encoding='UTF-8')
+                                        encoding=self._encoding)

     def write(self, datafile):
         self._writer.content(TEMPLATE_START % {'NAME': self._name},

Reply via email to