Revision: 4f9a34c5690c
Author: Janne Härkönen <[email protected]>
Date: Wed Jan 18 22:55:12 2012
Log: writer: better class and module names
rename modules:
serializer -> datafilewriter
writer -> filewriters
rename classes:
Serializer -> DataFileWriter
SerializationContext -> WriteConfiguration
Also update documentation and some parameter names
accordingly
http://code.google.com/p/robotframework/source/detail?r=4f9a34c5690c
Added:
/src/robot/writer/datafilewriter.py
/src/robot/writer/filewriters.py
/utest/writer/test_write_configuration.py
Deleted:
/src/robot/writer/serializer.py
/src/robot/writer/writer.py
/utest/writer/test_serialization_context.py
Modified:
/src/robot/parsing/model.py
/src/robot/writer/__init__.py
=======================================
--- /dev/null
+++ /src/robot/writer/datafilewriter.py Wed Jan 18 22:55:12 2012
@@ -0,0 +1,102 @@
+# Copyright 2008-2011 Nokia Siemens Networks Oyj
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+
+import os
+
+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 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
+ """
+ context = WriteConfiguration(datafile, **options)
+ FileWriter(context).write(datafile)
+ context.finish()
+
+
+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):
+ """
+ :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
+ omitted, value of `source` attribute of the given `datafile` is
+ used to construct a new file object.
+ :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.
+ """
+ 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):
+ 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)
+
+ 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()
=======================================
--- /dev/null
+++ /src/robot/writer/filewriters.py Wed Jan 18 22:55:12 2012
@@ -0,0 +1,150 @@
+# Copyright 2008-2011 Nokia Siemens Networks Oyj
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+
+try:
+ import csv
+except ImportError:
+ # csv module is missing from IronPython < 2.7.1
+ csv = None
+
+from robot import utils
+
+from .formatters import TsvFormatter, TxtFormatter, PipeFormatter,
HtmlFormatter
+from .htmltemplate import TEMPLATE_START, TEMPLATE_END
+
+
+def FileWriter(configuration):
+ """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`
+ """
+ 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)
+
+
+class _DataFileWriter(object):
+ _formatter = None
+
+ def __init__(self, configuration):
+ self._output = configuration.output
+ self._line_separator = configuration.line_separator
+
+ def write(self, datafile):
+ for table in datafile:
+ if table:
+ self._write_table(table)
+
+ def _write_table(self, table):
+ self._write_header(table)
+ self._write_rows(self._formatted_table(table))
+ self._write_empty_row()
+
+ def _write_header(self, table):
+ self._write_row(self._formatter.header_row(table))
+
+ def _formatted_table(self, table):
+ formatter = {'setting': self._formatter.setting_rows,
+ 'variable': self._formatter.variable_rows,
+ 'test case': self._formatter.test_rows,
+ 'keyword': self._formatter.keyword_rows}[table.type]
+ return formatter(table)
+
+ def _write_empty_row(self):
+ self._write_row(self._formatter.empty_row())
+
+ def _write_rows(self, rows):
+ for row in rows:
+ self._write_row(row)
+
+ def _encode(self, row):
+ return row.encode('UTF-8')
+
+
+class SpaceSeparatedTxtWriter(_DataFileWriter):
+ _separator = ' '*4
+ _formatter = TxtFormatter()
+
+ def _write_row(self, row):
+ line = self._separator.join(row) + self._line_separator
+ self._output.write(self._encode(line))
+
+
+class PipeSeparatedTxtWriter(_DataFileWriter):
+ _separator = ' | '
+ _formatter = PipeFormatter()
+
+ def _write_row(self, row):
+ row = self._separator.join(row)
+ if row:
+ row = '| ' + row + ' |'
+ self._output.write(self._encode(row + self._line_separator))
+
+
+class TsvFileWriter(_DataFileWriter):
+ _formatter = TsvFormatter()
+
+ def __init__(self, configuration):
+ if not csv:
+ raise RuntimeError('No csv module found. '
+ 'Writing tab separated format is not
possible.')
+ _DataFileWriter.__init__(self, configuration)
+ self._writer = csv.writer(configuration.output,
dialect='excel-tab',
+
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]
+
+
+class HtmlFileWriter(_DataFileWriter):
+ _formatter = HtmlFormatter()
+
+ def __init__(self, configuration):
+ _DataFileWriter.__init__(self, configuration)
+ self._name = configuration.datafile.name
+ self._writer = utils.HtmlWriter(configuration.output,
+ configuration.line_separator,
+ encoding='UTF-8')
+
+ def write(self, datafile):
+ self._writer.content(TEMPLATE_START % {'NAME': self._name},
+ escape=False)
+ _DataFileWriter.write(self, datafile)
+ self._writer.content(TEMPLATE_END, escape=False)
+
+ def _write_table(self, table):
+ self._writer.start('table', {'id': table.type.replace(' ', ''),
+ 'border': '1'})
+ _DataFileWriter._write_table(self, table)
+ self._writer.end('table')
+
+ def _write_row(self, row):
+ self._writer.start('tr')
+ for cell in row:
+ self._writer.element(cell.tag, cell.content, cell.attributes,
+ escape=False)
+ self._writer.end('tr')
=======================================
--- /dev/null
+++ /utest/writer/test_write_configuration.py Wed Jan 18 22:55:12 2012
@@ -0,0 +1,42 @@
+import unittest
+import os
+
+from robot.writer.datafilewriter import WriteConfiguration
+from robot.parsing.model import TestCaseFile
+from robot.utils.asserts import assert_equals
+
+HTML_SOURCE = os.path.abspath('foo.html')
+TXT_SOURCE= os.path.abspath('foo.txt')
+
+
+class TestOutput(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)
+
+ 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)
+
+
+class TestFormat(unittest.TestCase):
+
+ 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):
+ data = TestCaseFile(source=source)
+ ctx = WriteConfiguration(data, format=format, path=path)
+ assert_equals(ctx.format, expected)
=======================================
--- /src/robot/writer/serializer.py Tue Jan 17 06:08:32 2012
+++ /dev/null
@@ -1,103 +0,0 @@
-# Copyright 2008-2011 Nokia Siemens Networks Oyj
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# 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.
-
-import os
-import codecs
-
-from .writer import FileWriter
-
-
-class Serializer(object):
- """The Serializer object. It is used to serialize Robot Framework test
- data files.
- """
-
- def serialize(self, datafile, **options):
- """Serializes given `datafile` using `**options`.
-
- :param datafile: A robot.parsing.model.DataFile object to be
serialized
- :param options: A :py:class:`.SerializationContext` is initialized
based on these
- """
- context = SerializationContext(datafile, **options)
- FileWriter(context).write(datafile)
- context.finish()
-
-
-class SerializationContext(object):
- """The SerializationContext object. It holds needed information for
- serializing a test data file.
- """
-
- def __init__(self, datafile, path=None, format=None, output=None,
- recursive=False, pipe_separated=False,
- line_separator=os.linesep):
- """
- :param datafile: The datafile to be serialized.
- :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: Serialization format. If omitted, read from the
- extension of the `source` attribute of the given `datafile`.
- :param output: An open, file-like object used in serialization. If
- omitted, value of `source` attribute of the given `datafile` is
- used to construct a new file object.
- :param bool pipe_separated: Whether to use pipes as separator when
- serialization format is txt.
- :param str line_separator: Line separator used in serialization.
- """
- 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):
- 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)
-
- 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()
=======================================
--- /src/robot/writer/writer.py Tue Jan 17 05:07:13 2012
+++ /dev/null
@@ -1,148 +0,0 @@
-# Copyright 2008-2011 Nokia Siemens Networks Oyj
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# 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.
-
-try:
- import csv
-except ImportError:
- # csv module is missing from IronPython < 2.7.1
- csv = None
-
-from robot import utils
-
-from .formatters import TsvFormatter, TxtFormatter, PipeFormatter,
HtmlFormatter
-from .htmltemplate import TEMPLATE_START, TEMPLATE_END
-
-
-def FileWriter(serialization_context):
- """Creates and returns a FileWriter object.
-
- :param serialization_context: Type of returned
- FileWriter is determined based on `serialization_context.format`.
- Is also passed along to created writer for further configuration.
- :type serialization_context: :py:class:`SerializationContext`
- """
- Writer = {'tsv': TsvFileWriter,
- 'txt': TxtFileWriter,
- 'html': HtmlFileWriter}[serialization_context.format]
- return Writer(serialization_context)
-
-
-def TxtFileWriter(context):
- Writer = PipeSeparatedTxtWriter if context.pipe_separated else
SpaceSeparatedTxtWriter
- return Writer(context)
-
-
-class _DataFileWriter(object):
- _formatter = None
-
- def __init__(self, context):
- self._output = context.output
- self._line_separator = context.line_separator
-
- def write(self, datafile):
- for table in datafile:
- if table:
- self._write_table(table)
-
- def _write_table(self, table):
- self._write_header(table)
- self._write_rows(self._formatted_table(table))
- self._write_empty_row()
-
- def _formatted_table(self, table):
- formatter = {'setting': self._formatter.setting_rows,
- 'variable': self._formatter.variable_rows,
- 'test case': self._formatter.test_rows,
- 'keyword': self._formatter.keyword_rows}[table.type]
- return formatter(table)
-
- def _write_header(self, table):
- self._write_row(self._formatter.header_row(table))
-
- def _write_empty_row(self):
- self._write_row(self._formatter.empty_row())
-
- def _write_rows(self, rows):
- for row in rows:
- self._write_row(row)
-
- def _encode(self, row):
- return row.encode('UTF-8')
-
-
-class SpaceSeparatedTxtWriter(_DataFileWriter):
- _separator = ' '*4
- _formatter = TxtFormatter()
-
- def _write_row(self, row):
- line = self._separator.join(row) + self._line_separator
- self._output.write(self._encode(line))
-
-
-class PipeSeparatedTxtWriter(_DataFileWriter):
- _separator = ' | '
- _formatter = PipeFormatter()
-
- def _write_row(self, row):
- row = self._separator.join(row)
- if row:
- row = '| ' + row + ' |'
- self._output.write(self._encode(row + self._line_separator))
-
-
-class TsvFileWriter(_DataFileWriter):
- _formatter = TsvFormatter()
-
- def __init__(self, context):
- if not csv:
- raise RuntimeError('No csv module found. '
- 'Writing tab separated format is not
possible.')
- _DataFileWriter.__init__(self, context)
- self._writer = csv.writer(context.output, dialect='excel-tab',
- lineterminator=context.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]
-
-
-class HtmlFileWriter(_DataFileWriter):
- _formatter = HtmlFormatter()
-
- def __init__(self, context):
- _DataFileWriter.__init__(self, context)
- self._name = context.datafile.name
- self._writer = utils.HtmlWriter(context.output,
context.line_separator,
- encoding='UTF-8')
-
- def write(self, datafile):
- self._writer.content(TEMPLATE_START % {'NAME': self._name},
- escape=False)
- _DataFileWriter.write(self, datafile)
- self._writer.content(TEMPLATE_END, escape=False)
-
- def _write_table(self, table):
- self._writer.start('table', {'id': table.type.replace(' ', ''),
- 'border': '1'})
- _DataFileWriter._write_table(self, table)
- self._writer.end('table')
-
- def _write_row(self, row):
- self._writer.start('tr')
- for cell in row:
- self._writer.element(cell.tag, cell.content, cell.attributes,
- escape=False)
- self._writer.end('tr')
=======================================
--- /utest/writer/test_serialization_context.py Mon Dec 5 00:31:30 2011
+++ /dev/null
@@ -1,42 +0,0 @@
-import unittest
-import os
-
-from robot.writer.serializer import SerializationContext
-from robot.parsing.model import TestCaseFile
-from robot.utils.asserts import assert_equals
-
-HTML_SOURCE = os.path.abspath('foo.html')
-TXT_SOURCE= os.path.abspath('foo.txt')
-
-
-class TestOutput(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)
-
- 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 = SerializationContext(TestCaseFile(source=source), path=path,
format=format)
- assert_equals(ctx._get_source(), expected)
-
-
-class TestFormat(unittest.TestCase):
-
- 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):
- data = TestCaseFile(source=source)
- ctx = SerializationContext(data, format=format, path=path)
- assert_equals(ctx.format, expected)
=======================================
--- /src/robot/parsing/model.py Wed Jan 18 20:53:03 2012
+++ /src/robot/parsing/model.py Wed Jan 18 22:55:12 2012
@@ -19,7 +19,7 @@
from robot.variables import is_var
from robot.output import LOGGER
from robot import utils
-from robot.writer.serializer import Serializer
+from robot.writer import DataFileWriter
from settings import (Documentation, Fixture, Timeout, Tags, Metadata,
Library, Resource, Variables, Arguments, Return, Template, Comment)
@@ -94,16 +94,15 @@
% (path, table, message), level)
def save(self, **options):
- """Serializes this datafile.
-
- :param options: Configuration for serialization. These arguments
are
- passed to
- :py:class:`~robot.writer.serializer.SerializationContext` as
+ """Writes this datafile to disk.
+
+ :param options: Configuration for writing. These are passed to
+ :py:class:`~robot.writer.datafilewriter.WriteConfiguration` as
keyword arguments.
- See also :py:meth:`robot.writer.serializer.Serializer.serialize`
+ See
also :py:meth:`robot.writer.datafilewriter.DataFileWriter.write`
"""
- return Serializer().serialize(self, **options)
+ return DataFileWriter().write(self, **options)
class TestCaseFile(_TestData):
=======================================
--- /src/robot/writer/__init__.py Wed Nov 9 06:47:04 2011
+++ /src/robot/writer/__init__.py Wed Jan 18 22:55:12 2012
@@ -12,4 +12,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from serializer import Serializer
+from .datafilewriter import DataFileWriter