123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571 |
- # -*- coding: utf-8 -*-
- # tests/test_document.py
- # Part of ‘manpage’, a Python library for making Unix manual documents.
- #
- # Copyright © 2015–2016 Ben Finney <ben+python@benfinney.id.au>
- #
- # This is free software: see the grant of license at end of this file.
- """ Unit tests for manual page document behaviour. """
- import sys
- import os
- import os.path
- import collections
- import datetime
- import textwrap
- import unittest
- import unittest.mock
- __package__ = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
- __import__(__package__)
- sys.path.insert(1, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
- import manpage.document
- class NamedTuple_TestCaseMixIn:
- """ Mix-in class to add test cases for a `namedtuple` class. """
- def test_instantiate_with_positional_args(self):
- """ An instance should be created when positional args supplied. """
- args = self.test_args.values()
- instance = self.test_class(*args)
- self.assertIsInstance(instance, self.test_class)
- def test_instantiate_with_keyword_args(self):
- """ An instance should be created when keyword args supplied. """
- kwargs = self.test_args
- instance = self.test_class(**kwargs)
- self.assertIsInstance(instance, self.test_class)
- def test_instance_has_expected_items(self):
- """ The instance should have the expected items. """
- instance = self.test_class(**self.test_args)
- expected_items = list(self.test_args.values())
- instance_items = list(instance)
- self.assertEqual(instance_items, expected_items)
- def test_instance_has_expected_attributes(self):
- """ The instance should have the expected attributes. """
- instance = self.test_class(**self.test_args)
- expected_attributes = dict(self.test_args)
- for (name, expected_value) in expected_attributes.items():
- with self.subTest(attribute_name=name):
- attribute_value = getattr(instance, name)
- self.assertEqual(attribute_value, expected_value)
- class MetaData_TestCase(unittest.TestCase, NamedTuple_TestCaseMixIn):
- """ Test cases for class `MetaData`. """
- def setUp(self):
- """ Set up test fixtures. """
- super().setUp()
- self.test_class = manpage.document.MetaData
- self.test_args = collections.OrderedDict([
- ('name', "lorem"),
- ('whatis', "ipsum"),
- ('manual', "dolor"),
- ('section', "sit"),
- ('source', "amet"),
- ])
- def setup_metadata_instance(testcase):
- """ Set up a test `MetaData` instance. """
- testcase.test_metadata_instance = manpage.document.MetaData(
- "lorem", "ipsum", "dolor", "sit", "amet")
- def setup_document_instance(testcase, test_class=None, test_args=None):
- """ Set up a test `Document` instance. """
- if test_class is None:
- test_class = testcase.document_class
- if test_args is None:
- test_args = {}
- if 'metadata' not in test_args:
- setup_metadata_instance(testcase)
- test_args.update({
- 'metadata': testcase.test_metadata_instance,
- })
- testcase.test_document_instance = test_class(**test_args)
- class Document_content_sections_TestCaseMixIn:
- """ Mix-in class to add test cases for `Document.content_sections`. """
- def test_has_expected_content_sections(self):
- """ Should have expected content sections. """
- standard_section_titles = self.document_class.standard_section_titles
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- setup_document_instance(self)
- content_sections = self.test_document_instance.content_sections
- for section_title in standard_section_titles:
- with self.subTest(section_title):
- self.assertIn(section_title, content_sections)
- def test_content_sections_in_expected_sequence(self):
- """ Should have expected content sections. """
- standard_section_titles = self.document_class.standard_section_titles
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- setup_document_instance(self)
- content_sections = self.test_document_instance.content_sections
- self.assertEqual(
- list(content_sections.keys()),
- list(standard_section_titles))
- class Document_TestCase(
- unittest.TestCase, Document_content_sections_TestCaseMixIn):
- """ Test cases for class `Document`. """
- document_class = manpage.document.Document
- scenarios = [
- ('simple', {
- 'test_today_date': datetime.date(1234, 5, 6),
- 'expected_created_date': datetime.date(1234, 5, 6),
- }),
- ]
- def patch_date_today(self, scenario):
- """ Patch the `datetime.date.today` function for the scenario. """
- date_patcher = unittest.mock.patch.object(
- datetime, 'date', autospec=True)
- mock_date = date_patcher.start()
- self.addCleanup(date_patcher.stop)
- mock_date.today.return_value = scenario['test_today_date']
- def test_instantiate(self):
- """ An instance should be created. """
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- setup_document_instance(self)
- self.assertIsInstance(
- self.test_document_instance, self.document_class)
- def test_has_expected_metadata(self):
- """ Should have expected metadata. """
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- setup_document_instance(self)
- expected_metadata = self.test_metadata_instance
- self.assertEqual(
- self.test_document_instance.metadata,
- expected_metadata)
- def test_has_expected_date(self):
- """ Should have expected creation date. """
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- self.patch_date_today(scenario)
- setup_document_instance(self)
- self.assertEqual(
- self.test_document_instance.date,
- scenario['expected_created_date'])
- class Document_as_markup_TestCase(unittest.TestCase):
- """ Test cases for method `Document.as_markup`. """
- document_class = manpage.document.Document
- def setUp(self):
- """ Set up test fixtures. """
- super().setUp()
- setup_document_instance(self)
- self.patch_header()
- self.patch_editor_hints()
- def patch_header(self):
- """ Patch attributes of the header for this test case. """
- header_patcher = unittest.mock.patch.object(
- self.test_document_instance, 'header')
- mock_header = header_patcher.start()
- self.addCleanup(header_patcher.stop)
- mock_header.as_markup.return_value = "lorem ipsum dolor sit amet\n"
- def patch_editor_hints(self):
- """ Patch the `editor_hints` method for this test case. """
- editor_hints_patcher = unittest.mock.patch.object(
- manpage.document.GroffMarkup, 'editor_hints')
- mock_editor_hints = editor_hints_patcher.start()
- self.addCleanup(editor_hints_patcher.stop)
- mock_editor_hints.return_value = "vitae blandit eros\n"
- def make_expected_result(self):
- """ Make an expected result for this test case. """
- header = self.test_document_instance.header
- header_markup = header.as_markup.return_value
- content_sections = [
- section for section in
- self.test_document_instance.content_sections.values()
- if section is not None]
- content_markup = ".\n".join(
- section.as_markup() for section in content_sections)
- footer_markup = "\n".join([
- ".",
- manpage.document.GroffMarkup.editor_hints.return_value])
- result = "".join([header_markup, content_markup, footer_markup])
- return result
- def test_result_is_text(self):
- """ Result should be a text object. """
- result = self.test_document_instance.as_markup()
- self.assertIsInstance(result, type(u""))
- def test_returns_expected_markup(self):
- """ Result should be the expected markup text. """
- result = self.test_document_instance.as_markup()
- expected_result = self.make_expected_result()
- self.assertEqual(result, expected_result)
- class Document_insert_section_TestCase(unittest.TestCase):
- """ Test cases for method `Document.insert_section`. """
- document_class = manpage.document.Document
- scenarios = [
- ('index-first', {
- 'existing_section_titles': ["DOLOR", "SIT", "AMET"],
- 'test_args': {
- 'index': 0,
- 'section': manpage.document.DocumentSection("LOREM"),
- },
- 'expected_section_titles': ["LOREM", "DOLOR", "SIT", "AMET"],
- }),
- ('index-middle', {
- 'existing_section_titles': ["DOLOR", "SIT", "AMET"],
- 'test_args': {
- 'index': 2,
- 'section': manpage.document.DocumentSection("LOREM"),
- },
- 'expected_section_titles': ["DOLOR", "SIT", "LOREM", "AMET"],
- }),
- ('index-last', {
- 'existing_section_titles': ["DOLOR", "SIT", "AMET"],
- 'test_args': {
- 'index': 3,
- 'section': manpage.document.DocumentSection("LOREM"),
- },
- 'expected_section_titles': ["DOLOR", "SIT", "AMET", "LOREM"],
- }),
- ('index-end', {
- 'existing_section_titles': ["DOLOR", "SIT", "AMET"],
- 'test_args': {
- 'index': -1,
- 'section': manpage.document.DocumentSection("LOREM"),
- },
- 'expected_section_titles': ["DOLOR", "SIT", "LOREM", "AMET"],
- }),
- ]
- def setUp(self):
- """ Set up test fixtures. """
- super().setUp()
- setup_document_instance(self)
- def test_resulting_sections_in_expected_sequence(self):
- """ Resulting sections should be in expected sequence. """
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- test_sections = collections.OrderedDict(
- (title, manpage.document.DocumentSection(title))
- for title in scenario['existing_section_titles'])
- self.test_document_instance.content_sections = test_sections
- self.test_document_instance.insert_section(
- **scenario['test_args'])
- test_sections = self.test_document_instance.content_sections
- self.assertEqual(
- list(test_sections.keys()),
- scenario['expected_section_titles'])
- class DocumentHeader_TestCase(unittest.TestCase):
- """ Test cases for class `DocumentHeader`. """
- document_class = manpage.document.Document
- def setUp(self):
- """ Set up test fixtures. """
- super().setUp()
- setup_document_instance(self)
- def test_has_specified_document(self):
- """ Should have `document` value specified. """
- instance = manpage.document.DocumentHeader(
- self.test_document_instance)
- self.assertEqual(instance.document, self.test_document_instance)
- def test_has_metadata_from_document(self):
- """ Should have `metadata` value from document. """
- instance = manpage.document.DocumentHeader(
- self.test_document_instance)
- self.assertEqual(
- instance.metadata, self.test_document_instance.metadata)
- class DocumentHeader_title_markup_TestCase(unittest.TestCase):
- """ Test cases for method `DocumentHeader.title_markup`. """
- document_class = manpage.document.Document
- scenarios = [
- ('all fields', {
- 'metadata': manpage.document.MetaData(
- name="lorem", whatis=None,
- manual="dolor", section="sit", source="amet"),
- 'test_date': datetime.date(1234, 5, 6),
- 'expected_fields': manpage.document.TitleFields(
- "LOREM", "sit", "1234\\-05\\-06", "amet", "dolor"),
- }),
- ('missing manual', {
- 'metadata': manpage.document.MetaData(
- name="lorem", whatis=None,
- manual=None, section="sit", source="amet"),
- 'test_date': datetime.date(1234, 5, 6),
- 'expected_fields': manpage.document.TitleFields(
- "LOREM", "sit", "1234\\-05\\-06", "amet", None),
- }),
- ('missing source+manual', {
- 'metadata': manpage.document.MetaData(
- name="lorem", whatis=None,
- manual=None, section="sit", source=None),
- 'test_date': datetime.date(1234, 5, 6),
- 'expected_fields': manpage.document.TitleFields(
- "LOREM", "sit", "1234\\-05\\-06", None, None),
- }),
- ]
- def setUp(self):
- """ Set up test fixtures. """
- super().setUp()
- setup_document_instance(self)
- self.mock_title_command = unittest.mock.create_autospec(
- manpage.document.GroffMarkup.title_command,
- return_value=".TH example")
- title_command_patcher = unittest.mock.patch.object(
- manpage.document.GroffMarkup, 'title_command',
- new=self.mock_title_command)
- self.mock_title_command = title_command_patcher.start()
- self.addCleanup(title_command_patcher.stop)
- def test_calls_title_command_with_expected_fields(self):
- """ Should call `title_command` with expected fields. """
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- self.test_document_instance._created_date = scenario['test_date']
- self.test_document_instance.metadata = scenario['metadata']
- instance = manpage.document.DocumentHeader(
- self.test_document_instance)
- __ = instance.title_markup()
- self.mock_title_command.assert_called_with(
- scenario['expected_fields'])
- class DocumentHeader_as_markup_TestCase(unittest.TestCase):
- """ Test cases for method `DocumentHeader.as_markup`. """
- document_class = manpage.document.Document
- scenarios = [
- ('simple', {
- 'test_args': {
- 'encoding': "litora",
- },
- 'test_title_markup': "lorem ipsum dolor sit amet",
- 'expected_result': "lorem ipsum dolor sit amet",
- }),
- ]
- def setUp(self):
- """ Set up test fixtures. """
- super().setUp()
- setup_document_instance(self)
- title_markup_patcher = unittest.mock.patch.object(
- manpage.document.DocumentHeader, 'title_markup')
- title_markup_patcher.start()
- self.addCleanup(title_markup_patcher.stop)
- def test_returns_expected_result(self):
- """ Should return expected markup for inputs. """
- instance = manpage.document.DocumentHeader(self.test_document_instance)
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- instance.title_markup.return_value = scenario[
- 'test_title_markup']
- result = instance.as_markup(**scenario['test_args'])
- self.assertEqual(scenario['expected_result'], result)
- class DocumentSection_TestCase(unittest.TestCase):
- """ Test cases for class `DocumentSection`. """
- def setUp(self):
- """ Set up test fixtures. """
- super().setUp()
- self.test_args = {
- 'title': "LOREM IPSUM",
- 'body': textwrap.dedent("""\
- Dolor sit amet.
- """),
- }
- def test_has_specified_title(self):
- """ Should have `title` value specified. """
- instance = manpage.document.DocumentSection(**self.test_args)
- self.assertEqual(instance.title, self.test_args['title'])
- def test_has_specified_body(self):
- """ Should have `body` value specified. """
- instance = manpage.document.DocumentSection(**self.test_args)
- self.assertEqual(instance.body, self.test_args['body'])
- class DocumentSection_as_markup_TestCase(unittest.TestCase):
- """ Test cases for method `DocumentSection.as_markup`. """
- scenarios = [
- ('simple', {
- 'test_args': {
- 'title': "LOREM IPSUM",
- 'body': textwrap.dedent("""\
- Dolor sit amet.
- """),
- },
- 'expected_result': textwrap.dedent("""\
- .SH LOREM IPSUM
- Dolor sit amet.
- """),
- }),
- ('body-no-trailing-newline', {
- 'test_args': {
- 'title': "LOREM IPSUM",
- 'body': textwrap.dedent("""\
- Dolor sit amet."""),
- },
- 'expected_result': textwrap.dedent("""\
- .SH LOREM IPSUM
- Dolor sit amet.
- """),
- }),
- ('body-none', {
- 'test_args': {
- 'title': "LOREM IPSUM",
- 'body': None,
- },
- 'expected_result': textwrap.dedent("""\
- .SH LOREM IPSUM
- """),
- }),
- ]
- def setUp(self):
- """ Set up test fixtures. """
- super().setUp()
- title_markup_patcher = unittest.mock.patch.object(
- manpage.document.DocumentHeader, 'title_markup')
- title_markup_patcher.start()
- self.addCleanup(title_markup_patcher.stop)
- def test_returns_expected_result(self):
- """ Should return expected markup for inputs. """
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- test_args = scenario['test_args']
- instance = manpage.document.DocumentSection(**test_args)
- result = instance.as_markup()
- self.assertEqual(scenario['expected_result'], result)
- class CommandDocument_TestCase(
- unittest.TestCase, Document_content_sections_TestCaseMixIn):
- """ Test cases for class `CommandDocument`. """
- document_class = manpage.document.CommandDocument
- scenarios = [
- ('section-specified', {
- 'test_args': {
- 'metadata': manpage.document.MetaData(
- name="lorem", whatis="ipsum",
- manual="dolor", section="sit",
- source="amet"),
- },
- 'expected_metadata': manpage.document.MetaData(
- name="lorem", whatis="ipsum",
- manual="dolor", section="sit",
- source="amet"),
- }),
- ('section-default', {
- 'test_args': {
- 'metadata': manpage.document.MetaData(
- name="lorem", whatis="ipsum",
- manual="dolor", section=None,
- source="amet"),
- },
- 'expected_metadata': manpage.document.MetaData(
- name="lorem", whatis="ipsum",
- manual="dolor", section="1",
- source="amet"),
- }),
- ]
- def setUp(self):
- """ Set up test fixtures. """
- super().setUp()
- def test_instantiate(self):
- """ An instance should be created. """
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- test_args = scenario['test_args']
- setup_document_instance(self, test_args=scenario['test_args'])
- self.assertIsInstance(
- self.test_document_instance, self.document_class)
- def test_has_expected_metadata_value(self):
- """ The document `metadata` should have expected value. """
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- test_args = scenario['test_args']
- setup_document_instance(self, test_args=scenario['test_args'])
- self.assertEqual(
- self.test_document_instance.metadata,
- scenario['expected_metadata'])
- # This is free software: you may copy, modify, and/or distribute this work
- # under the terms of the GNU General Public License as published by the
- # Free Software Foundation; version 3 of that license or any later version.
- #
- # No warranty expressed or implied. See the file ‘LICENSE.GPL-3’ for details,
- # or view it online at <URL:https://www.gnu.org/licenses/gpl-3.0.html>.
- # Local variables:
- # coding: utf-8
- # mode: python
- # End:
- # vim: fileencoding=utf-8 filetype=python :
|