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,118 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Provides utility function for generating Sphinx-based documentation.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import absolute_import
|
|
7
|
+
import codecs
|
|
8
|
+
from behave.textutil import compute_words_maxsize, text as _text
|
|
9
|
+
import six
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# -----------------------------------------------------------------------------
|
|
13
|
+
# SPHINX OUTPUT GENERATION FUNCTIONS:
|
|
14
|
+
# -----------------------------------------------------------------------------
|
|
15
|
+
class DocumentWriter(object):
|
|
16
|
+
"""
|
|
17
|
+
Provides a simple "ReStructured Text Writer" to generate
|
|
18
|
+
Sphinx-based documentation.
|
|
19
|
+
"""
|
|
20
|
+
heading_styles = ["=", "=", "-", "~"]
|
|
21
|
+
default_encoding = "utf-8"
|
|
22
|
+
default_toctree_title = "**Contents:**"
|
|
23
|
+
|
|
24
|
+
def __init__(self, stream, filename=None, should_close=True):
|
|
25
|
+
self.stream = stream
|
|
26
|
+
self.filename = filename
|
|
27
|
+
self.should_close = should_close
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def open(cls, filename, encoding=None):
|
|
31
|
+
encoding = encoding or cls.default_encoding
|
|
32
|
+
stream = codecs.open(filename, "wb", encoding)
|
|
33
|
+
return cls(stream, filename)
|
|
34
|
+
|
|
35
|
+
def write(self, *args):
|
|
36
|
+
return self.stream.write(*args)
|
|
37
|
+
|
|
38
|
+
def close(self):
|
|
39
|
+
if self.stream and self.should_close:
|
|
40
|
+
self.stream.close()
|
|
41
|
+
self.stream = None
|
|
42
|
+
|
|
43
|
+
def write_heading(self, heading, level=0, index_id=None, label=None):
|
|
44
|
+
assert self.stream
|
|
45
|
+
assert heading, "Heading should not be empty"
|
|
46
|
+
assert 0 <= level < len(self.heading_styles)
|
|
47
|
+
if level >= len(self.heading_styles):
|
|
48
|
+
level = len(self.heading_styles) - 1
|
|
49
|
+
heading_size = len(heading)
|
|
50
|
+
heading_style = self.heading_styles[level]
|
|
51
|
+
if level == 0 and heading_size < 70:
|
|
52
|
+
heading_size = 70
|
|
53
|
+
separator = heading_style * heading_size
|
|
54
|
+
if index_id:
|
|
55
|
+
if isinstance(index_id, (list, tuple)):
|
|
56
|
+
index_id = ", ".join(index_id)
|
|
57
|
+
self.stream.write(".. index:: %s\n\n" % index_id)
|
|
58
|
+
if label:
|
|
59
|
+
self.stream.write(".. _%s:\n\n" % label)
|
|
60
|
+
if level == 0:
|
|
61
|
+
self.stream.write("%s\n" % separator)
|
|
62
|
+
self.stream.write("%s\n" % heading)
|
|
63
|
+
self.stream.write("%s\n" % separator)
|
|
64
|
+
self.stream.write("\n")
|
|
65
|
+
|
|
66
|
+
def write_toctree(self, entries, title=None, maxdepth=2):
|
|
67
|
+
if title is None:
|
|
68
|
+
title = self.default_toctree_title
|
|
69
|
+
line_prefix = " " * 4
|
|
70
|
+
if title:
|
|
71
|
+
self.stream.write("%s\n\n" % title)
|
|
72
|
+
self.stream.write(".. toctree::\n")
|
|
73
|
+
self.stream.write("%s:maxdepth: %d\n\n" % (line_prefix, maxdepth))
|
|
74
|
+
for entry in entries:
|
|
75
|
+
self.stream.write("%s%s\n" % (line_prefix, entry))
|
|
76
|
+
self.stream.write("\n")
|
|
77
|
+
|
|
78
|
+
def write_table(self, table):
|
|
79
|
+
"""
|
|
80
|
+
Write a ReST simple table.
|
|
81
|
+
|
|
82
|
+
EXAMPLE:
|
|
83
|
+
========================================= ===== ===== ===== =====
|
|
84
|
+
Step Definition Given When Then Step
|
|
85
|
+
========================================= ===== ===== ===== =====
|
|
86
|
+
Given a file named "{filename}" contains
|
|
87
|
+
Then the file "{filename}" should ...
|
|
88
|
+
========================================= ===== ===== ===== =====
|
|
89
|
+
|
|
90
|
+
:param table: Table to render (as `behave.model.Table`)
|
|
91
|
+
|
|
92
|
+
.. todo::
|
|
93
|
+
Column alignments
|
|
94
|
+
"""
|
|
95
|
+
assert self.stream
|
|
96
|
+
|
|
97
|
+
# -- STEP: Determine table layout dimensions
|
|
98
|
+
cols_size = []
|
|
99
|
+
separator_parts = []
|
|
100
|
+
row_schema_parts = []
|
|
101
|
+
for col_index, heading in enumerate(table.headings):
|
|
102
|
+
column = [six.text_type(row[col_index]) for row in table.rows]
|
|
103
|
+
column.append(heading)
|
|
104
|
+
column_size = compute_words_maxsize(column)
|
|
105
|
+
cols_size.append(column_size)
|
|
106
|
+
separator_parts.append("=" * column_size)
|
|
107
|
+
row_schema_parts.append("%-" + _text(column_size) + "s")
|
|
108
|
+
|
|
109
|
+
separator = " ".join(separator_parts) + "\n"
|
|
110
|
+
row_schema = " ".join(row_schema_parts) + "\n"
|
|
111
|
+
self.stream.write("\n") # -- ENSURE: Empty line before table start.
|
|
112
|
+
self.stream.write(separator)
|
|
113
|
+
self.stream.write(row_schema % tuple(table.headings))
|
|
114
|
+
self.stream.write(separator)
|
|
115
|
+
for row in table.rows:
|
|
116
|
+
self.stream.write(row_schema % tuple(row))
|
|
117
|
+
self.stream.write(separator)
|
|
118
|
+
self.stream.write("\n") # -- ENSURE: Empty line after table end.
|
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Provides a formatter that provides an overview of available step definitions
|
|
4
|
+
(step implementations).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import absolute_import
|
|
8
|
+
from operator import attrgetter
|
|
9
|
+
import inspect
|
|
10
|
+
from six.moves import zip
|
|
11
|
+
from behave.formatter.base import Formatter
|
|
12
|
+
from behave.step_registry import StepRegistry, registry
|
|
13
|
+
from behave.textutil import \
|
|
14
|
+
compute_words_maxsize, indent, make_indentation, text as _text
|
|
15
|
+
from behave import i18n
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# -----------------------------------------------------------------------------
|
|
19
|
+
# CLASS: AbstractStepsFormatter
|
|
20
|
+
# -----------------------------------------------------------------------------
|
|
21
|
+
class AbstractStepsFormatter(Formatter):
|
|
22
|
+
"""
|
|
23
|
+
Provides a formatter base class that provides the common functionality
|
|
24
|
+
for formatter classes that operate on step definitions (implementations).
|
|
25
|
+
|
|
26
|
+
.. note::
|
|
27
|
+
Supports behave dry-run mode.
|
|
28
|
+
"""
|
|
29
|
+
step_types = ("given", "when", "then", "step")
|
|
30
|
+
|
|
31
|
+
def __init__(self, stream_opener, config):
|
|
32
|
+
super(AbstractStepsFormatter, self).__init__(stream_opener, config)
|
|
33
|
+
self.step_registry = None
|
|
34
|
+
self.current_feature = None
|
|
35
|
+
self.shows_location = config.show_source
|
|
36
|
+
|
|
37
|
+
def reset(self):
|
|
38
|
+
self.step_registry = None
|
|
39
|
+
self.current_feature = None
|
|
40
|
+
|
|
41
|
+
def discover_step_definitions(self):
|
|
42
|
+
if self.step_registry is None:
|
|
43
|
+
self.step_registry = StepRegistry()
|
|
44
|
+
|
|
45
|
+
for step_type in registry.steps:
|
|
46
|
+
step_definitions = tuple(registry.steps[step_type])
|
|
47
|
+
for step_definition in step_definitions:
|
|
48
|
+
step_definition.step_type = step_type
|
|
49
|
+
self.step_registry.steps[step_type] = step_definitions
|
|
50
|
+
|
|
51
|
+
# -- FORMATTER API:
|
|
52
|
+
def feature(self, feature):
|
|
53
|
+
self.current_feature = feature
|
|
54
|
+
if not self.step_registry:
|
|
55
|
+
# -- ONLY-ONCE:
|
|
56
|
+
self.discover_step_definitions()
|
|
57
|
+
|
|
58
|
+
def eof(self):
|
|
59
|
+
"""Called at end of a feature."""
|
|
60
|
+
self.current_feature = None
|
|
61
|
+
|
|
62
|
+
def close(self):
|
|
63
|
+
"""Called at end of test run."""
|
|
64
|
+
if not self.step_registry:
|
|
65
|
+
self.discover_step_definitions()
|
|
66
|
+
|
|
67
|
+
if self.step_registry:
|
|
68
|
+
# -- ENSURE: Output stream is open.
|
|
69
|
+
self.stream = self.open()
|
|
70
|
+
self.report()
|
|
71
|
+
|
|
72
|
+
# -- FINALLY:
|
|
73
|
+
self.close_stream()
|
|
74
|
+
|
|
75
|
+
# -- REPORT SPECIFIC-API:
|
|
76
|
+
def report(self):
|
|
77
|
+
raise NotImplementedError()
|
|
78
|
+
|
|
79
|
+
# pylint: disable=no-self-use
|
|
80
|
+
def describe_step_definition(self, step_definition, step_type=None):
|
|
81
|
+
if not step_type:
|
|
82
|
+
step_type = step_definition.step_type
|
|
83
|
+
assert step_type
|
|
84
|
+
return u"@%s('%s')" % (step_type, step_definition.string)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# -----------------------------------------------------------------------------
|
|
88
|
+
# CLASS: StepsFormatter
|
|
89
|
+
# -----------------------------------------------------------------------------
|
|
90
|
+
class StepsFormatter(AbstractStepsFormatter):
|
|
91
|
+
"""
|
|
92
|
+
Provides formatter class that provides an overview
|
|
93
|
+
which step definitions are available.
|
|
94
|
+
|
|
95
|
+
EXAMPLE:
|
|
96
|
+
$ behave --dry-run -f steps features/
|
|
97
|
+
GIVEN STEP DEFINITIONS[21]:
|
|
98
|
+
Given a new working directory
|
|
99
|
+
Given I use the current directory as working directory
|
|
100
|
+
Given a file named "{filename}" with
|
|
101
|
+
...
|
|
102
|
+
Given a step passes
|
|
103
|
+
Given a step fails
|
|
104
|
+
|
|
105
|
+
WHEN STEP DEFINITIONS[14]:
|
|
106
|
+
When I run "{command}"
|
|
107
|
+
...
|
|
108
|
+
When a step passes
|
|
109
|
+
When a step fails
|
|
110
|
+
|
|
111
|
+
THEN STEP DEFINITIONS[45]:
|
|
112
|
+
Then the command should fail with returncode="{result:int}"
|
|
113
|
+
Then it should pass with
|
|
114
|
+
Then it should fail with
|
|
115
|
+
Then the command output should contain "{text}"
|
|
116
|
+
...
|
|
117
|
+
Then a step passes
|
|
118
|
+
Then a step fails
|
|
119
|
+
|
|
120
|
+
GENERIC STEP DEFINITIONS[13]:
|
|
121
|
+
* I remove the directory "{directory}"
|
|
122
|
+
* a file named "{filename}" exists
|
|
123
|
+
* a file named "{filename}" does not exist
|
|
124
|
+
...
|
|
125
|
+
* a step passes
|
|
126
|
+
* a step fails
|
|
127
|
+
|
|
128
|
+
.. note::
|
|
129
|
+
Supports behave dry-run mode.
|
|
130
|
+
"""
|
|
131
|
+
name = "steps"
|
|
132
|
+
description = "Shows step definitions (step implementations)."
|
|
133
|
+
shows_location = True
|
|
134
|
+
min_location_column = 40
|
|
135
|
+
|
|
136
|
+
# -- REPORT SPECIFIC-API:
|
|
137
|
+
def report(self):
|
|
138
|
+
self.report_steps_by_type()
|
|
139
|
+
|
|
140
|
+
def report_steps_by_type(self):
|
|
141
|
+
"""Show an overview of the existing step implementations per step type.
|
|
142
|
+
"""
|
|
143
|
+
# pylint: disable=too-many-branches
|
|
144
|
+
assert set(self.step_types) == set(self.step_registry.steps.keys())
|
|
145
|
+
language = self.config.lang or "en"
|
|
146
|
+
language_keywords = i18n.languages[language]
|
|
147
|
+
|
|
148
|
+
for step_type in self.step_types:
|
|
149
|
+
steps = list(self.step_registry.steps[step_type])
|
|
150
|
+
if step_type != "step":
|
|
151
|
+
steps.extend(self.step_registry.steps["step"])
|
|
152
|
+
if not steps:
|
|
153
|
+
continue
|
|
154
|
+
|
|
155
|
+
# -- PREPARE REPORT: For a step-type.
|
|
156
|
+
step_type_name = step_type.upper()
|
|
157
|
+
if step_type == "step":
|
|
158
|
+
step_keyword = "*"
|
|
159
|
+
step_type_name = "GENERIC"
|
|
160
|
+
else:
|
|
161
|
+
# step_keyword = step_type.capitalize()
|
|
162
|
+
keywords = language_keywords[step_type]
|
|
163
|
+
if keywords[0] == u"*":
|
|
164
|
+
assert len(keywords) > 1
|
|
165
|
+
step_keyword = keywords[1]
|
|
166
|
+
else:
|
|
167
|
+
step_keyword = keywords[0]
|
|
168
|
+
|
|
169
|
+
steps_text = [u"%s %s" % (step_keyword, step.string)
|
|
170
|
+
for step in steps]
|
|
171
|
+
if self.shows_location:
|
|
172
|
+
max_size = compute_words_maxsize(steps_text)
|
|
173
|
+
if max_size < self.min_location_column:
|
|
174
|
+
max_size = self.min_location_column
|
|
175
|
+
schema = u" %-" + _text(max_size) + "s # %s\n"
|
|
176
|
+
else:
|
|
177
|
+
schema = u" %s\n"
|
|
178
|
+
|
|
179
|
+
# -- REPORT:
|
|
180
|
+
message = "%s STEP DEFINITIONS[%s]:\n"
|
|
181
|
+
self.stream.write(message % (step_type_name, len(steps)))
|
|
182
|
+
for step, step_text in zip(steps, steps_text):
|
|
183
|
+
if self.shows_location:
|
|
184
|
+
self.stream.write(schema % (step_text, step.location))
|
|
185
|
+
else:
|
|
186
|
+
self.stream.write(schema % step_text)
|
|
187
|
+
self.stream.write("\n")
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
# -----------------------------------------------------------------------------
|
|
191
|
+
# CLASS: StepsDocFormatter
|
|
192
|
+
# -----------------------------------------------------------------------------
|
|
193
|
+
class StepsDocFormatter(AbstractStepsFormatter):
|
|
194
|
+
"""
|
|
195
|
+
Provides formatter class that shows the documentation of all registered
|
|
196
|
+
step definitions. The primary purpose is to provide help for a test writer.
|
|
197
|
+
|
|
198
|
+
EXAMPLE:
|
|
199
|
+
$ behave --dry-run -f steps.doc features/
|
|
200
|
+
@given('a file named "{filename}" with')
|
|
201
|
+
Function: step_a_file_named_filename_with()
|
|
202
|
+
Location: behave4cmd0/command_steps.py:50
|
|
203
|
+
Creates a textual file with the content provided as docstring.
|
|
204
|
+
|
|
205
|
+
@when('I run "{command}"')
|
|
206
|
+
Function: step_i_run_command()
|
|
207
|
+
Location: behave4cmd0/command_steps.py:80
|
|
208
|
+
Run a command as subprocess, collect its output and returncode.
|
|
209
|
+
|
|
210
|
+
@step('a file named "{filename}" exists')
|
|
211
|
+
Function: step_file_named_filename_exists()
|
|
212
|
+
Location: behave4cmd0/command_steps.py:305
|
|
213
|
+
Verifies that a file with this filename exists.
|
|
214
|
+
|
|
215
|
+
.. code-block:: gherkin
|
|
216
|
+
|
|
217
|
+
Given a file named "abc.txt" exists
|
|
218
|
+
When a file named "abc.txt" exists
|
|
219
|
+
...
|
|
220
|
+
|
|
221
|
+
.. note::
|
|
222
|
+
Supports behave dry-run mode.
|
|
223
|
+
"""
|
|
224
|
+
name = "steps.doc"
|
|
225
|
+
description = "Shows documentation for step definitions."
|
|
226
|
+
shows_location = True
|
|
227
|
+
shows_function_name = True
|
|
228
|
+
ordered_by_location = True
|
|
229
|
+
doc_prefix = make_indentation(4)
|
|
230
|
+
|
|
231
|
+
# -- REPORT SPECIFIC-API:
|
|
232
|
+
def report(self):
|
|
233
|
+
self.report_step_definition_docs()
|
|
234
|
+
self.stream.write("\n")
|
|
235
|
+
|
|
236
|
+
def report_step_definition_docs(self):
|
|
237
|
+
step_definitions = []
|
|
238
|
+
for step_type in self.step_types:
|
|
239
|
+
for step_definition in self.step_registry.steps[step_type]:
|
|
240
|
+
# step_definition.step_type = step_type
|
|
241
|
+
assert step_definition.step_type is not None
|
|
242
|
+
step_definitions.append(step_definition)
|
|
243
|
+
|
|
244
|
+
if self.ordered_by_location:
|
|
245
|
+
step_definitions = sorted(step_definitions,
|
|
246
|
+
key=attrgetter("location"))
|
|
247
|
+
|
|
248
|
+
for step_definition in step_definitions:
|
|
249
|
+
self.write_step_definition(step_definition)
|
|
250
|
+
|
|
251
|
+
def write_step_definition(self, step_definition):
|
|
252
|
+
step_definition_text = self.describe_step_definition(step_definition)
|
|
253
|
+
self.stream.write(u"%s\n" % step_definition_text)
|
|
254
|
+
doc = inspect.getdoc(step_definition.func)
|
|
255
|
+
func_name = step_definition.func.__name__
|
|
256
|
+
if self.shows_function_name and func_name not in ("step", "impl"):
|
|
257
|
+
self.stream.write(u" Function: %s()\n" % func_name)
|
|
258
|
+
if self.shows_location:
|
|
259
|
+
self.stream.write(u" Location: %s\n" % step_definition.location)
|
|
260
|
+
if doc:
|
|
261
|
+
doc = doc.strip()
|
|
262
|
+
self.stream.write(indent(doc, self.doc_prefix))
|
|
263
|
+
self.stream.write("\n")
|
|
264
|
+
self.stream.write("\n")
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
# -----------------------------------------------------------------------------
|
|
268
|
+
# CLASS: StepsCatalogFormatter
|
|
269
|
+
# -----------------------------------------------------------------------------
|
|
270
|
+
class StepsCatalogFormatter(StepsDocFormatter):
|
|
271
|
+
"""
|
|
272
|
+
Provides formatter class that shows the documentation of all registered
|
|
273
|
+
step definitions. The primary purpose is to provide help for a test writer.
|
|
274
|
+
|
|
275
|
+
In order to ease work for non-programmer testers, the technical details of
|
|
276
|
+
the steps (i.e. function name, source location) are ommited and the
|
|
277
|
+
steps are shown as they would apprear in a feature file (no noisy '@',
|
|
278
|
+
or '(', etc.).
|
|
279
|
+
|
|
280
|
+
Also, the output is sorted by step type (Given, When, Then)
|
|
281
|
+
|
|
282
|
+
Generic step definitions are listed with all three step types.
|
|
283
|
+
|
|
284
|
+
EXAMPLE:
|
|
285
|
+
$ behave --dry-run -f steps.catalog features/
|
|
286
|
+
Given a file named "{filename}" with
|
|
287
|
+
Creates a textual file with the content provided as docstring.
|
|
288
|
+
|
|
289
|
+
When I run "{command}"
|
|
290
|
+
Run a command as subprocess, collect its output and returncode.
|
|
291
|
+
|
|
292
|
+
Given a file named "{filename}" exists
|
|
293
|
+
When a file named "{filename}" exists
|
|
294
|
+
Then a file named "{filename}" exists
|
|
295
|
+
Verifies that a file with this filename exists.
|
|
296
|
+
|
|
297
|
+
.. code-block:: gherkin
|
|
298
|
+
|
|
299
|
+
Given a file named "abc.txt" exists
|
|
300
|
+
When a file named "abc.txt" exists
|
|
301
|
+
...
|
|
302
|
+
|
|
303
|
+
.. note::
|
|
304
|
+
Supports behave dry-run mode.
|
|
305
|
+
"""
|
|
306
|
+
name = "steps.catalog"
|
|
307
|
+
description = "Shows non-technical documentation for step definitions."
|
|
308
|
+
shows_location = False
|
|
309
|
+
shows_function_name = False
|
|
310
|
+
ordered_by_location = False
|
|
311
|
+
doc_prefix = make_indentation(4)
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def describe_step_definition(self, step_definition, step_type=None):
|
|
315
|
+
if not step_type:
|
|
316
|
+
step_type = step_definition.step_type
|
|
317
|
+
assert step_type
|
|
318
|
+
desc = []
|
|
319
|
+
if step_type == 'step':
|
|
320
|
+
for step_type in self.step_types[:-1]:
|
|
321
|
+
text = u"%5s %s" % (step_type.title(), step_definition.string)
|
|
322
|
+
desc.append(text)
|
|
323
|
+
else:
|
|
324
|
+
desc.append(u"%s %s" % (step_type.title(), step_definition.string))
|
|
325
|
+
|
|
326
|
+
return '\n'.join(desc)
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
# -----------------------------------------------------------------------------
|
|
330
|
+
# CLASS: StepsUsageFormatter
|
|
331
|
+
# -----------------------------------------------------------------------------
|
|
332
|
+
class StepsUsageFormatter(AbstractStepsFormatter):
|
|
333
|
+
"""
|
|
334
|
+
Provides formatter class that shows how step definitions are used by steps.
|
|
335
|
+
|
|
336
|
+
EXAMPLE:
|
|
337
|
+
$ behave --dry-run -f steps.usage features/
|
|
338
|
+
...
|
|
339
|
+
|
|
340
|
+
.. note::
|
|
341
|
+
Supports behave dry-run mode.
|
|
342
|
+
"""
|
|
343
|
+
name = "steps.usage"
|
|
344
|
+
description = "Shows how step definitions are used by steps."
|
|
345
|
+
doc_prefix = make_indentation(4)
|
|
346
|
+
min_location_column = 40
|
|
347
|
+
|
|
348
|
+
def __init__(self, stream_opener, config):
|
|
349
|
+
super(StepsUsageFormatter, self).__init__(stream_opener, config)
|
|
350
|
+
self.step_usage_database = {}
|
|
351
|
+
self.undefined_steps = []
|
|
352
|
+
|
|
353
|
+
def reset(self):
|
|
354
|
+
super(StepsUsageFormatter, self).reset()
|
|
355
|
+
self.step_usage_database = {}
|
|
356
|
+
self.undefined_steps = []
|
|
357
|
+
|
|
358
|
+
# pylint: disable=invalid-name
|
|
359
|
+
def get_step_type_for_step_definition(self, step_definition):
|
|
360
|
+
step_type = step_definition.step_type
|
|
361
|
+
if not step_type:
|
|
362
|
+
# -- DETERMINE STEP-TYPE FROM STEP-REGISTRY:
|
|
363
|
+
assert self.step_registry
|
|
364
|
+
for step_type, values in self.step_registry.steps.items():
|
|
365
|
+
if step_definition in values:
|
|
366
|
+
return step_type
|
|
367
|
+
# -- OTHERWISE:
|
|
368
|
+
step_type = "step"
|
|
369
|
+
return step_type
|
|
370
|
+
# pylint: enable=invalid-name
|
|
371
|
+
|
|
372
|
+
def select_unused_step_definitions(self):
|
|
373
|
+
step_definitions = set()
|
|
374
|
+
for step_type, values in self.step_registry.steps.items():
|
|
375
|
+
step_definitions.update(values)
|
|
376
|
+
used_step_definitions = set(self.step_usage_database.keys())
|
|
377
|
+
unused_step_definitions = step_definitions - used_step_definitions
|
|
378
|
+
return unused_step_definitions
|
|
379
|
+
|
|
380
|
+
def update_usage_database(self, step_definition, step):
|
|
381
|
+
matching_steps = self.step_usage_database.get(step_definition, None)
|
|
382
|
+
if matching_steps is None:
|
|
383
|
+
assert step_definition.step_type is not None
|
|
384
|
+
matching_steps = self.step_usage_database[step_definition] = []
|
|
385
|
+
# -- AVOID DUPLICATES: From Scenario Outlines
|
|
386
|
+
if not steps_contain(matching_steps, step):
|
|
387
|
+
matching_steps.append(step)
|
|
388
|
+
|
|
389
|
+
def update_usage_database_for_step(self, step):
|
|
390
|
+
step_definition = self.step_registry.find_step_definition(step)
|
|
391
|
+
if step_definition:
|
|
392
|
+
self.update_usage_database(step_definition, step)
|
|
393
|
+
# elif step not in self.undefined_steps:
|
|
394
|
+
elif not steps_contain(self.undefined_steps, step):
|
|
395
|
+
# -- AVOID DUPLICATES: From Scenario Outlines
|
|
396
|
+
self.undefined_steps.append(step)
|
|
397
|
+
|
|
398
|
+
# pylint: disable=invalid-name
|
|
399
|
+
def update_usage_database_for_feature(self, feature):
|
|
400
|
+
# -- PROCESS BACKGROUND (if exists): Use Background steps only once.
|
|
401
|
+
if feature.background:
|
|
402
|
+
for step in feature.background.steps:
|
|
403
|
+
self.update_usage_database_for_step(step)
|
|
404
|
+
|
|
405
|
+
# -- PROCESS SCENARIOS: Without background steps.
|
|
406
|
+
for scenario in feature.walk_scenarios():
|
|
407
|
+
for step in scenario.steps:
|
|
408
|
+
self.update_usage_database_for_step(step)
|
|
409
|
+
# pylint: enable=invalid-name
|
|
410
|
+
|
|
411
|
+
# -- FORMATTER API:
|
|
412
|
+
def feature(self, feature):
|
|
413
|
+
super(StepsUsageFormatter, self).feature(feature)
|
|
414
|
+
self.update_usage_database_for_feature(feature)
|
|
415
|
+
|
|
416
|
+
# -- REPORT API:
|
|
417
|
+
def report(self):
|
|
418
|
+
self.report_used_step_definitions()
|
|
419
|
+
self.report_unused_step_definitions()
|
|
420
|
+
self.report_undefined_steps()
|
|
421
|
+
self.stream.write("\n")
|
|
422
|
+
|
|
423
|
+
# -- REPORT SPECIFIC-API:
|
|
424
|
+
def report_used_step_definitions(self):
|
|
425
|
+
# -- STEP: Used step definitions.
|
|
426
|
+
# ORDERING: Sort step definitions by file location.
|
|
427
|
+
get_location = lambda x: x[0].location
|
|
428
|
+
step_definition_items = self.step_usage_database.items()
|
|
429
|
+
step_definition_items = sorted(step_definition_items, key=get_location)
|
|
430
|
+
|
|
431
|
+
for step_definition, steps in step_definition_items:
|
|
432
|
+
stepdef_text = self.describe_step_definition(step_definition)
|
|
433
|
+
steps_text = [u" %s %s" % (step.keyword, step.name)
|
|
434
|
+
for step in steps]
|
|
435
|
+
steps_text.append(stepdef_text)
|
|
436
|
+
max_size = compute_words_maxsize(steps_text)
|
|
437
|
+
if max_size < self.min_location_column:
|
|
438
|
+
max_size = self.min_location_column
|
|
439
|
+
|
|
440
|
+
schema = u"%-" + _text(max_size) + "s # %s\n"
|
|
441
|
+
self.stream.write(schema % (stepdef_text, step_definition.location))
|
|
442
|
+
schema = u"%-" + _text(max_size) + "s # %s\n"
|
|
443
|
+
for step, step_text in zip(steps, steps_text):
|
|
444
|
+
self.stream.write(schema % (step_text, step.location))
|
|
445
|
+
self.stream.write("\n")
|
|
446
|
+
|
|
447
|
+
def report_unused_step_definitions(self):
|
|
448
|
+
unused_step_definitions = self.select_unused_step_definitions()
|
|
449
|
+
if not unused_step_definitions:
|
|
450
|
+
return
|
|
451
|
+
|
|
452
|
+
# -- STEP: Prepare report for unused step definitions.
|
|
453
|
+
# ORDERING: Sort step definitions by file location.
|
|
454
|
+
get_location = lambda x: x.location
|
|
455
|
+
step_definitions = sorted(unused_step_definitions, key=get_location)
|
|
456
|
+
step_texts = [self.describe_step_definition(step_definition)
|
|
457
|
+
for step_definition in step_definitions]
|
|
458
|
+
|
|
459
|
+
max_size = compute_words_maxsize(step_texts)
|
|
460
|
+
if max_size < self.min_location_column-2:
|
|
461
|
+
max_size = self.min_location_column-2
|
|
462
|
+
|
|
463
|
+
# -- STEP: Write report.
|
|
464
|
+
schema = u" %-" + _text(max_size) + "s # %s\n"
|
|
465
|
+
self.stream.write("UNUSED STEP DEFINITIONS[%d]:\n" % len(step_texts))
|
|
466
|
+
for step_definition, step_text in zip(step_definitions, step_texts):
|
|
467
|
+
self.stream.write(schema % (step_text, step_definition.location))
|
|
468
|
+
|
|
469
|
+
def report_undefined_steps(self):
|
|
470
|
+
if not self.undefined_steps:
|
|
471
|
+
return
|
|
472
|
+
|
|
473
|
+
# -- STEP: Undefined steps.
|
|
474
|
+
undefined_steps = sorted(self.undefined_steps,
|
|
475
|
+
key=attrgetter("location"))
|
|
476
|
+
|
|
477
|
+
steps_text = [u" %s %s" % (step.keyword, step.name)
|
|
478
|
+
for step in undefined_steps]
|
|
479
|
+
max_size = compute_words_maxsize(steps_text)
|
|
480
|
+
if max_size < self.min_location_column:
|
|
481
|
+
max_size = self.min_location_column
|
|
482
|
+
|
|
483
|
+
self.stream.write("\nUNDEFINED STEPS[%d]:\n" % len(steps_text))
|
|
484
|
+
schema = u"%-" + _text(max_size) + "s # %s\n"
|
|
485
|
+
for step, step_text in zip(undefined_steps, steps_text):
|
|
486
|
+
self.stream.write(schema % (step_text, step.location))
|
|
487
|
+
|
|
488
|
+
# -----------------------------------------------------------------------------
|
|
489
|
+
# UTILITY FUNCTIONS:
|
|
490
|
+
# -----------------------------------------------------------------------------
|
|
491
|
+
def steps_contain(steps, step):
|
|
492
|
+
for other_step in steps:
|
|
493
|
+
if step == other_step and step.location == other_step.location:
|
|
494
|
+
# -- NOTE: Step comparison does not take location into account.
|
|
495
|
+
return True
|
|
496
|
+
# -- OTHERWISE: Not contained yet (or step in other location).
|
|
497
|
+
return False
|