예제 #1
0
def test_render(capsys, tmpdir, engine, format_, renderer, formatter, expected_suffix,
                filename='hello.gv', data=b'digraph { hello -> world }'):
    lpath = tmpdir / filename
    lpath.write_binary(data)
    rendered = lpath.new(ext='%s.%s' % (lpath.ext, expected_suffix))

    assert render(engine, format_, str(lpath), renderer, formatter) == str(rendered)

    assert rendered.size()
    assert capsys.readouterr() == ('', '')
예제 #2
0
def test_render(capsys, tmpdir, engine='dot', format_='pdf',
                filename='hello.gv', data=b'digraph { hello -> world }'):
    lpath = tmpdir.join(filename)
    lpath.write_binary(data)
    rendered = lpath.new(ext='%s.%s' % (lpath.ext, format_))

    assert render(engine, format_, str(lpath)) == str(rendered)

    assert rendered.size()
    assert capsys.readouterr() == ('', '')
예제 #3
0
def test_render(capsys, tmp_path, engine, format_, renderer, formatter,
                expected_suffix, filename='hello.gv',
                data=b'digraph { hello -> world }'):
    lpath = tmp_path / filename
    lpath.write_bytes(data)
    rendered = lpath.with_suffix(f'{lpath.suffix}.{expected_suffix}')

    assert render(engine, format_, str(lpath), renderer, formatter) == str(rendered)

    assert rendered.stat().st_size
    assert capsys.readouterr() == ('', '')
예제 #4
0
def test_render(capsys, tmpdir, engine, format_, renderer, formatter,
                expected_suffix, filename='hello.gv',
                data=b'digraph { hello -> world }'):
    lpath = tmpdir / filename
    lpath.write_binary(data)
    rendered = lpath.new(ext='%s.%s' % (lpath.ext, expected_suffix))

    assert render(engine, format_, str(lpath), renderer, formatter) == str(rendered)

    assert rendered.size()
    assert capsys.readouterr() == ('', '')
예제 #5
0
def test_render(tmpdir,
                engine='dot',
                format_='pdf',
                filename='hello.gv',
                data=b'digraph { hello -> world }'):
    source = tmpdir.join(filename)
    source.write(data)
    rendered = source.new(ext='%s.%s' % (source.ext, format_))

    assert render(engine, format_, str(source)) == str(rendered)

    assert rendered.size()
예제 #6
0
    def render(self,
               filename=None,
               directory=None,
               view=False,
               cleanup=False,
               format=None,
               renderer=None,
               formatter=None,
               quiet=False):
        """Save the source to file and render with the Graphviz engine.

        Args:
            filename: Filename for saving the source (defaults to ``name`` + ``'.gv'``)
            directory: (Sub)directory for source saving and rendering.
            view (bool): Open the rendered result with the default application.
            cleanup (bool): Delete the source file after rendering.
            format: The output format used for rendering (``'pdf'``, ``'png'``, etc.).
            renderer: The output renderer used for rendering (``'cairo'``, ``'gd'``, ...).
            formatter: The output formatter used for rendering (``'cairo'``, ``'gd'``, ...).
            quiet (bool): Suppress ``stderr`` output from the layout subprocess.
        Returns:
            The (possibly relative) path of the rendered file.
        Raises:
            ValueError: If ``format``, ``renderer``, or ``formatter`` are not known.
            graphviz.RequiredArgumentError: If ``formatter`` is given but ``renderer`` is None.
            graphviz.ExecutableNotFound: If the Graphviz executable is not found.
            subprocess.CalledProcessError: If the exit status is non-zero.
            RuntimeError: If viewer opening is requested but not supported.

        The layout command is started from the directory of ``filepath``, so that
        references to external files (e.g. ``[image=...]``) can be given as paths
        relative to the DOT source file.
        """
        filepath = self.save(filename, directory)

        if format is None:
            format = self._format

        rendered = backend.render(self._engine,
                                  format,
                                  filepath,
                                  renderer=renderer,
                                  formatter=formatter,
                                  quiet=quiet)

        if cleanup:
            os.remove(filepath)

        if view:
            self._view(rendered, self._format)

        return rendered
