import datetime import os.path import tempfile import unittest import yaclog from tests.common import log, log_segments, log_text from yaclog.changelog import VersionEntry class TestParser(unittest.TestCase): @classmethod def setUpClass(cls): with tempfile.TemporaryDirectory() as td: cls.path = os.path.join(td, 'changelog.md') with open(cls.path, 'w') as fd: fd.write(log_text) cls.log = yaclog.read(cls.path) def test_path(self): """Test the log's path""" self.assertEqual(self.path, self.log.path) def test_preamble(self): """Test the preamble at the top of the file""" self.assertEqual(log.preamble, self.log.preamble) def test_links(self): """Test the links at the end of the file""" self.assertEqual({'fullversion': 'http://endless.horse', **log.links}, self.log.links) def test_versions(self): """Test the version headers""" for i in range(len(self.log.versions)): self.assertEqual(log.versions[i].name, self.log.versions[i].name) self.assertEqual(log.versions[i].link, self.log.versions[i].link) self.assertEqual(log.versions[i].date, self.log.versions[i].date) self.assertEqual(log.versions[i].tags, self.log.versions[i].tags) def test_entries(self): """Test the change entries""" self.assertEqual(log.versions[0].sections, self.log.versions[0].sections) class TestWriter(unittest.TestCase): @classmethod def setUpClass(cls): with tempfile.TemporaryDirectory() as td: cls.path = os.path.join(td, 'changelog.md') log.write(cls.path) with open(cls.path) as fd: cls.log_text = fd.read() cls.log_segments = [line.lstrip('\n') for line in cls.log_text.split('\n\n') if line] def test_preamble(self): """Test the header information at the top of the file""" self.assertEqual(log_segments[0:2], self.log_segments[0:2]) def test_links(self): """Test the links at the end of the file""" self.assertEqual( {'[fullversion]: http://endless.horse', '[id]: http://www.koalastothemax.com'}, set(self.log_segments[16:18])) def test_versions(self): """Test the version headers""" self.assertEqual('## [Tests]', self.log_segments[2]) self.assertEqual('## [FullVersion] - 1969-07-20 [TAG1] [TAG2]', self.log_segments[14]) self.assertEqual('## Long Version Name', self.log_segments[15]) def test_entries(self): """Test the change entries""" self.assertEqual(log_segments[3], self.log_segments[3]) self.assertEqual('### Bullet Points', self.log_segments[4]) self.assertEqual(log_segments[5], self.log_segments[5]) self.assertEqual('### Blocks', self.log_segments[6]) self.assertEqual(log_segments[7:14], self.log_segments[7:14]) class TestVersionEntry(unittest.TestCase): def test_header_name(self): """Test reading version names from headers""" headers = { 'short': ('## Test', 'Test'), 'with dash': ('## Test - ', 'Test'), 'multi word': ('## Very long version name 1.0.0', 'Very long version name 1.0.0'), 'with brackets': ('## [Test]', '[Test]'), } for c, t in headers.items(): h = t[0] with self.subTest(c, h=h): version = VersionEntry.from_header(h) self.assertEqual(version.name, t[1]) self.assertEqual(version.tags, []) self.assertIsNone(version.date) self.assertIsNone(version.link) self.assertIsNone(version.link_id) def test_header_tags(self): """Test reading version tags from headers""" headers = { 'no dash': ('## Test [Foo] [Bar]', 'Test', ['FOO', 'BAR']), 'with dash': ('## Test - [Foo] [Bar]', 'Test', ['FOO', 'BAR']), 'with brackets': ('## [Test] [Foo] [Bar]', '[Test]', ['FOO', 'BAR']), 'with brackets & dash': ('## [Test] - [Foo] [Bar]', '[Test]', ['FOO', 'BAR']), } for c, t in headers.items(): h = t[0] with self.subTest(c, h=h): version = VersionEntry.from_header(h) self.assertEqual(version.name, t[1]) self.assertEqual(version.tags, t[2]) self.assertIsNone(version.date) self.assertIsNone(version.link) self.assertIsNone(version.link_id) def test_header_date(self): """Test reading version dates from headers""" headers = { 'no dash': ('## Test 1961-04-12', 'Test', datetime.date.fromisoformat('1961-04-12'), []), 'with dash': ('## Test 1969-07-20', 'Test', datetime.date.fromisoformat('1969-07-20'), []), 'two dates': ('## 1981-07-20 1988-11-15', '1981-07-20', datetime.date.fromisoformat('1988-11-15'), []), 'single date': ('## 2020-05-30', '2020-05-30', None, []), 'with tags': ('## 1.0.0 - 2021-04-19 [Foo] [Bar]', '1.0.0', datetime.date.fromisoformat('2021-04-19'), ['FOO', 'BAR']), } for c, t in headers.items(): h = t[0] with self.subTest(c, h=h): version = VersionEntry.from_header(h) self.assertEqual(version.name, t[1]) self.assertEqual(version.date, t[2]) self.assertEqual(version.tags, t[3]) self.assertIsNone(version.link) self.assertIsNone(version.link_id) def test_header_noncompliant(self): """Test reading version that dont fit the schema, and should just be read as literals""" headers = { 'no space between tags': 'Test [Foo][Bar]', 'text at end': 'Test [Foo] [Bar] Test', 'invalid date': 'Test - 9999-99-99', } for c, h in headers.items(): with self.subTest(c, h=h): version = VersionEntry.from_header('## ' + h) self.assertEqual(version.name, h) self.assertEqual(version.tags, []) self.assertIsNone(version.date) self.assertIsNone(version.link) self.assertIsNone(version.link_id) if __name__ == '__main__': unittest.main()