busser-behave 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.cane +0 -0
- data/.gitignore +17 -0
- data/.tailor +4 -0
- data/.travis.yml +11 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +3 -0
- data/LICENSE +15 -0
- data/README.md +41 -0
- data/Rakefile +68 -0
- data/busser-behave.gemspec +30 -0
- data/features/plugin_install_command.feature +11 -0
- data/features/plugin_list_command.feature +8 -0
- data/features/support/env.rb +13 -0
- data/features/test_command.feature +31 -0
- data/lib/busser/behave/version.rb +26 -0
- data/lib/busser/runner_plugin/behave.rb +37 -0
- data/vendor/behave/CHANGES.rst +483 -0
- data/vendor/behave/LICENSE +23 -0
- data/vendor/behave/MANIFEST.in +37 -0
- data/vendor/behave/PROJECT_INFO.rst +21 -0
- data/vendor/behave/README.rst +112 -0
- data/vendor/behave/VERSION.txt +1 -0
- data/vendor/behave/behave.ini +22 -0
- data/vendor/behave/behave/__init__.py +30 -0
- data/vendor/behave/behave/__main__.py +187 -0
- data/vendor/behave/behave/_stepimport.py +185 -0
- data/vendor/behave/behave/_types.py +134 -0
- data/vendor/behave/behave/api/__init__.py +7 -0
- data/vendor/behave/behave/api/async_step.py +283 -0
- data/vendor/behave/behave/capture.py +227 -0
- data/vendor/behave/behave/compat/__init__.py +5 -0
- data/vendor/behave/behave/compat/collections.py +20 -0
- data/vendor/behave/behave/configuration.py +788 -0
- data/vendor/behave/behave/contrib/__init__.py +0 -0
- data/vendor/behave/behave/contrib/scenario_autoretry.py +73 -0
- data/vendor/behave/behave/formatter/__init__.py +12 -0
- data/vendor/behave/behave/formatter/_builtins.py +39 -0
- data/vendor/behave/behave/formatter/_registry.py +135 -0
- data/vendor/behave/behave/formatter/ansi_escapes.py +91 -0
- data/vendor/behave/behave/formatter/base.py +200 -0
- data/vendor/behave/behave/formatter/formatters.py +57 -0
- data/vendor/behave/behave/formatter/json.py +253 -0
- data/vendor/behave/behave/formatter/null.py +12 -0
- data/vendor/behave/behave/formatter/plain.py +158 -0
- data/vendor/behave/behave/formatter/pretty.py +351 -0
- data/vendor/behave/behave/formatter/progress.py +287 -0
- data/vendor/behave/behave/formatter/rerun.py +114 -0
- data/vendor/behave/behave/formatter/sphinx_steps.py +372 -0
- data/vendor/behave/behave/formatter/sphinx_util.py +118 -0
- data/vendor/behave/behave/formatter/steps.py +497 -0
- data/vendor/behave/behave/formatter/tags.py +178 -0
- data/vendor/behave/behave/i18n.py +614 -0
- data/vendor/behave/behave/importer.py +102 -0
- data/vendor/behave/behave/json_parser.py +264 -0
- data/vendor/behave/behave/log_capture.py +233 -0
- data/vendor/behave/behave/matchers.py +402 -0
- data/vendor/behave/behave/model.py +1737 -0
- data/vendor/behave/behave/model_core.py +416 -0
- data/vendor/behave/behave/model_describe.py +105 -0
- data/vendor/behave/behave/parser.py +615 -0
- data/vendor/behave/behave/reporter/__init__.py +0 -0
- data/vendor/behave/behave/reporter/base.py +45 -0
- data/vendor/behave/behave/reporter/junit.py +473 -0
- data/vendor/behave/behave/reporter/summary.py +94 -0
- data/vendor/behave/behave/runner.py +753 -0
- data/vendor/behave/behave/runner_util.py +417 -0
- data/vendor/behave/behave/step_registry.py +112 -0
- data/vendor/behave/behave/tag_expression.py +111 -0
- data/vendor/behave/behave/tag_matcher.py +465 -0
- data/vendor/behave/behave/textutil.py +137 -0
- data/vendor/behave/behave/userdata.py +130 -0
- data/vendor/behave/behave4cmd0/__all_steps__.py +12 -0
- data/vendor/behave/behave4cmd0/__init__.py +5 -0
- data/vendor/behave/behave4cmd0/__setup.py +11 -0
- data/vendor/behave/behave4cmd0/command_shell.py +216 -0
- data/vendor/behave/behave4cmd0/command_shell_proc.py +256 -0
- data/vendor/behave/behave4cmd0/command_steps.py +532 -0
- data/vendor/behave/behave4cmd0/command_util.py +147 -0
- data/vendor/behave/behave4cmd0/failing_steps.py +49 -0
- data/vendor/behave/behave4cmd0/log/__init__.py +1 -0
- data/vendor/behave/behave4cmd0/log/steps.py +395 -0
- data/vendor/behave/behave4cmd0/note_steps.py +29 -0
- data/vendor/behave/behave4cmd0/passing_steps.py +36 -0
- data/vendor/behave/behave4cmd0/pathutil.py +146 -0
- data/vendor/behave/behave4cmd0/setup_command_shell.py +24 -0
- data/vendor/behave/behave4cmd0/textutil.py +304 -0
- data/vendor/behave/bin/behave +44 -0
- data/vendor/behave/bin/behave.cmd +10 -0
- data/vendor/behave/bin/behave.junit_filter.py +85 -0
- data/vendor/behave/bin/behave.step_durations.py +163 -0
- data/vendor/behave/bin/behave2cucumber_json.py +63 -0
- data/vendor/behave/bin/behave_cmd.py +44 -0
- data/vendor/behave/bin/convert_i18n_yaml.py +77 -0
- data/vendor/behave/bin/explore_platform_encoding.py +24 -0
- data/vendor/behave/bin/i18n.yml +621 -0
- data/vendor/behave/bin/invoke +8 -0
- data/vendor/behave/bin/invoke.cmd +9 -0
- data/vendor/behave/bin/json.format.py +167 -0
- data/vendor/behave/bin/jsonschema_validate.py +122 -0
- data/vendor/behave/bin/make_localpi.py +279 -0
- data/vendor/behave/bin/project_bootstrap.sh +30 -0
- data/vendor/behave/bin/toxcmd.py +270 -0
- data/vendor/behave/bin/toxcmd3.py +270 -0
- data/vendor/behave/conftest.py +27 -0
- data/vendor/behave/docs/Makefile +154 -0
- data/vendor/behave/docs/_static/agogo.css +501 -0
- data/vendor/behave/docs/_static/behave_logo.png +0 -0
- data/vendor/behave/docs/_static/behave_logo1.png +0 -0
- data/vendor/behave/docs/_static/behave_logo2.png +0 -0
- data/vendor/behave/docs/_static/behave_logo3.png +0 -0
- data/vendor/behave/docs/_themes/LICENSE +45 -0
- data/vendor/behave/docs/_themes/kr/layout.html +17 -0
- data/vendor/behave/docs/_themes/kr/relations.html +19 -0
- data/vendor/behave/docs/_themes/kr/static/flasky.css_t +480 -0
- data/vendor/behave/docs/_themes/kr/static/small_flask.css +90 -0
- data/vendor/behave/docs/_themes/kr/theme.conf +7 -0
- data/vendor/behave/docs/_themes/kr_small/layout.html +22 -0
- data/vendor/behave/docs/_themes/kr_small/static/flasky.css_t +287 -0
- data/vendor/behave/docs/_themes/kr_small/theme.conf +10 -0
- data/vendor/behave/docs/api.rst +408 -0
- data/vendor/behave/docs/appendix.rst +19 -0
- data/vendor/behave/docs/behave.rst +640 -0
- data/vendor/behave/docs/behave.rst-template +86 -0
- data/vendor/behave/docs/behave_ecosystem.rst +81 -0
- data/vendor/behave/docs/comparison.rst +85 -0
- data/vendor/behave/docs/conf.py +293 -0
- data/vendor/behave/docs/context_attributes.rst +66 -0
- data/vendor/behave/docs/django.rst +192 -0
- data/vendor/behave/docs/formatters.rst +61 -0
- data/vendor/behave/docs/gherkin.rst +673 -0
- data/vendor/behave/docs/index.rst +57 -0
- data/vendor/behave/docs/install.rst +60 -0
- data/vendor/behave/docs/more_info.rst +184 -0
- data/vendor/behave/docs/new_and_noteworthy.rst +18 -0
- data/vendor/behave/docs/new_and_noteworthy_v1.2.4.rst +11 -0
- data/vendor/behave/docs/new_and_noteworthy_v1.2.5.rst +814 -0
- data/vendor/behave/docs/new_and_noteworthy_v1.2.6.rst +255 -0
- data/vendor/behave/docs/parse_builtin_types.rst +59 -0
- data/vendor/behave/docs/philosophy.rst +235 -0
- data/vendor/behave/docs/regular_expressions.rst +71 -0
- data/vendor/behave/docs/related.rst +14 -0
- data/vendor/behave/docs/test_domains.rst +62 -0
- data/vendor/behave/docs/tutorial.rst +636 -0
- data/vendor/behave/docs/update_behave_rst.py +100 -0
- data/vendor/behave/etc/json/behave.json-schema +172 -0
- data/vendor/behave/etc/junit.xml/behave_junit.xsd +103 -0
- data/vendor/behave/etc/junit.xml/junit-4.xsd +92 -0
- data/vendor/behave/examples/async_step/README.txt +8 -0
- data/vendor/behave/examples/async_step/behave.ini +14 -0
- data/vendor/behave/examples/async_step/features/async_dispatch.feature +8 -0
- data/vendor/behave/examples/async_step/features/async_run.feature +6 -0
- data/vendor/behave/examples/async_step/features/environment.py +28 -0
- data/vendor/behave/examples/async_step/features/steps/async_dispatch_steps.py +26 -0
- data/vendor/behave/examples/async_step/features/steps/async_steps34.py +10 -0
- data/vendor/behave/examples/async_step/features/steps/async_steps35.py +10 -0
- data/vendor/behave/examples/async_step/testrun_example.async_dispatch.txt +11 -0
- data/vendor/behave/examples/async_step/testrun_example.async_run.txt +9 -0
- data/vendor/behave/examples/env_vars/README.rst +26 -0
- data/vendor/behave/examples/env_vars/behave.ini +15 -0
- data/vendor/behave/examples/env_vars/behave_run.output_example.txt +12 -0
- data/vendor/behave/examples/env_vars/features/env_var.feature +6 -0
- data/vendor/behave/examples/env_vars/features/steps/env_var_steps.py +38 -0
- data/vendor/behave/features/README.txt +12 -0
- data/vendor/behave/features/background.feature +392 -0
- data/vendor/behave/features/capture_stderr.feature +172 -0
- data/vendor/behave/features/capture_stdout.feature +125 -0
- data/vendor/behave/features/cmdline.lang_list.feature +33 -0
- data/vendor/behave/features/configuration.default_paths.feature +116 -0
- data/vendor/behave/features/context.global_params.feature +35 -0
- data/vendor/behave/features/context.local_params.feature +17 -0
- data/vendor/behave/features/directory_layout.advanced.feature +147 -0
- data/vendor/behave/features/directory_layout.basic.feature +75 -0
- data/vendor/behave/features/directory_layout.basic2.feature +87 -0
- data/vendor/behave/features/environment.py +53 -0
- data/vendor/behave/features/exploratory_testing.with_table.feature +141 -0
- data/vendor/behave/features/feature.description.feature +0 -0
- data/vendor/behave/features/feature.exclude_from_run.feature +96 -0
- data/vendor/behave/features/formatter.help.feature +30 -0
- data/vendor/behave/features/formatter.json.feature +420 -0
- data/vendor/behave/features/formatter.progress3.feature +235 -0
- data/vendor/behave/features/formatter.rerun.feature +296 -0
- data/vendor/behave/features/formatter.steps.feature +181 -0
- data/vendor/behave/features/formatter.steps_catalog.feature +100 -0
- data/vendor/behave/features/formatter.steps_doc.feature +140 -0
- data/vendor/behave/features/formatter.steps_usage.feature +404 -0
- data/vendor/behave/features/formatter.tags.feature +134 -0
- data/vendor/behave/features/formatter.tags_location.feature +183 -0
- data/vendor/behave/features/formatter.user_defined.feature +196 -0
- data/vendor/behave/features/i18n.unicode_problems.feature +445 -0
- data/vendor/behave/features/logcapture.clear_handlers.feature +114 -0
- data/vendor/behave/features/logcapture.feature +188 -0
- data/vendor/behave/features/logcapture.filter.feature +130 -0
- data/vendor/behave/features/logging.no_capture.feature +99 -0
- data/vendor/behave/features/logging.setup_format.feature +157 -0
- data/vendor/behave/features/logging.setup_level.feature +168 -0
- data/vendor/behave/features/logging.setup_with_configfile.feature +137 -0
- data/vendor/behave/features/parser.background.sad_cases.feature +129 -0
- data/vendor/behave/features/parser.feature.sad_cases.feature +144 -0
- data/vendor/behave/features/runner.abort_by_user.feature +305 -0
- data/vendor/behave/features/runner.continue_after_failed_step.feature +136 -0
- data/vendor/behave/features/runner.default_format.feature +175 -0
- data/vendor/behave/features/runner.dry_run.feature +184 -0
- data/vendor/behave/features/runner.feature_listfile.feature +223 -0
- data/vendor/behave/features/runner.hook_errors.feature +382 -0
- data/vendor/behave/features/runner.multiple_formatters.feature +285 -0
- data/vendor/behave/features/runner.scenario_autoretry.feature +131 -0
- data/vendor/behave/features/runner.select_files_by_regexp.example.feature +71 -0
- data/vendor/behave/features/runner.select_files_by_regexp.feature +84 -0
- data/vendor/behave/features/runner.select_scenarios_by_file_location.feature +403 -0
- data/vendor/behave/features/runner.select_scenarios_by_name.feature +289 -0
- data/vendor/behave/features/runner.select_scenarios_by_tag.feature +225 -0
- data/vendor/behave/features/runner.stop_after_failure.feature +122 -0
- data/vendor/behave/features/runner.tag_logic.feature +67 -0
- data/vendor/behave/features/runner.unknown_formatter.feature +23 -0
- data/vendor/behave/features/runner.use_stage_implementations.feature +126 -0
- data/vendor/behave/features/scenario.description.feature +171 -0
- data/vendor/behave/features/scenario.exclude_from_run.feature +217 -0
- data/vendor/behave/features/scenario_outline.basics.feature +100 -0
- data/vendor/behave/features/scenario_outline.improved.feature +177 -0
- data/vendor/behave/features/scenario_outline.name_annotation.feature +157 -0
- data/vendor/behave/features/scenario_outline.parametrized.feature +401 -0
- data/vendor/behave/features/scenario_outline.tagged_examples.feature +118 -0
- data/vendor/behave/features/step.async_steps.feature +225 -0
- data/vendor/behave/features/step.duplicated_step.feature +106 -0
- data/vendor/behave/features/step.execute_steps.feature +59 -0
- data/vendor/behave/features/step.execute_steps.with_table.feature +65 -0
- data/vendor/behave/features/step.import_other_step_module.feature +103 -0
- data/vendor/behave/features/step.pending_steps.feature +128 -0
- data/vendor/behave/features/step.undefined_steps.feature +307 -0
- data/vendor/behave/features/step.use_step_library.feature +44 -0
- data/vendor/behave/features/step_dialect.generic_steps.feature +189 -0
- data/vendor/behave/features/step_dialect.given_when_then.feature +89 -0
- data/vendor/behave/features/step_param.builtin_types.with_float.feature +239 -0
- data/vendor/behave/features/step_param.builtin_types.with_integer.feature +305 -0
- data/vendor/behave/features/step_param.custom_types.feature +134 -0
- data/vendor/behave/features/steps/behave_active_tags_steps.py +86 -0
- data/vendor/behave/features/steps/behave_context_steps.py +67 -0
- data/vendor/behave/features/steps/behave_model_tag_logic_steps.py +105 -0
- data/vendor/behave/features/steps/behave_model_util.py +105 -0
- data/vendor/behave/features/steps/behave_select_files_steps.py +83 -0
- data/vendor/behave/features/steps/behave_tag_expression_steps.py +166 -0
- data/vendor/behave/features/steps/behave_undefined_steps.py +101 -0
- data/vendor/behave/features/steps/use_steplib_behave4cmd.py +12 -0
- data/vendor/behave/features/summary.undefined_steps.feature +114 -0
- data/vendor/behave/features/tags.active_tags.feature +385 -0
- data/vendor/behave/features/tags.default_tags.feature +104 -0
- data/vendor/behave/features/tags.tag_expression.feature +105 -0
- data/vendor/behave/features/userdata.feature +331 -0
- data/vendor/behave/invoke.yaml +21 -0
- data/vendor/behave/issue.features/README.txt +17 -0
- data/vendor/behave/issue.features/environment.py +97 -0
- data/vendor/behave/issue.features/issue0030.feature +21 -0
- data/vendor/behave/issue.features/issue0031.feature +16 -0
- data/vendor/behave/issue.features/issue0032.feature +28 -0
- data/vendor/behave/issue.features/issue0035.feature +74 -0
- data/vendor/behave/issue.features/issue0040.feature +154 -0
- data/vendor/behave/issue.features/issue0041.feature +135 -0
- data/vendor/behave/issue.features/issue0042.feature +230 -0
- data/vendor/behave/issue.features/issue0044.feature +51 -0
- data/vendor/behave/issue.features/issue0046.feature +77 -0
- data/vendor/behave/issue.features/issue0052.feature +66 -0
- data/vendor/behave/issue.features/issue0059.feature +29 -0
- data/vendor/behave/issue.features/issue0063.feature +102 -0
- data/vendor/behave/issue.features/issue0064.feature +97 -0
- data/vendor/behave/issue.features/issue0065.feature +18 -0
- data/vendor/behave/issue.features/issue0066.feature +80 -0
- data/vendor/behave/issue.features/issue0067.feature +90 -0
- data/vendor/behave/issue.features/issue0069.feature +64 -0
- data/vendor/behave/issue.features/issue0072.feature +32 -0
- data/vendor/behave/issue.features/issue0073.feature +228 -0
- data/vendor/behave/issue.features/issue0075.feature +18 -0
- data/vendor/behave/issue.features/issue0077.feature +89 -0
- data/vendor/behave/issue.features/issue0080.feature +49 -0
- data/vendor/behave/issue.features/issue0081.feature +138 -0
- data/vendor/behave/issue.features/issue0083.feature +69 -0
- data/vendor/behave/issue.features/issue0084.feature +69 -0
- data/vendor/behave/issue.features/issue0085.feature +119 -0
- data/vendor/behave/issue.features/issue0092.feature +66 -0
- data/vendor/behave/issue.features/issue0096.feature +173 -0
- data/vendor/behave/issue.features/issue0099.feature +130 -0
- data/vendor/behave/issue.features/issue0109.feature +60 -0
- data/vendor/behave/issue.features/issue0111.feature +53 -0
- data/vendor/behave/issue.features/issue0112.feature +64 -0
- data/vendor/behave/issue.features/issue0114.feature +118 -0
- data/vendor/behave/issue.features/issue0116.feature +71 -0
- data/vendor/behave/issue.features/issue0125.feature +49 -0
- data/vendor/behave/issue.features/issue0127.feature +64 -0
- data/vendor/behave/issue.features/issue0139.feature +67 -0
- data/vendor/behave/issue.features/issue0142.feature +37 -0
- data/vendor/behave/issue.features/issue0143.feature +54 -0
- data/vendor/behave/issue.features/issue0145.feature +63 -0
- data/vendor/behave/issue.features/issue0148.feature +105 -0
- data/vendor/behave/issue.features/issue0152.feature +52 -0
- data/vendor/behave/issue.features/issue0159.feature +74 -0
- data/vendor/behave/issue.features/issue0162.feature +86 -0
- data/vendor/behave/issue.features/issue0171.feature +16 -0
- data/vendor/behave/issue.features/issue0172.feature +51 -0
- data/vendor/behave/issue.features/issue0175.feature +91 -0
- data/vendor/behave/issue.features/issue0177.feature +40 -0
- data/vendor/behave/issue.features/issue0181.feature +36 -0
- data/vendor/behave/issue.features/issue0184.feature +144 -0
- data/vendor/behave/issue.features/issue0186.feature +12 -0
- data/vendor/behave/issue.features/issue0188.feature +60 -0
- data/vendor/behave/issue.features/issue0191.feature +178 -0
- data/vendor/behave/issue.features/issue0194.feature +215 -0
- data/vendor/behave/issue.features/issue0197.feature +11 -0
- data/vendor/behave/issue.features/issue0216.feature +129 -0
- data/vendor/behave/issue.features/issue0226.feature +51 -0
- data/vendor/behave/issue.features/issue0228.feature +41 -0
- data/vendor/behave/issue.features/issue0230.feature +46 -0
- data/vendor/behave/issue.features/issue0231.feature +77 -0
- data/vendor/behave/issue.features/issue0238.feature +52 -0
- data/vendor/behave/issue.features/issue0251.feature +15 -0
- data/vendor/behave/issue.features/issue0280.feature +118 -0
- data/vendor/behave/issue.features/issue0288.feature +95 -0
- data/vendor/behave/issue.features/issue0300.feature +49 -0
- data/vendor/behave/issue.features/issue0302.feature +91 -0
- data/vendor/behave/issue.features/issue0309.feature +52 -0
- data/vendor/behave/issue.features/issue0330.feature +124 -0
- data/vendor/behave/issue.features/issue0349.feature +9 -0
- data/vendor/behave/issue.features/issue0361.feature +79 -0
- data/vendor/behave/issue.features/issue0383.feature +76 -0
- data/vendor/behave/issue.features/issue0384.feature +103 -0
- data/vendor/behave/issue.features/issue0385.feature +109 -0
- data/vendor/behave/issue.features/issue0424.feature +66 -0
- data/vendor/behave/issue.features/issue0446.feature +116 -0
- data/vendor/behave/issue.features/issue0449.feature +42 -0
- data/vendor/behave/issue.features/issue0453.feature +42 -0
- data/vendor/behave/issue.features/issue0457.feature +65 -0
- data/vendor/behave/issue.features/issue0462.feature +38 -0
- data/vendor/behave/issue.features/issue0476.feature +39 -0
- data/vendor/behave/issue.features/issue0487.feature +92 -0
- data/vendor/behave/issue.features/issue0506.feature +77 -0
- data/vendor/behave/issue.features/issue0510.feature +51 -0
- data/vendor/behave/issue.features/requirements.txt +12 -0
- data/vendor/behave/issue.features/steps/ansi_steps.py +20 -0
- data/vendor/behave/issue.features/steps/behave_hooks_steps.py +10 -0
- data/vendor/behave/issue.features/steps/use_steplib_behave4cmd.py +13 -0
- data/vendor/behave/more.features/formatter.json.validate_output.feature +37 -0
- data/vendor/behave/more.features/steps/tutorial_steps.py +16 -0
- data/vendor/behave/more.features/steps/use_steplib_behave4cmd.py +7 -0
- data/vendor/behave/more.features/tutorial.feature +6 -0
- data/vendor/behave/py.requirements/README.txt +5 -0
- data/vendor/behave/py.requirements/all.txt +16 -0
- data/vendor/behave/py.requirements/basic.txt +21 -0
- data/vendor/behave/py.requirements/develop.txt +28 -0
- data/vendor/behave/py.requirements/docs.txt +6 -0
- data/vendor/behave/py.requirements/json.txt +7 -0
- data/vendor/behave/py.requirements/more_py26.txt +8 -0
- data/vendor/behave/py.requirements/testing.txt +10 -0
- data/vendor/behave/pytest.ini +24 -0
- data/vendor/behave/setup.cfg +29 -0
- data/vendor/behave/setup.py +118 -0
- data/vendor/behave/setuptools_behave.py +130 -0
- data/vendor/behave/tasks/__behave.py +45 -0
- data/vendor/behave/tasks/__init__.py +55 -0
- data/vendor/behave/tasks/__main__.py +70 -0
- data/vendor/behave/tasks/_setup.py +135 -0
- data/vendor/behave/tasks/_vendor/README.rst +35 -0
- data/vendor/behave/tasks/_vendor/invoke.zip +0 -0
- data/vendor/behave/tasks/_vendor/path.py +1725 -0
- data/vendor/behave/tasks/_vendor/pathlib.py +1280 -0
- data/vendor/behave/tasks/_vendor/six.py +868 -0
- data/vendor/behave/tasks/clean.py +246 -0
- data/vendor/behave/tasks/docs.py +97 -0
- data/vendor/behave/tasks/requirements.txt +17 -0
- data/vendor/behave/tasks/test.py +192 -0
- data/vendor/behave/test/__init__.py +0 -0
- data/vendor/behave/test/_importer_candidate.py +3 -0
- data/vendor/behave/test/reporters/__init__.py +0 -0
- data/vendor/behave/test/reporters/test_summary.py +240 -0
- data/vendor/behave/test/test_ansi_escapes.py +73 -0
- data/vendor/behave/test/test_configuration.py +172 -0
- data/vendor/behave/test/test_formatter.py +265 -0
- data/vendor/behave/test/test_formatter_progress.py +39 -0
- data/vendor/behave/test/test_formatter_rerun.py +97 -0
- data/vendor/behave/test/test_formatter_tags.py +57 -0
- data/vendor/behave/test/test_importer.py +151 -0
- data/vendor/behave/test/test_log_capture.py +29 -0
- data/vendor/behave/test/test_matchers.py +236 -0
- data/vendor/behave/test/test_model.py +871 -0
- data/vendor/behave/test/test_parser.py +1590 -0
- data/vendor/behave/test/test_runner.py +1074 -0
- data/vendor/behave/test/test_step_registry.py +96 -0
- data/vendor/behave/test/test_tag_expression.py +506 -0
- data/vendor/behave/test/test_tag_expression2.py +462 -0
- data/vendor/behave/test/test_tag_matcher.py +729 -0
- data/vendor/behave/test/test_userdata.py +184 -0
- data/vendor/behave/tests/README.txt +12 -0
- data/vendor/behave/tests/__init__.py +0 -0
- data/vendor/behave/tests/api/__ONLY_PY34_or_newer.txt +0 -0
- data/vendor/behave/tests/api/__init__.py +0 -0
- data/vendor/behave/tests/api/_test_async_step34.py +130 -0
- data/vendor/behave/tests/api/_test_async_step35.py +75 -0
- data/vendor/behave/tests/api/test_async_step.py +18 -0
- data/vendor/behave/tests/api/testing_support.py +94 -0
- data/vendor/behave/tests/api/testing_support_async.py +21 -0
- data/vendor/behave/tests/issues/test_issue0336.py +66 -0
- data/vendor/behave/tests/issues/test_issue0449.py +55 -0
- data/vendor/behave/tests/issues/test_issue0453.py +62 -0
- data/vendor/behave/tests/issues/test_issue0458.py +54 -0
- data/vendor/behave/tests/issues/test_issue0495.py +65 -0
- data/vendor/behave/tests/unit/__init__.py +0 -0
- data/vendor/behave/tests/unit/test_behave4cmd_command_shell_proc.py +135 -0
- data/vendor/behave/tests/unit/test_capture.py +280 -0
- data/vendor/behave/tests/unit/test_model_core.py +56 -0
- data/vendor/behave/tests/unit/test_textutil.py +267 -0
- data/vendor/behave/tools/test-features/background.feature +9 -0
- data/vendor/behave/tools/test-features/environment.py +8 -0
- data/vendor/behave/tools/test-features/french.feature +11 -0
- data/vendor/behave/tools/test-features/outline.feature +39 -0
- data/vendor/behave/tools/test-features/parse.feature +10 -0
- data/vendor/behave/tools/test-features/step-data.feature +60 -0
- data/vendor/behave/tools/test-features/steps/steps.py +120 -0
- data/vendor/behave/tools/test-features/tags.feature +18 -0
- data/vendor/behave/tox.ini +159 -0
- metadata +562 -0
|
@@ -0,0 +1,1074 @@
|
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
|
2
|
+
# pylint: disable=too-many-lines, line-too-long
|
|
3
|
+
|
|
4
|
+
from __future__ import absolute_import, print_function, with_statement
|
|
5
|
+
from collections import defaultdict
|
|
6
|
+
from platform import python_implementation
|
|
7
|
+
import os.path
|
|
8
|
+
import sys
|
|
9
|
+
import warnings
|
|
10
|
+
import tempfile
|
|
11
|
+
import unittest
|
|
12
|
+
import six
|
|
13
|
+
from six import StringIO
|
|
14
|
+
|
|
15
|
+
from mock import Mock, patch
|
|
16
|
+
from nose.tools import * # pylint: disable=wildcard-import, unused-wildcard-import
|
|
17
|
+
|
|
18
|
+
from behave.model import Table
|
|
19
|
+
from behave.step_registry import StepRegistry
|
|
20
|
+
from behave import parser, runner
|
|
21
|
+
from behave.configuration import ConfigError
|
|
22
|
+
from behave.formatter.base import StreamOpener
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# -- CONVENIENCE-ALIAS:
|
|
26
|
+
_text = six.text_type
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class TestContext(unittest.TestCase):
|
|
30
|
+
# pylint: disable=invalid-name, protected-access, no-self-use
|
|
31
|
+
|
|
32
|
+
def setUp(self):
|
|
33
|
+
r = Mock()
|
|
34
|
+
self.config = r.config = Mock()
|
|
35
|
+
r.config.verbose = False
|
|
36
|
+
self.context = runner.Context(r)
|
|
37
|
+
|
|
38
|
+
def test_user_mode_shall_restore_behave_mode(self):
|
|
39
|
+
# -- CASE: No exception is raised.
|
|
40
|
+
initial_mode = runner.Context.BEHAVE
|
|
41
|
+
eq_(self.context._mode, initial_mode)
|
|
42
|
+
with self.context.user_mode():
|
|
43
|
+
eq_(self.context._mode, runner.Context.USER)
|
|
44
|
+
self.context.thing = "stuff"
|
|
45
|
+
eq_(self.context._mode, initial_mode)
|
|
46
|
+
|
|
47
|
+
def test_user_mode_shall_restore_behave_mode_if_assert_fails(self):
|
|
48
|
+
initial_mode = runner.Context.BEHAVE
|
|
49
|
+
eq_(self.context._mode, initial_mode)
|
|
50
|
+
try:
|
|
51
|
+
with self.context.user_mode():
|
|
52
|
+
eq_(self.context._mode, runner.Context.USER)
|
|
53
|
+
assert False, "XFAIL"
|
|
54
|
+
except AssertionError:
|
|
55
|
+
eq_(self.context._mode, initial_mode)
|
|
56
|
+
|
|
57
|
+
def test_user_mode_shall_restore_behave_mode_if_exception_is_raised(self):
|
|
58
|
+
initial_mode = runner.Context.BEHAVE
|
|
59
|
+
eq_(self.context._mode, initial_mode)
|
|
60
|
+
try:
|
|
61
|
+
with self.context.user_mode():
|
|
62
|
+
eq_(self.context._mode, runner.Context.USER)
|
|
63
|
+
raise RuntimeError("XFAIL")
|
|
64
|
+
except RuntimeError:
|
|
65
|
+
eq_(self.context._mode, initial_mode)
|
|
66
|
+
|
|
67
|
+
def test_use_with_user_mode__shall_restore_initial_mode(self):
|
|
68
|
+
# -- CASE: No exception is raised.
|
|
69
|
+
# pylint: disable=protected-access
|
|
70
|
+
initial_mode = runner.Context.BEHAVE
|
|
71
|
+
self.context._mode = initial_mode
|
|
72
|
+
with self.context.use_with_user_mode():
|
|
73
|
+
eq_(self.context._mode, runner.Context.USER)
|
|
74
|
+
self.context.thing = "stuff"
|
|
75
|
+
eq_(self.context._mode, initial_mode)
|
|
76
|
+
|
|
77
|
+
def test_use_with_user_mode__shall_restore_initial_mode_with_error(self):
|
|
78
|
+
# -- CASE: Exception is raised.
|
|
79
|
+
# pylint: disable=protected-access
|
|
80
|
+
initial_mode = runner.Context.BEHAVE
|
|
81
|
+
self.context._mode = initial_mode
|
|
82
|
+
try:
|
|
83
|
+
with self.context.use_with_user_mode():
|
|
84
|
+
eq_(self.context._mode, runner.Context.USER)
|
|
85
|
+
raise RuntimeError("XFAIL")
|
|
86
|
+
except RuntimeError:
|
|
87
|
+
eq_(self.context._mode, initial_mode)
|
|
88
|
+
|
|
89
|
+
def test_use_with_behave_mode__shall_restore_initial_mode(self):
|
|
90
|
+
# -- CASE: No exception is raised.
|
|
91
|
+
# pylint: disable=protected-access
|
|
92
|
+
initial_mode = runner.Context.USER
|
|
93
|
+
self.context._mode = initial_mode
|
|
94
|
+
with self.context._use_with_behave_mode():
|
|
95
|
+
eq_(self.context._mode, runner.Context.BEHAVE)
|
|
96
|
+
self.context.thing = "stuff"
|
|
97
|
+
eq_(self.context._mode, initial_mode)
|
|
98
|
+
|
|
99
|
+
def test_use_with_behave_mode__shall_restore_initial_mode_with_error(self):
|
|
100
|
+
# -- CASE: Exception is raised.
|
|
101
|
+
# pylint: disable=protected-access
|
|
102
|
+
initial_mode = runner.Context.USER
|
|
103
|
+
self.context._mode = initial_mode
|
|
104
|
+
try:
|
|
105
|
+
with self.context._use_with_behave_mode():
|
|
106
|
+
eq_(self.context._mode, runner.Context.BEHAVE)
|
|
107
|
+
raise RuntimeError("XFAIL")
|
|
108
|
+
except RuntimeError:
|
|
109
|
+
eq_(self.context._mode, initial_mode)
|
|
110
|
+
|
|
111
|
+
def test_context_contains(self):
|
|
112
|
+
eq_("thing" in self.context, False)
|
|
113
|
+
self.context.thing = "stuff"
|
|
114
|
+
eq_("thing" in self.context, True)
|
|
115
|
+
self.context._push()
|
|
116
|
+
eq_("thing" in self.context, True)
|
|
117
|
+
|
|
118
|
+
def test_attribute_set_at_upper_level_visible_at_lower_level(self):
|
|
119
|
+
self.context.thing = "stuff"
|
|
120
|
+
self.context._push()
|
|
121
|
+
eq_(self.context.thing, "stuff")
|
|
122
|
+
|
|
123
|
+
def test_attribute_set_at_lower_level_not_visible_at_upper_level(self):
|
|
124
|
+
self.context._push()
|
|
125
|
+
self.context.thing = "stuff"
|
|
126
|
+
self.context._pop()
|
|
127
|
+
assert getattr(self.context, "thing", None) is None
|
|
128
|
+
|
|
129
|
+
def test_attributes_set_at_upper_level_visible_at_lower_level(self):
|
|
130
|
+
self.context.thing = "stuff"
|
|
131
|
+
self.context._push()
|
|
132
|
+
eq_(self.context.thing, "stuff")
|
|
133
|
+
self.context.other_thing = "more stuff"
|
|
134
|
+
self.context._push()
|
|
135
|
+
eq_(self.context.thing, "stuff")
|
|
136
|
+
eq_(self.context.other_thing, "more stuff")
|
|
137
|
+
self.context.third_thing = "wombats"
|
|
138
|
+
self.context._push()
|
|
139
|
+
eq_(self.context.thing, "stuff")
|
|
140
|
+
eq_(self.context.other_thing, "more stuff")
|
|
141
|
+
eq_(self.context.third_thing, "wombats")
|
|
142
|
+
|
|
143
|
+
def test_attributes_set_at_lower_level_not_visible_at_upper_level(self):
|
|
144
|
+
self.context.thing = "stuff"
|
|
145
|
+
|
|
146
|
+
self.context._push()
|
|
147
|
+
self.context.other_thing = "more stuff"
|
|
148
|
+
|
|
149
|
+
self.context._push()
|
|
150
|
+
self.context.third_thing = "wombats"
|
|
151
|
+
eq_(self.context.thing, "stuff")
|
|
152
|
+
eq_(self.context.other_thing, "more stuff")
|
|
153
|
+
eq_(self.context.third_thing, "wombats")
|
|
154
|
+
|
|
155
|
+
self.context._pop()
|
|
156
|
+
eq_(self.context.thing, "stuff")
|
|
157
|
+
eq_(self.context.other_thing, "more stuff")
|
|
158
|
+
assert getattr(self.context, "third_thing", None) is None, "%s is not None" % self.context.third_thing
|
|
159
|
+
|
|
160
|
+
self.context._pop()
|
|
161
|
+
eq_(self.context.thing, "stuff")
|
|
162
|
+
assert getattr(self.context, "other_thing", None) is None, "%s is not None" % self.context.other_thing
|
|
163
|
+
assert getattr(self.context, "third_thing", None) is None, "%s is not None" % self.context.third_thing
|
|
164
|
+
|
|
165
|
+
def test_masking_existing_user_attribute_when_verbose_causes_warning(self):
|
|
166
|
+
warns = []
|
|
167
|
+
|
|
168
|
+
def catch_warning(*args, **kwargs):
|
|
169
|
+
warns.append(args[0])
|
|
170
|
+
|
|
171
|
+
old_showwarning = warnings.showwarning
|
|
172
|
+
warnings.showwarning = catch_warning
|
|
173
|
+
|
|
174
|
+
# pylint: disable=protected-access
|
|
175
|
+
self.config.verbose = True
|
|
176
|
+
with self.context.use_with_user_mode():
|
|
177
|
+
self.context.thing = "stuff"
|
|
178
|
+
self.context._push()
|
|
179
|
+
self.context.thing = "other stuff"
|
|
180
|
+
|
|
181
|
+
warnings.showwarning = old_showwarning
|
|
182
|
+
|
|
183
|
+
print(repr(warns))
|
|
184
|
+
assert warns, "warns is empty!"
|
|
185
|
+
warning = warns[0]
|
|
186
|
+
assert isinstance(warning, runner.ContextMaskWarning), "warning is not a ContextMaskWarning"
|
|
187
|
+
info = warning.args[0]
|
|
188
|
+
assert info.startswith("user code"), "%r doesn't start with 'user code'" % info
|
|
189
|
+
assert "'thing'" in info, "%r not in %r" % ("'thing'", info)
|
|
190
|
+
assert "tutorial" in info, '"tutorial" not in %r' % (info, )
|
|
191
|
+
|
|
192
|
+
def test_masking_existing_user_attribute_when_not_verbose_causes_no_warning(self):
|
|
193
|
+
warns = []
|
|
194
|
+
|
|
195
|
+
def catch_warning(*args, **kwargs):
|
|
196
|
+
warns.append(args[0])
|
|
197
|
+
|
|
198
|
+
old_showwarning = warnings.showwarning
|
|
199
|
+
warnings.showwarning = catch_warning
|
|
200
|
+
|
|
201
|
+
# explicit
|
|
202
|
+
# pylint: disable=protected-access
|
|
203
|
+
self.config.verbose = False
|
|
204
|
+
with self.context.use_with_user_mode():
|
|
205
|
+
self.context.thing = "stuff"
|
|
206
|
+
self.context._push()
|
|
207
|
+
self.context.thing = "other stuff"
|
|
208
|
+
|
|
209
|
+
warnings.showwarning = old_showwarning
|
|
210
|
+
|
|
211
|
+
assert not warns
|
|
212
|
+
|
|
213
|
+
def test_behave_masking_user_attribute_causes_warning(self):
|
|
214
|
+
warns = []
|
|
215
|
+
|
|
216
|
+
def catch_warning(*args, **kwargs):
|
|
217
|
+
warns.append(args[0])
|
|
218
|
+
|
|
219
|
+
old_showwarning = warnings.showwarning
|
|
220
|
+
warnings.showwarning = catch_warning
|
|
221
|
+
|
|
222
|
+
with self.context.use_with_user_mode():
|
|
223
|
+
self.context.thing = "stuff"
|
|
224
|
+
# pylint: disable=protected-access
|
|
225
|
+
self.context._push()
|
|
226
|
+
self.context.thing = "other stuff"
|
|
227
|
+
|
|
228
|
+
warnings.showwarning = old_showwarning
|
|
229
|
+
|
|
230
|
+
print(repr(warns))
|
|
231
|
+
assert warns, "OOPS: warns is empty, but expected non-empty"
|
|
232
|
+
warning = warns[0]
|
|
233
|
+
assert isinstance(warning, runner.ContextMaskWarning), "warning is not a ContextMaskWarning"
|
|
234
|
+
info = warning.args[0]
|
|
235
|
+
assert info.startswith("behave runner"), "%r doesn't start with 'behave runner'" % info
|
|
236
|
+
assert "'thing'" in info, "%r not in %r" % ("'thing'", info)
|
|
237
|
+
filename = __file__.rsplit(".", 1)[0]
|
|
238
|
+
if python_implementation() == "Jython":
|
|
239
|
+
filename = filename.replace("$py", ".py")
|
|
240
|
+
assert filename in info, "%r not in %r" % (filename, info)
|
|
241
|
+
|
|
242
|
+
def test_setting_root_attribute_that_masks_existing_causes_warning(self):
|
|
243
|
+
# pylint: disable=protected-access
|
|
244
|
+
warns = []
|
|
245
|
+
|
|
246
|
+
def catch_warning(*args, **kwargs):
|
|
247
|
+
warns.append(args[0])
|
|
248
|
+
|
|
249
|
+
old_showwarning = warnings.showwarning
|
|
250
|
+
warnings.showwarning = catch_warning
|
|
251
|
+
|
|
252
|
+
with self.context.use_with_user_mode():
|
|
253
|
+
self.context._push()
|
|
254
|
+
self.context.thing = "teak"
|
|
255
|
+
self.context._set_root_attribute("thing", "oak")
|
|
256
|
+
|
|
257
|
+
warnings.showwarning = old_showwarning
|
|
258
|
+
|
|
259
|
+
print(repr(warns))
|
|
260
|
+
assert warns
|
|
261
|
+
warning = warns[0]
|
|
262
|
+
assert isinstance(warning, runner.ContextMaskWarning)
|
|
263
|
+
info = warning.args[0]
|
|
264
|
+
assert info.startswith("behave runner"), "%r doesn't start with 'behave runner'" % info
|
|
265
|
+
assert "'thing'" in info, "%r not in %r" % ("'thing'", info)
|
|
266
|
+
filename = __file__.rsplit(".", 1)[0]
|
|
267
|
+
if python_implementation() == "Jython":
|
|
268
|
+
filename = filename.replace("$py", ".py")
|
|
269
|
+
assert filename in info, "%r not in %r" % (filename, info)
|
|
270
|
+
|
|
271
|
+
def test_context_deletable(self):
|
|
272
|
+
eq_("thing" in self.context, False)
|
|
273
|
+
self.context.thing = "stuff"
|
|
274
|
+
eq_("thing" in self.context, True)
|
|
275
|
+
del self.context.thing
|
|
276
|
+
eq_("thing" in self.context, False)
|
|
277
|
+
|
|
278
|
+
@raises(AttributeError)
|
|
279
|
+
def test_context_deletable_raises(self):
|
|
280
|
+
# pylint: disable=protected-access
|
|
281
|
+
eq_("thing" in self.context, False)
|
|
282
|
+
self.context.thing = "stuff"
|
|
283
|
+
eq_("thing" in self.context, True)
|
|
284
|
+
self.context._push()
|
|
285
|
+
eq_("thing" in self.context, True)
|
|
286
|
+
del self.context.thing
|
|
287
|
+
|
|
288
|
+
class ExampleSteps(object):
|
|
289
|
+
text = None
|
|
290
|
+
table = None
|
|
291
|
+
|
|
292
|
+
@staticmethod
|
|
293
|
+
def step_passes(context): # pylint: disable=unused-argument
|
|
294
|
+
pass
|
|
295
|
+
|
|
296
|
+
@staticmethod
|
|
297
|
+
def step_fails(context): # pylint: disable=unused-argument
|
|
298
|
+
assert False, "XFAIL"
|
|
299
|
+
|
|
300
|
+
@classmethod
|
|
301
|
+
def step_with_text(cls, context):
|
|
302
|
+
assert context.text is not None, "REQUIRE: multi-line text"
|
|
303
|
+
cls.text = context.text
|
|
304
|
+
|
|
305
|
+
@classmethod
|
|
306
|
+
def step_with_table(cls, context):
|
|
307
|
+
assert context.table, "REQUIRE: table"
|
|
308
|
+
cls.table = context.table
|
|
309
|
+
|
|
310
|
+
@classmethod
|
|
311
|
+
def register_steps_with(cls, step_registry):
|
|
312
|
+
# pylint: disable=bad-whitespace
|
|
313
|
+
step_definitions = [
|
|
314
|
+
("step", "a step passes", cls.step_passes),
|
|
315
|
+
("step", "a step fails", cls.step_fails),
|
|
316
|
+
("step", "a step with text", cls.step_with_text),
|
|
317
|
+
("step", "a step with a table", cls.step_with_table),
|
|
318
|
+
]
|
|
319
|
+
for keyword, string, func in step_definitions:
|
|
320
|
+
step_registry.add_step_definition(keyword, string, func)
|
|
321
|
+
|
|
322
|
+
class TestContext_ExecuteSteps(unittest.TestCase):
|
|
323
|
+
"""
|
|
324
|
+
Test the behave.runner.Context.execute_steps() functionality.
|
|
325
|
+
"""
|
|
326
|
+
# pylint: disable=invalid-name, no-self-use
|
|
327
|
+
step_registry = None
|
|
328
|
+
|
|
329
|
+
def setUp(self):
|
|
330
|
+
if not self.step_registry:
|
|
331
|
+
# -- SETUP ONCE:
|
|
332
|
+
self.step_registry = StepRegistry()
|
|
333
|
+
ExampleSteps.register_steps_with(self.step_registry)
|
|
334
|
+
ExampleSteps.text = None
|
|
335
|
+
ExampleSteps.table = None
|
|
336
|
+
|
|
337
|
+
runner_ = Mock()
|
|
338
|
+
self.config = runner_.config = Mock()
|
|
339
|
+
runner_.config.verbose = False
|
|
340
|
+
runner_.config.stdout_capture = False
|
|
341
|
+
runner_.config.stderr_capture = False
|
|
342
|
+
runner_.config.log_capture = False
|
|
343
|
+
runner_.step_registry = self.step_registry
|
|
344
|
+
|
|
345
|
+
self.context = runner.Context(runner_)
|
|
346
|
+
runner_.context = self.context
|
|
347
|
+
self.context.feature = Mock()
|
|
348
|
+
self.context.feature.parser = parser.Parser()
|
|
349
|
+
self.context.runner = runner_
|
|
350
|
+
# self.context.text = None
|
|
351
|
+
# self.context.table = None
|
|
352
|
+
|
|
353
|
+
def test_execute_steps_with_simple_steps(self):
|
|
354
|
+
doc = u"""
|
|
355
|
+
Given a step passes
|
|
356
|
+
Then a step passes
|
|
357
|
+
""".lstrip()
|
|
358
|
+
with patch("behave.step_registry.registry", self.step_registry):
|
|
359
|
+
result = self.context.execute_steps(doc)
|
|
360
|
+
eq_(result, True)
|
|
361
|
+
|
|
362
|
+
def test_execute_steps_with_failing_step(self):
|
|
363
|
+
doc = u"""
|
|
364
|
+
Given a step passes
|
|
365
|
+
When a step fails
|
|
366
|
+
Then a step passes
|
|
367
|
+
""".lstrip()
|
|
368
|
+
with patch("behave.step_registry.registry", self.step_registry):
|
|
369
|
+
try:
|
|
370
|
+
result = self.context.execute_steps(doc)
|
|
371
|
+
except AssertionError as e:
|
|
372
|
+
ok_("FAILED SUB-STEP: When a step fails" in _text(e))
|
|
373
|
+
|
|
374
|
+
def test_execute_steps_with_undefined_step(self):
|
|
375
|
+
doc = u"""
|
|
376
|
+
Given a step passes
|
|
377
|
+
When a step is undefined
|
|
378
|
+
Then a step passes
|
|
379
|
+
""".lstrip()
|
|
380
|
+
with patch("behave.step_registry.registry", self.step_registry):
|
|
381
|
+
try:
|
|
382
|
+
result = self.context.execute_steps(doc)
|
|
383
|
+
except AssertionError as e:
|
|
384
|
+
ok_("UNDEFINED SUB-STEP: When a step is undefined" in _text(e))
|
|
385
|
+
|
|
386
|
+
def test_execute_steps_with_text(self):
|
|
387
|
+
doc = u'''
|
|
388
|
+
Given a step passes
|
|
389
|
+
When a step with text:
|
|
390
|
+
"""
|
|
391
|
+
Lorem ipsum
|
|
392
|
+
Ipsum lorem
|
|
393
|
+
"""
|
|
394
|
+
Then a step passes
|
|
395
|
+
'''.lstrip()
|
|
396
|
+
with patch("behave.step_registry.registry", self.step_registry):
|
|
397
|
+
result = self.context.execute_steps(doc)
|
|
398
|
+
expected_text = "Lorem ipsum\nIpsum lorem"
|
|
399
|
+
eq_(result, True)
|
|
400
|
+
eq_(expected_text, ExampleSteps.text)
|
|
401
|
+
|
|
402
|
+
def test_execute_steps_with_table(self):
|
|
403
|
+
doc = u"""
|
|
404
|
+
Given a step with a table:
|
|
405
|
+
| Name | Age |
|
|
406
|
+
| Alice | 12 |
|
|
407
|
+
| Bob | 23 |
|
|
408
|
+
Then a step passes
|
|
409
|
+
""".lstrip()
|
|
410
|
+
with patch("behave.step_registry.registry", self.step_registry):
|
|
411
|
+
# pylint: disable=bad-whitespace, bad-continuation
|
|
412
|
+
result = self.context.execute_steps(doc)
|
|
413
|
+
expected_table = Table([u"Name", u"Age"], 0, [
|
|
414
|
+
[u"Alice", u"12"],
|
|
415
|
+
[u"Bob", u"23"],
|
|
416
|
+
])
|
|
417
|
+
eq_(result, True)
|
|
418
|
+
eq_(expected_table, ExampleSteps.table)
|
|
419
|
+
|
|
420
|
+
def test_context_table_is_restored_after_execute_steps_without_table(self):
|
|
421
|
+
doc = u"""
|
|
422
|
+
Given a step passes
|
|
423
|
+
Then a step passes
|
|
424
|
+
""".lstrip()
|
|
425
|
+
with patch("behave.step_registry.registry", self.step_registry):
|
|
426
|
+
original_table = "<ORIGINAL_TABLE>"
|
|
427
|
+
self.context.table = original_table
|
|
428
|
+
self.context.execute_steps(doc)
|
|
429
|
+
eq_(self.context.table, original_table)
|
|
430
|
+
|
|
431
|
+
def test_context_table_is_restored_after_execute_steps_with_table(self):
|
|
432
|
+
doc = u"""
|
|
433
|
+
Given a step with a table:
|
|
434
|
+
| Name | Age |
|
|
435
|
+
| Alice | 12 |
|
|
436
|
+
| Bob | 23 |
|
|
437
|
+
Then a step passes
|
|
438
|
+
""".lstrip()
|
|
439
|
+
with patch("behave.step_registry.registry", self.step_registry):
|
|
440
|
+
original_table = "<ORIGINAL_TABLE>"
|
|
441
|
+
self.context.table = original_table
|
|
442
|
+
self.context.execute_steps(doc)
|
|
443
|
+
eq_(self.context.table, original_table)
|
|
444
|
+
|
|
445
|
+
def test_context_text_is_restored_after_execute_steps_without_text(self):
|
|
446
|
+
doc = u"""
|
|
447
|
+
Given a step passes
|
|
448
|
+
Then a step passes
|
|
449
|
+
""".lstrip()
|
|
450
|
+
with patch("behave.step_registry.registry", self.step_registry):
|
|
451
|
+
original_text = "<ORIGINAL_TEXT>"
|
|
452
|
+
self.context.text = original_text
|
|
453
|
+
self.context.execute_steps(doc)
|
|
454
|
+
eq_(self.context.text, original_text)
|
|
455
|
+
|
|
456
|
+
def test_context_text_is_restored_after_execute_steps_with_text(self):
|
|
457
|
+
doc = u'''
|
|
458
|
+
Given a step passes
|
|
459
|
+
When a step with text:
|
|
460
|
+
"""
|
|
461
|
+
Lorem ipsum
|
|
462
|
+
Ipsum lorem
|
|
463
|
+
"""
|
|
464
|
+
'''.lstrip()
|
|
465
|
+
with patch("behave.step_registry.registry", self.step_registry):
|
|
466
|
+
original_text = "<ORIGINAL_TEXT>"
|
|
467
|
+
self.context.text = original_text
|
|
468
|
+
self.context.execute_steps(doc)
|
|
469
|
+
eq_(self.context.text, original_text)
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
@raises(ValueError)
|
|
473
|
+
def test_execute_steps_should_fail_when_called_without_feature(self):
|
|
474
|
+
doc = u"""
|
|
475
|
+
Given a passes
|
|
476
|
+
Then a step passes
|
|
477
|
+
""".lstrip()
|
|
478
|
+
with patch("behave.step_registry.registry", self.step_registry):
|
|
479
|
+
self.context.feature = None
|
|
480
|
+
self.context.execute_steps(doc)
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
def create_mock_config():
|
|
484
|
+
config = Mock()
|
|
485
|
+
config.steps_dir = "steps"
|
|
486
|
+
config.environment_file = "environment.py"
|
|
487
|
+
return config
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
class TestRunner(object):
|
|
491
|
+
# pylint: disable=invalid-name, no-self-use
|
|
492
|
+
|
|
493
|
+
def test_load_hooks_execfiles_hook_file(self):
|
|
494
|
+
with patch("behave.runner.exec_file") as ef:
|
|
495
|
+
with patch("os.path.exists") as exists:
|
|
496
|
+
exists.return_value = True
|
|
497
|
+
base_dir = "fake/path"
|
|
498
|
+
hooks_path = os.path.join(base_dir, "environment.py")
|
|
499
|
+
|
|
500
|
+
r = runner.Runner(create_mock_config())
|
|
501
|
+
r.base_dir = base_dir
|
|
502
|
+
r.load_hooks()
|
|
503
|
+
|
|
504
|
+
exists.assert_called_with(hooks_path)
|
|
505
|
+
ef.assert_called_with(hooks_path, r.hooks)
|
|
506
|
+
|
|
507
|
+
def test_run_hook_runs_a_hook_that_exists(self):
|
|
508
|
+
config = Mock()
|
|
509
|
+
r = runner.Runner(config)
|
|
510
|
+
# XXX r.config = Mock()
|
|
511
|
+
r.config.stdout_capture = False
|
|
512
|
+
r.config.stderr_capture = False
|
|
513
|
+
r.config.dry_run = False
|
|
514
|
+
r.hooks["before_lunch"] = hook = Mock()
|
|
515
|
+
args = (runner.Context(Mock()), Mock(), Mock())
|
|
516
|
+
r.run_hook("before_lunch", *args)
|
|
517
|
+
|
|
518
|
+
hook.assert_called_with(*args)
|
|
519
|
+
|
|
520
|
+
def test_run_hook_does_not_runs_a_hook_that_exists_if_dry_run(self):
|
|
521
|
+
r = runner.Runner(None)
|
|
522
|
+
r.config = Mock()
|
|
523
|
+
r.config.dry_run = True
|
|
524
|
+
r.hooks["before_lunch"] = hook = Mock()
|
|
525
|
+
args = (runner.Context(Mock()), Mock(), Mock())
|
|
526
|
+
r.run_hook("before_lunch", *args)
|
|
527
|
+
|
|
528
|
+
assert len(hook.call_args_list) == 0
|
|
529
|
+
|
|
530
|
+
def test_setup_capture_creates_stringio_for_stdout(self):
|
|
531
|
+
r = runner.Runner(Mock())
|
|
532
|
+
r.config.stdout_capture = True
|
|
533
|
+
r.config.log_capture = False
|
|
534
|
+
r.context = Mock()
|
|
535
|
+
|
|
536
|
+
r.setup_capture()
|
|
537
|
+
|
|
538
|
+
assert r.capture_controller.stdout_capture is not None
|
|
539
|
+
assert isinstance(r.capture_controller.stdout_capture, StringIO)
|
|
540
|
+
|
|
541
|
+
def test_setup_capture_does_not_create_stringio_if_not_wanted(self):
|
|
542
|
+
r = runner.Runner(Mock())
|
|
543
|
+
r.config.stdout_capture = False
|
|
544
|
+
r.config.stderr_capture = False
|
|
545
|
+
r.config.log_capture = False
|
|
546
|
+
|
|
547
|
+
r.setup_capture()
|
|
548
|
+
|
|
549
|
+
assert r.capture_controller.stdout_capture is None
|
|
550
|
+
|
|
551
|
+
@patch("behave.capture.LoggingCapture")
|
|
552
|
+
def test_setup_capture_creates_memory_handler_for_logging(self, handler):
|
|
553
|
+
r = runner.Runner(Mock())
|
|
554
|
+
r.config.stdout_capture = False
|
|
555
|
+
r.config.log_capture = True
|
|
556
|
+
r.context = Mock()
|
|
557
|
+
|
|
558
|
+
r.setup_capture()
|
|
559
|
+
|
|
560
|
+
assert r.capture_controller.log_capture is not None
|
|
561
|
+
handler.assert_called_with(r.config)
|
|
562
|
+
r.capture_controller.log_capture.inveigle.assert_called_with()
|
|
563
|
+
|
|
564
|
+
def test_setup_capture_does_not_create_memory_handler_if_not_wanted(self):
|
|
565
|
+
r = runner.Runner(Mock())
|
|
566
|
+
r.config.stdout_capture = False
|
|
567
|
+
r.config.stderr_capture = False
|
|
568
|
+
r.config.log_capture = False
|
|
569
|
+
|
|
570
|
+
r.setup_capture()
|
|
571
|
+
|
|
572
|
+
assert r.capture_controller.log_capture is None
|
|
573
|
+
|
|
574
|
+
def test_start_stop_capture_switcheroos_sys_stdout(self):
|
|
575
|
+
old_stdout = sys.stdout
|
|
576
|
+
sys.stdout = new_stdout = Mock()
|
|
577
|
+
|
|
578
|
+
r = runner.Runner(Mock())
|
|
579
|
+
r.config.stdout_capture = True
|
|
580
|
+
r.config.log_capture = False
|
|
581
|
+
r.context = Mock()
|
|
582
|
+
|
|
583
|
+
r.setup_capture()
|
|
584
|
+
r.start_capture()
|
|
585
|
+
|
|
586
|
+
eq_(sys.stdout, r.capture_controller.stdout_capture)
|
|
587
|
+
|
|
588
|
+
r.stop_capture()
|
|
589
|
+
|
|
590
|
+
eq_(sys.stdout, new_stdout)
|
|
591
|
+
|
|
592
|
+
sys.stdout = old_stdout
|
|
593
|
+
|
|
594
|
+
def test_start_stop_capture_leaves_sys_stdout_alone_if_off(self):
|
|
595
|
+
r = runner.Runner(Mock())
|
|
596
|
+
r.config.stdout_capture = False
|
|
597
|
+
r.config.log_capture = False
|
|
598
|
+
|
|
599
|
+
old_stdout = sys.stdout
|
|
600
|
+
|
|
601
|
+
r.start_capture()
|
|
602
|
+
|
|
603
|
+
eq_(sys.stdout, old_stdout)
|
|
604
|
+
|
|
605
|
+
r.stop_capture()
|
|
606
|
+
|
|
607
|
+
eq_(sys.stdout, old_stdout)
|
|
608
|
+
|
|
609
|
+
def test_teardown_capture_removes_log_tap(self):
|
|
610
|
+
r = runner.Runner(Mock())
|
|
611
|
+
r.config.stdout_capture = False
|
|
612
|
+
r.config.log_capture = True
|
|
613
|
+
|
|
614
|
+
r.capture_controller.log_capture = Mock()
|
|
615
|
+
|
|
616
|
+
r.teardown_capture()
|
|
617
|
+
|
|
618
|
+
r.capture_controller.log_capture.abandon.assert_called_with()
|
|
619
|
+
|
|
620
|
+
def test_exec_file(self):
|
|
621
|
+
fn = tempfile.mktemp()
|
|
622
|
+
with open(fn, "w") as f:
|
|
623
|
+
f.write("spam = __file__\n")
|
|
624
|
+
g = {}
|
|
625
|
+
l = {}
|
|
626
|
+
runner.exec_file(fn, g, l)
|
|
627
|
+
assert "__file__" in l
|
|
628
|
+
# pylint: disable=too-many-format-args
|
|
629
|
+
assert "spam" in l, '"spam" variable not set in locals (%r)' % (g, l)
|
|
630
|
+
# pylint: enable=too-many-format-args
|
|
631
|
+
eq_(l["spam"], fn)
|
|
632
|
+
|
|
633
|
+
def test_run_returns_true_if_everything_passed(self):
|
|
634
|
+
r = runner.Runner(Mock())
|
|
635
|
+
r.setup_capture = Mock()
|
|
636
|
+
r.setup_paths = Mock()
|
|
637
|
+
r.run_with_paths = Mock()
|
|
638
|
+
r.run_with_paths.return_value = True
|
|
639
|
+
assert r.run()
|
|
640
|
+
|
|
641
|
+
def test_run_returns_false_if_anything_failed(self):
|
|
642
|
+
r = runner.Runner(Mock())
|
|
643
|
+
r.setup_capture = Mock()
|
|
644
|
+
r.setup_paths = Mock()
|
|
645
|
+
r.run_with_paths = Mock()
|
|
646
|
+
r.run_with_paths.return_value = False
|
|
647
|
+
assert not r.run()
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
class TestRunWithPaths(unittest.TestCase):
|
|
651
|
+
# pylint: disable=invalid-name, no-self-use
|
|
652
|
+
|
|
653
|
+
def setUp(self):
|
|
654
|
+
self.config = Mock()
|
|
655
|
+
self.config.reporters = []
|
|
656
|
+
self.config.logging_level = None
|
|
657
|
+
self.config.logging_filter = None
|
|
658
|
+
self.config.outputs = [Mock(), StreamOpener(stream=sys.stdout)]
|
|
659
|
+
self.config.format = ["plain", "progress"]
|
|
660
|
+
self.runner = runner.Runner(self.config)
|
|
661
|
+
self.load_hooks = self.runner.load_hooks = Mock()
|
|
662
|
+
self.load_step_definitions = self.runner.load_step_definitions = Mock()
|
|
663
|
+
self.run_hook = self.runner.run_hook = Mock()
|
|
664
|
+
self.run_step = self.runner.run_step = Mock()
|
|
665
|
+
self.feature_locations = self.runner.feature_locations = Mock()
|
|
666
|
+
self.calculate_summaries = self.runner.calculate_summaries = Mock()
|
|
667
|
+
|
|
668
|
+
self.formatter_class = patch("behave.formatter.pretty.PrettyFormatter")
|
|
669
|
+
formatter_class = self.formatter_class.start()
|
|
670
|
+
formatter_class.return_value = self.formatter = Mock()
|
|
671
|
+
|
|
672
|
+
def tearDown(self):
|
|
673
|
+
self.formatter_class.stop()
|
|
674
|
+
|
|
675
|
+
def test_loads_hooks_and_step_definitions(self):
|
|
676
|
+
self.feature_locations.return_value = []
|
|
677
|
+
self.runner.run_with_paths()
|
|
678
|
+
|
|
679
|
+
assert self.load_hooks.called
|
|
680
|
+
assert self.load_step_definitions.called
|
|
681
|
+
|
|
682
|
+
def test_runs_before_all_and_after_all_hooks(self):
|
|
683
|
+
# Make runner.feature_locations() and runner.run_hook() the same mock so
|
|
684
|
+
# we can make sure things happen in the right order.
|
|
685
|
+
self.runner.feature_locations = self.run_hook
|
|
686
|
+
self.runner.feature_locations.return_value = []
|
|
687
|
+
self.runner.context = Mock()
|
|
688
|
+
self.runner.run_with_paths()
|
|
689
|
+
|
|
690
|
+
eq_(self.run_hook.call_args_list, [
|
|
691
|
+
((), {}),
|
|
692
|
+
(("before_all", self.runner.context), {}),
|
|
693
|
+
(("after_all", self.runner.context), {}),
|
|
694
|
+
])
|
|
695
|
+
|
|
696
|
+
@patch("behave.parser.parse_file")
|
|
697
|
+
@patch("os.path.abspath")
|
|
698
|
+
def test_parses_feature_files_and_appends_to_feature_list(self, abspath,
|
|
699
|
+
parse_file):
|
|
700
|
+
feature_locations = ["one", "two", "three"]
|
|
701
|
+
feature = Mock()
|
|
702
|
+
feature.tags = []
|
|
703
|
+
feature.__iter__ = Mock(return_value=iter([]))
|
|
704
|
+
feature.run.return_value = False
|
|
705
|
+
self.runner.feature_locations.return_value = feature_locations
|
|
706
|
+
abspath.side_effect = lambda x: x.upper()
|
|
707
|
+
self.config.lang = "fritz"
|
|
708
|
+
self.config.format = ["plain"]
|
|
709
|
+
self.config.outputs = [StreamOpener(stream=sys.stdout)]
|
|
710
|
+
self.config.output.encoding = None
|
|
711
|
+
self.config.exclude = lambda s: False
|
|
712
|
+
self.config.junit = False
|
|
713
|
+
self.config.summary = False
|
|
714
|
+
parse_file.return_value = feature
|
|
715
|
+
|
|
716
|
+
self.runner.run_with_paths()
|
|
717
|
+
|
|
718
|
+
expected_parse_file_args = \
|
|
719
|
+
[((x.upper(),), {"language": "fritz"}) for x in feature_locations]
|
|
720
|
+
eq_(parse_file.call_args_list, expected_parse_file_args)
|
|
721
|
+
eq_(self.runner.features, [feature] * 3)
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
class FsMock(object):
|
|
725
|
+
def __init__(self, *paths):
|
|
726
|
+
self.base = os.path.abspath(".")
|
|
727
|
+
self.sep = os.path.sep
|
|
728
|
+
|
|
729
|
+
# This bit of gymnastics is to support Windows. We feed in a bunch of
|
|
730
|
+
# paths in places using FsMock that assume that POSIX-style paths
|
|
731
|
+
# work. This is faster than fixing all of those but at some point we
|
|
732
|
+
# should totally do it properly with os.path.join() and all that.
|
|
733
|
+
def full_split(path):
|
|
734
|
+
bits = []
|
|
735
|
+
|
|
736
|
+
while path:
|
|
737
|
+
path, bit = os.path.split(path)
|
|
738
|
+
bits.insert(0, bit)
|
|
739
|
+
|
|
740
|
+
return bits
|
|
741
|
+
|
|
742
|
+
paths = [os.path.join(self.base, *full_split(path)) for path in paths]
|
|
743
|
+
print(repr(paths))
|
|
744
|
+
self.paths = paths
|
|
745
|
+
self.files = set()
|
|
746
|
+
self.dirs = defaultdict(list)
|
|
747
|
+
separators = [sep for sep in (os.path.sep, os.path.altsep) if sep]
|
|
748
|
+
for path in paths:
|
|
749
|
+
if path[-1] in separators:
|
|
750
|
+
self.dirs[path[:-1]] = []
|
|
751
|
+
d, p = os.path.split(path[:-1])
|
|
752
|
+
while d and p:
|
|
753
|
+
self.dirs[d].append(p)
|
|
754
|
+
d, p = os.path.split(d)
|
|
755
|
+
else:
|
|
756
|
+
self.files.add(path)
|
|
757
|
+
d, f = os.path.split(path)
|
|
758
|
+
self.dirs[d].append(f)
|
|
759
|
+
self.calls = []
|
|
760
|
+
|
|
761
|
+
def listdir(self, dir):
|
|
762
|
+
# pylint: disable=W0622
|
|
763
|
+
# W0622 Redefining built-in dir
|
|
764
|
+
self.calls.append(("listdir", dir))
|
|
765
|
+
return self.dirs.get(dir, [])
|
|
766
|
+
|
|
767
|
+
def isfile(self, path):
|
|
768
|
+
self.calls.append(("isfile", path))
|
|
769
|
+
return path in self.files
|
|
770
|
+
|
|
771
|
+
def isdir(self, path):
|
|
772
|
+
self.calls.append(("isdir", path))
|
|
773
|
+
return path in self.dirs
|
|
774
|
+
|
|
775
|
+
def exists(self, path):
|
|
776
|
+
self.calls.append(("exists", path))
|
|
777
|
+
return path in self.dirs or path in self.files
|
|
778
|
+
|
|
779
|
+
def walk(self, path, locations=None):
|
|
780
|
+
if locations is None:
|
|
781
|
+
assert path in self.dirs, "%s not in %s" % (path, self.dirs)
|
|
782
|
+
locations = []
|
|
783
|
+
dirnames = []
|
|
784
|
+
filenames = []
|
|
785
|
+
for e in self.dirs[path]:
|
|
786
|
+
if os.path.join(path, e) in self.dirs:
|
|
787
|
+
dirnames.append(e)
|
|
788
|
+
self.walk(os.path.join(path, e), locations)
|
|
789
|
+
else:
|
|
790
|
+
filenames.append(e)
|
|
791
|
+
locations.append((path, dirnames, filenames))
|
|
792
|
+
return locations
|
|
793
|
+
|
|
794
|
+
# utilities that we need
|
|
795
|
+
# pylint: disable=no-self-use
|
|
796
|
+
def dirname(self, path, orig=os.path.dirname):
|
|
797
|
+
return orig(path)
|
|
798
|
+
|
|
799
|
+
def abspath(self, path, orig=os.path.abspath):
|
|
800
|
+
return orig(path)
|
|
801
|
+
|
|
802
|
+
def join(self, x, y, orig=os.path.join):
|
|
803
|
+
return orig(x, y)
|
|
804
|
+
|
|
805
|
+
def split(self, path, orig=os.path.split):
|
|
806
|
+
return orig(path)
|
|
807
|
+
|
|
808
|
+
def splitdrive(self, path, orig=os.path.splitdrive):
|
|
809
|
+
return orig(path)
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
class TestFeatureDirectory(object):
|
|
813
|
+
# pylint: disable=invalid-name, no-self-use
|
|
814
|
+
|
|
815
|
+
def test_default_path_no_steps(self):
|
|
816
|
+
config = create_mock_config()
|
|
817
|
+
config.paths = []
|
|
818
|
+
config.verbose = True
|
|
819
|
+
r = runner.Runner(config)
|
|
820
|
+
|
|
821
|
+
fs = FsMock()
|
|
822
|
+
|
|
823
|
+
# will look for a "features" directory and not find one
|
|
824
|
+
with patch("os.path", fs):
|
|
825
|
+
assert_raises(ConfigError, r.setup_paths)
|
|
826
|
+
|
|
827
|
+
ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
|
|
828
|
+
|
|
829
|
+
def test_default_path_no_features(self):
|
|
830
|
+
config = create_mock_config()
|
|
831
|
+
config.paths = []
|
|
832
|
+
config.verbose = True
|
|
833
|
+
r = runner.Runner(config)
|
|
834
|
+
|
|
835
|
+
fs = FsMock("features/steps/")
|
|
836
|
+
with patch("os.path", fs):
|
|
837
|
+
with patch("os.walk", fs.walk):
|
|
838
|
+
assert_raises(ConfigError, r.setup_paths)
|
|
839
|
+
|
|
840
|
+
def test_default_path(self):
|
|
841
|
+
config = create_mock_config()
|
|
842
|
+
config.paths = []
|
|
843
|
+
config.verbose = True
|
|
844
|
+
r = runner.Runner(config)
|
|
845
|
+
|
|
846
|
+
fs = FsMock("features/steps/", "features/foo.feature")
|
|
847
|
+
|
|
848
|
+
with patch("os.path", fs):
|
|
849
|
+
with patch("os.walk", fs.walk):
|
|
850
|
+
with r.path_manager:
|
|
851
|
+
r.setup_paths()
|
|
852
|
+
|
|
853
|
+
eq_(r.base_dir, os.path.abspath("features"))
|
|
854
|
+
|
|
855
|
+
def test_supplied_feature_file(self):
|
|
856
|
+
config = create_mock_config()
|
|
857
|
+
config.paths = ["foo.feature"]
|
|
858
|
+
config.verbose = True
|
|
859
|
+
r = runner.Runner(config)
|
|
860
|
+
r.context = Mock()
|
|
861
|
+
|
|
862
|
+
fs = FsMock("steps/", "foo.feature")
|
|
863
|
+
|
|
864
|
+
with patch("os.path", fs):
|
|
865
|
+
with patch("os.walk", fs.walk):
|
|
866
|
+
with r.path_manager:
|
|
867
|
+
r.setup_paths()
|
|
868
|
+
ok_(("isdir", os.path.join(fs.base, "steps")) in fs.calls)
|
|
869
|
+
ok_(("isfile", os.path.join(fs.base, "foo.feature")) in fs.calls)
|
|
870
|
+
|
|
871
|
+
eq_(r.base_dir, fs.base)
|
|
872
|
+
|
|
873
|
+
def test_supplied_feature_file_no_steps(self):
|
|
874
|
+
config = create_mock_config()
|
|
875
|
+
config.paths = ["foo.feature"]
|
|
876
|
+
config.verbose = True
|
|
877
|
+
r = runner.Runner(config)
|
|
878
|
+
|
|
879
|
+
fs = FsMock("foo.feature")
|
|
880
|
+
|
|
881
|
+
with patch("os.path", fs):
|
|
882
|
+
with patch("os.walk", fs.walk):
|
|
883
|
+
with r.path_manager:
|
|
884
|
+
assert_raises(ConfigError, r.setup_paths)
|
|
885
|
+
|
|
886
|
+
def test_supplied_feature_directory(self):
|
|
887
|
+
config = create_mock_config()
|
|
888
|
+
config.paths = ["spam"]
|
|
889
|
+
config.verbose = True
|
|
890
|
+
r = runner.Runner(config)
|
|
891
|
+
|
|
892
|
+
fs = FsMock("spam/", "spam/steps/", "spam/foo.feature")
|
|
893
|
+
|
|
894
|
+
with patch("os.path", fs):
|
|
895
|
+
with patch("os.walk", fs.walk):
|
|
896
|
+
with r.path_manager:
|
|
897
|
+
r.setup_paths()
|
|
898
|
+
|
|
899
|
+
ok_(("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls)
|
|
900
|
+
|
|
901
|
+
eq_(r.base_dir, os.path.join(fs.base, "spam"))
|
|
902
|
+
|
|
903
|
+
def test_supplied_feature_directory_no_steps(self):
|
|
904
|
+
config = create_mock_config()
|
|
905
|
+
config.paths = ["spam"]
|
|
906
|
+
config.verbose = True
|
|
907
|
+
r = runner.Runner(config)
|
|
908
|
+
|
|
909
|
+
fs = FsMock("spam/", "spam/foo.feature")
|
|
910
|
+
|
|
911
|
+
with patch("os.path", fs):
|
|
912
|
+
with patch("os.walk", fs.walk):
|
|
913
|
+
assert_raises(ConfigError, r.setup_paths)
|
|
914
|
+
|
|
915
|
+
ok_(("isdir", os.path.join(fs.base, "spam", "steps")) in fs.calls)
|
|
916
|
+
|
|
917
|
+
def test_supplied_feature_directory_missing(self):
|
|
918
|
+
config = create_mock_config()
|
|
919
|
+
config.paths = ["spam"]
|
|
920
|
+
config.verbose = True
|
|
921
|
+
r = runner.Runner(config)
|
|
922
|
+
|
|
923
|
+
fs = FsMock()
|
|
924
|
+
|
|
925
|
+
with patch("os.path", fs):
|
|
926
|
+
with patch("os.walk", fs.walk):
|
|
927
|
+
assert_raises(ConfigError, r.setup_paths)
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
class TestFeatureDirectoryLayout2(object):
|
|
931
|
+
# pylint: disable=invalid-name, no-self-use
|
|
932
|
+
|
|
933
|
+
def test_default_path(self):
|
|
934
|
+
config = create_mock_config()
|
|
935
|
+
config.paths = []
|
|
936
|
+
config.verbose = True
|
|
937
|
+
r = runner.Runner(config)
|
|
938
|
+
|
|
939
|
+
fs = FsMock(
|
|
940
|
+
"features/",
|
|
941
|
+
"features/steps/",
|
|
942
|
+
"features/group1/",
|
|
943
|
+
"features/group1/foo.feature",
|
|
944
|
+
)
|
|
945
|
+
|
|
946
|
+
with patch("os.path", fs):
|
|
947
|
+
with patch("os.walk", fs.walk):
|
|
948
|
+
with r.path_manager:
|
|
949
|
+
r.setup_paths()
|
|
950
|
+
|
|
951
|
+
eq_(r.base_dir, os.path.abspath("features"))
|
|
952
|
+
|
|
953
|
+
def test_supplied_root_directory(self):
|
|
954
|
+
config = create_mock_config()
|
|
955
|
+
config.paths = ["features"]
|
|
956
|
+
config.verbose = True
|
|
957
|
+
r = runner.Runner(config)
|
|
958
|
+
|
|
959
|
+
fs = FsMock(
|
|
960
|
+
"features/",
|
|
961
|
+
"features/group1/",
|
|
962
|
+
"features/group1/foo.feature",
|
|
963
|
+
"features/steps/",
|
|
964
|
+
)
|
|
965
|
+
|
|
966
|
+
with patch("os.path", fs):
|
|
967
|
+
with patch("os.walk", fs.walk):
|
|
968
|
+
with r.path_manager:
|
|
969
|
+
r.setup_paths()
|
|
970
|
+
|
|
971
|
+
ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
|
|
972
|
+
eq_(r.base_dir, os.path.join(fs.base, "features"))
|
|
973
|
+
|
|
974
|
+
def test_supplied_root_directory_no_steps(self):
|
|
975
|
+
config = create_mock_config()
|
|
976
|
+
config.paths = ["features"]
|
|
977
|
+
config.verbose = True
|
|
978
|
+
r = runner.Runner(config)
|
|
979
|
+
|
|
980
|
+
fs = FsMock(
|
|
981
|
+
"features/",
|
|
982
|
+
"features/group1/",
|
|
983
|
+
"features/group1/foo.feature",
|
|
984
|
+
)
|
|
985
|
+
|
|
986
|
+
with patch("os.path", fs):
|
|
987
|
+
with patch("os.walk", fs.walk):
|
|
988
|
+
with r.path_manager:
|
|
989
|
+
assert_raises(ConfigError, r.setup_paths)
|
|
990
|
+
|
|
991
|
+
ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
|
|
992
|
+
eq_(r.base_dir, None)
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
def test_supplied_feature_file(self):
|
|
996
|
+
config = create_mock_config()
|
|
997
|
+
config.paths = ["features/group1/foo.feature"]
|
|
998
|
+
config.verbose = True
|
|
999
|
+
r = runner.Runner(config)
|
|
1000
|
+
r.context = Mock()
|
|
1001
|
+
|
|
1002
|
+
fs = FsMock(
|
|
1003
|
+
"features/",
|
|
1004
|
+
"features/group1/",
|
|
1005
|
+
"features/group1/foo.feature",
|
|
1006
|
+
"features/steps/",
|
|
1007
|
+
)
|
|
1008
|
+
|
|
1009
|
+
with patch("os.path", fs):
|
|
1010
|
+
with patch("os.walk", fs.walk):
|
|
1011
|
+
with r.path_manager:
|
|
1012
|
+
r.setup_paths()
|
|
1013
|
+
|
|
1014
|
+
ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
|
|
1015
|
+
ok_(("isfile", os.path.join(fs.base, "features", "group1", "foo.feature")) in fs.calls)
|
|
1016
|
+
eq_(r.base_dir, fs.join(fs.base, "features"))
|
|
1017
|
+
|
|
1018
|
+
def test_supplied_feature_file_no_steps(self):
|
|
1019
|
+
config = create_mock_config()
|
|
1020
|
+
config.paths = ["features/group1/foo.feature"]
|
|
1021
|
+
config.verbose = True
|
|
1022
|
+
r = runner.Runner(config)
|
|
1023
|
+
|
|
1024
|
+
fs = FsMock(
|
|
1025
|
+
"features/",
|
|
1026
|
+
"features/group1/",
|
|
1027
|
+
"features/group1/foo.feature",
|
|
1028
|
+
)
|
|
1029
|
+
|
|
1030
|
+
with patch("os.path", fs):
|
|
1031
|
+
with patch("os.walk", fs.walk):
|
|
1032
|
+
with r.path_manager:
|
|
1033
|
+
assert_raises(ConfigError, r.setup_paths)
|
|
1034
|
+
|
|
1035
|
+
def test_supplied_feature_directory(self):
|
|
1036
|
+
config = create_mock_config()
|
|
1037
|
+
config.paths = ["features/group1"]
|
|
1038
|
+
config.verbose = True
|
|
1039
|
+
r = runner.Runner(config)
|
|
1040
|
+
|
|
1041
|
+
fs = FsMock(
|
|
1042
|
+
"features/",
|
|
1043
|
+
"features/group1/",
|
|
1044
|
+
"features/group1/foo.feature",
|
|
1045
|
+
"features/steps/",
|
|
1046
|
+
)
|
|
1047
|
+
|
|
1048
|
+
with patch("os.path", fs):
|
|
1049
|
+
with patch("os.walk", fs.walk):
|
|
1050
|
+
with r.path_manager:
|
|
1051
|
+
r.setup_paths()
|
|
1052
|
+
|
|
1053
|
+
ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
|
|
1054
|
+
eq_(r.base_dir, os.path.join(fs.base, "features"))
|
|
1055
|
+
|
|
1056
|
+
|
|
1057
|
+
def test_supplied_feature_directory_no_steps(self):
|
|
1058
|
+
config = create_mock_config()
|
|
1059
|
+
config.paths = ["features/group1"]
|
|
1060
|
+
config.verbose = True
|
|
1061
|
+
r = runner.Runner(config)
|
|
1062
|
+
|
|
1063
|
+
fs = FsMock(
|
|
1064
|
+
"features/",
|
|
1065
|
+
"features/group1/",
|
|
1066
|
+
"features/group1/foo.feature",
|
|
1067
|
+
)
|
|
1068
|
+
|
|
1069
|
+
with patch("os.path", fs):
|
|
1070
|
+
with patch("os.walk", fs.walk):
|
|
1071
|
+
assert_raises(ConfigError, r.setup_paths)
|
|
1072
|
+
|
|
1073
|
+
ok_(("isdir", os.path.join(fs.base, "features", "steps")) in fs.calls)
|
|
1074
|
+
|