#! /usr/bin/env python3 # $Id: test__init__.py 9877 2024-08-09 07:52:36Z aa-turner $ # Authors: Günter Milde , # David Goodger # Copyright: This module has been placed in the public domain. """ Test module for the docutils' __init__.py. """ from __future__ import annotations from pathlib import Path import sys import unittest if __name__ == '__main__': # prepend the "docutils root" to the Python library path # so we import the local `docutils` package. sys.path.insert(0, str(Path(__file__).resolve().parents[1])) import docutils import docutils.utils from docutils import VersionInfo _RELEASE_LEVEL_ABBREVIATIONS: dict[str, str] = { 'alpha': 'a', 'beta': 'b', 'candidate': 'rc', 'final': '', } def version_identifier(version_info: VersionInfo) -> str: """ Return a version identifier string built from `version_info`, a `docutils.VersionInfo` namedtuple instance or compatible tuple. If `version_info` is not provided, by default return a version identifier string based on `docutils.__version_info__` (i.e. the current Docutils version). """ if version_info.micro: micro = f'.{version_info.micro}' else: # 0 is omitted: micro = '' releaselevel = _RELEASE_LEVEL_ABBREVIATIONS[version_info.releaselevel] if version_info.serial: serial = version_info.serial else: # 0 is omitted: serial = '' if version_info.release: dev = '' else: dev = '.dev' version = (f'{version_info.major}.{version_info.minor}{micro}' f'{releaselevel}{serial}{dev}') return version class ApplicationErrorTests(unittest.TestCase): def test_message(self): err = docutils.ApplicationError('the message') self.assertEqual('the message', str(err)) def test_non_ASCII_message(self): err = docutils.ApplicationError('\u0169') self.assertEqual('\u0169', str(err)) class VersionInfoTests(unittest.TestCase): def test_VersionInfo(self): # arguments may use keywords self.assertEqual(VersionInfo(0, 1, 2, 'beta', 3, False), VersionInfo(major=0, minor=1, micro=2, releaselevel='beta', serial=3, release=False)) # check defaults: self.assertEqual(VersionInfo(), VersionInfo(0, 0, 0, releaselevel='final', serial=0, release=True)) def test_VersionInfo_value_check(self): # releaselevel must be one of ('alpha', 'beta', 'candidate', 'final') with self.assertRaises(ValueError): VersionInfo(0, 1, 0, 'gamma') # releaselevel 'final' must not be used with development versions with self.assertRaises(ValueError): VersionInfo(0, 1, releaselevel='final', release=False) # "serial" must be 0 for final releases' with self.assertRaises(ValueError): VersionInfo(0, 1, releaselevel='final', serial=1) def test__version_info__(self): """Ensure that the current __version_info__ is valid.""" releaselevels = ('alpha', 'beta', 'candidate', 'final') self.assertEqual(len(docutils.__version_info__), 6) self.assertEqual(type(docutils.__version_info__.major), int) self.assertEqual(type(docutils.__version_info__.minor), int) self.assertEqual(type(docutils.__version_info__.micro), int) self.assertTrue( docutils.__version_info__.releaselevel in releaselevels) self.assertEqual(type(docutils.__version_info__.serial), int) self.assertEqual(type(docutils.__version_info__.release), bool) def test__version__(self): """Test that __version__ is equivalent to __version_info__.""" self.assertEqual( version_identifier(docutils.__version_info__), docutils.__version__, f'{docutils.__version_info__} differs') def test_version_info_comparing(self): """Test comparing of __version_info__ instances.""" # Example development cycle: devcycle = ('0.1a.dev 0.1a 0.1a1.dev ' '0.1b.dev 0.1b 0.1b1.dev ' '0.1rc1.dev 0.1rc1 0.1rc2.dev ' '0.1 0.1.1b.dev 0.1.1b 0.1.1 ' '0.2b.dev 0.2b 0.2') # corresponding version_info values: versioninfos = [VersionInfo(0, 1, 0, 'alpha', 0, False), VersionInfo(0, 1, 0, 'alpha', 0, True), VersionInfo(0, 1, 0, 'alpha', 1, False), VersionInfo(0, 1, 0, 'beta', 0, False), VersionInfo(0, 1, 0, 'beta', 0, True), VersionInfo(0, 1, 0, 'beta', 1, False), VersionInfo(0, 1, 0, 'candidate', 1, False), VersionInfo(0, 1, 0, 'candidate', 1, True), VersionInfo(0, 1, 0, 'candidate', 2, False), VersionInfo(0, 1, 0, 'final', 0, True), VersionInfo(0, 1, 1, 'beta', 0, False), VersionInfo(0, 1, 1, 'beta', 0, True), VersionInfo(0, 1, 1, 'final', 0, True), VersionInfo(0, 2, 0, 'beta', 0, False), VersionInfo(0, 2, 0, 'beta', 0, True), VersionInfo(0, 2, 0, 'final', 0, True), ] # transform to version strings versions = [version_identifier(vinfo) for vinfo in versioninfos] # ensure version infos corresponding to the dev cycle are ascending self.assertEqual(versions, devcycle.split()) self.assertEqual(versioninfos, sorted(versioninfos)) def test_version_info_tuple_comparing(self): """Test comparing of __version_info__ instances to tuples.""" # {: } v01b = VersionInfo(0, 1, 0, 'beta', 0, True) v01 = VersionInfo(0, 1, 0, 'final', 0, True) v02b_dev = VersionInfo(0, 2, 0, 'beta', 0, False) # compare to ordinary tuples: self.assertTrue(v01b < (0, 2)) self.assertTrue((0, 2) > v01b) self.assertTrue(v01b < (0, 1)) self.assertTrue((0, 1) > v01b) self.assertTrue(v01 <= (0, 1)) self.assertTrue(v01 >= (0, 1)) self.assertTrue((0, 1) <= v01) self.assertTrue((0, 1) >= v01) self.assertTrue(v02b_dev > (0, 1)) self.assertTrue((0, 1) < v02b_dev) # Test for equality requires complete tuple, because __eg__() is # not called when comparing a namedtuple subclass to a tuple: self.assertTrue((0, 1, 0, 'final', 0, True) == v01) # self.assertTrue((0, 1) == v01) # fails # self.assertTrue(v01 == (0, 1)) # fails if __name__ == '__main__': unittest.main()