Skip to content

Commit

Permalink
Add CLI tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
dacut committed Mar 21, 2017
1 parent ec7b69b commit 2df05ec
Show file tree
Hide file tree
Showing 11 changed files with 282 additions and 4 deletions.
9 changes: 6 additions & 3 deletions assemyaml/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def main(args=None):
local_tags = True
output = sys.stdout

if args is None:
if args is None: # pragma: nocover
args = argv[1:]

try:
Expand Down Expand Up @@ -106,7 +106,10 @@ def main(args=None):
return result


def usage(fd=sys.stderr):
def usage(fd=None):
if fd is None: # Can't use default args for unit testing.
fd = sys.stderr

fd.write("""
Usage: %(argv0)s [options] template-document resource-documents...
%(argv0)s [options] --template template-document resource-documents...
Expand Down Expand Up @@ -148,5 +151,5 @@ def usage(fd=sys.stderr):
return


if __name__ == "__main__":
if __name__ == "__main__": # pragma: nocover
sys_exit(main(argv[1:]))
4 changes: 3 additions & 1 deletion assemyaml/transclude.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ def transclude(node, assemblies):
getattr(trans_value, "start_mark", None))

value = existing_value.union(trans_value)
elif not isinstance(existing_value, (NoneType, LocatableNull)):
elif isinstance(existing_value, (NoneType, LocatableNull)):
value = trans_value
else:
raise TranscludeError(
"Cannot set value for assembly %s: %s at" % (
trans_name, existing_value.py_type.__name__),
Expand Down
2 changes: 2 additions & 0 deletions tests/cli/bad-resource.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
!Assembly Hello:
!Assembly Foo:
2 changes: 2 additions & 0 deletions tests/cli/bad-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
!Template Hello:
!Template Bar:
21 changes: 21 additions & 0 deletions tests/cli/basic-expected.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-
- X
- Y
- Z
- M
- N
- O
-
A: 1
B: 2
C: 3
D: 4
E: 5
F: 6
- !!set
? F
? E
? D
? C
? B
? A
14 changes: 14 additions & 0 deletions tests/cli/basic-resource-1.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
- !Assembly ListTest:
- M
- N
- O
- !Assembly DictTest:
D: 4
E: 5
F: 6
- !Assembly SetTest: !!set
? D
? E
? A
? B
? F
12 changes: 12 additions & 0 deletions tests/cli/basic-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
- !Transclude ListTest:
- X
- Y
- Z
- !Transclude DictTest:
A: 1
B: 2
C: 3
- !Transclude SetTest: !!set
? A
? B
? C
21 changes: 21 additions & 0 deletions tests/cli/globaltag-expected.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-
- X
- Y
- Z
- M
- N
- O
-
A: 1
B: 2
C: 3
D: 4
E: 5
F: 6
- !!set
? F
? E
? D
? C
? B
? A
16 changes: 16 additions & 0 deletions tests/cli/globaltag-resource-1.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
%TAG !assemyaml! tag:assemyaml.nz,2017:
---
- !assemyaml!Assembly ListTest:
- M
- N
- O
- !assemyaml!Assembly DictTest:
D: 4
E: 5
F: 6
- !assemyaml!Assembly SetTest: !!set
? D
? E
? A
? B
? F
14 changes: 14 additions & 0 deletions tests/cli/globaltag-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
%TAG !assemyaml! tag:assemyaml.nz,2017:
---
- !assemyaml!Transclude ListTest:
- X
- Y
- Z
- !assemyaml!Transclude DictTest:
A: 1
B: 2
C: 3
- !assemyaml!Transclude SetTest: !!set
? A
? B
? C
171 changes: 171 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
from __future__ import absolute_import, print_function
from assemyaml import main
from contextlib import contextmanager
from os.path import dirname, exists
from shutil import rmtree
from six import string_types
from six.moves import cStringIO as StringIO
import sys
from tempfile import mkdtemp
from unittest import TestCase
from yaml import load as yaml_load


@contextmanager
def captured_output():
new_out, new_err = StringIO(), StringIO()
old_out, old_err = sys.stdout, sys.stderr
try:
sys.stdout, sys.stderr = new_out, new_err
yield sys.stdout, sys.stderr
finally:
sys.stdout, sys.stderr = old_out, old_err


class TestCLI(TestCase):
def setUp(self):
self.testdir = dirname(__file__) + "/cli/"
self.tempdir = mkdtemp()

def tearDown(self):
rmtree(self.tempdir)

def run_docs(self, template_filename, resource_filenames=(),
expected_returncode=0, expected_filename=None,
expected_errors=None, template_arg=False, local_tags=True,
output_filename=None, long_parameters=True):
args = []

if not local_tags:
args += ["--no-local-tag" if long_parameters else "-n"]

if output_filename is not None:
args += ["--output" if long_parameters else "-o", output_filename]

if template_arg:
args += ["--template" if long_parameters else "-t",
self.testdir + template_filename]
else:
args += [self.testdir + template_filename]

args += [self.testdir + r for r in resource_filenames]
with captured_output() as (out, err):
result = main(args)

out = out.getvalue()
err = err.getvalue()

self.assertEquals(result, expected_returncode)

if expected_filename is not None:
if output_filename:
with open(output_filename, "r") as fd:
actual = yaml_load(fd)
else:
actual = yaml_load(out)
with open(self.testdir + expected_filename, "r") as fd:
expected = yaml_load(fd)

self.assertEquals(actual, expected)

if expected_errors is not None:
if isinstance(expected_errors, string_types):
self.assertIn(expected_errors, err)
else:
for error in expected_errors:
self.assertIn(error, err)
return

def test_basic(self):
self.run_docs(
template_filename="basic-template.yml",
resource_filenames=["basic-resource-1.yml"],
expected_filename="basic-expected.yml")
self.run_docs(
template_filename="basic-template.yml",
resource_filenames=["basic-resource-1.yml"],
expected_filename="basic-expected.yml",
template_arg=True)
self.run_docs(
template_filename="basic-template.yml",
resource_filenames=["basic-resource-1.yml"],
expected_filename="basic-expected.yml",
output_filename=self.tempdir + "basic-actual.yml")
self.run_docs(
template_filename="basic-template.yml",
resource_filenames=["basic-resource-1.yml"],
expected_filename="basic-expected.yml",
template_arg=True,
output_filename=self.tempdir + "basic-actual.yml")

def test_globaltag(self):
self.run_docs(
template_filename="globaltag-template.yml",
resource_filenames=["globaltag-resource-1.yml"],
expected_filename="globaltag-expected.yml",
local_tags=False)
self.run_docs(
template_filename="globaltag-template.yml",
resource_filenames=["globaltag-resource-1.yml"],
expected_filename="globaltag-expected.yml",
template_arg=True,
local_tags=False)

def test_bad_template(self):
self.run_docs(
template_filename="bad-template.yml",
expected_returncode=1,
expected_errors="Error while processing template document")

self.run_docs(
template_filename="bad-template.yml",
resource_filenames=["bad-resource.yml"],
expected_returncode=1,
expected_errors="Error while processing resource document")

def test_bad_args(self):
with captured_output() as (out, err):
result = main(["-x"])

self.assertEquals(result, 2)
err = err.getvalue()
self.assertIn("option -x not recognized", err)
self.assertIn("Usage:", err)

def test_help(self):
with captured_output() as (out, err):
result = main(["-h"])

self.assertEquals(result, 0)
out = out.getvalue()
err = err.getvalue()
self.assertIn("Usage:", out)

def test_unwritable_output(self):
self.run_docs(
template_filename="basic-template.yml",
expected_returncode=1,
expected_errors="Unable to open / for writing",
output_filename="/")

def test_unreadable_input(self):
self.run_docs(
template_filename="missing",
resource_filenames=["basic-resource-1.yml"],
expected_returncode=1,
expected_errors=("Unable to open", "for reading:"))

self.run_docs(
template_filename="basic-template.yml",
resource_filenames=["missing"],
expected_returncode=1,
expected_errors=("Unable to open", "for reading:"))

def test_no_args(self):
with captured_output() as (out, err):
result = main([])

self.assertEquals(result, 2)
err = err.getvalue()
self.assertIn("Missing template filename", err)
self.assertIn("Usage:", err)

0 comments on commit 2df05ec

Please sign in to comment.