Skip to content

Commit

Permalink
refactor tests to fix cross-unix compatability issues, make variable …
Browse files Browse the repository at this point in the history
…file parser tests easier to read and understand, and implementent testing for ini and csv file parsing
  • Loading branch information
Alex Tremblay authored and kblomqvist committed Aug 18, 2020
1 parent aebda08 commit 2ff0ba2
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 40 deletions.
227 changes: 188 additions & 39 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,18 @@
THE SOFTWARE.
"""

import pytest
from os import path, chdir
import subprocess
from subprocess import call, check_output
from textwrap import dedent

import pytest
from yasha.cli import cli
from click.testing import CliRunner

def wrap(text):
return dedent(text).lstrip()


@pytest.fixture(params=('json', 'yaml', 'yml', 'toml'))
def vartpl(request):
Expand All @@ -39,24 +47,162 @@ def vartpl(request):
return (template[fmt], fmt)


@pytest.fixture
def varfile(vartpl, tmpdir):
content = {'int': 1}
template, filext = vartpl
file = tmpdir.join('variables.{}'.format(filext))
file.write(template.format(**content))
return file


def test_explicit_variable_file(tmpdir, varfile):
@pytest.fixture(params=('json', 'yaml', 'yml', 'toml', 'ini', 'csv', 'csv_with_header'))
def testdata(request):
templates = dict(
default=wrap("""
{% for item in list_data %}
"{{ item.key1 }}"=>{{ item.key2 }}
{% endfor %}
{{ a_variable }}
{{ a.nested.variable }}"""),
# Ini files don't support the kinds of arbitrarily nested data structures found in the default template,
# so they can only be tested with a template which uses data structured in ini-format (ie a dict (the ini file)
# of dicts(the sections of the ini file) of keys (whose values can be None or strings)
ini=wrap("""
Section One, variable one: {{ section_one.variable_one }}
{{ section_two.key }}"""),
# CSV files don't support the kinds of arbitrarily nested data structures found in the default template,
# so they can only be tested with a template which uses data structured in csv-format
# ie. a list of dicts if the csv file has a header row, a list of lists if it doesn't
csv=wrap("""
{% for row in data %}
cell 1 is {{ row[0] }}, cell 2 is {{ row[1] }}
{% endfor %}"""),
csv_with_header=wrap("""
{% for row in data %}
cell 1 is {{ row.first_column }}, cell 2 is {{ row.second_column }}
{% endfor %}""")
)
output = dict(
default=wrap("""
"some value"=>key2 value
"another value"=>another key2 value
a variable value
a nested value"""),
ini=wrap("""
Section One, variable one: S1 V1 value
S2 key value"""),
csv=wrap("""
cell 1 is value1, cell 2 is 2
cell 1 is value3, cell 2 is 4
cell 1 is value5, cell 2 is 6
cell 1 is value7, cell 2 is 8
cell 1 is value9, cell 2 is 10
""")
)
data = dict(
# Each entry is a list of strings [template, expected_output, data, extension]
json=[
templates['default'],
output['default'],
wrap("""
{
"list_data": [
{
"key1": "some value",
"key2": "key2 value"
},
{
"key1": "another value",
"key2": "another key2 value"
}
],
"a_variable": "a variable value",
"a": {
"nested": {
"variable": "a nested value"
}
}
}"""),
'json'
],
yaml=[
templates['default'],
output['default'],
wrap("""
list_data:
- key1: some value
key2: key2 value
- key1: another value
key2: another key2 value
a_variable: a variable value
a:
nested:
variable: a nested value
"""),
'yaml'
],
toml=[
templates['default'],
output['default'],
wrap("""
a_variable = "a variable value"
[[list_data]]
key1 = "some value"
key2 = "key2 value"
[[list_data]]
key1 = "another value"
key2 = "another key2 value"
[a.nested]
variable = "a nested value"
"""),
'toml'
],
ini=[
templates['ini'],
output['ini'],
wrap("""
[section_one]
variable_one = S1 V1 value
[section_two]
key = S2 key value
"""),
'ini'
],
csv=[
templates['csv'],
output['csv'],
wrap("""
value1,2
value3,4
value5,6
value7,8
value9,10"""),
'csv'
],
csv_with_header=[
templates['csv_with_header'],
output['csv'],
wrap("""
first_column,second_column
value1,2
value3,4
value5,6
value7,8
value9,10"""),
'csv'
]
)
data['yml'] = data['yaml']
data['yml'][3] = 'yml'
fmt = request.param
return data[fmt]


def test_explicit_variable_file(tmpdir, testdata):
template, expected_output, data, extension = testdata
tpl = tmpdir.join('template.j2')
tpl.write('{{ int }}')
tpl.write(template)
datafile = tmpdir.join('data.{}'.format(extension))
datafile.write(data)

errno = call(('yasha', '-v', str(varfile), str(tpl)))
assert errno == 0
runner = CliRunner()
result = runner.invoke(cli, ['-v', str(datafile), str(tpl)])
assert result.exit_code == 0

output = tmpdir.join('template')
assert output.read() == '1'
assert output.read() == expected_output


def test_two_explicitly_given_variables_files(tmpdir):
Expand All @@ -72,8 +218,9 @@ def test_two_explicitly_given_variables_files(tmpdir):
b = tmpdir.join('b.toml')
b.write('b = 2\nc = 3')

errno = call(('yasha', '-v', str(a), '-v', str(b), str(tpl)))
assert errno == 0
runner = CliRunner()
result = runner.invoke(cli, ['-v', str(a), '-v', str(b), str(tpl)])
assert result.exit_code == 0

output = tmpdir.join('template')
assert output.read() == '6' # a + b + c = 1 + 2 + 3 = 6
Expand All @@ -98,8 +245,9 @@ def test_variable_file_lookup(tmpdir, vartpl):
varfile = tmpdir.join(varfile)
varfile.write(vartpl[0].format(int=i))

errno = call(('yasha', 'sub/foo.c.j2'))
assert errno == 0
runner = CliRunner()
result = runner.invoke(cli, ['sub/foo.c.j2'])
assert result.exit_code == 0
assert path.isfile('sub/foo.c')

output = tmpdir.join('sub/foo.c')
Expand Down Expand Up @@ -152,8 +300,9 @@ def parse_xml(file):
file = tmpdir.join("foo.j2ext")
file.write(extensions)

errno = call(["yasha", "foo.toml.jinja"])
assert errno == 0
runner = CliRunner()
result = runner.invoke(cli, ['foo.toml.jinja'])
assert result.exit_code == 0
assert path.isfile("foo.toml")

o = tmpdir.join("foo.toml")
Expand All @@ -180,11 +329,11 @@ def test_broken_extensions(tmpdir):
ext = tmpdir.join("foo.j2ext")
ext.write(extensions)

with pytest.raises(CalledProcessError) as e:
cmd = ["yasha", "foo.jinja"]
check_output(cmd, stderr=STDOUT)
assert e.value.returncode == 1
assert b"Invalid syntax (foo.j2ext, line 1)" in e.value.output
runner = CliRunner()
result = runner.invoke(cli, ['foo.jinja'])
assert result.exit_code == 1
assert result.exception
assert "Invalid syntax (foo.j2ext, line 1)" in result.stdout


def test_broken_extensions_name_error(tmpdir):
Expand All @@ -199,16 +348,16 @@ def test_broken_extensions_name_error(tmpdir):
ext = tmpdir.join("foo.j2ext")
ext.write(extensions)

with pytest.raises(CalledProcessError) as e:
cmd = ["yasha", "foo.jinja"]
check_output(cmd, stderr=STDOUT)
assert e.value.returncode == 1
assert b"name 'asd' is not defined" in e.value.output
runner = CliRunner()
result = runner.invoke(cli, ['foo.jinja'])
assert result.exit_code == 1
assert result.exception
assert "name 'asd' is not defined" in result.stdout


def test_render_template_from_stdin_to_stdout():
cmd = r'echo -n "{{ foo }}" | yasha --foo=bar -'
out = check_output(cmd, shell=True)
cmd = r'yasha --foo=bar -'
out = check_output(cmd, shell=True, input=b"{{ foo }}")
assert out == b'bar'


Expand All @@ -225,24 +374,24 @@ def test_json_template(tmpdir):

def test_mode_is_none():
"""gh-42, and gh-44"""
cmd = r'echo -n "{{ foo }}" | yasha -'
out = check_output(cmd, shell=True)
cmd = r'yasha -'
out = check_output(cmd, shell=True, input=b"{{ foo }}")
assert out == b''


def test_mode_is_pedantic():
"""gh-42, and gh-48"""
with pytest.raises(subprocess.CalledProcessError) as err:
cmd = r'echo -n "{{ foo }}" | yasha --mode=pedantic -'
out = check_output(cmd, shell=True, stderr=subprocess.STDOUT)
cmd = r'yasha --mode=pedantic -'
out = check_output(cmd, shell=True, stderr=subprocess.STDOUT, input=b"{{ foo }}")
out = err.value.output
assert out == b"Error: Variable 'foo' is undefined\n"


def test_mode_is_debug():
"""gh-44"""
cmd = r'echo -n "{{ foo }}" | yasha --mode=debug -'
out = check_output(cmd, shell=True)
cmd = r'yasha --mode=debug -'
out = check_output(cmd, shell=True, input=b"{{ foo }}")
assert out == b'{{ foo }}'


Expand Down
2 changes: 1 addition & 1 deletion tests/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def test_subprocess_with_unknown_cmd():
template = '{{ "unknown_cmd" | subprocess }}'
out, retcode = check_output('yasha', '-', stdin=template)
assert retcode != 0
assert b'unknown_cmd: not found' in out
assert b'not found' in out


@requires_py3
Expand Down

0 comments on commit 2ff0ba2

Please sign in to comment.