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
|
File without changes
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# -*- coding: UTF -*-
|
|
2
|
+
# pylint: disable=line-too-long
|
|
3
|
+
"""
|
|
4
|
+
Provides support functionality to retry scenarios a number of times before
|
|
5
|
+
their failure is accepted. This functionality can be helpful when you use
|
|
6
|
+
behave tests in a unreliable server/network infrastructure.
|
|
7
|
+
|
|
8
|
+
EXAMPLE:
|
|
9
|
+
|
|
10
|
+
.. sourcecode:: gherkin
|
|
11
|
+
|
|
12
|
+
# -- FILE: features/alice.feature
|
|
13
|
+
# TAG: Feature or Scenario/ScenarioOutline with @autoretry
|
|
14
|
+
# NOTE: If you tag the feature, all its scenarios are retried.
|
|
15
|
+
@autoretry
|
|
16
|
+
Feature: Use unreliable Server infrastructure
|
|
17
|
+
|
|
18
|
+
Scenario: ...
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
.. sourcecode:: python
|
|
22
|
+
|
|
23
|
+
# -- FILE: features/environment.py
|
|
24
|
+
from behave.contrib.scenario_autoretry import patch_scenario_with_autoretry
|
|
25
|
+
|
|
26
|
+
def before_feature(context, feature):
|
|
27
|
+
for scenario in feature.scenarios:
|
|
28
|
+
if "autoretry" in scenario.effective_tags:
|
|
29
|
+
patch_scenario_with_autoretry(scenario, max_attempts=2)
|
|
30
|
+
|
|
31
|
+
.. seealso::
|
|
32
|
+
* https://github.com/behave/behave/pull/328
|
|
33
|
+
* https://github.com/hypothesis/smokey/blob/sauce-reliability/smokey/features/environment.py
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
from __future__ import print_function
|
|
37
|
+
import functools
|
|
38
|
+
from behave.model import ScenarioOutline
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def patch_scenario_with_autoretry(scenario, max_attempts=3):
|
|
42
|
+
"""Monkey-patches :func:`~behave.model.Scenario.run()` to auto-retry a
|
|
43
|
+
scenario that fails. The scenario is retried a number of times
|
|
44
|
+
before its failure is accepted.
|
|
45
|
+
|
|
46
|
+
This is helpful when the test infrastructure (server/network environment)
|
|
47
|
+
is unreliable (which should be a rare case).
|
|
48
|
+
|
|
49
|
+
:param scenario: Scenario or ScenarioOutline to patch.
|
|
50
|
+
:param max_attempts: How many times the scenario can be run.
|
|
51
|
+
"""
|
|
52
|
+
def scenario_run_with_retries(scenario_run, *args, **kwargs):
|
|
53
|
+
for attempt in range(1, max_attempts+1):
|
|
54
|
+
if not scenario_run(*args, **kwargs):
|
|
55
|
+
if attempt > 1:
|
|
56
|
+
message = u"AUTO-RETRY SCENARIO PASSED (after {0} attempts)"
|
|
57
|
+
print(message.format(attempt))
|
|
58
|
+
return False # -- NOT-FAILED = PASSED
|
|
59
|
+
# -- SCENARIO FAILED:
|
|
60
|
+
if attempt < max_attempts:
|
|
61
|
+
print(u"AUTO-RETRY SCENARIO (attempt {0})".format(attempt))
|
|
62
|
+
message = u"AUTO-RETRY SCENARIO FAILED (after {0} attempts)"
|
|
63
|
+
print(message.format(max_attempts))
|
|
64
|
+
return True
|
|
65
|
+
|
|
66
|
+
if isinstance(scenario, ScenarioOutline):
|
|
67
|
+
scenario_outline = scenario
|
|
68
|
+
for scenario in scenario_outline.scenarios:
|
|
69
|
+
scenario_run = scenario.run
|
|
70
|
+
scenario.run = functools.partial(scenario_run_with_retries, scenario_run)
|
|
71
|
+
else:
|
|
72
|
+
scenario_run = scenario.run
|
|
73
|
+
scenario.run = functools.partial(scenario_run_with_retries, scenario_run)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Root module for all behave formatters.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import absolute_import
|
|
7
|
+
from behave.formatter import _builtins
|
|
8
|
+
|
|
9
|
+
# -----------------------------------------------------------------------------
|
|
10
|
+
# MODULE-INIT:
|
|
11
|
+
# -----------------------------------------------------------------------------
|
|
12
|
+
_builtins.setup_formatters()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Knowledge base of all built-on formatters.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import absolute_import
|
|
7
|
+
from behave.formatter import _registry
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# -----------------------------------------------------------------------------
|
|
11
|
+
# DATA:
|
|
12
|
+
# -----------------------------------------------------------------------------
|
|
13
|
+
# SCHEMA: formatter.name, formatter.class(_name)
|
|
14
|
+
_BUILTIN_FORMATS = [
|
|
15
|
+
# pylint: disable=bad-whitespace
|
|
16
|
+
("plain", "behave.formatter.plain:PlainFormatter"),
|
|
17
|
+
("pretty", "behave.formatter.pretty:PrettyFormatter"),
|
|
18
|
+
("json", "behave.formatter.json:JSONFormatter"),
|
|
19
|
+
("json.pretty", "behave.formatter.json:PrettyJSONFormatter"),
|
|
20
|
+
("null", "behave.formatter.null:NullFormatter"),
|
|
21
|
+
("progress", "behave.formatter.progress:ScenarioProgressFormatter"),
|
|
22
|
+
("progress2", "behave.formatter.progress:StepProgressFormatter"),
|
|
23
|
+
("progress3", "behave.formatter.progress:ScenarioStepProgressFormatter"),
|
|
24
|
+
("rerun", "behave.formatter.rerun:RerunFormatter"),
|
|
25
|
+
("tags", "behave.formatter.tags:TagsFormatter"),
|
|
26
|
+
("tags.location", "behave.formatter.tags:TagsLocationFormatter"),
|
|
27
|
+
("steps", "behave.formatter.steps:StepsFormatter"),
|
|
28
|
+
("steps.doc", "behave.formatter.steps:StepsDocFormatter"),
|
|
29
|
+
("steps.catalog", "behave.formatter.steps:StepsCatalogFormatter"),
|
|
30
|
+
("steps.usage", "behave.formatter.steps:StepsUsageFormatter"),
|
|
31
|
+
("sphinx.steps", "behave.formatter.sphinx_steps:SphinxStepsFormatter"),
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
# -----------------------------------------------------------------------------
|
|
35
|
+
# FUNCTIONS:
|
|
36
|
+
# -----------------------------------------------------------------------------
|
|
37
|
+
def setup_formatters():
|
|
38
|
+
"""Register all built-in formatters (lazy-loaded)."""
|
|
39
|
+
_registry.register_formats(_BUILTIN_FORMATS)
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import warnings
|
|
5
|
+
from behave.formatter.base import Formatter, StreamOpener
|
|
6
|
+
from behave.importer import LazyDict, LazyObject, parse_scoped_name, load_module
|
|
7
|
+
import six
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# -----------------------------------------------------------------------------
|
|
11
|
+
# FORMATTER REGISTRY:
|
|
12
|
+
# -----------------------------------------------------------------------------
|
|
13
|
+
_formatter_registry = LazyDict()
|
|
14
|
+
|
|
15
|
+
def format_iter():
|
|
16
|
+
return iter(_formatter_registry.keys())
|
|
17
|
+
|
|
18
|
+
def format_items(resolved=False):
|
|
19
|
+
if resolved:
|
|
20
|
+
# -- ENSURE: All formatter classes are loaded (and resolved).
|
|
21
|
+
_formatter_registry.load_all(strict=False)
|
|
22
|
+
return iter(_formatter_registry.items())
|
|
23
|
+
|
|
24
|
+
def register_as(name, formatter_class):
|
|
25
|
+
"""
|
|
26
|
+
Register formatter class with given name.
|
|
27
|
+
|
|
28
|
+
:param name: Name for this formatter (as identifier).
|
|
29
|
+
:param formatter_class: Formatter class to register.
|
|
30
|
+
|
|
31
|
+
.. since:: 1.2.5
|
|
32
|
+
Parameter ordering starts with name.
|
|
33
|
+
"""
|
|
34
|
+
if not isinstance(name, six.string_types):
|
|
35
|
+
# -- REORDER-PARAMS: Used old ordering before behave-1.2.5 (2015).
|
|
36
|
+
warnings.warn("Use parameter ordering: name, formatter_class (for: %s)"\
|
|
37
|
+
% formatter_class)
|
|
38
|
+
_formatter_class = name
|
|
39
|
+
name = formatter_class
|
|
40
|
+
formatter_class = _formatter_class
|
|
41
|
+
|
|
42
|
+
if isinstance(formatter_class, six.string_types):
|
|
43
|
+
# -- SPEEDUP-STARTUP: Only import formatter_class when used.
|
|
44
|
+
scoped_formatter_class_name = formatter_class
|
|
45
|
+
formatter_class = LazyObject(scoped_formatter_class_name)
|
|
46
|
+
assert (isinstance(formatter_class, LazyObject) or
|
|
47
|
+
issubclass(formatter_class, Formatter))
|
|
48
|
+
_formatter_registry[name] = formatter_class
|
|
49
|
+
|
|
50
|
+
def register(formatter_class):
|
|
51
|
+
register_as(formatter_class.name, formatter_class)
|
|
52
|
+
|
|
53
|
+
def register_formats(formats):
|
|
54
|
+
"""Register many format items into the registry.
|
|
55
|
+
|
|
56
|
+
:param formats: List of format items (as: (name, class|class_name)).
|
|
57
|
+
"""
|
|
58
|
+
for formatter_name, formatter_class_name in formats:
|
|
59
|
+
register_as(formatter_name, formatter_class_name)
|
|
60
|
+
|
|
61
|
+
def load_formatter_class(scoped_class_name):
|
|
62
|
+
"""Load a formatter class by using its scoped class name.
|
|
63
|
+
|
|
64
|
+
:param scoped_class_name: Formatter module and class name (as string).
|
|
65
|
+
:return: Formatter class.
|
|
66
|
+
:raises: ValueError, if scoped_class_name is invalid.
|
|
67
|
+
:raises: ImportError, if module cannot be loaded or class is not in module.
|
|
68
|
+
"""
|
|
69
|
+
if ":" not in scoped_class_name:
|
|
70
|
+
message = 'REQUIRE: "module:class", but was: "%s"' % scoped_class_name
|
|
71
|
+
raise ValueError(message)
|
|
72
|
+
module_name, class_name = parse_scoped_name(scoped_class_name)
|
|
73
|
+
formatter_module = load_module(module_name)
|
|
74
|
+
formatter_class = getattr(formatter_module, class_name, None)
|
|
75
|
+
if formatter_class is None:
|
|
76
|
+
raise ImportError("CLASS NOT FOUND: %s" % scoped_class_name)
|
|
77
|
+
return formatter_class
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def select_formatter_class(formatter_name):
|
|
81
|
+
"""Resolve the formatter class by:
|
|
82
|
+
|
|
83
|
+
* using one of the registered ones
|
|
84
|
+
* loading a user-specified formatter class (like: my.module_name:MyClass)
|
|
85
|
+
|
|
86
|
+
:param formatter_name: Name of the formatter or scoped name (as string).
|
|
87
|
+
:return: Formatter class
|
|
88
|
+
:raises: LookupError, if not found.
|
|
89
|
+
:raises: ImportError, if a user-specific formatter class cannot be loaded.
|
|
90
|
+
:raises: ValueError, if formatter name is invalid.
|
|
91
|
+
"""
|
|
92
|
+
try:
|
|
93
|
+
return _formatter_registry[formatter_name]
|
|
94
|
+
except KeyError:
|
|
95
|
+
# -- NOT-FOUND:
|
|
96
|
+
if ":" not in formatter_name:
|
|
97
|
+
raise
|
|
98
|
+
# -- OTHERWISE: SCOPED-NAME, try to load a user-specific formatter.
|
|
99
|
+
# MAY RAISE: ImportError
|
|
100
|
+
return load_formatter_class(formatter_name)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def is_formatter_valid(formatter_name):
|
|
104
|
+
"""Checks if the formatter is known (registered) or loadable.
|
|
105
|
+
|
|
106
|
+
:param formatter_name: Format(ter) name to check (as string).
|
|
107
|
+
:return: True, if formatter is known or can be loaded.
|
|
108
|
+
"""
|
|
109
|
+
try:
|
|
110
|
+
formatter_class = select_formatter_class(formatter_name)
|
|
111
|
+
return issubclass(formatter_class, Formatter)
|
|
112
|
+
except (LookupError, ImportError, ValueError):
|
|
113
|
+
return False
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def make_formatters(config, stream_openers):
|
|
117
|
+
"""Build a list of formatter, used by a behave runner.
|
|
118
|
+
|
|
119
|
+
:param config: Configuration object to use.
|
|
120
|
+
:param stream_openers: List of stream openers to use (for formatters).
|
|
121
|
+
:return: List of formatters.
|
|
122
|
+
:raises: LookupError/KeyError if a formatter class is unknown.
|
|
123
|
+
:raises: ImportError, if a formatter class cannot be loaded/resolved.
|
|
124
|
+
"""
|
|
125
|
+
# -- BUILD: Formatter list
|
|
126
|
+
default_stream_opener = StreamOpener(stream=sys.stdout)
|
|
127
|
+
formatter_list = []
|
|
128
|
+
for i, name in enumerate(config.format):
|
|
129
|
+
stream_opener = default_stream_opener
|
|
130
|
+
if i < len(stream_openers):
|
|
131
|
+
stream_opener = stream_openers[i]
|
|
132
|
+
formatter_class = select_formatter_class(name)
|
|
133
|
+
formatter_object = formatter_class(stream_opener, config)
|
|
134
|
+
formatter_list.append(formatter_object)
|
|
135
|
+
return formatter_list
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Provides ANSI escape sequences for coloring/formatting output in ANSI terminals.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import absolute_import
|
|
7
|
+
import os
|
|
8
|
+
import re
|
|
9
|
+
|
|
10
|
+
colors = {
|
|
11
|
+
"black": u"\x1b[30m",
|
|
12
|
+
"red": u"\x1b[31m",
|
|
13
|
+
"green": u"\x1b[32m",
|
|
14
|
+
"yellow": u"\x1b[33m",
|
|
15
|
+
"blue": u"\x1b[34m",
|
|
16
|
+
"magenta": u"\x1b[35m",
|
|
17
|
+
"cyan": u"\x1b[36m",
|
|
18
|
+
"white": u"\x1b[37m",
|
|
19
|
+
"grey": u"\x1b[90m",
|
|
20
|
+
"bold": u"\x1b[1m",
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
aliases = {
|
|
24
|
+
"untested": "cyan", # SAME-COLOR AS: skipped
|
|
25
|
+
"undefined": "yellow",
|
|
26
|
+
"pending": "yellow",
|
|
27
|
+
"executing": "grey",
|
|
28
|
+
"failed": "red",
|
|
29
|
+
"passed": "green",
|
|
30
|
+
"outline": "cyan",
|
|
31
|
+
"skipped": "cyan",
|
|
32
|
+
"comments": "grey",
|
|
33
|
+
"tag": "cyan",
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
escapes = {
|
|
37
|
+
"reset": u"\x1b[0m",
|
|
38
|
+
"up": u"\x1b[1A",
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if "GHERKIN_COLORS" in os.environ:
|
|
42
|
+
new_aliases = [p.split("=") for p in os.environ["GHERKIN_COLORS"].split(":")]
|
|
43
|
+
aliases.update(dict(new_aliases))
|
|
44
|
+
|
|
45
|
+
for alias in aliases:
|
|
46
|
+
escapes[alias] = "".join([colors[c] for c in aliases[alias].split(",")])
|
|
47
|
+
arg_alias = alias + "_arg"
|
|
48
|
+
arg_seq = aliases.get(arg_alias, aliases[alias] + ",bold")
|
|
49
|
+
escapes[arg_alias] = "".join([colors[c] for c in arg_seq.split(",")])
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def up(n):
|
|
53
|
+
return u"\x1b[%dA" % n
|
|
54
|
+
|
|
55
|
+
_ANSI_ESCAPE_PATTERN = re.compile(u"\x1b\[\d+[mA]", re.UNICODE)
|
|
56
|
+
def strip_escapes(text):
|
|
57
|
+
"""
|
|
58
|
+
Removes ANSI escape sequences from text (if any are contained).
|
|
59
|
+
|
|
60
|
+
:param text: Text that may or may not contain ANSI escape sequences.
|
|
61
|
+
:return: Text without ANSI escape sequences.
|
|
62
|
+
"""
|
|
63
|
+
return _ANSI_ESCAPE_PATTERN.sub("", text)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def use_ansi_escape_colorbold_composites(): # pragma: no cover
|
|
67
|
+
"""
|
|
68
|
+
Patch for "sphinxcontrib-ansi" to process the following ANSI escapes
|
|
69
|
+
correctly (set-color set-bold sequences):
|
|
70
|
+
|
|
71
|
+
ESC[{color}mESC[1m => ESC[{color};1m
|
|
72
|
+
|
|
73
|
+
Reapply aliases to ANSI escapes mapping.
|
|
74
|
+
"""
|
|
75
|
+
# NOT-NEEDED: global escapes
|
|
76
|
+
color_codes = {}
|
|
77
|
+
for color_name, color_escape in colors.items():
|
|
78
|
+
color_code = color_escape.replace(u"\x1b[", u"").replace(u"m", u"")
|
|
79
|
+
color_codes[color_name] = color_code
|
|
80
|
+
|
|
81
|
+
# pylint: disable=redefined-outer-name
|
|
82
|
+
for alias in aliases:
|
|
83
|
+
parts = [color_codes[c] for c in aliases[alias].split(",")]
|
|
84
|
+
composite_escape = u"\x1b[{0}m".format(u";".join(parts))
|
|
85
|
+
escapes[alias] = composite_escape
|
|
86
|
+
|
|
87
|
+
arg_alias = alias + "_arg"
|
|
88
|
+
arg_seq = aliases.get(arg_alias, aliases[alias] + ",bold")
|
|
89
|
+
parts = [color_codes[c] for c in arg_seq.split(",")]
|
|
90
|
+
composite_escape = u"\x1b[{0}m".format(u";".join(parts))
|
|
91
|
+
escapes[arg_alias] = composite_escape
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
import codecs
|
|
4
|
+
import os.path
|
|
5
|
+
import six
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class StreamOpener(object):
|
|
9
|
+
"""Provides a transport vehicle to open the formatter output stream
|
|
10
|
+
when the formatter needs it.
|
|
11
|
+
In addition, it provides the formatter with more control:
|
|
12
|
+
|
|
13
|
+
* when a stream is opened
|
|
14
|
+
* if a stream is opened at all
|
|
15
|
+
* the name (filename/dirname) of the output stream
|
|
16
|
+
* let it decide if directory mode is used instead of file mode
|
|
17
|
+
"""
|
|
18
|
+
default_encoding = "UTF-8"
|
|
19
|
+
|
|
20
|
+
def __init__(self, filename=None, stream=None, encoding=None):
|
|
21
|
+
if not encoding:
|
|
22
|
+
encoding = self.default_encoding
|
|
23
|
+
if stream:
|
|
24
|
+
stream = self.ensure_stream_with_encoder(stream, encoding)
|
|
25
|
+
self.name = filename
|
|
26
|
+
self.stream = stream
|
|
27
|
+
self.encoding = encoding
|
|
28
|
+
self.should_close_stream = not stream # Only for not pre-opened ones.
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
def ensure_dir_exists(directory):
|
|
32
|
+
if directory and not os.path.isdir(directory):
|
|
33
|
+
os.makedirs(directory)
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def ensure_stream_with_encoder(cls, stream, encoding=None):
|
|
37
|
+
if not encoding:
|
|
38
|
+
encoding = cls.default_encoding
|
|
39
|
+
|
|
40
|
+
if six.PY3:
|
|
41
|
+
return stream
|
|
42
|
+
elif hasattr(stream, "stream"):
|
|
43
|
+
return stream # Already wrapped with a codecs.StreamWriter
|
|
44
|
+
else:
|
|
45
|
+
assert six.PY2
|
|
46
|
+
# py2 does, however, sometimes declare an encoding on sys.stdout,
|
|
47
|
+
# even if it doesn't use it (or it might be explicitly None)
|
|
48
|
+
stream = codecs.getwriter(encoding)(stream)
|
|
49
|
+
# elif not getattr(stream, 'encoding', None):
|
|
50
|
+
# # -- TODO: POTENTIAL DEAD-CODE: Inspect and cleanup later.
|
|
51
|
+
# # ok, so the stream doesn't have an encoding at all so add one
|
|
52
|
+
# stream = codecs.getwriter(encoding)(stream)
|
|
53
|
+
return stream
|
|
54
|
+
|
|
55
|
+
def open(self):
|
|
56
|
+
if not self.stream or self.stream.closed:
|
|
57
|
+
self.ensure_dir_exists(os.path.dirname(self.name))
|
|
58
|
+
stream = open(self.name, "w")
|
|
59
|
+
# stream = codecs.open(self.name, "w", encoding=self.encoding)
|
|
60
|
+
stream = self.ensure_stream_with_encoder(stream, self.encoding)
|
|
61
|
+
self.stream = stream # -- Keep stream for house-keeping.
|
|
62
|
+
self.should_close_stream = True
|
|
63
|
+
assert self.should_close_stream
|
|
64
|
+
return self.stream
|
|
65
|
+
|
|
66
|
+
def close(self):
|
|
67
|
+
"""
|
|
68
|
+
Close the stream, if it was opened by this stream_opener.
|
|
69
|
+
Skip closing for sys.stdout and pre-opened streams.
|
|
70
|
+
:return: True, if stream was closed.
|
|
71
|
+
"""
|
|
72
|
+
closed = False
|
|
73
|
+
if self.stream and self.should_close_stream:
|
|
74
|
+
closed = getattr(self.stream, "closed", False)
|
|
75
|
+
if not closed:
|
|
76
|
+
self.stream.close()
|
|
77
|
+
closed = True
|
|
78
|
+
self.stream = None
|
|
79
|
+
return closed
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class Formatter(object):
|
|
83
|
+
"""
|
|
84
|
+
Base class for all formatter classes.
|
|
85
|
+
A formatter is an extension point (variation point) for the runner logic.
|
|
86
|
+
A formatter is called while processing model elements.
|
|
87
|
+
|
|
88
|
+
Processing Logic (simplified, without ScenarioOutline and skip logic)::
|
|
89
|
+
|
|
90
|
+
for feature in runner.features:
|
|
91
|
+
formatter = make_formatters(...)
|
|
92
|
+
formatter.uri(feature.filename)
|
|
93
|
+
formatter.feature(feature)
|
|
94
|
+
for scenario in feature.scenarios:
|
|
95
|
+
formatter.scenario(scenario)
|
|
96
|
+
for step in scenario.all_steps:
|
|
97
|
+
formatter.step(step)
|
|
98
|
+
step_match = step_registry.find_match(step)
|
|
99
|
+
formatter.match(step_match)
|
|
100
|
+
if step_match:
|
|
101
|
+
step_match.run()
|
|
102
|
+
else:
|
|
103
|
+
step.status = Status.undefined
|
|
104
|
+
formatter.result(step.status)
|
|
105
|
+
formatter.eof() # -- FEATURE-END
|
|
106
|
+
formatter.close()
|
|
107
|
+
"""
|
|
108
|
+
name = None
|
|
109
|
+
description = None
|
|
110
|
+
|
|
111
|
+
def __init__(self, stream_opener, config):
|
|
112
|
+
self.stream_opener = stream_opener
|
|
113
|
+
self.stream = stream_opener.stream
|
|
114
|
+
self.config = config
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def stdout_mode(self):
|
|
118
|
+
return not self.stream_opener.name
|
|
119
|
+
|
|
120
|
+
def open(self):
|
|
121
|
+
"""
|
|
122
|
+
Ensure that the output stream is open.
|
|
123
|
+
Triggers the stream opener protocol (if necessary).
|
|
124
|
+
|
|
125
|
+
:return: Output stream to use (just opened or already open).
|
|
126
|
+
"""
|
|
127
|
+
if not self.stream:
|
|
128
|
+
self.stream = self.stream_opener.open()
|
|
129
|
+
return self.stream
|
|
130
|
+
|
|
131
|
+
def uri(self, uri):
|
|
132
|
+
"""Called before processing a file (normally a feature file).
|
|
133
|
+
|
|
134
|
+
:param uri: URI or filename (as string).
|
|
135
|
+
"""
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
def feature(self, feature):
|
|
139
|
+
"""Called before a feature is executed.
|
|
140
|
+
|
|
141
|
+
:param feature: Feature object (as :class:`behave.model.Feature`)
|
|
142
|
+
"""
|
|
143
|
+
pass
|
|
144
|
+
|
|
145
|
+
def background(self, background):
|
|
146
|
+
"""Called when a (Feature) Background is provided.
|
|
147
|
+
Called after :method:`feature()` is called.
|
|
148
|
+
Called before processing any scenarios or scenario outlines.
|
|
149
|
+
|
|
150
|
+
:param background: Background object (as :class:`behave.model.Background`)
|
|
151
|
+
"""
|
|
152
|
+
pass
|
|
153
|
+
|
|
154
|
+
def scenario(self, scenario):
|
|
155
|
+
"""Called before a scenario is executed (or ScenarioOutline scenarios).
|
|
156
|
+
|
|
157
|
+
:param scenario: Scenario object (as :class:`behave.model.Scenario`)
|
|
158
|
+
"""
|
|
159
|
+
pass
|
|
160
|
+
|
|
161
|
+
def step(self, step):
|
|
162
|
+
"""Called before a step is executed (and matched).
|
|
163
|
+
NOTE: Normally called before scenario is executed for all its steps.
|
|
164
|
+
|
|
165
|
+
:param step: Step object (as :class:`behave.model.Step`)
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
def match(self, match):
|
|
169
|
+
"""Called when a step was matched against its step implementation.
|
|
170
|
+
|
|
171
|
+
:param match: Registered step (as Match), undefined step (as NoMatch).
|
|
172
|
+
"""
|
|
173
|
+
pass
|
|
174
|
+
|
|
175
|
+
def result(self, step_result):
|
|
176
|
+
"""Called after processing a step (when the step result is known).
|
|
177
|
+
|
|
178
|
+
:param step_result: Step result (as string-enum).
|
|
179
|
+
"""
|
|
180
|
+
pass
|
|
181
|
+
|
|
182
|
+
def eof(self):
|
|
183
|
+
"""Called after processing a feature (or a feature file)."""
|
|
184
|
+
pass
|
|
185
|
+
|
|
186
|
+
def close(self):
|
|
187
|
+
"""Called before the formatter is no longer used
|
|
188
|
+
(stream/io compatibility).
|
|
189
|
+
"""
|
|
190
|
+
self.close_stream()
|
|
191
|
+
|
|
192
|
+
def close_stream(self):
|
|
193
|
+
"""Close the stream, but only if this is needed.
|
|
194
|
+
This step is skipped if the stream is sys.stdout.
|
|
195
|
+
"""
|
|
196
|
+
if self.stream:
|
|
197
|
+
# -- DELEGATE STREAM-CLOSING: To stream_opener
|
|
198
|
+
assert self.stream is self.stream_opener.stream
|
|
199
|
+
self.stream_opener.close()
|
|
200
|
+
self.stream = None # -- MARK CLOSED.
|