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,416 @@
|
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
This module provides the abstract base classes and core concepts
|
|
4
|
+
for the model elements in behave.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os.path
|
|
8
|
+
import sys
|
|
9
|
+
import six
|
|
10
|
+
from behave.capture import Captured
|
|
11
|
+
from behave.textutil import text as _text
|
|
12
|
+
from enum import Enum
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
PLATFORM_WIN = sys.platform.startswith("win")
|
|
16
|
+
def posixpath_normalize(path):
|
|
17
|
+
return path.replace("\\", "/")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# -----------------------------------------------------------------------------
|
|
21
|
+
# GENERIC MODEL CLASSES:
|
|
22
|
+
# -----------------------------------------------------------------------------
|
|
23
|
+
class Status(Enum):
|
|
24
|
+
"""Provides the (test-run) status of a model element.
|
|
25
|
+
Features and Scenarios use: untested, skipped, passed, failed.
|
|
26
|
+
Steps may use all enum-values.
|
|
27
|
+
|
|
28
|
+
Enum values:
|
|
29
|
+
* untested (initial state):
|
|
30
|
+
|
|
31
|
+
Defines the initial state before a test-run.
|
|
32
|
+
Sometimes used to indicate that the model element was not executed
|
|
33
|
+
during a test run.
|
|
34
|
+
|
|
35
|
+
* skipped:
|
|
36
|
+
|
|
37
|
+
A model element is skipped because it should not run.
|
|
38
|
+
This is caused by filtering mechanisms, like tags, active-tags,
|
|
39
|
+
file-location arg, select-by-name, etc.
|
|
40
|
+
|
|
41
|
+
* passed: A model element was executed and passed (without failures).
|
|
42
|
+
* failed: Failures occurred while executing it.
|
|
43
|
+
* undefined: Used for undefined-steps (no step implementation was found).
|
|
44
|
+
* executing: Marks the steps during execution (used in a formatter)
|
|
45
|
+
|
|
46
|
+
.. versionadded:: 1.2.6
|
|
47
|
+
Superceeds string-based status values.
|
|
48
|
+
"""
|
|
49
|
+
untested = 0
|
|
50
|
+
skipped = 1
|
|
51
|
+
passed = 2
|
|
52
|
+
failed = 3
|
|
53
|
+
undefined = 4
|
|
54
|
+
executing = 5
|
|
55
|
+
|
|
56
|
+
def __eq__(self, other):
|
|
57
|
+
"""Comparison operator equals-to other value.
|
|
58
|
+
Supports other enum-values and string (for backward compatibility).
|
|
59
|
+
|
|
60
|
+
EXAMPLES::
|
|
61
|
+
|
|
62
|
+
status = Status.passed
|
|
63
|
+
assert status == Status.passed
|
|
64
|
+
assert status == "passed"
|
|
65
|
+
assert status != "failed"
|
|
66
|
+
|
|
67
|
+
:param other: Other value to compare (enum-value, string).
|
|
68
|
+
:return: True, if both values are equal. False, otherwise.
|
|
69
|
+
"""
|
|
70
|
+
if isinstance(other, six.string_types):
|
|
71
|
+
# -- CONVENIENCE: Compare with string-name (backward-compatible)
|
|
72
|
+
return self.name == other
|
|
73
|
+
return super(Status, self).__eq__(other)
|
|
74
|
+
|
|
75
|
+
@classmethod
|
|
76
|
+
def from_name(cls, name):
|
|
77
|
+
"""Select enumeration value by using its name.
|
|
78
|
+
|
|
79
|
+
:param name: Name as key to the enum value (as string).
|
|
80
|
+
:return: Enum value (instance)
|
|
81
|
+
:raises: LookupError, if status name is unknown.
|
|
82
|
+
"""
|
|
83
|
+
# pylint: disable=no-member
|
|
84
|
+
enum_value = cls.__members__.get(name, None)
|
|
85
|
+
if enum_value is None:
|
|
86
|
+
known_names = ", ".join(cls.__members__.keys())
|
|
87
|
+
raise LookupError("%s (expected: %s)" % (name, known_names))
|
|
88
|
+
return enum_value
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class Argument(object):
|
|
92
|
+
"""An argument found in a *feature file* step name and extracted using
|
|
93
|
+
step decorator `parameters`_.
|
|
94
|
+
|
|
95
|
+
The attributes are:
|
|
96
|
+
|
|
97
|
+
.. attribute:: original
|
|
98
|
+
|
|
99
|
+
The actual text matched in the step name.
|
|
100
|
+
|
|
101
|
+
.. attribute:: value
|
|
102
|
+
|
|
103
|
+
The potentially type-converted value of the argument.
|
|
104
|
+
|
|
105
|
+
.. attribute:: name
|
|
106
|
+
|
|
107
|
+
The name of the argument. This will be None if the parameter is
|
|
108
|
+
anonymous.
|
|
109
|
+
|
|
110
|
+
.. attribute:: start
|
|
111
|
+
|
|
112
|
+
The start index in the step name of the argument. Used for display.
|
|
113
|
+
|
|
114
|
+
.. attribute:: end
|
|
115
|
+
|
|
116
|
+
The end index in the step name of the argument. Used for display.
|
|
117
|
+
"""
|
|
118
|
+
def __init__(self, start, end, original, value, name=None):
|
|
119
|
+
self.start = start
|
|
120
|
+
self.end = end
|
|
121
|
+
self.original = original
|
|
122
|
+
self.value = value
|
|
123
|
+
self.name = name
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# @total_ordering
|
|
127
|
+
# class FileLocation(unicode):
|
|
128
|
+
class FileLocation(object):
|
|
129
|
+
"""
|
|
130
|
+
Provides a value object for file location objects.
|
|
131
|
+
A file location consists of:
|
|
132
|
+
|
|
133
|
+
* filename
|
|
134
|
+
* line (number), optional
|
|
135
|
+
|
|
136
|
+
LOCATION SCHEMA:
|
|
137
|
+
* "{filename}:{line}" or
|
|
138
|
+
* "{filename}" (if line number is not present)
|
|
139
|
+
"""
|
|
140
|
+
__pychecker__ = "missingattrs=line" # -- Ignore warnings for 'line'.
|
|
141
|
+
|
|
142
|
+
def __init__(self, filename, line=None):
|
|
143
|
+
if PLATFORM_WIN:
|
|
144
|
+
filename = posixpath_normalize(filename)
|
|
145
|
+
self.filename = filename
|
|
146
|
+
self.line = line
|
|
147
|
+
|
|
148
|
+
def get(self):
|
|
149
|
+
return self.filename
|
|
150
|
+
|
|
151
|
+
def abspath(self):
|
|
152
|
+
return os.path.abspath(self.filename)
|
|
153
|
+
|
|
154
|
+
def basename(self):
|
|
155
|
+
return os.path.basename(self.filename)
|
|
156
|
+
|
|
157
|
+
def dirname(self):
|
|
158
|
+
return os.path.dirname(self.filename)
|
|
159
|
+
|
|
160
|
+
def relpath(self, start=os.curdir):
|
|
161
|
+
"""Compute relative path for start to filename.
|
|
162
|
+
|
|
163
|
+
:param start: Base path or start directory (default=current dir).
|
|
164
|
+
:return: Relative path from start to filename
|
|
165
|
+
"""
|
|
166
|
+
return os.path.relpath(self.filename, start)
|
|
167
|
+
|
|
168
|
+
def exists(self):
|
|
169
|
+
return os.path.exists(self.filename)
|
|
170
|
+
|
|
171
|
+
def _line_lessthan(self, other_line):
|
|
172
|
+
if self.line is None:
|
|
173
|
+
# return not (other_line is None)
|
|
174
|
+
return other_line is not None
|
|
175
|
+
elif other_line is None:
|
|
176
|
+
return False
|
|
177
|
+
else:
|
|
178
|
+
return self.line < other_line
|
|
179
|
+
|
|
180
|
+
def __eq__(self, other):
|
|
181
|
+
if isinstance(other, FileLocation):
|
|
182
|
+
return self.filename == other.filename and self.line == other.line
|
|
183
|
+
elif isinstance(other, six.string_types):
|
|
184
|
+
return self.filename == other
|
|
185
|
+
else:
|
|
186
|
+
raise TypeError("Cannot compare FileLocation with %s:%s" % \
|
|
187
|
+
(type(other), other))
|
|
188
|
+
|
|
189
|
+
def __ne__(self, other):
|
|
190
|
+
# return not self == other # pylint: disable=unneeded-not
|
|
191
|
+
return not self.__eq__(other)
|
|
192
|
+
|
|
193
|
+
def __lt__(self, other):
|
|
194
|
+
if isinstance(other, FileLocation):
|
|
195
|
+
if self.filename < other.filename:
|
|
196
|
+
return True
|
|
197
|
+
elif self.filename > other.filename:
|
|
198
|
+
return False
|
|
199
|
+
else:
|
|
200
|
+
assert self.filename == other.filename
|
|
201
|
+
return self._line_lessthan(other.line)
|
|
202
|
+
|
|
203
|
+
elif isinstance(other, six.string_types):
|
|
204
|
+
return self.filename < other
|
|
205
|
+
else:
|
|
206
|
+
raise TypeError("Cannot compare FileLocation with %s:%s" % \
|
|
207
|
+
(type(other), other))
|
|
208
|
+
|
|
209
|
+
def __le__(self, other):
|
|
210
|
+
# -- SEE ALSO: python2.7, functools.total_ordering
|
|
211
|
+
# return not other < self # pylint unneeded-not
|
|
212
|
+
return other >= self
|
|
213
|
+
|
|
214
|
+
def __gt__(self, other):
|
|
215
|
+
# -- SEE ALSO: python2.7, functools.total_ordering
|
|
216
|
+
if isinstance(other, FileLocation):
|
|
217
|
+
return other < self
|
|
218
|
+
else:
|
|
219
|
+
return self.filename > other
|
|
220
|
+
|
|
221
|
+
def __ge__(self, other):
|
|
222
|
+
# -- SEE ALSO: python2.7, functools.total_ordering
|
|
223
|
+
# return not self < other
|
|
224
|
+
return not self.__lt__(other)
|
|
225
|
+
|
|
226
|
+
def __repr__(self):
|
|
227
|
+
return u'<FileLocation: filename="%s", line=%s>' % \
|
|
228
|
+
(self.filename, self.line)
|
|
229
|
+
|
|
230
|
+
def __str__(self):
|
|
231
|
+
filename = self.filename
|
|
232
|
+
if isinstance(filename, six.binary_type):
|
|
233
|
+
filename = _text(filename, "utf-8")
|
|
234
|
+
if self.line is None:
|
|
235
|
+
return filename
|
|
236
|
+
return u"%s:%d" % (filename, self.line)
|
|
237
|
+
|
|
238
|
+
if six.PY2:
|
|
239
|
+
__unicode__ = __str__
|
|
240
|
+
__str__ = lambda self: self.__unicode__().encode("utf-8")
|
|
241
|
+
|
|
242
|
+
@classmethod
|
|
243
|
+
def for_function(cls, func, curdir=None):
|
|
244
|
+
"""Extracts the location information from the function and builds
|
|
245
|
+
the location string (schema: "{source_filename}:{line_number}").
|
|
246
|
+
|
|
247
|
+
:param func: Function whose location should be determined.
|
|
248
|
+
:return: FileLocation object
|
|
249
|
+
"""
|
|
250
|
+
func = unwrap_function(func)
|
|
251
|
+
function_code = six.get_function_code(func)
|
|
252
|
+
filename = function_code.co_filename
|
|
253
|
+
line_number = function_code.co_firstlineno
|
|
254
|
+
|
|
255
|
+
curdir = curdir or os.getcwd()
|
|
256
|
+
filename = os.path.relpath(filename, curdir)
|
|
257
|
+
return cls(filename, line_number)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
# -----------------------------------------------------------------------------
|
|
261
|
+
# ABSTRACT MODEL CLASSES (and concepts):
|
|
262
|
+
# -----------------------------------------------------------------------------
|
|
263
|
+
class BasicStatement(object):
|
|
264
|
+
def __init__(self, filename, line, keyword, name):
|
|
265
|
+
filename = filename or '<string>'
|
|
266
|
+
filename = os.path.relpath(filename, os.getcwd()) # -- NEEDS: abspath?
|
|
267
|
+
self.location = FileLocation(filename, line)
|
|
268
|
+
assert isinstance(keyword, six.text_type)
|
|
269
|
+
assert isinstance(name, six.text_type)
|
|
270
|
+
self.keyword = keyword
|
|
271
|
+
self.name = name
|
|
272
|
+
# -- SINCE: 1.2.6
|
|
273
|
+
self.captured = Captured()
|
|
274
|
+
# -- ERROR CONTEXT INFO:
|
|
275
|
+
self.exception = None
|
|
276
|
+
self.exc_traceback = None
|
|
277
|
+
self.error_message = None
|
|
278
|
+
|
|
279
|
+
@property
|
|
280
|
+
def filename(self):
|
|
281
|
+
# return os.path.abspath(self.location.filename)
|
|
282
|
+
return self.location.filename
|
|
283
|
+
|
|
284
|
+
@property
|
|
285
|
+
def line(self):
|
|
286
|
+
return self.location.line
|
|
287
|
+
|
|
288
|
+
def reset(self):
|
|
289
|
+
# -- RESET: Captured output data
|
|
290
|
+
self.captured.reset()
|
|
291
|
+
# -- RESET: ERROR CONTEXT INFO
|
|
292
|
+
self.exception = None
|
|
293
|
+
self.exc_traceback = None
|
|
294
|
+
self.error_message = None
|
|
295
|
+
|
|
296
|
+
def store_exception_context(self, exception):
|
|
297
|
+
self.exception = exception
|
|
298
|
+
self.exc_traceback = sys.exc_info()[2]
|
|
299
|
+
|
|
300
|
+
def __hash__(self):
|
|
301
|
+
# -- NEEDED-FOR: PYTHON3
|
|
302
|
+
# return id((self.keyword, self.name))
|
|
303
|
+
return id(self)
|
|
304
|
+
|
|
305
|
+
def __eq__(self, other):
|
|
306
|
+
# -- PYTHON3 SUPPORT, ORDERABLE:
|
|
307
|
+
# NOTE: Ignore potential FileLocation differences.
|
|
308
|
+
return (self.keyword, self.name) == (other.keyword, other.name)
|
|
309
|
+
|
|
310
|
+
def __lt__(self, other):
|
|
311
|
+
# -- PYTHON3 SUPPORT, ORDERABLE:
|
|
312
|
+
# NOTE: Ignore potential FileLocation differences.
|
|
313
|
+
return (self.keyword, self.name) < (other.keyword, other.name)
|
|
314
|
+
|
|
315
|
+
def __ne__(self, other):
|
|
316
|
+
return not self.__eq__(other)
|
|
317
|
+
|
|
318
|
+
def __le__(self, other):
|
|
319
|
+
# -- SEE ALSO: python2.7, functools.total_ordering
|
|
320
|
+
# return not other < self
|
|
321
|
+
return other >= self
|
|
322
|
+
|
|
323
|
+
def __gt__(self, other):
|
|
324
|
+
# -- SEE ALSO: python2.7, functools.total_ordering
|
|
325
|
+
assert isinstance(other, BasicStatement)
|
|
326
|
+
return other < self
|
|
327
|
+
|
|
328
|
+
def __ge__(self, other):
|
|
329
|
+
# -- SEE ALSO: python2.7, functools.total_ordering
|
|
330
|
+
# OR: return self >= other
|
|
331
|
+
return not self < other # pylint: disable=unneeded-not
|
|
332
|
+
|
|
333
|
+
# def __cmp__(self, other):
|
|
334
|
+
# # -- NOTE: Ignore potential FileLocation differences.
|
|
335
|
+
# return cmp((self.keyword, self.name), (other.keyword, other.name))
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
class TagStatement(BasicStatement):
|
|
339
|
+
|
|
340
|
+
def __init__(self, filename, line, keyword, name, tags):
|
|
341
|
+
if tags is None:
|
|
342
|
+
tags = []
|
|
343
|
+
super(TagStatement, self).__init__(filename, line, keyword, name)
|
|
344
|
+
self.tags = tags
|
|
345
|
+
|
|
346
|
+
def should_run_with_tags(self, tag_expression):
|
|
347
|
+
"""Determines if statement should run when the tag expression is used.
|
|
348
|
+
|
|
349
|
+
:param tag_expression: Runner/config environment tags to use.
|
|
350
|
+
:return: True, if examples should run. False, otherwise (skip it).
|
|
351
|
+
"""
|
|
352
|
+
return tag_expression.check(self.tags)
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
class TagAndStatusStatement(BasicStatement):
|
|
356
|
+
# final_status = ('passed', 'failed', 'skipped')
|
|
357
|
+
final_status = (Status.passed, Status.failed, Status.skipped)
|
|
358
|
+
|
|
359
|
+
def __init__(self, filename, line, keyword, name, tags):
|
|
360
|
+
super(TagAndStatusStatement, self).__init__(filename, line, keyword, name)
|
|
361
|
+
self.tags = tags
|
|
362
|
+
self.should_skip = False
|
|
363
|
+
self.skip_reason = None
|
|
364
|
+
self._cached_status = Status.untested
|
|
365
|
+
|
|
366
|
+
def should_run_with_tags(self, tag_expression):
|
|
367
|
+
"""Determines if statement should run when the tag expression is used.
|
|
368
|
+
|
|
369
|
+
:param tag_expression: Runner/config environment tags to use.
|
|
370
|
+
:return: True, if examples should run. False, otherwise (skip it).
|
|
371
|
+
"""
|
|
372
|
+
return tag_expression.check(self.tags)
|
|
373
|
+
|
|
374
|
+
@property
|
|
375
|
+
def status(self):
|
|
376
|
+
if self._cached_status not in self.final_status:
|
|
377
|
+
# -- RECOMPUTE: As long as final status is not reached.
|
|
378
|
+
self._cached_status = self.compute_status()
|
|
379
|
+
return self._cached_status
|
|
380
|
+
|
|
381
|
+
def set_status(self, value):
|
|
382
|
+
if isinstance(value, six.string_types):
|
|
383
|
+
value = Status.from_name(value)
|
|
384
|
+
self._cached_status = value
|
|
385
|
+
|
|
386
|
+
def clear_status(self):
|
|
387
|
+
self._cached_status = Status.untested
|
|
388
|
+
|
|
389
|
+
def reset(self):
|
|
390
|
+
self.should_skip = False
|
|
391
|
+
self.skip_reason = None
|
|
392
|
+
self.clear_status()
|
|
393
|
+
|
|
394
|
+
def compute_status(self):
|
|
395
|
+
raise NotImplementedError
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
class Replayable(object):
|
|
399
|
+
type = None
|
|
400
|
+
|
|
401
|
+
def replay(self, formatter):
|
|
402
|
+
getattr(formatter, self.type)(self)
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
# -----------------------------------------------------------------------------
|
|
406
|
+
# UTILITY FUNCTIONS:
|
|
407
|
+
# -----------------------------------------------------------------------------
|
|
408
|
+
def unwrap_function(func, max_depth=10):
|
|
409
|
+
"""Unwraps a function that is wrapped with :func:`functools.partial()`"""
|
|
410
|
+
iteration = 0
|
|
411
|
+
wrapped = getattr(func, "__wrapped__", None)
|
|
412
|
+
while wrapped and iteration < max_depth:
|
|
413
|
+
func = wrapped
|
|
414
|
+
wrapped = getattr(func, "__wrapped__", None)
|
|
415
|
+
iteration += 1
|
|
416
|
+
return func
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Provides textual descriptions for :mod:`behave.model` elements.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import absolute_import
|
|
7
|
+
from six.moves import range # pylint: disable=redefined-builtin
|
|
8
|
+
from six.moves import zip # pylint: disable=redefined-builtin
|
|
9
|
+
from behave.textutil import indent
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# -----------------------------------------------------------------------------
|
|
13
|
+
# FUNCTIONS:
|
|
14
|
+
# -----------------------------------------------------------------------------
|
|
15
|
+
def escape_cell(cell):
|
|
16
|
+
"""
|
|
17
|
+
Escape table cell contents.
|
|
18
|
+
:param cell: Table cell (as unicode string).
|
|
19
|
+
:return: Escaped cell (as unicode string).
|
|
20
|
+
"""
|
|
21
|
+
cell = cell.replace(u'\\', u'\\\\')
|
|
22
|
+
cell = cell.replace(u'\n', u'\\n')
|
|
23
|
+
cell = cell.replace(u'|', u'\\|')
|
|
24
|
+
return cell
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def escape_triple_quotes(text):
|
|
28
|
+
"""
|
|
29
|
+
Escape triple-quotes, used for multi-line text/doc-strings.
|
|
30
|
+
"""
|
|
31
|
+
return text.replace(u'"""', u'\\"\\"\\"')
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# -----------------------------------------------------------------------------
|
|
35
|
+
# CLASS:
|
|
36
|
+
# -----------------------------------------------------------------------------
|
|
37
|
+
class ModelDescriptor(object):
|
|
38
|
+
|
|
39
|
+
@staticmethod
|
|
40
|
+
def describe_table(table, indentation=None):
|
|
41
|
+
"""
|
|
42
|
+
Provide a textual description of the table (as used w/ Gherkin).
|
|
43
|
+
|
|
44
|
+
:param table: Table to use (as :class:`behave.model.Table`)
|
|
45
|
+
:param indentation: Line prefix to use (as string, if any).
|
|
46
|
+
:return: Textual table description (as unicode string).
|
|
47
|
+
"""
|
|
48
|
+
# -- STEP: Determine output size of all cells.
|
|
49
|
+
cell_lengths = []
|
|
50
|
+
all_rows = [table.headings] + table.rows
|
|
51
|
+
for row in all_rows:
|
|
52
|
+
lengths = [len(escape_cell(c)) for c in row]
|
|
53
|
+
cell_lengths.append(lengths)
|
|
54
|
+
|
|
55
|
+
# -- STEP: Determine max. output size for each column.
|
|
56
|
+
max_lengths = []
|
|
57
|
+
for col in range(0, len(cell_lengths[0])):
|
|
58
|
+
max_lengths.append(max([c[col] for c in cell_lengths]))
|
|
59
|
+
|
|
60
|
+
# -- STEP: Build textual table description.
|
|
61
|
+
lines = []
|
|
62
|
+
for r, row in enumerate(all_rows):
|
|
63
|
+
line = u"|"
|
|
64
|
+
for c, (cell, max_length) in enumerate(zip(row, max_lengths)):
|
|
65
|
+
pad_size = max_length - cell_lengths[r][c]
|
|
66
|
+
line += u" %s%s |" % (escape_cell(cell), " " * pad_size)
|
|
67
|
+
line += u"\n"
|
|
68
|
+
lines.append(line)
|
|
69
|
+
|
|
70
|
+
if indentation:
|
|
71
|
+
return indent(lines, indentation)
|
|
72
|
+
# -- OTHERWISE:
|
|
73
|
+
return u"".join(lines)
|
|
74
|
+
|
|
75
|
+
@staticmethod
|
|
76
|
+
def describe_docstring(doc_string, indentation=None):
|
|
77
|
+
"""
|
|
78
|
+
Provide a textual description of the multi-line text/triple-quoted
|
|
79
|
+
doc-string (as used w/ Gherkin).
|
|
80
|
+
|
|
81
|
+
:param doc_string: Multi-line text to use.
|
|
82
|
+
:param indentation: Line prefix to use (as string, if any).
|
|
83
|
+
:return: Textual table description (as unicode string).
|
|
84
|
+
"""
|
|
85
|
+
text = escape_triple_quotes(doc_string)
|
|
86
|
+
text = u'"""\n' + text + '\n"""\n'
|
|
87
|
+
|
|
88
|
+
if indentation:
|
|
89
|
+
text = indent(text, indentation)
|
|
90
|
+
return text
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class ModelPrinter(ModelDescriptor):
|
|
94
|
+
|
|
95
|
+
def __init__(self, stream):
|
|
96
|
+
super(ModelPrinter, self).__init__()
|
|
97
|
+
self.stream = stream
|
|
98
|
+
|
|
99
|
+
def print_table(self, table, indentation=None):
|
|
100
|
+
self.stream.write(self.describe_table(table, indentation))
|
|
101
|
+
self.stream.flush()
|
|
102
|
+
|
|
103
|
+
def print_docstring(self, text, indentation=None):
|
|
104
|
+
self.stream.write(self.describe_docstring(text, indentation))
|
|
105
|
+
self.stream.flush()
|