import unittest from shell_command import ShellCommand from shell_command.tests import ShellCommandSharedTestCase class ShellCommandTestCase(ShellCommandSharedTestCase): """Test the ShellCommand class.""" def setUp(self): """Set up for test.""" # Make sure the input and output options are explicitly set to # [] otherwise they hang around from previous tests. self.command = ShellCommand(input_options=[], output_options=[]) self.expected_executable = "" self.expected_base_options = [] self.expected_input_options = [] self.expected_filter_options = [] self.expected_output_options = [] def tearDown(self): """Clean up after test.""" self.command = None def test_shellquote(self): """Test shell quoting (static method).""" test_data = ( (None, None, "None ⇒ None"), ("", "", "(empty string) ⇒ (empty string)"), (" ", '" "', '␢ ⇒ " "'), (" ", '" "', '␢␢␢␢␢ ⇒ " "'), ("foobar", "foobar", "foobar ⇒ foobar"), ("foo bar", '"foo bar"', 'foo bar ⇒ "foo bar"'), ('"foobar"', '\'"foobar"\'', '"foobar" ⇒ \'"foobar"\''), ("'foobar'", "'foobar'", "'foobar' ⇒ 'foobar'"), ("foo 'bar'", '"foo \'bar\'"', "foo 'bar' ⇒ \"foo 'bar'\""), ('foo"bar', '\'foo"bar\'', 'foo"bar ⇒ \'foo"bar\''), ("foo.bar", '"foo.bar"', 'foo.bar ⇒ "foo.bar"'), ("foo(bar)", '"foo(bar)"', 'foo(bar) ⇒ "foo(bar)"'), ("[foobar]", '"[foobar]"', '[foobar] ⇒ "[foobar]"'), ("foo[bar", '"foo[bar"', 'foo[bar ⇒ "foo[bar"'), ("/foo/bar", "/foo/bar", "/foo/bar ⇒ /foo/bar"), ("-f", "-f", "-f ⇒ -f"), ("--foobar", "--foobar", "--foobar ⇒ --foobar"), ("(", r"\(", r"( ⇒ \("), (")", r"\)", r"( ⇒ \)"), ("'", '"\'"', '\' ⇒ "\'"'), ) for original, expected, description in test_data: with self.subTest(msg=description): self.assertEqual(ShellCommand.shellquote(original), expected) def test_append_input_options(self): """Test appending to input options.""" with self.subTest(msg="should initially be []"): self.assertEqual(self.command.input_options, []) test_data = ( ([], [], "[] ⇒ []"), (["foo"], ["foo"], '["foo"] ⇒ ["foo"]'), (["bar"], ["foo", "bar"], '["bar"] ⇒ ["foo", "bar"]'), (["baz", 42], ["foo", "bar", "baz", 42], '["baz", 42] ⇒ ["foo", "bar", "baz", 42]'), ) for appended, expected, description in test_data: with self.subTest(msg="appending {}".format(description)): self.command.append_input_options(appended) self.assertEqual(self.command.input_options, expected) def test_prepend_input_options(self): """Test prepending to input options.""" with self.subTest(msg="should initially be []"): self.assertEqual(self.command.input_options, []) test_data = ( ([], [], "[] ⇒ []"), (["foo"], ["foo"], '["foo"] ⇒ ["foo"]'), (["bar"], ["bar", "foo"], '["bar"] ⇒ ["bar", "foo"]'), (["baz", 42], ["baz", 42, "bar", "foo"], '["baz", 42] ⇒ ["baz", 42, "bar", "foo"]'), ) for prepended, expected, description in test_data: with self.subTest(msg="prepending {}".format(description)): self.command.prepend_input_options(prepended) self.assertEqual(self.command.input_options, expected) def test_append_output_options(self): """Test appending to output options.""" with self.subTest(msg="should initially be []"): self.assertEqual(self.command.output_options, []) test_data = ( ([], [], "[] ⇒ []"), (["foo"], ["foo"], '["foo"] ⇒ ["foo"]'), (["bar"], ["foo", "bar"], '["bar"] ⇒ ["foo", "bar"]'), (["baz", 42], ["foo", "bar", "baz", 42], '["baz", 42] ⇒ ["foo", "bar", "baz", 42]'), ) for appended, expected, description in test_data: with self.subTest(msg="appending {}".format(description)): self.command.append_output_options(appended) self.assertEqual(self.command.output_options, expected) def test_prepend_output_options(self): """Test prepending to output options.""" with self.subTest(msg="should initially be []"): self.assertEqual(self.command.output_options, []) test_data = ( ([], [], "[] ⇒ []"), (["foo"], ["foo"], '["foo"] ⇒ ["foo"]'), (["bar"], ["bar", "foo"], '["bar"] ⇒ ["bar", "foo"]'), (["baz", 42], ["baz", 42, "bar", "foo"], '["baz", 42] ⇒ ["baz", 42, "bar", "foo"]'), ) for prepended, expected, description in test_data: with self.subTest(msg="prepending {}".format(description)): self.command.prepend_output_options(prepended) self.assertEqual(self.command.output_options, expected) def test_process_pattern(self): """ Test pattern processing.""" # True on EOF (0) with self.subTest(msg="returns True on EOF"): self.assertTrue(self.command.process_pattern(0)) # False on anything else for i in (x for x in range(-1000, 1001) if x is not 0): with self.subTest(msg="returns False on {}".format(i)): self.assertFalse(self.command.process_pattern(i)) # The following two will require mocking of pexpect? def test_run(self): """Test running of subprocess.""" pass def test_get_output(self): """Test getting output from subprocess.""" pass # Remove ShellCommandSharedTestCase from the namespace so we don't run # the shared tests twice. See <https://stackoverflow.com/a/22836015>. del(ShellCommandSharedTestCase)