def test_extensions(self): config = self.config.clone() config['confluence_sourcelink']['container'] += 'extensions/' config['extensions'].append('sphinx.ext.autodoc') config['extensions'].append('sphinx.ext.autosummary') config['extensions'].append('sphinx.ext.graphviz') config['extensions'].append('sphinx.ext.ifconfig') config['extensions'].append('sphinx.ext.inheritance_diagram') config['extensions'].append('sphinx.ext.todo') config['graphviz_output_format'] = 'svg' config['todo_include_todos'] = True config['todo_link_only'] = True # inject a navdoc from the last header/footer page, to the # extended autodocs start page def navdocs_transform(builder, docnames): builder.state.register_title('_validation_prev', 'Markdown Table', None) docnames.insert(0, '_validation_prev') builder.state.register_title('_validation_next', 'Extended - autodocs', None) docnames.append('_validation_next') return docnames config['confluence_navdocs_transform'] = navdocs_transform dataset = os.path.join(self.datasets, 'extensions') doc_dir = prepare_dirs('validation-set-extensions') sys.path.insert(0, os.path.join(dataset, 'src')) build_sphinx(dataset, config=config, out_dir=doc_dir) sys.path.pop(0)
def test_extended_autodocs(self): if parse_version(sphinx_version) < parse_version('2.3.1'): raise unittest.SkipTest('breathe requires sphinx>=2.3.1') config = self.config.clone() config['confluence_sourcelink']['container'] += 'extended-autodocs/' config['extensions'].append('breathe') config['extensions'].append('sphinx.ext.autodoc') # inject a navdoc from the last header/footer page, to the # extended autodocs start page def navdocs_transform(builder, docnames): builder.state.register_title('_validation_prev', 'sphinx.ext.todo', None) docnames.insert(0, '_validation_prev') return docnames config['confluence_navdocs_transform'] = navdocs_transform dataset = os.path.join(self.datasets, 'extended-autodocs') doc_dir = prepare_dirs('validation-set-extended-autodocs') xml_dir = os.path.join(dataset, 'xml') config['breathe_projects'] = {} for name in os.listdir(xml_dir): sample_dir = os.path.join(xml_dir, name) if os.path.isdir(sample_dir): config['breathe_projects'][name] = sample_dir build_sphinx(dataset, config=config, out_dir=doc_dir)
def test_nonjsonresponse(self): config = dict(self.config) config['confluence_server_url'] = 'https://example.com/' dataset = os.path.join(self.datasets, 'base') doc_dir = prepare_dirs('validation-set-nonjsonresponse') with self.assertRaises(ConfluenceBadApiError): build_sphinx(dataset, config=config, out_dir=doc_dir)
def test_hierarchy(self): config = dict(self.config) config['confluence_max_doc_depth'] = 2 config['confluence_page_hierarchy'] = True dataset = os.path.join(self.datasets, 'hierarchy') doc_dir = prepare_dirs('validation-set-hierarchy') build_sphinx(dataset, config=config, out_dir=doc_dir)
def test_header_footer(self): config = dict(self.config) dataset = os.path.join(self.datasets, 'header-footer') doc_dir = prepare_dirs('validation-set-hf') config['confluence_header_file'] = os.path.join(dataset, 'header.tpl') config['confluence_footer_file'] = os.path.join(dataset, 'footer.tpl') build_sphinx(dataset, config=config, out_dir=doc_dir)
def process_sandbox(target_sandbox, builder=None, defines=None): test_dir = os.path.dirname(os.path.realpath(__file__)) base_dir = os.path.join(test_dir, os.pardir) sandbox_dir = os.path.join(base_dir, target_sandbox) container = 'sandbox-test' if builder: container += '-' + builder doc_dir = prepare_dirs(container) build_sphinx(sandbox_dir, out_dir=doc_dir, builder=builder, extra_config=defines, relax=True)
def test_storage_sphinx_image_candidate(self): config = prepare_conf() assets_dir = os.path.join(self.test_dir, 'assets') sample_img = os.path.join(assets_dir, 'test.png') for mime_type in SUPPORTED_IMAGE_TYPES: ext = mimetypes.guess_extension(mime_type) # handle python 3.7 interpreter | image/x-ms-bmp -> image/bmp # https://bugs.python.org/issue22589 if not ext and mime_type == 'image/x-ms-bmp': ext = mimetypes.guess_extension('image/bmp') self.assertIsNotNone(ext) pyver = 'py{}{}'.format(sys.version_info.major, sys.version_info.minor) doc_dir = prepare_dirs( postfix='-{}-docs-{}'.format(pyver, ext[1:])) out_dir = prepare_dirs(postfix='-{}-out-{}'.format(pyver, ext[1:])) # prepare documentation set # - create and index document with an asterisk image extension # - copies over an image which should be mapped; note that a real # image is needed as the contents can be parsed through sphinx # to see if its a real image before considering it to be a # candidate os.makedirs(doc_dir) index_file = os.path.join(doc_dir, 'index.rst') with open(index_file, 'w') as f: f.write('.. image:: candidate.*') img_filename = 'candidate' + ext dummy_img_file = os.path.join(doc_dir, img_filename) shutil.copyfile(sample_img, dummy_img_file) # build and check build_sphinx(doc_dir, config=config, out_dir=out_dir) with parse('index', out_dir) as data: image = data.find('ac:image') self.assertIsNotNone(image) attachment = image.find('ri:attachment', recursive=False) self.assertIsNotNone(attachment) self.assertTrue(attachment.has_attr('ri:filename')) self.assertEqual(attachment['ri:filename'], img_filename)
def test_storage_rst_markup(self): out_dir = build_sphinx(self.dataset, config=self.config, filenames=self.filenames) with parse('markup', out_dir) as data: emphasis = data.find('em', text='emphasis') self.assertIsNotNone(emphasis) strong_emphasis = data.find('strong', text='strong emphasis') self.assertIsNotNone(strong_emphasis) interpreted = data.find('em', text='interpreted') self.assertIsNotNone(interpreted) inline = data.find('code', text='inline') self.assertIsNotNone(inline) subscript = data.find('sub', text='subscript') self.assertIsNotNone(subscript) superscript = data.find('sup', text='superscript') self.assertIsNotNone(superscript) ems = data.find_all('em') self.assertIsNotNone(len(ems), 3) guilabel = ems[-1] self.assertEqual(guilabel.text, 'guilabel') guilabel_hint = guilabel.find('u', text='g') self.assertIsNotNone(guilabel_hint)
def test_usecase_nestedref(self): out_dir = build_sphinx(self.dataset, config=self.config, filenames=self.filenames) with parse('nested-ref-contents', out_dir) as data: # contents link to header (via anchor) root_toc = data.find('ul', recursive=False) self.assertIsNotNone(root_toc) toc_link = root_toc.find('ac:link') self.assertIsNotNone(toc_link) self.assertTrue(toc_link.has_attr('ac:anchor')) # note: anchor will be `customname` as confluence will strip # underscores in headers with links self.assertEqual(toc_link['ac:anchor'], 'customname') toc_link_body = toc_link.find('ac:link-body', recursive=False) self.assertIsNotNone(toc_link_body) self.assertEqual(toc_link_body.text, 'custom_name') # header link to external page header = data.find('h2', recursive=False) self.assertIsNotNone(header) header_link = header.find('ac:link', recursive=False) self.assertIsNotNone(header_link) self.assertFalse(header_link.has_attr('ac:anchor')) header_link_body = header_link.find('ac:link-body', recursive=False) self.assertIsNotNone(header_link_body) self.assertEqual(header_link_body.text, 'custom_name')
def test_storage_sharedasset_force_standalone(self): config = dict(self.config) config['confluence_asset_force_standalone'] = True out_dir = build_sphinx(self.dataset, config=config) with parse('doc-a', out_dir) as data: image = data.find('ac:image') self.assertIsNotNone(image) attachment = image.find('ri:attachment') self.assertIsNotNone(attachment) self.assertTrue(attachment.has_attr('ri:filename')) self.assertEqual(attachment['ri:filename'], 'image03.png') page_ref = attachment.find('ri:page') self.assertIsNone(page_ref) with parse('doc-b', out_dir) as data: image = data.find('ac:image') self.assertIsNotNone(image) attachment = image.find('ri:attachment') self.assertIsNotNone(attachment) self.assertTrue(attachment.has_attr('ri:filename')) self.assertEqual(attachment['ri:filename'], 'image03.png') page_ref = attachment.find('ri:page') self.assertIsNone(page_ref)
def test_storage_rst_headings_with_title(self): config = dict(self.config) config['confluence_remove_title'] = False out_dir = build_sphinx(self.dataset, config=config, filenames=self.filenames) with parse('headings', out_dir) as data: header_lvl1 = data.find('h1') self.assertIsNotNone(header_lvl1) self.assertEqual(header_lvl1.text, 'header 1') header_lvl2 = data.find('h2') self.assertIsNotNone(header_lvl2) self.assertEqual(header_lvl2.text, 'header 2') header_lvl3 = data.find_all('h3') self.assertIsNotNone(header_lvl3) self.assertEqual(len(header_lvl3), 2) self.assertEqual(header_lvl3[0].text, 'header 3') self.assertEqual(header_lvl3[1].text, 'header 12') header_lvl4 = data.find('h4') self.assertIsNotNone(header_lvl4) self.assertEqual(header_lvl4.text, 'header 4') header_lvl5 = data.find('h5') self.assertIsNotNone(header_lvl5) self.assertEqual(header_lvl5.text, 'header 5') header_lvl6 = data.find_all('h6') self.assertIsNotNone(header_lvl6) self.assertEqual(len(header_lvl6), 6)
def test_storage_sharedasset_defaults(self): out_dir = build_sphinx(self.dataset, config=self.config) with parse('doc-a', out_dir) as data: image = data.find('ac:image') self.assertIsNotNone(image) attachment = image.find('ri:attachment') self.assertIsNotNone(attachment) self.assertTrue(attachment.has_attr('ri:filename')) self.assertEqual(attachment['ri:filename'], 'image03.png') page_ref = attachment.find('ri:page') self.assertIsNotNone(page_ref) self.assertTrue(page_ref.has_attr('ri:content-title')) self.assertEqual(page_ref['ri:content-title'], 'shared asset') with parse('doc-b', out_dir) as data: image = data.find('ac:image') self.assertIsNotNone(image) attachment = image.find('ri:attachment') self.assertIsNotNone(attachment) self.assertTrue(attachment.has_attr('ri:filename')) self.assertEqual(attachment['ri:filename'], 'image03.png') page_ref = attachment.find('ri:page') self.assertIsNotNone(page_ref) self.assertTrue(page_ref.has_attr('ri:content-title')) self.assertEqual(page_ref['ri:content-title'], 'shared asset')
def test_storage_sphinx_codeblock_highlight_linenothreshold(self): # skip code-block tests in Sphinx v1.8.x due to regression # https://github.com/sphinx-contrib/confluencebuilder/issues/148 if parse_version(sphinx_version) < parse_version('2.0'): raise unittest.SkipTest('not supported in sphinx-1.8.x') out_dir = build_sphinx(self.dataset, config=self.config, filenames=['code-block-linenothreshold']) with parse('code-block-linenothreshold', out_dir) as data: code_macros = data.find_all('ac:structured-macro', {'ac:name': 'code'}) self.assertIsNotNone(code_macros) self.assertEqual(len(code_macros), 2) for code_macro in code_macros: self.assertTrue(code_macro.has_attr('ac:name')) self.assertEqual(code_macro['ac:name'], 'code') # no lines block under `linenothreshold` count block = code_macros.pop(0) linenumbers = block.find('ac:parameter', {'ac:name': 'linenumbers'}) self.assertIsNotNone(linenumbers) self.assertEqual(linenumbers.text, 'false') # with lines block under `linenothreshold` count block = code_macros.pop(0) linenumbers = block.find('ac:parameter', {'ac:name': 'linenumbers'}) self.assertIsNotNone(linenumbers) self.assertEqual(linenumbers.text, 'true')
def test_storage_sphinx_download_defaults(self): out_dir = build_sphinx(self.dataset, config=self.config, filenames=self.filenames) with parse('download', out_dir) as data: # view-file view_file_macro = data.find('ac:structured-macro', {'ac:name': 'view-file'}) self.assertIsNotNone(view_file_macro) view_file_name = view_file_macro.find('ac:parameter', {'ac:name': 'name'}) self.assertIsNotNone(view_file_name) attachment_ref = view_file_name.find('ri:attachment') self.assertIsNotNone(attachment_ref) self.assertTrue(attachment_ref.has_attr('ri:filename')) self.assertEqual(attachment_ref['ri:filename'], 'example.pdf') # link to file file_link = data.find('ac:link') self.assertIsNotNone(file_link) attachment_ref = file_link.find('ri:attachment') self.assertIsNotNone(attachment_ref) self.assertTrue(attachment_ref.has_attr('ri:filename')) self.assertEqual(attachment_ref['ri:filename'], 'example.pdf') link_body = file_link.find('ac:plain-text-link-body') self.assertIsNotNone(link_body) cdata_block = next(link_body.children, None) self.assertTrue(isinstance(cdata_block, CData)) self.assertEqual(cdata_block, 'label')
def test_storage_sphinx_domain_c(self): out_dir = build_sphinx(self.dataset, config=self.config, filenames=['domains-c']) with parse('domains-c', out_dir) as data: definition = data.find('dl') self.assertIsNotNone(definition) # term term = definition.find('dt', recursive=False) self.assertIsNotNone(term) stronged_term = term.find('strong') self.assertIsNotNone(stronged_term) self.assertEqual(stronged_term.text, 'my_func') # ignore pre-v3.0 as it embeds asterisk in variable if parse_version(sphinx_version) >= parse_version('3.0'): param_context = term.find('em', text='context') self.assertIsNotNone(param_context) # description desc = definition.find('dd', recursive=False) self.assertIsNotNone(desc) self.assertEqual(desc.text, '') # no description in this example
def test_storage_rst_admonitions(self): out_dir = build_sphinx(self.dataset, config=self.config, filenames=self.filenames) with parse('admonitions', out_dir) as data: self._verify_storage_tags(data, 'attention', 'note') self._verify_storage_tags(data, 'caution', 'note') self._verify_storage_tags(data, 'danger', 'warning') self._verify_storage_tags(data, 'error', 'warning') self._verify_storage_tags(data, 'hint', 'tip') self._verify_storage_tags(data, 'important', 'warning') self._verify_storage_tags(data, 'note', 'info') self._verify_storage_tags(data, 'tip', 'tip') self._verify_storage_tags(data, 'warning', 'warning') macro = self._verify_storage_tags(data, 'admonition', 'info') title_param = macro.find('ac:parameter', {'ac:name': 'title'}) self.assertIsNotNone(title_param, 'admonition is missing a title paramater') self.assertEqual(title_param.text, 'my-title', 'admonition title value does not match expected') icon_param = macro.find('ac:parameter', {'ac:name': 'icon'}) self.assertIsNotNone(icon_param, 'admonition is missing a icon paramater') self.assertEqual(icon_param.text, 'false', 'admonition icon value is not disabled')
def test_storage_sphinx_codeblock_highlight_override(self): config = dict(self.config) def test_override_lang_method(lang): if lang == 'csharp': return 'custom-csharp' return 'custom' config['confluence_lang_transform'] = test_override_lang_method out_dir = build_sphinx(self.dataset, config=config, filenames=['code-block-highlight']) with parse('code-block-highlight', out_dir) as data: expected = [ 'custom', 'custom', 'custom-csharp', 'custom', 'custom', 'custom', ] languages = data.find_all('ac:parameter', {'ac:name': 'language'}) self._verify_set_languages(languages, expected)
def test_storage_rst_headings_default(self): out_dir = build_sphinx(self.dataset, config=self.config, filenames=self.filenames) with parse('headings', out_dir) as data: header_lvl1 = data.find('h1') self.assertIsNone(header_lvl1) header_lvl2 = data.find('h2') self.assertIsNotNone(header_lvl2) self.assertEqual(header_lvl2.text, 'header 2') header_lvl3 = data.find_all('h3') self.assertIsNotNone(header_lvl3) self.assertEqual(len(header_lvl3), 2) self.assertEqual(header_lvl3[0].text, 'header 3') self.assertEqual(header_lvl3[1].text, 'header 12') header_lvl4 = data.find('h4') self.assertIsNotNone(header_lvl4) self.assertEqual(header_lvl4.text, 'header 4') header_lvl5 = data.find('h5') self.assertIsNotNone(header_lvl5) self.assertEqual(header_lvl5.text, 'header 5') header_lvl6 = data.find_all('h6') self.assertIsNotNone(header_lvl6) self.assertEqual(len(header_lvl6), 6)
def test_storage_sphinx_codeblock_caption(self): out_dir = build_sphinx(self.dataset, config=self.config, filenames=['code-block-caption']) with parse('code-block-caption', out_dir) as data: title_param = data.find('ac:parameter', {'ac:name': 'title'}) self.assertIsNotNone(title_param) self.assertEqual(title_param.text, 'code caption test')
def test_storage_rst_definition_lists(self): out_dir = build_sphinx(self.dataset, config=self.config, filenames=self.filenames) with parse('definition-lists', out_dir) as data: def_list = data.find('dl') self.assertIsNotNone(def_list) def_list_tags = def_list.find_all(recursive=False) self.assertEqual(len(def_list_tags), 8) # term 1 term = def_list_tags.pop(0) self.assertEqual(term.text, 'term 1') # definition 1 definition = def_list_tags.pop(0) self.assertEqual(definition.text.strip(), 'definition 1') # term 2 term = def_list_tags.pop(0) self.assertEqual(term.text, 'term 2') # definition 2 definition = def_list_tags.pop(0) definition_paras = definition.find_all('p') self.assertEqual(len(definition_paras), 2) self.assertEqual(definition_paras[0].text, 'definition 2, paragraph 1') self.assertEqual(definition_paras[1].text, 'definition 2, paragraph 2') # term 3 term = def_list_tags.pop(0) children = list(term.children) self.assertEqual(len(children), 2) self.assertEqual(children[0], 'term 3 : ') self.assertEqual(children[1].name, 'em') self.assertEqual(children[1].text, 'classifier') # definition 3 definition = def_list_tags.pop(0) self.assertEqual(definition.text.strip(), 'definition 3') # term 4 term = def_list_tags.pop(0) children = list(term.children) self.assertEqual(len(children), 4) self.assertEqual(children[0], 'term 4 : ') self.assertEqual(children[1].name, 'em') self.assertEqual(children[1].text, 'classifier one') self.assertEqual(children[2], ' : ') self.assertEqual(children[3].name, 'em') self.assertEqual(children[3].text, 'classifier two') # definition 4 definition = def_list_tags.pop(0) self.assertEqual(definition.text.strip(), 'definition 4')
def test_storage_rst_raw_default(self): out_dir = build_sphinx(self.dataset, config=self.config, filenames=['raw-storage']) with parse('raw-storage', out_dir) as data: strong = data.find('strong') self.assertIsNotNone(strong) self.assertEqual(strong.text, 'raw content')
def test_config_prevnext_top(self): config = dict(self.config) config['confluence_prev_next_buttons_location'] = 'top' out_dir = build_sphinx(self.dataset, config=config) self._character_check('index', out_dir, {'←': 0, '→': 1}) self._character_check('middle', out_dir, {'←': 1, '→': 1}) self._character_check('final', out_dir, {'←': 1, '→': 0})
def test_standard_macro_restricted(self): config = dict(self.config) dataset = os.path.join(self.datasets, 'standard') doc_dir = prepare_dirs('validation-set-standard-nm') config['confluence_adv_restricted'] = [ 'anchor', 'children', 'code', 'info', 'viewfile', 'jira' ] config['confluence_header_file'] = os.path.join(dataset, 'no-macro.tpl') config['confluence_publish_postfix'] = ' (nomacro)' build_sphinx(dataset, config=config, out_dir=doc_dir)
def test_storage_rst_contents_caption(self): out_dir = build_sphinx(self.dataset, config=self.config, filenames=['contents-caption']) with parse('contents-caption', out_dir) as data: caption = data.find(re.compile('^h[1-6]$'), text='table of contents') self.assertIsNotNone(caption)
def test_storage_sphinx_alignment_default(self): out_dir = build_sphinx(self.dataset, config=self.config, filenames=self.filenames) with parse('alignment', out_dir) as data: image = data.find('ac:image') self.assertIsNotNone(image) self.assertTrue(image.has_attr('ac:align')) self.assertEqual(image['ac:align'], 'center')
def test_extensions(self): config = dict(self.config) config['extensions'].append('sphinx.ext.autodoc') config['extensions'].append('sphinx.ext.autosummary') config['extensions'].append('sphinx.ext.graphviz') config['extensions'].append('sphinx.ext.ifconfig') config['extensions'].append('sphinx.ext.inheritance_diagram') config['extensions'].append('sphinx.ext.todo') config['graphviz_output_format'] = 'svg' config['todo_include_todos'] = True config['todo_link_only'] = True dataset = os.path.join(self.datasets, 'extensions') doc_dir = prepare_dirs('validation-set-extensions') sys.path.insert(0, os.path.join(dataset, 'src')) build_sphinx(dataset, config=config, out_dir=doc_dir) sys.path.pop(0)
def test_config_hierarchy_parent_registration(self): ConfluenceState.reset() build_sphinx(self.dataset, config=self.config) # root toctree should not have a parent root_doc = ConfluenceState.parentDocname('index') self.assertIsNone(root_doc) # check various documents for expected parents parent_doc = ConfluenceState.parentDocname('toctree-doc1') self.assertEqual(parent_doc, 'index') parent_doc = ConfluenceState.parentDocname('toctree-doc2') self.assertEqual(parent_doc, 'index') parent_doc = ConfluenceState.parentDocname('toctree-doc3') self.assertEqual(parent_doc, 'index') parent_doc = ConfluenceState.parentDocname('toctree-doc2a') self.assertEqual(parent_doc, 'toctree-doc2')
def test_storage_rst_parsedliteral_defaults(self): out_dir = build_sphinx(self.dataset, config=self.config, filenames=self.filenames) with parse('parsed-literal', out_dir) as data: container_block = data.find('pre') self.assertIsNotNone(container_block) styled_markup = container_block.find('strong') self.assertIsNotNone(styled_markup)
def test_standard_default(self): config = self.config.clone() config['confluence_sourcelink']['container'] += 'standard/' dataset = os.path.join(self.datasets, 'standard') doc_dir = prepare_dirs('validation-set-standard') # inject a navdoc to the header/footer start page def navdocs_transform(builder, docnames): builder.state.register_title('_validation_prev', self.test_key, None) docnames.insert(0, '_validation_prev') builder.state.register_title('_validation_next', 'Header/footer example', None) docnames.append('_validation_next') return docnames config['confluence_navdocs_transform'] = navdocs_transform build_sphinx(dataset, config=config, out_dir=doc_dir)
def test_storage_sphinx_manpage_noconfig(self): out_dir = build_sphinx(self.dataset, config=self.config, filenames=self.filenames) with parse('manpage', out_dir) as data: em = data.find('em') self.assertIsNotNone(em) self.assertEqual(em.text, 'ls(1)') link = data.find('a') self.assertIsNone(link)