1""" 2 test_ext_graphviz 3 ~~~~~~~~~~~~~~~~~ 4 5 Test sphinx.ext.graphviz extension. 6 7 :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. 8 :license: BSD, see LICENSE for details. 9""" 10 11import re 12 13import pytest 14 15from sphinx.ext.graphviz import ClickableMapDefinition 16 17 18@pytest.mark.sphinx('html', testroot='ext-graphviz') 19@pytest.mark.usefixtures('if_graphviz_found') 20def test_graphviz_png_html(app, status, warning): 21 app.builder.build_all() 22 23 content = (app.outdir / 'index.html').read_text() 24 html = (r'<div class="figure align-default" .*?>\s*' 25 r'<div class="graphviz"><img .*?/></div>\s*<p class="caption">' 26 r'<span class="caption-text">caption of graph</span>.*</p>\s*</div>') 27 assert re.search(html, content, re.S) 28 29 html = 'Hello <div class="graphviz"><img .*?/></div>\n graphviz world' 30 assert re.search(html, content, re.S) 31 32 html = ('<img src=".*?" alt="digraph foo {\nbaz -> qux\n}" ' 33 'class="graphviz neato-graph" />') 34 assert re.search(html, content, re.S) 35 36 html = (r'<div class="figure align-right" .*?>\s*' 37 r'<div class="graphviz"><img .*?/></div>\s*<p class="caption">' 38 r'<span class="caption-text">on <em>right</em></span>.*</p>\s*</div>') 39 assert re.search(html, content, re.S) 40 41 html = (r'<div align=\"center\" class=\"align-center\">' 42 r'<div class="graphviz"><img src=\".*\.png\" alt=\"digraph foo {\n' 43 r'centered\n' 44 r'}\" class="graphviz" /></div>\n</div>') 45 assert re.search(html, content, re.S) 46 47 48@pytest.mark.sphinx('html', testroot='ext-graphviz', 49 confoverrides={'graphviz_output_format': 'svg'}) 50@pytest.mark.usefixtures('if_graphviz_found') 51def test_graphviz_svg_html(app, status, warning): 52 app.builder.build_all() 53 54 content = (app.outdir / 'index.html').read_text() 55 56 html = (r'<div class=\"figure align-default\" .*?>\n' 57 r'<div class="graphviz"><object data=\".*\.svg\".*>\n' 58 r'\s*<p class=\"warning\">digraph foo {\n' 59 r'bar -> baz\n' 60 r'}</p></object></div>\n' 61 r'<p class=\"caption\"><span class=\"caption-text\">' 62 r'caption of graph</span>.*</p>\n</div>') 63 assert re.search(html, content, re.S) 64 65 html = (r'Hello <div class="graphviz"><object.*>\n' 66 r'\s*<p class=\"warning\">graph</p></object></div>\n' 67 r' graphviz world') 68 assert re.search(html, content, re.S) 69 70 html = (r'<div class=\"figure align-right\" .*\>\n' 71 r'<div class="graphviz"><object data=\".*\.svg\".*>\n' 72 r'\s*<p class=\"warning\">digraph bar {\n' 73 r'foo -> bar\n' 74 r'}</p></object></div>\n' 75 r'<p class=\"caption\"><span class=\"caption-text\">' 76 r'on <em>right</em></span>.*</p>\n' 77 r'</div>') 78 assert re.search(html, content, re.S) 79 80 html = (r'<div align=\"center\" class=\"align-center\">' 81 r'<div class="graphviz"><object data=\".*\.svg\".*>\n' 82 r'\s*<p class=\"warning\">digraph foo {\n' 83 r'centered\n' 84 r'}</p></object></div>\n' 85 r'</div>') 86 assert re.search(html, content, re.S) 87 88 89@pytest.mark.sphinx('latex', testroot='ext-graphviz') 90@pytest.mark.usefixtures('if_graphviz_found') 91def test_graphviz_latex(app, status, warning): 92 app.builder.build_all() 93 94 content = (app.outdir / 'python.tex').read_text() 95 macro = ('\\\\begin{figure}\\[htbp\\]\n\\\\centering\n\\\\capstart\n\n' 96 '\\\\sphinxincludegraphics\\[\\]{graphviz-\\w+.pdf}\n' 97 '\\\\caption{caption of graph}\\\\label{.*}\\\\end{figure}') 98 assert re.search(macro, content, re.S) 99 100 macro = 'Hello \\\\sphinxincludegraphics\\[\\]{graphviz-\\w+.pdf} graphviz world' 101 assert re.search(macro, content, re.S) 102 103 macro = ('\\\\begin{wrapfigure}{r}{0pt}\n\\\\centering\n' 104 '\\\\sphinxincludegraphics\\[\\]{graphviz-\\w+.pdf}\n' 105 '\\\\caption{on \\\\sphinxstyleemphasis{right}}' 106 '\\\\label{.*}\\\\end{wrapfigure}') 107 assert re.search(macro, content, re.S) 108 109 macro = (r'\{\\hfill' 110 r'\\sphinxincludegraphics\[\]{graphviz-.*}' 111 r'\\hspace\*{\\fill}}') 112 assert re.search(macro, content, re.S) 113 114 115@pytest.mark.sphinx('html', testroot='ext-graphviz', confoverrides={'language': 'xx'}) 116@pytest.mark.usefixtures('if_graphviz_found') 117def test_graphviz_i18n(app, status, warning): 118 app.builder.build_all() 119 120 content = (app.outdir / 'index.html').read_text() 121 html = '<img src=".*?" alt="digraph {\n BAR -> BAZ\n}" class="graphviz" />' 122 assert re.search(html, content, re.M) 123 124 125def test_graphviz_parse_mapfile(): 126 # empty graph 127 code = ('# digraph {\n' 128 '# }\n') 129 content = ('<map id="%3" name="%3">\n' 130 '</map>') 131 cmap = ClickableMapDefinition('dummy.map', content, code) 132 assert cmap.filename == 'dummy.map' 133 assert cmap.id == 'grapvizb08107169e' 134 assert len(cmap.clickable) == 0 135 assert cmap.generate_clickable_map() == '' 136 137 # normal graph 138 code = ('digraph {\n' 139 ' foo [href="http://www.google.com/"];\n' 140 ' foo -> bar;\n' 141 '}\n') 142 content = ('<map id="%3" name="%3">\n' 143 '<area shape="poly" id="node1" href="http://www.google.com/" title="foo" alt=""' 144 ' coords="77,29,76,22,70,15,62,10,52,7,41,5,30,7,20,10,12,15,7,22,5,29,7,37,12,' 145 '43,20,49,30,52,41,53,52,52,62,49,70,43,76,37"/>\n' 146 '</map>') 147 cmap = ClickableMapDefinition('dummy.map', content, code) 148 assert cmap.filename == 'dummy.map' 149 assert cmap.id == 'grapviza4ccdd48ce' 150 assert len(cmap.clickable) == 1 151 assert cmap.generate_clickable_map() == content.replace('%3', cmap.id) 152 153 # inheritance-diagram:: sphinx.builders.html 154 content = ( 155 '<map id="inheritance66ff5471b9" name="inheritance66ff5471b9">\n' 156 '<area shape="rect" id="node1" title="Builds target formats from the reST sources."' 157 ' alt="" coords="26,95,125,110"/>\n' 158 '<area shape="rect" id="node5" title="Builds standalone HTML docs."' 159 ' alt="" coords="179,95,362,110"/>\n' 160 '<area shape="rect" id="node2" title="buildinfo file manipulator." ' 161 ' alt="" coords="14,64,138,80"/>\n' 162 '<area shape="rect" id="node3" title="The container of stylesheets."' 163 ' alt="" coords="3,34,148,49"/>\n' 164 '<area shape="rect" id="node4" title="A StandaloneHTMLBuilder that creates all HTML' 165 ' pages as "index.html" in" alt="" coords="395,64,569,80"/>\n' 166 '<area shape="rect" id="node7" title="An abstract builder that serializes' 167 ' the generated HTML." alt="" coords="392,95,571,110"/>\n' 168 '<area shape="rect" id="node9" title="A StandaloneHTMLBuilder subclass that puts' 169 ' the whole document tree on one" alt="" coords="393,125,570,141"/>\n' 170 '<area shape="rect" id="node6" title="A builder that dumps the generated HTML' 171 ' into JSON files." alt="" coords="602,80,765,95"/>\n' 172 '<area shape="rect" id="node8" title="A Builder that dumps the generated HTML' 173 ' into pickle files." alt="" coords="602,110,765,125"/>\n' 174 '<area shape="rect" id="node10" title="The metadata of stylesheet."' 175 ' alt="" coords="11,3,141,19"/>\n' 176 '</map>' 177 ) 178 cmap = ClickableMapDefinition('dummy.map', content, 'dummy_code') 179 assert cmap.filename == 'dummy.map' 180 assert cmap.id == 'inheritance66ff5471b9' 181 assert len(cmap.clickable) == 0 182 assert cmap.generate_clickable_map() == '' 183