Skip to content

Commit

Permalink
Merge pull request #27 from NyanKiyoshi/feature/save_html
Browse files Browse the repository at this point in the history
The html command now writes to a file instead of stdout
  • Loading branch information
NyanKiyoshi authored May 27, 2019
2 parents f83b903 + afdd635 commit 8489240
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 14 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ venv/
dist/
docs/_build/
.DS*
django-queries-results.html
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,10 @@ You will get something like this to represent the results:
## Exporting the results (HTML)
For a nicer presentation, use the `html` command, to export the results as HTML.
```shell
django-queries html > results.html
django-queries html
```
<!-- todo: add example page link -->

It will generate something [like this](docs/extra_html/html_export_results.html).

## Comparing results

Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Quick Start
| module3 | |
+---------+-------------------------+
5. Or for a nicer presentation, use ``django-queries html > results.html`` to export the results as HTML. See `this example <./html_export_results.html>`_ for a demo!
5. Or for a nicer presentation, use ``django-queries html`` to export the results as HTML. See `this example <./html_export_results.html>`_ for a demo!

.. image:: _static/html_export_results.png
:width: 500 px
Expand Down
5 changes: 4 additions & 1 deletion docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,14 @@ The HTML Command

.. code-block:: text
Usage: django-queries html [OPTIONS] [INPUT_FILE]
Usage: django-queries html [OPTIONS] [INPUT_FILE] [-o OUTPUT FILE]
Render the results as HTML instead of a raw table.
Options:
-o The path to save the HTML file into
django-queries.html by default.
You can pass a dash (-) to write to stdout as well.
--template INTEGER
--help Show this message and exit.
Expand Down
26 changes: 21 additions & 5 deletions pytest_django_queries/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,21 @@
DEFAULT_OLD_RESULT_FILENAME,
DEFAULT_RESULT_FILENAME,
)
from pytest_django_queries.tables import print_entries, print_entries_as_html
from pytest_django_queries.tables import entries_to_html, print_entries

HERE = dirname(__file__)
DEFAULT_TEMPLATE_PATH = abspath(pathjoin(HERE, "templates", "default_bootstrap.jinja2"))
DEFAULT_HTML_SAVE_PATH = "django-queries-results.html"

DIFF_TERM_COLOR = {"-": "red", "+": "green"}
DEFAULT_TERM_DIFF_COLOR = None


def _write_html_to_file(content, path):
with open(path, "w") as fp:
fp.write(content)


class JsonFileParamType(click.File):
name = "integer"

Expand All @@ -41,7 +47,7 @@ class Jinja2TemplateFile(click.File):
def convert(self, value, param, ctx):
fp = super(Jinja2TemplateFile, self).convert(value, param, ctx)
try:
return Template(fp.read())
return Template(fp.read(), trim_blocks=True)
except jinja_exceptions.TemplateError as e:
self.fail(
"The file is not a valid jinja2 template: %s" % str(e), param, ctx
Expand All @@ -66,10 +72,20 @@ def show(input_file):
@click.argument(
"input_file", type=JsonFileParamType("r"), default=DEFAULT_RESULT_FILENAME
)
@click.option("-o", "--output", type=str, default=DEFAULT_HTML_SAVE_PATH)
@click.option("--template", type=Jinja2TemplateFile("r"), default=DEFAULT_TEMPLATE_PATH)
def html(input_file, template):
"""Render the results as HTML instead of a raw table."""
return print_entries_as_html(input_file, template)
def html(input_file, output, template):
"""
Render the results as HTML instead of a raw table.
Note: you can pass a dash (-) as the path to print the HTML content to stdout."""
html_content = entries_to_html(input_file, template)

if output == "-":
click.echo(html_content, nl=False)
return

_write_html_to_file(html_content, output)


@main.command()
Expand Down
4 changes: 2 additions & 2 deletions pytest_django_queries/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def print_entries(data):
click.echo(table)


def print_entries_as_html(data, template):
def entries_to_html(data, template):
html_content = template.render(
data=iter_entries(data), humanize=format_underscore_name_to_human
)
click.echo(html_content, nl=False)
return html_content
44 changes: 41 additions & 3 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
from textwrap import dedent

import mock
import pytest
from bs4 import BeautifulSoup
from click.testing import CliRunner
Expand Down Expand Up @@ -99,7 +100,7 @@ def test_load_valid_json_file_shows_correct_data(testdir):
def test_load_valid_json_file_shows_correct_html_data(testdir):
testdir.makefile(".json", test_file=json.dumps(VALID_DATA))
runner = CliRunner()
result = runner.invoke(cli.main, ["html", "test_file.json"])
result = runner.invoke(cli.main, ["html", "test_file.json", "-o", "-"])
assert result.exit_code == 0, result.stdout
soup = BeautifulSoup(result.stdout, "lxml")
sections = soup.select("section")
Expand Down Expand Up @@ -130,7 +131,7 @@ def test_load_valid_json_without_data_is_empty_result(testdir, test_data):
testdir.makefile(".json", test_file=json.dumps(test_data))

runner = CliRunner()
result = runner.invoke(cli.main, ["html", "test_file.json"])
result = runner.invoke(cli.main, ["html", "test_file.json", "-o", "-"])
assert result.exit_code == 0, result.stdout

soup = BeautifulSoup(result.stdout, "lxml")
Expand All @@ -156,18 +157,55 @@ def test_load_valid_json_without_data_is_empty_result(testdir, test_data):
assert received_text.get_text(strip=True) == "No data."


def test_export_to_html_using_custom_path(testdir):
testdir.makefile(".json", test_file="{}")
results_path = testdir.tmpdir.join("results.html")

runner = CliRunner()
result = runner.invoke(
cli.main, ["html", "test_file.json", "-o", str(results_path)]
)
assert result.exit_code == 0, result.stdout
assert not result.stdout
assert results_path.check()


def test_export_to_html_using_custom_template(testdir):
testdir.makefile(".json", test_file="{}")
testdir.makefile(".html", test_template='{{ "hello world" }}')

runner = CliRunner()
result = runner.invoke(
cli.main, ["html", "test_file.json", "--template", "test_template.html"]
cli.main,
["html", "test_file.json", "-o", "-", "--template", "test_template.html"],
)
assert result.exit_code == 0, result.stdout
assert result.stdout == "hello world"


@pytest.mark.parametrize(
"additional_args, expected_save_path",
((["-o", "/somewhere/html"], "/somewhere/html"), ([], cli.DEFAULT_HTML_SAVE_PATH)),
)
@mock.patch.object(cli, "entries_to_html")
@mock.patch.object(cli, "_write_html_to_file")
def test_export_to_html_into_file(
mocked_write, mocked_entries_to_html, testdir, additional_args, expected_save_path
):
testdir.makefile(".json", test_file="{}")
runner = CliRunner()

mocked_entries_to_html.return_value = "hi!"

args = ["html", "test_file.json"] + additional_args
result = runner.invoke(cli.main, args)

assert result.exit_code == 0, result.stdout
assert not result.stdout

mocked_write.assert_called_once_with("hi!", expected_save_path)


def test_export_to_html_using_invalid_custom_template_should_fail(testdir):
testdir.makefile(".json", test_file="{}")
testdir.makefile(".html", test_template='{% "hello world" %}')
Expand Down

0 comments on commit 8489240

Please sign in to comment.