# -*- 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 anytree import PreOrderIter
from lxml import etree
from parameterized import parameterized
from gtkdoc import mkhtml2
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
"""),
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()