# -*- python; coding: utf-8 -*- # # gtk-doc - GTK DocBook documentation generator. # Copyright (C) 2018 Stefan Sauer # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # import logging import textwrap import unittest from lxml import etree from parameterized import parameterized from gtkdoc import mkhtml2 from gtkdoc.mkhtml2 import PreOrderIter class TestChunking(unittest.TestCase): # def setUp(self): # logging.basicConfig( # level=logging.INFO, # format='%(asctime)s:%(filename)s:%(funcName)s:%(lineno)d:%(levelname)s:%(message)s') def test_chunk_only_root_gives_single_chunk(self): root = etree.XML('') files = mkhtml2.chunk(root, 'test') self.assertEqual('book', files.name) self.assertEqual(0, len(files.descendants)) def test_chunk_single_chapter_gives_two_chunks(self): root = etree.XML('') files = mkhtml2.chunk(root, 'test') descendants = [f for f in files.descendants if f.anchor is None] logging.info('descendants : %s', str(descendants)) self.assertEqual(1, len(descendants)) def test_chunk_first_sect1_is_inlined(self): root = etree.XML('') files = mkhtml2.chunk(root, 'test') descendants = [f for f in files.descendants if f.anchor is None] logging.info('descendants : %s', str(descendants)) self.assertEqual(1, len(descendants)) def test_chunk_second_sect1_is_not_inlined(self): root = etree.XML('') files = mkhtml2.chunk(root, 'test') descendants = [f for f in files.descendants if f.anchor is None] logging.info('descendants : %s', str(descendants)) self.assertEqual(2, len(descendants)) class TestDataExtraction(unittest.TestCase): # def setUp(self): # logging.basicConfig( # level=logging.INFO, # format='%(asctime)s:%(filename)s:%(funcName)s:%(lineno)d:%(levelname)s:%(message)s') def chunk_db(self, xml): root = etree.XML(xml) files = mkhtml2.chunk(root, 'test') return [f for f in PreOrderIter(files) if f.anchor is None] def test_extract_ids(self): files = self.chunk_db('') links = {} mkhtml2.add_id_links_and_titles(files, links) self.assertIn('chap1', links) def test_extract_titles(self): files = self.chunk_db('Intro') links = {} mkhtml2.add_id_links_and_titles(files, links) self.assertIn('chap1', mkhtml2.titles) self.assertEqual('Intro', mkhtml2.titles['chap1']['title']) self.assertEqual('chapter', mkhtml2.titles['chap1']['tag']) def test_extract_glossaries(self): files = self.chunk_db(textwrap.dedent("""\ API Application Programming Interface """)) mkhtml2.build_glossary(files) self.assertIn('API', mkhtml2.glossary) self.assertEqual('Application Programming Interface', mkhtml2.glossary['API']) class TestDevhelp(unittest.TestCase): xml_minimal = textwrap.dedent("""\ Intro """) xml_basic = textwrap.dedent("""\ test Reference Manual The latest version of this documentation can be found on-line at online-site. Intro """) # TODO: need one with multiple conditions xml_full = textwrap.dedent("""\ test Reference Manual Reference GtkdocObject TESTER Library GtkdocObject class for gtk-doc unit test     Functions   Functions gtkdoc_object_new () Members GtkdocObjectClass parent; parent/ Types and Values enum GtkdocEnum GtkdocEnum Enum values for the GtkdocEnum type. Members GTKDOC_ENUM_V1 first GTKDOC_ENUM_V2 second Since: 0.5 """) # def setUp(self): # logging.basicConfig( # level=logging.INFO, # format='%(asctime)s:%(filename)s:%(funcName)s:%(lineno)d:%(levelname)s:%(message)s') def convert(self, xml): root = etree.XML(xml) files = mkhtml2.chunk(root, 'test') files = [f for f in PreOrderIter(files) if f.anchor is None] mkhtml2.add_id_links_and_titles(files, {}) return '\n'.join(mkhtml2.create_devhelp2_content('test', root, files)) def test_create_devhelp_has_minimal_structure(self): devhelp = self.convert(self.xml_minimal) self.assertIn('', devhelp) self.assertIn('', devhelp) def test_create_devhelp_with_refentry_has_keywords(self): devhelp = self.convert(self.xml_full) self.assertIn( '', devhelp) def test_create_devhelp_with_refesect3_has_member_keywords(self): devhelp = self.convert(self.xml_full) self.assertIn( '', devhelp) def test_create_devhelp_with_refesect3_has_constant_keywords(self): devhelp = self.convert(self.xml_full) self.assertIn( '', devhelp) class TestNavNodes(unittest.TestCase): # def setUp(self): # logging.basicConfig( # level=logging.INFO, # format='%(asctime)s:%(filename)s:%(funcName)s:%(lineno)d:%(levelname)s:%(message)s') def chunk_db(self, xml): root = etree.XML(xml) files = mkhtml2.chunk(root, 'test') return [f for f in PreOrderIter(files) if f.anchor is None] def test_nav_nodes_contains_home(self): files = self.chunk_db(textwrap.dedent("""\ """)) nav = mkhtml2.generate_nav_nodes(files, files[0]) self.assertEqual(1, len(nav)) self.assertIn('nav_home', nav) def test_nav_nodes_contains_up_and_prev(self): files = self.chunk_db(textwrap.dedent("""\ Intro """)) nav = mkhtml2.generate_nav_nodes(files, files[1]) self.assertEqual(3, len(nav)) self.assertIn('nav_up', nav) self.assertIn('nav_prev', nav) self.assertNotIn('nav_next', nav) def test_nav_nodes_contains_next(self): files = self.chunk_db(textwrap.dedent("""\ Intro Content """)) nav = mkhtml2.generate_nav_nodes(files, files[1]) self.assertEqual(4, len(nav)) self.assertIn('nav_next', nav) class TestConverter(unittest.TestCase): xml_book_beg = textwrap.dedent("""\ test Reference Manual """) xml_book_end = textwrap.dedent("""\ """) xml_book = '\n'.join([xml_book_beg, xml_book_end]) xml_book_preface = '\n'.join([ xml_book_beg, ' Intro', xml_book_end]) xml_book_chapter = '\n'.join([ xml_book_beg, ' Intro', xml_book_end]) xml_book_reference = '\n'.join([ xml_book_beg, ' Reference', xml_book_end]) xml_book_part_chapter = '\n'.join([ xml_book_beg, textwrap.dedent("""\ Overview Intro """), xml_book_end]) # 2 sections since the first one is not chunked xml_book_chapter_secton = '\n'.join([ xml_book_beg, textwrap.dedent("""\ Overview
Intro
getting started
"""), xml_book_end]) xml_book_chapter_sect1 = xml_book_chapter_secton.replace('section', 'sect1') xml_book_chapter_refentry_beg = '\n'.join([ xml_book_beg, textwrap.dedent("""\ Reference GtkdocObject """)]) xml_book_chapter_refentry_end = '\n'.join([ textwrap.dedent("""\ """), xml_book_end]) xml_book_chapter_refentry = '\n'.join([xml_book_chapter_refentry_beg, xml_book_chapter_refentry_end]) xml_book_index_empty = '\n'.join([ xml_book_beg, ' API Index', xml_book_end]) xml_book_index = '\n'.join([ xml_book_beg, textwrap.dedent("""\ API Index O """), xml_book_end]) xml_book_glossary_empty = '\n'.join([ xml_book_beg, ' Glossary', xml_book_end]) xml_book_glossary = '\n'.join([ xml_book_beg, textwrap.dedent("""\ Glossary A API Application Programming Interface """), xml_book_end]) # def setUp(self): # logging.basicConfig( # level=logging.INFO, # format='%(asctime)s:%(filename)s:%(funcName)s:%(lineno)d:%(levelname)s:%(message)s') def convert(self, xml, ix): root = etree.XML(xml) files = mkhtml2.chunk(root, 'test') nodes = [f for f in PreOrderIter(files) if f.anchor is None] return '\n'.join(mkhtml2.convert_content('test', nodes, nodes[ix], 'c')) @parameterized.expand([ ('book', (xml_book, 0)), ('preface', (xml_book_preface, 1)), ('reference', (xml_book_reference, 1)), ('chapter', (xml_book_chapter, 1)), ('part', (xml_book_part_chapter, 1)), ('section', (xml_book_chapter_secton, 2)), ('sect1', (xml_book_chapter_sect1, 2)), ('refentry', (xml_book_chapter_refentry, 2)), ('index', (xml_book_index, 1)), ('index_empty', (xml_book_index_empty, 1)), ('glossary', (xml_book_glossary, 1)), ('glossary_empty', (xml_book_glossary_empty, 1)), ]) def test_convert_produces_html(self, _, params): html = self.convert(params[0], params[1]) self.assertIn('', html) self.assertIn('', html) self.assertIn('', html) def test_convert_book_has_title(self): html = self.convert(self.xml_book, 0) self.assertIn('test Reference Manual', html) def test_refnav_includes_normal_refsect1(self): xml = '\n'.join([ self.xml_book_chapter_refentry_beg, textwrap.dedent("""\ Description """), self.xml_book_chapter_refentry_end]) html = self.convert(xml, 2) self.assertIn('class="shortcut">Description', html) def test_refnav_skips_protos_refsect1(self): xml = '\n'.join([ self.xml_book_chapter_refentry_beg, textwrap.dedent("""\ Functions """), self.xml_book_chapter_refentry_end]) html = self.convert(xml, 2) self.assertNotIn('class="shortcut">Functions', html) if __name__ == '__main__': unittest.main()