From ff38fa455c0fc788b1316339949e345c01a65212 Mon Sep 17 00:00:00 2001 From: Sebastian Bank Date: Fri, 12 May 2017 17:58:59 +0200 Subject: [PATCH] ensure full coverage with --skioexe --- graphviz/backend.py | 2 +- tests/conftest.py | 5 +++ tests/test_backend.py | 84 ++++++++++++++++++++++++++++++------------- 3 files changed, 66 insertions(+), 25 deletions(-) diff --git a/graphviz/backend.py b/graphviz/backend.py index 65d7caf6ae..8db485e220 100644 --- a/graphviz/backend.py +++ b/graphviz/backend.py @@ -157,7 +157,7 @@ def pipe(engine, format, data, quiet=False): outs, errs = proc.communicate(data) if proc.returncode: - if not quiet: # pragma: no cover + if not quiet: sys.stderr.write(errs) sys.stderr.flush() raise subprocess.CalledProcessError(proc.returncode, args, output=outs) diff --git a/tests/conftest.py b/tests/conftest.py index 2ab4871d59..bfe880263e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -52,6 +52,11 @@ def empty_path(monkeypatch): monkeypatch.setenv('PATH', '') +@pytest.fixture(params=[False, True]) +def quiet(request): + return request.param + + @pytest.fixture def pipe(mocker): yield mocker.patch('graphviz.backend.pipe') diff --git a/tests/test_backend.py b/tests/test_backend.py index 30d5e672ed..7d8c608e01 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -9,84 +9,120 @@ def test_render_engine_unknown(): with pytest.raises(ValueError) as e: - render('', 'pdf', '') + render('', 'pdf', 'nonfilepath') e.match(r'engine') def test_render_format_unknown(): with pytest.raises(ValueError) as e: - render('dot', '', '') + render('dot', '', 'nonfilepath') e.match(r'format') def test_render_missingdot(empty_path): with pytest.raises(ExecutableNotFound) as e: - render('dot', 'pdf', '') + render('dot', 'pdf', 'nonfilepath') e.match(r'execute') @pytest.exe -def test_render_missingfile(): +def test_render_missingfile(engine='dot', format_='pdf'): with pytest.raises(subprocess.CalledProcessError) as e: - render('dot', 'pdf', '', quiet=True) + render(engine, format_, '', quiet=True) assert e.value.returncode == 2 -def test_render_mocked(check_call): - assert render('dot', 'pdf', '') == '.pdf' - check_call.assert_called_once_with(['dot', '-Tpdf', '-O', ''], - startupinfo=STARTUPINFO, stderr=None) +def test_render_mocked(mocker, check_call, quiet): + open = mocker.patch('io.open') + devnull = mocker.patch('os.devnull') + + assert render('dot', 'pdf', 'nonfilepath', quiet=quiet) == 'nonfilepath.pdf' + + if quiet: + open.called_once_with(devnull, 'w') + stderr = open.return_value.__enter__.return_value + else: + stderr = None + check_call.assert_called_once_with(['dot', '-Tpdf', '-O', 'nonfilepath'], + startupinfo=STARTUPINFO, stderr=stderr) + @pytest.exe -def test_render(check_call): - pass # TODO +def test_render(tmpdir, engine='dot', format_='pdf', filename='hello.gv', + data=b'digraph { hello -> world }'): + source = tmpdir.join(filename) + source.write(data) + + result = render(engine, format_, str(source)) + + rendered = source.new(ext='%s.%s' % (source.ext, format_)) + assert rendered.size() + assert result == str(rendered) def test_pipe_missingdot(empty_path): with pytest.raises(ExecutableNotFound) as e: - pipe('dot', 'pdf', b'') + pipe('dot', 'pdf', b'nongraph') e.match(r'execute') @pytest.exe -def test_pipe_invalid_data(): +def test_pipe_invalid_data(engine='dot', format_='svg'): with pytest.raises(subprocess.CalledProcessError) as e: - pipe('dot', 'svg', b'nongraph', quiet=True) + pipe(engine, format_, b'nongraph', quiet=True) assert e.value.returncode == 1 +def test_pipe_mocked_fail(mocker, Popen, quiet): + stderr = mocker.patch('sys.stderr') + proc = Popen.return_value + proc.returncode = 1 + outs, errs = proc.communicate.return_value = mocker.MagicMock(), mocker.MagicMock() + + with pytest.raises(subprocess.CalledProcessError) as e: + pipe('dot', 'png', b'nongraph', quiet=quiet) + assert e.value.returncode == 1 + + Popen.assert_called_once_with(['dot', '-Tpng'], + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, startupinfo=STARTUPINFO) + proc.communicate.assert_called_once_with(b'nongraph') + if not quiet: + stderr.write.assert_called_once_with(errs) + stderr.flush.assert_called_once_with() + + def test_pipe_mocked(mocker, Popen): proc = Popen.return_value proc.returncode = 0 outs, errs = proc.communicate.return_value = mocker.MagicMock(), mocker.MagicMock() - result = pipe('dot', 'png', b'nograph', quiet=True) + assert pipe('dot', 'png', b'nongraph') is outs Popen.assert_called_once_with(['dot', '-Tpng'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, startupinfo=STARTUPINFO) - proc.communicate.assert_called_once_with(b'nograph') - assert result is outs + proc.communicate.assert_called_once_with(b'nongraph') @pytest.exe -def test_pipe(svg_pattern): - src = pipe('dot', 'svg', b'graph { spam }').decode('ascii') +def test_pipe(svg_pattern, engine='dot', format_='svg', data=b'graph { spam }'): + src = pipe(engine, format_, data).decode('ascii') assert svg_pattern.match(src) def test_view(platform, Popen, startfile): if not platform: with pytest.raises(RuntimeError) as e: - view('spam') + view('nonfilepath') e.match(r'platform') else: - view('spam') + view('nonfilepath') if platform == 'darwin': - Popen.assert_called_once_with(['open', 'spam']) + Popen.assert_called_once_with(['open', 'nonfilepath']) elif platform in ('linux', 'freebsd'): - Popen.assert_called_once_with(['xdg-open', 'spam']) + Popen.assert_called_once_with(['xdg-open', 'nonfilepath']) elif platform == 'windows': - startfile.assert_called_once_with('spam') + startfile.assert_called_once_with('nonfilepath') else: raise RuntimeError