123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487 |
- # -*- coding: utf-8 -*-
- # tests/test_reference.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 references within manual page documents. """
- import sys
- import os
- import os.path
- import operator
- 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
- def setup_reference_instance(testcase, test_class=None, test_args=None):
- """ Set up a `Reference` instance. """
- if test_class is None:
- test_class = testcase.reference_class
- if test_args is None:
- test_args = testcase.test_args
- testcase.test_reference_instance = test_class(**test_args)
- class Reference_TestCase(unittest.TestCase):
- """ Test cases for class `Reference`. """
- reference_class = manpage.document.Reference
- scenarios = [
- ('simple', {
- 'test_args': {},
- 'expected_class': reference_class,
- }),
- ]
- def setUp(self):
- """ Set up test fixtures. """
- super().setUp()
- self.scenarios_by_name = dict(self.scenarios)
- def test_instantiate(self):
- """ An instance should be created. """
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- setup_reference_instance(self, test_args=scenario['test_args'])
- self.assertIsInstance(
- self.test_reference_instance,
- self.reference_class)
- def test_as_markup_not_implemented(self):
- """ Method `as_markup` should raise NotImplementedError. """
- scenario = self.scenarios_by_name['simple']
- instance = self.reference_class(**scenario['test_args'])
- with self.assertRaises(NotImplementedError):
- instance.as_markup()
- def test_comparison_tuple_not_implemented(self):
- """ Property `_comparison_tuple` should raise NotImplementedError. """
- scenario = self.scenarios_by_name['simple']
- instance = self.reference_class(**scenario['test_args'])
- with self.assertRaises(NotImplementedError):
- instance._comparison_tuple
- class Reference_comparison_TestCaseMixIn:
- """ Mix-in to add comparison test cases for a `Reference` class. """
- def test_comparisons_as_expected(self):
- """ Comparisons should be as expected. """
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- for (operator_name, operator_func) in (
- (name, getattr(operator, name))
- for name in scenario['expected_true']):
- with self.subTest(operator=operator_name):
- result = operator_func(
- scenario['instance_this'],
- scenario['instance_other'])
- self.assertTrue(result)
- for (operator_name, operator_func) in (
- (name, getattr(operator, name))
- for name in scenario['expected_false']):
- with self.subTest(operator=operator_name):
- result = operator_func(
- scenario['instance_this'],
- scenario['instance_other'])
- self.assertFalse(result)
- class DocumentReference_TestCase(unittest.TestCase):
- """ Test cases for class `DocumentReference`. """
- reference_class = manpage.document.DocumentReference
- def setUp(self):
- """ Set up test fixtures. """
- super().setUp()
- self.test_args = {
- 'name': "lorem",
- 'section': "99",
- }
- setup_reference_instance(self)
- def test_instantiate(self):
- """ An instance should be created. """
- self.assertIsInstance(
- self.test_reference_instance, self.reference_class)
- def test_has_specified_name(self):
- """ Should have `name` value specified. """
- self.assertEqual(
- self.test_reference_instance.name, self.test_args['name'])
- def test_has_specified_section(self):
- """ Should have `section` value specified. """
- self.assertEqual(
- self.test_reference_instance.section,
- self.test_args['section'])
- def test_text_representation_as_expected(self):
- """ Should have expected text representation. """
- expected_text = "{0.name} ({0.section})".format(
- self.test_reference_instance)
- self.assertEqual(
- str(self.test_reference_instance), expected_text)
- def test_programmer_representation_as_expected(self):
- """ Should have expected programmer representation. """
- class_name = self.reference_class.__name__
- expected_text = "{class_name}({name!r}, {section!r})".format(
- class_name=class_name,
- name=self.test_reference_instance.name,
- section=self.test_reference_instance.section)
- self.assertEqual(
- repr(self.test_reference_instance), expected_text)
- class DocumentReference_as_markup_TestCase(unittest.TestCase):
- """ Test cases for method `DocumentReference.as_markup`. """
- reference_class = manpage.document.DocumentReference
- scenarios = [
- ('simple', {
- 'test_args': {
- 'name': "lorem",
- 'section': "99",
- },
- 'expected_result': textwrap.dedent("""\
- .BR lorem (99)
- """),
- }),
- ('name-hyphenated', {
- 'test_args': {
- 'name': "lorem-ipsum",
- 'section': "99",
- },
- 'expected_result': textwrap.dedent("""\
- .BR lorem\\-ipsum (99)
- """),
- }),
- ]
- 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):
- setup_reference_instance(self, test_args=scenario['test_args'])
- expected_markup = textwrap.dedent("""\
- .BR {0[name]} ({0[section]})
- """).format(scenario['test_args'])
- result = self.test_reference_instance.as_markup()
- self.assertEqual(result, expected_markup)
- class DocumentReference_from_text_TestCase(unittest.TestCase):
- """ Test cases for method `DocumentReference.from_text`. """
- error_class = manpage.document.DocumentReference.ReferenceFormatError
- scenarios = [
- ('simple', {
- 'test_text': "lorem(99)",
- 'expected_instance': manpage.document.DocumentReference(
- "lorem", "99"),
- }),
- ('name-hyphenated', {
- 'test_text': "lorem-ipsum(99)",
- 'expected_instance': manpage.document.DocumentReference(
- "lorem-ipsum", "99"),
- }),
- ('section-contains-nondigit', {
- 'test_text': "lorem-ipsum(99xyz)",
- 'expected_instance': manpage.document.DocumentReference(
- "lorem-ipsum", "99xyz"),
- }),
- ('empty', {
- 'test_text': "",
- 'expected_error': error_class,
- }),
- ('name-only', {
- 'test_text': "lorem-ipsum",
- 'expected_error': error_class,
- }),
- ('section-empty', {
- 'test_text': "lorem-ipsum()",
- 'expected_error': error_class,
- }),
- ('section-starts-nondigit', {
- 'test_text': "lorem-ipsum(xyz99)",
- 'expected_error': error_class,
- }),
- ]
- def setUp(self):
- """ Set up test fixtures. """
- super().setUp()
- self.reference_class = manpage.document.DocumentReference
- def test_returns_expected_result(self):
- """ Should return expected instance for inputs. """
- for (scenario_name, scenario) in (
- (scenario_name, scenario)
- for (scenario_name, scenario) in self.scenarios
- if 'expected_instance' in scenario):
- with self.subTest(scenario=scenario_name):
- instance = self.reference_class.from_text(
- scenario['test_text'])
- self.assertEqual(instance, scenario['expected_instance'])
- def test_raises_expected_error(self):
- """ Should raise expected error for inputs. """
- for (scenario_name, scenario) in (
- (scenario_name, scenario)
- for (scenario_name, scenario) in self.scenarios
- if 'expected_error' in scenario):
- with self.subTest(scenario=scenario_name):
- with self.assertRaises(scenario['expected_error']):
- __ = self.reference_class.from_text(
- scenario['test_text'])
- class DocumentReference_comparison_TestCase(
- unittest.TestCase, Reference_comparison_TestCaseMixIn):
- """ Test cases for `DocumentReference` comparison methods. """
- reference_class = manpage.document.DocumentReference
- scenarios = [
- ('type-same,equal', {
- 'instance_this': reference_class("lorem", "5"),
- 'instance_other': reference_class("lorem", "5"),
- 'expected_true': ['eq', 'le', 'ge'],
- 'expected_false': ['ne', 'lt', 'gt'],
- }),
- ('type-same,name-less', {
- 'instance_this': reference_class("lorem", "5"),
- 'instance_other': reference_class("nullam", "5"),
- 'expected_true': ['ne', 'le', 'lt'],
- 'expected_false': ['eq', 'ge', 'gt'],
- }),
- ('type-same,name-greater', {
- 'instance_this': reference_class("lorem", "5"),
- 'instance_other': reference_class("dolor", "5"),
- 'expected_true': ['ne', 'ge', 'gt'],
- 'expected_false': ['eq', 'le', 'lt'],
- }),
- ('type-same,section-less', {
- 'instance_this': reference_class("lorem", "5"),
- 'instance_other': reference_class("lorem", "8"),
- 'expected_true': ['ne', 'le', 'lt'],
- 'expected_false': ['eq', 'ge', 'gt'],
- }),
- ('type-same,section-greater', {
- 'instance_this': reference_class("lorem", "5"),
- 'instance_other': reference_class("lorem", "1"),
- 'expected_true': ['ne', 'ge', 'gt'],
- 'expected_false': ['eq', 'le', 'lt'],
- }),
- ('type-different,other-external', {
- 'instance_this': reference_class("lorem", "5"),
- 'instance_other': manpage.document.ExternalReference(
- "Alpha Beta"),
- 'expected_true': ['ne', 'le', 'lt'],
- 'expected_false': ['eq', 'ge', 'gt'],
- }),
- ('type-different,other-not-reference', {
- 'instance_this': reference_class("lorem", "5"),
- 'instance_other': (5, 5),
- 'expected_true': ['ne', 'ge', 'gt'],
- 'expected_false': ['eq', 'le', 'lt'],
- }),
- ]
- class ExternalReference_TestCase(unittest.TestCase):
- """ Test cases for class `ExternalReference`. """
- reference_class = manpage.document.ExternalReference
- scenarios = [
- ('simple', {
- 'test_args': {
- 'title': "Lorem Ipsum",
- 'url': "spam://example.org/beans/",
- },
- 'expected_text_representation': (
- "Lorem Ipsum <URL:spam://example.org/beans/>"),
- 'expected_programmer_representation': (
- "ExternalReference"
- "('Lorem Ipsum', 'spam://example.org/beans/')"),
- }),
- ('url-missing', {
- 'test_args': {
- 'title': "Lorem Ipsum",
- 'url': None,
- },
- 'expected_text_representation': "Lorem Ipsum",
- 'expected_programmer_representation': (
- "ExternalReference('Lorem Ipsum', None)"),
- }),
- ]
- def setUp(self):
- """ Set up test fixtures. """
- super().setUp()
- simple_scenario = dict(self.scenarios)['simple']
- self.test_args = simple_scenario['test_args']
- setup_reference_instance(self)
- def test_instantiate(self):
- """ An instance should be created. """
- self.assertIsInstance(
- self.test_reference_instance, self.reference_class)
- def test_has_specified_title(self):
- """ Should have `title` value specified. """
- self.assertEqual(
- self.test_reference_instance.title, self.test_args['title'])
- def test_has_specified_url(self):
- """ Should have `url` value specified. """
- self.assertEqual(
- self.test_reference_instance.url, self.test_args['url'])
- def test_text_representation_as_expected(self):
- """ Should have expected text representation. """
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- instance = self.reference_class(
- **scenario['test_args'])
- self.assertEqual(
- str(instance),
- scenario['expected_text_representation'])
- def test_programmer_representation_as_expected(self):
- """ Should have expected programmer representation. """
- for (scenario_name, scenario) in self.scenarios:
- with self.subTest(scenario=scenario_name):
- instance = self.reference_class(
- **scenario['test_args'])
- self.assertEqual(
- repr(instance),
- scenario['expected_programmer_representation'])
- class ExternalReference_as_markup_TestCase(unittest.TestCase):
- """ Test cases for method `DocumentReference.as_markup`. """
- reference_class = manpage.document.ExternalReference
- scenarios = [
- ('simple', {
- 'test_args': {
- 'title': "Lorem Ipsum",
- 'url': "spam://example.org/beans/",
- },
- 'expected_result': textwrap.dedent("""\
- .UR spam://example.org/beans/
- Lorem Ipsum
- .UE
- """),
- }),
- ('url-missing', {
- 'test_args': {
- 'title': "Lorem Ipsum",
- 'url': None,
- },
- 'expected_result': textwrap.dedent("""\
- Lorem Ipsum
- """),
- }),
- ]
- 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):
- setup_reference_instance(self, test_args=scenario['test_args'])
- result = self.test_reference_instance.as_markup()
- self.assertEqual(result, scenario['expected_result'])
- class ExternalReference_comparison_TestCase(
- unittest.TestCase, Reference_comparison_TestCaseMixIn):
- """ Test cases for `ExternalReference` comparison methods. """
- reference_class = manpage.document.ExternalReference
- scenarios = [
- ('type-same,equal', {
- 'instance_this': reference_class("Lorem", "spam"),
- 'instance_other': reference_class("Lorem", "spam"),
- 'expected_true': ['eq', 'le', 'ge'],
- 'expected_false': ['ne', 'lt', 'gt'],
- }),
- ('type-same,title-less', {
- 'instance_this': reference_class("Lorem", "spam"),
- 'instance_other': reference_class("Nullam", "spam"),
- 'expected_true': ['ne', 'le', 'lt'],
- 'expected_false': ['eq', 'ge', 'gt'],
- }),
- ('type-same,title-greater', {
- 'instance_this': reference_class("Lorem", "spam"),
- 'instance_other': reference_class("Dolor", "spam"),
- 'expected_true': ['ne', 'ge', 'gt'],
- 'expected_false': ['eq', 'le', 'lt'],
- }),
- ('type-same,url-less', {
- 'instance_this': reference_class("Lorem", "spam"),
- 'instance_other': reference_class("Lorem", "xyzzy"),
- 'expected_true': ['ne', 'le', 'lt'],
- 'expected_false': ['eq', 'ge', 'gt'],
- }),
- ('type-same,section-greater', {
- 'instance_this': reference_class("Lorem", "spam"),
- 'instance_other': reference_class("Lorem", "beans"),
- 'expected_true': ['ne', 'ge', 'gt'],
- 'expected_false': ['eq', 'le', 'lt'],
- }),
- ('type-different,other-document', {
- 'instance_this': reference_class("Lorem", "spam"),
- 'instance_other': manpage.document.DocumentReference.from_text(
- "nullam(8)"),
- 'expected_true': ['ne', 'ge', 'gt'],
- 'expected_false': ['eq', 'le', 'lt'],
- }),
- ('type-different,other-not-reference', {
- 'instance_this': reference_class("Lorem", "spam"),
- 'instance_other': (5, 5),
- 'expected_true': ['ne', 'ge', 'gt'],
- 'expected_false': ['eq', 'le', 'lt'],
- }),
- ]
- # 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 :
|