def tasks_dedupe_honors_configuration(self): # Kinda-sorta duplicates some tests in executor.py, but eh. with cd('configs'): # Runtime conf file expect("-c integration -f no-dedupe.yaml biz", out=""" foo foo bar biz post1 post2 post2 """.lstrip()) # Flag beats runtime expect("-c integration -f dedupe.yaml --no-dedupe biz", out=""" foo foo bar biz post1 post2 post2 """.lstrip())
def per_project_config_files_are_loaded_before_task_parsing(self): # Relies on auto_dash_names being loaded at project-conf level; # fixes #467; when bug present, project conf is loaded _after_ # attempt to parse tasks, causing explosion when i_have_underscores # is only sent to parser as i-have-underscores. with cd(os.path.join('configs', 'underscores')): expect("i_have_underscores")
def core_help_option_prints_core_help(self): # TODO: change dynamically based on parser contents? # e.g. no core args == no [--core-opts], # no tasks == no task stuff? # NOTE: test will trigger default pty size of 80x24, so the # below string is formatted appropriately. # TODO: add more unit-y tests for specific behaviors: # * fill terminal w/ columns + spacing # * line-wrap help text in its own column expected = """ Usage: inv[oke] [--core-opts] task1 [--task1-opts] ... taskN [--taskN-opts] Core options: --complete Print tab-completion candidates for given parse remainder. --hide=STRING Set default value of run()'s 'hide' kwarg. --no-dedupe Disable task deduplication. --write-pyc Enable creation of .pyc files. -c STRING, --collection=STRING Specify collection name to load. -d, --debug Enable debug output. -e, --echo Echo executed commands before running. -f STRING, --config=STRING Runtime configuration file to use. -h [STRING], --help[=STRING] Show core or per-task help and exit. -l, --list List available tasks. -p, --pty Use a pty when executing shell commands. -r STRING, --root=STRING Change root directory used for finding task modules. -V, --version Show version and exit. -w, --warn-only Warn, instead of failing, when shell commands fail. """.lstrip() for flag in ['-h', '--help']: expect(flag, out=expected, program=main.program)
def honors_program_binary(self): expect( '-c decorator -h biz', out="Usage: notinvoke", test=assert_contains, program=Program(binary='notinvoke') )
def benefits_from_binary_absolute_behavior(self): "benefits from binary()'s absolute path behavior" expect( "/usr/local/bin/myapp --version", out="Myapp unknown\n", invoke=False, )
def defaults_to_argv_when_None(self): expect( "myapp --help", out="myapp [--core-opts]", invoke=False, test=assert_contains )
def core_help_option_prints_core_help(self): # TODO: change dynamically based on parser contents? # e.g. no core args == no [--core-opts], # no tasks == no task stuff? # NOTE: test will trigger default pty size of 80x24, so the # below string is formatted appropriately. # TODO: add more unit-y tests for specific behaviors: # * fill terminal w/ columns + spacing # * line-wrap help text in its own column expected = """ Usage: inv[oke] [--core-opts] task1 [--task1-opts] ... taskN [--taskN-opts] Core options: --complete Print tab-completion candidates for given parse remainder. --hide=STRING Set default value of run()'s 'hide' kwarg. --no-dedupe Disable task deduplication. -c STRING, --collection=STRING Specify collection name to load. -d, --debug Enable debug output. -e, --echo Echo executed commands before running. -f STRING, --config=STRING Runtime configuration file to use. -h [STRING], --help[=STRING] Show core or per-task help and exit. -l, --list List available tasks. -p, --pty Use a pty when executing shell commands. -r STRING, --root=STRING Change root directory used for finding task modules. -V, --version Show version and exit. -w, --warn-only Warn, instead of failing, when shell commands fail. """.lstrip() for flag in ['-h', '--help']: expect(flag, out=expected, program=main.program)
def tasks_dedupe_honors_configuration(self): # Kinda-sorta duplicates some tests in executor.py, but eh. with cd('configs'): # Runtime conf file expect( "-c integration -f no-dedupe.yaml biz", out=""" foo foo bar biz post1 post2 post2 """.lstrip()) # Flag beats runtime expect( "-c integration -f dedupe.yaml --no-dedupe biz", out=""" foo foo bar biz post1 post2 post2 """.lstrip())
def loads_fabfile_not_tasks(self): "Loads fabfile.py, not tasks.py" with cd(support): expect( "--list", """ Available tasks: basic-run build deploy expect-from-env expect-identities expect-identity expect-mutation expect-mutation-to-fail expect-vanilla-Context first hosts-are-host-stringlike hosts-are-init-kwargs hosts-are-mixed-values hosts-are-myhost mutate second third two-hosts vanilla-Task-works-ok """.lstrip(), )
def null_namespace_triggers_task_related_args(self): program = Program(namespace=None) for arg in program.task_args(): expect("--help", program=program, out=arg.name, test=assert_contains)
def does_not_seek_tasks_module_if_namespace_was_given(self): with cd('implicit'): expect( 'foo', err="No idea what 'foo' is!\n", program=Program(namespace=Collection('blank')) )
def version_output_contains_our_name_plus_deps(self): expect("--version", r""" Fabric .+ Paramiko .+ Invoke .+ """.strip(), test='regex')
def cli_option_wins_over_env(self, reset_environ): # Set env var to load the JSON config instead of the YAML one, # which contains a "json" string internally. os.environ["INVOKE_RUNTIME_CONFIG"] = "json/invoke.json" with cd("configs"): # But run the default test task, which expects a "yaml" # string. If the env var won, this would explode. expect("-c runtime -f yaml/invoke.yaml mytask")
def non_null_namespace_does_not_trigger_task_related_args(self): for arg in Program().task_args(): expect( "--help", out=arg.name, program=Program(namespace=Collection(mytask=Task(Mock()))), test=assert_not_contains, )
def custom_binary_name_completes(self): expect( "myapp -c integration --complete -- ba", program=Program(binary="myapp"), invoke=False, out="bar", test=_assert_contains, )
def uses_overridden_value_when_given(self): expect( "myapp --help", out="nope [--core-opts]", program=Program(binary='nope'), invoke=False, test=assert_contains )
def explicit_namespace_works_correctly(self): # Regression-ish test re #288 ns = Collection.from_module(load('integration')) expect( 'print-foo', out='foo\n', program=Program(namespace=ns), )
def explicit_namespace_works_correctly(self): # Regression-ish test re #288 ns = Collection.from_module(load('integration')) expect( 'print_foo', out='foo\n', program=Program(namespace=ns), )
def contains_truly_core_arguments_regardless_of_namespace_value(self): # Spot check. See integration-style --help tests for full argument # checkup. for program in (Program(), Program(namespace=Collection())): for arg in ('--complete', '--debug', '--warn-only', '--list'): expect("--help", program=program, out=arg, test=assert_contains)
def aliased_custom_binary_name_completes(self): for used_binary in ("my", "myapp"): expect( "{0} -c integration --complete -- ba".format(used_binary), program=Program(binary="my[app]"), invoke=False, out="bar", test=_assert_contains, )
def null_namespace_triggers_task_related_args(self): program = Program(namespace=None) for arg in program.task_args(): expect( "--help", program=program, out=arg.name, test=assert_contains )
def version_output_contains_our_name_plus_deps(self): expect( "--version", r""" Fabric .+ Paramiko .+ Invoke .+ """.strip(), test='regex' )
def empty_namespaces_say_no_tasks_in_namespace(self): # In other words, outer namespace may not be empty, but the # inner one is - this should act just like when there is no # namespace explicitly requested and there's no tasks. # TODO: should the name in the error message be the fully # qualified one instead? expect( "-c empty_subcollection -l subcollection", err="No tasks found in collection 'subcollection'!\n" # noqa )
def chaining_is_depth_first(self): expect('-c depth_first deploy', out=""" Cleaning HTML Cleaning .tar.gz files Cleaned everything Making directories Building Deploying Preparing for testing Testing """.lstrip())
def contains_truly_core_arguments_regardless_of_namespace_value(self): # Spot check. See integration-style --help tests for full argument # checkup. for program in (Program(), Program(namespace=Collection())): for arg in ('--complete', '--debug', '--warn-only'): expect( "--help", program=program, out=arg, test=assert_contains )
def displays_docstrings_if_given(self): expected = """ Usage: invoke [--core-opts] foo [other tasks here ...] Docstring: Foo the bar. Options: none """.lstrip() expect('-c decorator -h foo', out=expected)
def works_for_unparameterized_tasks(self): expected = """ Usage: invoke [--core-opts] biz [other tasks here ...] Docstring: none Options: none """.lstrip() expect('-c decorator -h biz', out=expected)
def works_for_unparameterized_tasks(self): expected = """ Usage: invoke [--core-opts] biz [other tasks here ...] Docstring: none Options: none """.lstrip() expect("-c decorators -h biz", out=expected)
def displays_docstrings_if_given(self): expected = """ Usage: invoke [--core-opts] foo [other tasks here ...] Docstring: Foo the bar. Options: none """.lstrip() expect("-c decorators -h foo", out=expected)
def simple_output(self): expected = self._listing(( 'bar', 'biz', 'boz', 'foo', 'post1', 'post2', 'print_foo', 'print_name', 'print_underscored_arg', )) for flag in ('-l', '--list'): expect('-c integration {0}'.format(flag), out=expected)
def only_accepts_certain_shells(self): expect( "--print-completion-script", err="needed value and was not given one", test=_assert_contains, ) expect( "--print-completion-script bla", # NOTE: this needs updating when the real world changes, just like # eg our --help output tests. That's OK & better than just # reimplementing the code under test here. err='Completion for shell "bla" not supported (options are: bash, fish, zsh).', # noqa test=_assert_contains, )
def prints_help_for_task_only(self): expected = """ Usage: invoke [--core-opts] punch [--options] [other tasks here ...] Docstring: none Options: -h STRING, --why=STRING Motive -w STRING, --who=STRING Who to punch """.lstrip() for flag in ['-h', '--help']: expect('-c decorator {0} punch'.format(flag), out=expected)
def prints_help_for_task_only(self): expected = """ Usage: invoke [--core-opts] punch [--options] [other tasks here ...] Docstring: none Options: -h STRING, --why=STRING Motive -w STRING, --who=STRING Who to punch """.lstrip() for flag in ["-h", "--help"]: expect("-c decorators {} punch".format(flag), out=expected)
def simple_output(self): expected = self._listing(( "bar", "biz", "boz", "foo", "post1", "post2", "print-foo", "print-name", "print-underscored-arg", )) for flag in ("-l", "--list"): expect("-c integration {}".format(flag), out=expected)
def exits_after_printing(self): # TODO: find & test the other variants of this error case, such # as core --help not exiting, --list not exiting, etc expected = """ Usage: invoke [--core-opts] punch [--options] [other tasks here ...] Docstring: none Options: -h STRING, --why=STRING Motive -w STRING, --who=STRING Who to punch """.lstrip() expect("-c decorator -h punch --list", out=expected)
def exits_after_printing(self): # TODO: find & test the other variants of this error case, such # as core --help not exiting, --list not exiting, etc expected = """ Usage: invoke [--core-opts] punch [--options] [other tasks here ...] Docstring: none Options: -h STRING, --why=STRING Motive -w STRING, --who=STRING Who to punch """.lstrip() expect("-c decorators -h punch --list", out=expected)
def simple_output(self): expected = self._listing( ( "bar", "biz", "boz", "foo", "post1", "post2", "print-foo", "print-name", "print-underscored-arg", ) ) for flag in ("-l", "--list"): expect("-c integration {}".format(flag), out=expected)
def dedents_correctly_for_alt_docstring_style(self): expected = """ Usage: invoke [--core-opts] foo3 [other tasks here ...] Docstring: Foo the other bar: example code Added in 1.1 Options: none """.lstrip() expect("-c decorators -h foo3", out=expected)
def dedents_correctly(self): expected = """ Usage: invoke [--core-opts] foo2 [other tasks here ...] Docstring: Foo the bar: example code Added in 1.0 Options: none """.lstrip() expect('-c decorator -h foo2', out=expected)
def dedents_correctly(self): expected = """ Usage: invoke [--core-opts] foo2 [other tasks here ...] Docstring: Foo the bar: example code Added in 1.0 Options: none """.lstrip() expect("-c decorators -h foo2", out=expected)
def dedents_correctly_for_alt_docstring_style(self): expected = """ Usage: invoke [--core-opts] foo3 [other tasks here ...] Docstring: Foo the other bar: example code Added in 1.1 Options: none """.lstrip() expect('-c decorator -h foo3', out=expected)
def default_binary_names_is_completing_argv_0(self): out, err = expect( "someappname --print-completion-script zsh", program=Program(binary_names=None), invoke=False, ) assert "_complete_someappname() {" in out assert " someappname" in out
def core_help_option_prints_core_help(self): # TODO: change dynamically based on parser contents? # e.g. no core args == no [--core-opts], # no tasks == no task stuff? # NOTE: test will trigger default pty size of 80x24, so the # below string is formatted appropriately. # TODO: add more unit-y tests for specific behaviors: # * fill terminal w/ columns + spacing # * line-wrap help text in its own column expected = """ Usage: inv[oke] [--core-opts] task1 [--task1-opts] ... taskN [--taskN-opts] Core options: --complete Print tab-completion candidates for given parse remainder. --hide=STRING Set default value of run()'s 'hide' kwarg. --no-dedupe Disable task deduplication. --print-completion-script=STRING Print the tab-completion script for your preferred shell (bash|zsh|fish). --prompt-for-sudo-password Prompt user at start of session for the sudo.password config value. --write-pyc Enable creation of .pyc files. -c STRING, --collection=STRING Specify collection name to load. -d, --debug Enable debug output. -D INT, --list-depth=INT When listing tasks, only show the first INT levels. -e, --echo Echo executed commands before running. -f STRING, --config=STRING Runtime configuration file to use. -F STRING, --list-format=STRING Change the display format used when listing tasks. Should be one of: flat (default), nested, json. -h [STRING], --help[=STRING] Show core or per-task help and exit. -l [STRING], --list[=STRING] List available tasks, optionally limited to a namespace. -p, --pty Use a pty when executing shell commands. -r STRING, --search-root=STRING Change root directory used for finding task modules. -V, --version Show version and exit. -w, --warn-only Warn, instead of failing, when shell commands fail. """.lstrip() for flag in ["-h", "--help"]: expect(flag, out=expected, program=main.program)
def bash_works(self): out, err = expect( "someappname --print-completion-script bash", invoke=False ) assert "_complete_someappname() {" in out assert "complete -F" in out for line in out.splitlines(): if line.startswith("complete -F"): assert line.endswith(" someappname")
def prints_for_custom_binary_names(self): out, err = expect( "myapp --print-completion-script zsh", program=Program(binary_names=["mya", "myapp"]), invoke=False, ) # Combines some sentinels from vanilla test, with checks that it's # really replacing 'invoke' with desired binary names assert "_complete_mya() {" in out assert "invoke" not in out assert " mya myapp" in out