예제 #7
0
def test_render_mocked(mocker, check_call, quiet):
    open_ = mocker.patch('io.open', mocker.mock_open())
    mocker.patch('os.devnull', mocker.sentinel.devnull)

    assert render('dot', 'pdf', 'nonfilepath', quiet=quiet) == 'nonfilepath.pdf'

    if quiet:
        open_.assert_called_once_with(mocker.sentinel.devnull, 'w')
        stderr = open_.return_value
    else:
        stderr = None
    check_call.assert_called_once_with(['dot', '-Tpdf', '-O', 'nonfilepath'],
                                       startupinfo=STARTUPINFO, stderr=stderr)
예제 #8
0
def test_render_mocked(capsys, mocker, Popen, quiet):  # noqa: N803
    proc = Popen.return_value
    proc.returncode = 0
    proc.communicate.return_value = (b'stdout', b'stderr')

    assert render('dot', 'pdf', 'nonfilepath', quiet=quiet) == 'nonfilepath.pdf'

    Popen.assert_called_once_with(['dot', '-Tpdf', '-O', 'nonfilepath'],
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  startupinfo=mocker.ANY)
    check_startupinfo(Popen)
    proc.communicate.assert_called_once_with(None)
    assert capsys.readouterr() == ('', '' if quiet else 'stderr')
예제 #9
0
def test_render_img(capsys, tmp_path, engine='dot', format_='pdf'):
    subdir = tmp_path / 'subdir'
    subdir.mkdir()

    img_path = subdir / 'dot_red.png'
    shutil.copy(TESTDATA / img_path.name, img_path)
    assert img_path.stat().st_size

    gv_path = subdir / 'img.gv'
    rendered = gv_path.with_suffix(f'{gv_path.suffix}.{format_}')
    gv_rel, rendered_rel = (p.relative_to(tmp_path) for p in (gv_path, rendered))
    assert all(str(s).startswith('subdir') for s in (gv_rel, rendered_rel))
    gv_path.write_text(f'graph {{ red_dot [image="{img_path.name}"] }}',
                       encoding='ascii')

    with utils.as_cwd(tmp_path):
        assert render(engine, format_, gv_rel) == str(rendered_rel)

    assert rendered.stat().st_size
    assert capsys.readouterr() == ('', '')
예제 #10
0
def test_render_missingdot(empty_path):
    with pytest.raises(ExecutableNotFound) as e:
        render('dot', 'pdf', 'nonfilepath')
    e.match(r'execute')
예제 #11
0
 def test_render_missing_file(self):
     with self.assertRaises(subprocess.CalledProcessError) as c:
         render('dot', 'pdf', 'doesnotexist')
     self.assertEqual(c.exception.returncode, 2)
예제 #12
0
def test_render_missing_file(quiet, engine='dot', format_='pdf'):
    with pytest.raises(subprocess.CalledProcessError) as e:
        render(engine, format_, '', quiet=quiet)
    assert e.value.returncode == 2
예제 #13
0
def test_render_missing_executable():
    with pytest.raises(ExecutableNotFound, match=r'execute'):
        render('dot', 'pdf', 'nonfilepath')
예제 #14
0
def test_render_formatter_unknown():
    with pytest.raises(ValueError, match=r'unknown formatter'):
        render('dot', 'ps', 'nonfilepath', 'ps', '')
예제 #15
0
def test_render_renderer_missing():
    with pytest.raises(RequiredArgumentError, match=r'without renderer'):
        render('dot', 'ps', 'nonfilepath', None, 'core')
예제 #16
0
def test_render_engine_unknown():
    with pytest.raises(ValueError, match=r'unknown engine'):
        render('', 'pdf', 'nonfilepath')