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,151 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Tests for behave.importing.
|
|
4
|
+
The module provides a lazy-loading/importing mechanism.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import absolute_import
|
|
8
|
+
from behave.importer import LazyObject, LazyDict, load_module, parse_scoped_name
|
|
9
|
+
from behave.formatter.base import Formatter
|
|
10
|
+
from nose.tools import eq_, assert_raises
|
|
11
|
+
import sys
|
|
12
|
+
import types
|
|
13
|
+
# import unittest
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TestTheory(object): pass
|
|
17
|
+
class ImportModuleTheory(TestTheory):
|
|
18
|
+
"""
|
|
19
|
+
Provides a test theory for importing modules.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def ensure_module_is_not_imported(cls, module_name):
|
|
24
|
+
if module_name in sys.modules:
|
|
25
|
+
del sys.modules[module_name]
|
|
26
|
+
cls.assert_module_is_not_imported(module_name)
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def assert_module_is_imported(module_name):
|
|
30
|
+
module = sys.modules.get(module_name, None)
|
|
31
|
+
assert module_name in sys.modules
|
|
32
|
+
assert module is not None
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def assert_module_is_not_imported(module_name):
|
|
36
|
+
assert module_name not in sys.modules
|
|
37
|
+
|
|
38
|
+
@staticmethod
|
|
39
|
+
def assert_module_with_name(module, name):
|
|
40
|
+
assert isinstance(module, types.ModuleType)
|
|
41
|
+
eq_(module.__name__, name)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class TestLoadModule(object):
|
|
45
|
+
theory = ImportModuleTheory
|
|
46
|
+
|
|
47
|
+
def test_load_module__should_fail_for_unknown_module(self):
|
|
48
|
+
assert_raises(ImportError, load_module, "__unknown_module__")
|
|
49
|
+
|
|
50
|
+
def test_load_module__should_succeed_for_already_imported_module(self):
|
|
51
|
+
module_name = "behave.importer"
|
|
52
|
+
self.theory.assert_module_is_imported(module_name)
|
|
53
|
+
|
|
54
|
+
module = load_module(module_name)
|
|
55
|
+
self.theory.assert_module_with_name(module, module_name)
|
|
56
|
+
self.theory.assert_module_is_imported(module_name)
|
|
57
|
+
|
|
58
|
+
def test_load_module__should_succeed_for_existing_module(self):
|
|
59
|
+
module_name = "test._importer_candidate"
|
|
60
|
+
self.theory.ensure_module_is_not_imported(module_name)
|
|
61
|
+
|
|
62
|
+
module = load_module(module_name)
|
|
63
|
+
self.theory.assert_module_with_name(module, module_name)
|
|
64
|
+
self.theory.assert_module_is_imported(module_name)
|
|
65
|
+
|
|
66
|
+
class TestLazyObject(object):
|
|
67
|
+
|
|
68
|
+
def test_get__should_succeed_for_known_object(self):
|
|
69
|
+
lazy = LazyObject("behave.importer", "LazyObject")
|
|
70
|
+
value = lazy.get()
|
|
71
|
+
assert value is LazyObject
|
|
72
|
+
|
|
73
|
+
lazy2 = LazyObject("behave.importer:LazyObject")
|
|
74
|
+
value2 = lazy2.get()
|
|
75
|
+
assert value2 is LazyObject
|
|
76
|
+
|
|
77
|
+
lazy3 = LazyObject("behave.formatter.steps", "StepsFormatter")
|
|
78
|
+
value3 = lazy3.get()
|
|
79
|
+
assert issubclass(value3, Formatter)
|
|
80
|
+
|
|
81
|
+
def test_get__should_fail_for_unknown_module(self):
|
|
82
|
+
lazy = LazyObject("__unknown_module__", "xxx")
|
|
83
|
+
assert_raises(ImportError, lazy.get)
|
|
84
|
+
|
|
85
|
+
def test_get__should_fail_for_unknown_object_in_module(self):
|
|
86
|
+
lazy = LazyObject("test._importer_candidate", "xxx")
|
|
87
|
+
assert_raises(ImportError, lazy.get)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class LazyDictTheory(TestTheory):
|
|
91
|
+
|
|
92
|
+
@staticmethod
|
|
93
|
+
def safe_getitem(data, key):
|
|
94
|
+
return dict.__getitem__(data, key)
|
|
95
|
+
|
|
96
|
+
@classmethod
|
|
97
|
+
def assert_item_is_lazy(cls, data, key):
|
|
98
|
+
value = cls.safe_getitem(data, key)
|
|
99
|
+
cls.assert_is_lazy_object(value)
|
|
100
|
+
|
|
101
|
+
@classmethod
|
|
102
|
+
def assert_item_is_not_lazy(cls, data, key):
|
|
103
|
+
value = cls.safe_getitem(data, key)
|
|
104
|
+
cls.assert_is_not_lazy_object(value)
|
|
105
|
+
|
|
106
|
+
@staticmethod
|
|
107
|
+
def assert_is_lazy_object(obj):
|
|
108
|
+
assert isinstance(obj, LazyObject)
|
|
109
|
+
|
|
110
|
+
@staticmethod
|
|
111
|
+
def assert_is_not_lazy_object(obj):
|
|
112
|
+
assert not isinstance(obj, LazyObject)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class TestLazyDict(object):
|
|
116
|
+
theory = LazyDictTheory
|
|
117
|
+
|
|
118
|
+
def test_unknown_item_access__should_raise_keyerror(self):
|
|
119
|
+
lazy_dict = LazyDict({"alice": 42})
|
|
120
|
+
item_access = lambda key: lazy_dict[key]
|
|
121
|
+
assert_raises(KeyError, item_access, "unknown")
|
|
122
|
+
|
|
123
|
+
def test_plain_item_access__should_succeed(self):
|
|
124
|
+
theory = LazyDictTheory
|
|
125
|
+
lazy_dict = LazyDict({"alice": 42})
|
|
126
|
+
theory.assert_item_is_not_lazy(lazy_dict, "alice")
|
|
127
|
+
|
|
128
|
+
value = lazy_dict["alice"]
|
|
129
|
+
eq_(value, 42)
|
|
130
|
+
|
|
131
|
+
def test_lazy_item_access__should_load_object(self):
|
|
132
|
+
ImportModuleTheory.ensure_module_is_not_imported("inspect")
|
|
133
|
+
lazy_dict = LazyDict({"alice": LazyObject("inspect:ismodule")})
|
|
134
|
+
self.theory.assert_item_is_lazy(lazy_dict, "alice")
|
|
135
|
+
self.theory.assert_item_is_lazy(lazy_dict, "alice")
|
|
136
|
+
|
|
137
|
+
value = lazy_dict["alice"]
|
|
138
|
+
self.theory.assert_is_not_lazy_object(value)
|
|
139
|
+
self.theory.assert_item_is_not_lazy(lazy_dict, "alice")
|
|
140
|
+
|
|
141
|
+
def test_lazy_item_access__should_fail_with_unknown_module(self):
|
|
142
|
+
lazy_dict = LazyDict({"bob": LazyObject("__unknown_module__", "xxx")})
|
|
143
|
+
item_access = lambda key: lazy_dict[key]
|
|
144
|
+
assert_raises(ImportError, item_access, "bob")
|
|
145
|
+
|
|
146
|
+
def test_lazy_item_access__should_fail_with_unknown_object(self):
|
|
147
|
+
lazy_dict = LazyDict({
|
|
148
|
+
"bob": LazyObject("behave.importer", "XUnknown")
|
|
149
|
+
})
|
|
150
|
+
item_access = lambda key: lazy_dict[key]
|
|
151
|
+
assert_raises(ImportError, item_access, "bob")
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from __future__ import absolute_import, with_statement
|
|
2
|
+
|
|
3
|
+
from nose.tools import *
|
|
4
|
+
from mock import patch
|
|
5
|
+
|
|
6
|
+
from behave.log_capture import LoggingCapture
|
|
7
|
+
from six.moves import range
|
|
8
|
+
|
|
9
|
+
class TestLogCapture(object):
|
|
10
|
+
def test_get_value_returns_all_log_records(self):
|
|
11
|
+
class FakeConfig(object):
|
|
12
|
+
logging_filter = None
|
|
13
|
+
logging_format = None
|
|
14
|
+
logging_datefmt = None
|
|
15
|
+
logging_level = None
|
|
16
|
+
|
|
17
|
+
fake_records = [object() for x in range(0, 10)]
|
|
18
|
+
|
|
19
|
+
handler = LoggingCapture(FakeConfig())
|
|
20
|
+
handler.buffer = fake_records
|
|
21
|
+
|
|
22
|
+
with patch.object(handler.formatter, 'format') as format:
|
|
23
|
+
format.return_value = 'foo'
|
|
24
|
+
expected = '\n'.join(['foo'] * len(fake_records))
|
|
25
|
+
|
|
26
|
+
eq_(handler.getvalue(), expected)
|
|
27
|
+
|
|
28
|
+
calls = [args[0][0] for args in format.call_args_list]
|
|
29
|
+
eq_(calls, fake_records)
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
|
2
|
+
from __future__ import absolute_import, with_statement
|
|
3
|
+
from mock import Mock, patch
|
|
4
|
+
from nose.tools import * # pylint: disable=wildcard-import, unused-wildcard-import
|
|
5
|
+
import parse
|
|
6
|
+
from behave.matchers import Match, Matcher, ParseMatcher, RegexMatcher, \
|
|
7
|
+
SimplifiedRegexMatcher, CucumberRegexMatcher
|
|
8
|
+
from behave import matchers, runner
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DummyMatcher(Matcher):
|
|
12
|
+
desired_result = None
|
|
13
|
+
|
|
14
|
+
def check_match(self, step):
|
|
15
|
+
return DummyMatcher.desired_result
|
|
16
|
+
|
|
17
|
+
class TestMatcher(object):
|
|
18
|
+
# pylint: disable=invalid-name, no-self-use
|
|
19
|
+
|
|
20
|
+
def setUp(self):
|
|
21
|
+
DummyMatcher.desired_result = None
|
|
22
|
+
|
|
23
|
+
def test_returns_none_if_check_match_returns_none(self):
|
|
24
|
+
matcher = DummyMatcher(None, None)
|
|
25
|
+
assert matcher.match('just a random step') is None
|
|
26
|
+
|
|
27
|
+
def test_returns_match_object_if_check_match_returns_arguments(self):
|
|
28
|
+
arguments = ['some', 'random', 'objects']
|
|
29
|
+
func = lambda x: -x
|
|
30
|
+
|
|
31
|
+
DummyMatcher.desired_result = arguments
|
|
32
|
+
matcher = DummyMatcher(func, None)
|
|
33
|
+
|
|
34
|
+
match = matcher.match('just a random step')
|
|
35
|
+
assert isinstance(match, Match)
|
|
36
|
+
assert match.func is func
|
|
37
|
+
assert match.arguments == arguments
|
|
38
|
+
|
|
39
|
+
class TestParseMatcher(object):
|
|
40
|
+
# pylint: disable=invalid-name, no-self-use
|
|
41
|
+
|
|
42
|
+
def setUp(self):
|
|
43
|
+
self.recorded_args = None
|
|
44
|
+
|
|
45
|
+
def record_args(self, *args, **kwargs):
|
|
46
|
+
self.recorded_args = (args, kwargs)
|
|
47
|
+
|
|
48
|
+
def test_returns_none_if_parser_does_not_match(self):
|
|
49
|
+
# pylint: disable=redefined-outer-name
|
|
50
|
+
# REASON: parse
|
|
51
|
+
matcher = ParseMatcher(None, 'a string')
|
|
52
|
+
with patch.object(matcher.parser, 'parse') as parse:
|
|
53
|
+
parse.return_value = None
|
|
54
|
+
assert matcher.match('just a random step') is None
|
|
55
|
+
|
|
56
|
+
def test_returns_arguments_based_on_matches(self):
|
|
57
|
+
func = lambda x: -x
|
|
58
|
+
matcher = ParseMatcher(func, 'foo')
|
|
59
|
+
|
|
60
|
+
results = parse.Result([1, 2, 3], {'foo': 'bar', 'baz': -45.3},
|
|
61
|
+
{
|
|
62
|
+
0: (13, 14),
|
|
63
|
+
1: (16, 17),
|
|
64
|
+
2: (22, 23),
|
|
65
|
+
'foo': (32, 35),
|
|
66
|
+
'baz': (39, 44),
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
expected = [
|
|
70
|
+
(13, 14, '1', 1, None),
|
|
71
|
+
(16, 17, '2', 2, None),
|
|
72
|
+
(22, 23, '3', 3, None),
|
|
73
|
+
(32, 35, 'bar', 'bar', 'foo'),
|
|
74
|
+
(39, 44, '-45.3', -45.3, 'baz'),
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
with patch.object(matcher.parser, 'parse') as p:
|
|
78
|
+
p.return_value = results
|
|
79
|
+
m = matcher.match('some numbers 1, 2 and 3 and the bar is -45.3')
|
|
80
|
+
assert m.func is func
|
|
81
|
+
args = m.arguments
|
|
82
|
+
have = [(a.start, a.end, a.original, a.value, a.name) for a in args]
|
|
83
|
+
eq_(have, expected)
|
|
84
|
+
|
|
85
|
+
def test_named_arguments(self):
|
|
86
|
+
text = "has a {string}, an {integer:d} and a {decimal:f}"
|
|
87
|
+
matcher = ParseMatcher(self.record_args, text)
|
|
88
|
+
context = runner.Context(Mock())
|
|
89
|
+
|
|
90
|
+
m = matcher.match("has a foo, an 11 and a 3.14159")
|
|
91
|
+
m.run(context)
|
|
92
|
+
eq_(self.recorded_args, ((context,), {
|
|
93
|
+
'string': 'foo',
|
|
94
|
+
'integer': 11,
|
|
95
|
+
'decimal': 3.14159
|
|
96
|
+
}))
|
|
97
|
+
|
|
98
|
+
def test_positional_arguments(self):
|
|
99
|
+
text = "has a {}, an {:d} and a {:f}"
|
|
100
|
+
matcher = ParseMatcher(self.record_args, text)
|
|
101
|
+
context = runner.Context(Mock())
|
|
102
|
+
|
|
103
|
+
m = matcher.match("has a foo, an 11 and a 3.14159")
|
|
104
|
+
m.run(context)
|
|
105
|
+
eq_(self.recorded_args, ((context, 'foo', 11, 3.14159), {}))
|
|
106
|
+
|
|
107
|
+
class TestRegexMatcher(object):
|
|
108
|
+
# pylint: disable=invalid-name, no-self-use
|
|
109
|
+
MATCHER_CLASS = RegexMatcher
|
|
110
|
+
|
|
111
|
+
def test_returns_none_if_regex_does_not_match(self):
|
|
112
|
+
RegexMatcher = self.MATCHER_CLASS
|
|
113
|
+
matcher = RegexMatcher(None, 'a string')
|
|
114
|
+
regex = Mock()
|
|
115
|
+
regex.match.return_value = None
|
|
116
|
+
matcher.regex = regex
|
|
117
|
+
assert matcher.match('just a random step') is None
|
|
118
|
+
|
|
119
|
+
def test_returns_arguments_based_on_groups(self):
|
|
120
|
+
RegexMatcher = self.MATCHER_CLASS
|
|
121
|
+
func = lambda x: -x
|
|
122
|
+
matcher = RegexMatcher(func, 'foo')
|
|
123
|
+
|
|
124
|
+
regex = Mock()
|
|
125
|
+
regex.groupindex = {'foo': 4, 'baz': 5}
|
|
126
|
+
|
|
127
|
+
match = Mock()
|
|
128
|
+
match.groups.return_value = ('1', '2', '3', 'bar', '-45.3')
|
|
129
|
+
positions = {
|
|
130
|
+
1: (13, 14),
|
|
131
|
+
2: (16, 17),
|
|
132
|
+
3: (22, 23),
|
|
133
|
+
4: (32, 35),
|
|
134
|
+
5: (39, 44),
|
|
135
|
+
}
|
|
136
|
+
match.start.side_effect = lambda idx: positions[idx][0]
|
|
137
|
+
match.end.side_effect = lambda idx: positions[idx][1]
|
|
138
|
+
|
|
139
|
+
regex.match.return_value = match
|
|
140
|
+
matcher.regex = regex
|
|
141
|
+
|
|
142
|
+
expected = [
|
|
143
|
+
(13, 14, '1', '1', None),
|
|
144
|
+
(16, 17, '2', '2', None),
|
|
145
|
+
(22, 23, '3', '3', None),
|
|
146
|
+
(32, 35, 'bar', 'bar', 'foo'),
|
|
147
|
+
(39, 44, '-45.3', '-45.3', 'baz'),
|
|
148
|
+
]
|
|
149
|
+
|
|
150
|
+
m = matcher.match('some numbers 1, 2 and 3 and the bar is -45.3')
|
|
151
|
+
assert m.func is func
|
|
152
|
+
args = m.arguments
|
|
153
|
+
have = [(a.start, a.end, a.original, a.value, a.name) for a in args]
|
|
154
|
+
eq_(have, expected)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class TestSimplifiedRegexMatcher(TestRegexMatcher):
|
|
159
|
+
MATCHER_CLASS = SimplifiedRegexMatcher
|
|
160
|
+
|
|
161
|
+
def test_steps_with_same_prefix_are_not_ordering_sensitive(self):
|
|
162
|
+
# -- RELATED-TO: issue #280
|
|
163
|
+
# pylint: disable=unused-argument
|
|
164
|
+
def step_func1(context): pass # pylint: disable=multiple-statements
|
|
165
|
+
def step_func2(context): pass # pylint: disable=multiple-statements
|
|
166
|
+
# pylint: enable=unused-argument
|
|
167
|
+
matcher1 = SimplifiedRegexMatcher(step_func1, "I do something")
|
|
168
|
+
matcher2 = SimplifiedRegexMatcher(step_func2, "I do something more")
|
|
169
|
+
|
|
170
|
+
# -- CHECK: ORDERING SENSITIVITY
|
|
171
|
+
matched1 = matcher1.match(matcher2.string)
|
|
172
|
+
matched2 = matcher2.match(matcher1.string)
|
|
173
|
+
assert matched1 is None
|
|
174
|
+
assert matched2 is None
|
|
175
|
+
|
|
176
|
+
# -- CHECK: Can match itself (if step text is simple)
|
|
177
|
+
matched1 = matcher1.match(matcher1.string)
|
|
178
|
+
matched2 = matcher2.match(matcher2.string)
|
|
179
|
+
assert isinstance(matched1, Match)
|
|
180
|
+
assert isinstance(matched2, Match)
|
|
181
|
+
|
|
182
|
+
@raises(AssertionError)
|
|
183
|
+
def test_step_should_not_use_regex_begin_marker(self):
|
|
184
|
+
SimplifiedRegexMatcher(None, "^I do something")
|
|
185
|
+
|
|
186
|
+
@raises(AssertionError)
|
|
187
|
+
def test_step_should_not_use_regex_end_marker(self):
|
|
188
|
+
SimplifiedRegexMatcher(None, "I do something$")
|
|
189
|
+
|
|
190
|
+
@raises(AssertionError)
|
|
191
|
+
def test_step_should_not_use_regex_begin_and_end_marker(self):
|
|
192
|
+
SimplifiedRegexMatcher(None, "^I do something$")
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class TestCucumberRegexMatcher(TestRegexMatcher):
|
|
196
|
+
MATCHER_CLASS = CucumberRegexMatcher
|
|
197
|
+
|
|
198
|
+
def test_steps_with_same_prefix_are_not_ordering_sensitive(self):
|
|
199
|
+
# -- RELATED-TO: issue #280
|
|
200
|
+
# pylint: disable=unused-argument
|
|
201
|
+
def step_func1(context): pass # pylint: disable=multiple-statements
|
|
202
|
+
def step_func2(context): pass # pylint: disable=multiple-statements
|
|
203
|
+
# pylint: enable=unused-argument
|
|
204
|
+
matcher1 = CucumberRegexMatcher(step_func1, "^I do something$")
|
|
205
|
+
matcher2 = CucumberRegexMatcher(step_func2, "^I do something more$")
|
|
206
|
+
|
|
207
|
+
# -- CHECK: ORDERING SENSITIVITY
|
|
208
|
+
matched1 = matcher1.match(matcher2.string[1:-1])
|
|
209
|
+
matched2 = matcher2.match(matcher1.string[1:-1])
|
|
210
|
+
assert matched1 is None
|
|
211
|
+
assert matched2 is None
|
|
212
|
+
|
|
213
|
+
# -- CHECK: Can match itself (if step text is simple)
|
|
214
|
+
matched1 = matcher1.match(matcher1.string[1:-1])
|
|
215
|
+
matched2 = matcher2.match(matcher2.string[1:-1])
|
|
216
|
+
assert isinstance(matched1, Match)
|
|
217
|
+
assert isinstance(matched2, Match)
|
|
218
|
+
|
|
219
|
+
def test_step_should_use_regex_begin_marker(self):
|
|
220
|
+
CucumberRegexMatcher(None, "^I do something")
|
|
221
|
+
|
|
222
|
+
def test_step_should_use_regex_end_marker(self):
|
|
223
|
+
CucumberRegexMatcher(None, "I do something$")
|
|
224
|
+
|
|
225
|
+
def test_step_should_use_regex_begin_and_end_marker(self):
|
|
226
|
+
CucumberRegexMatcher(None, "^I do something$")
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def test_step_matcher_current_matcher():
|
|
230
|
+
current_matcher = matchers.current_matcher
|
|
231
|
+
for name, klass in list(matchers.matcher_mapping.items()):
|
|
232
|
+
matchers.use_step_matcher(name)
|
|
233
|
+
matcher = matchers.get_matcher(lambda x: -x, 'foo')
|
|
234
|
+
assert isinstance(matcher, klass)
|
|
235
|
+
|
|
236
|
+
matchers.current_matcher = current_matcher
|
|
@@ -0,0 +1,871 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# pylint: disable=no-self-use, line-too-long
|
|
3
|
+
|
|
4
|
+
from __future__ import absolute_import, print_function, with_statement
|
|
5
|
+
import unittest
|
|
6
|
+
from mock import Mock, patch
|
|
7
|
+
from nose.tools import * # pylint: disable=wildcard-import, unused-wildcard-import
|
|
8
|
+
import six
|
|
9
|
+
from six.moves import range # pylint: disable=redefined-builtin
|
|
10
|
+
from six.moves import zip # pylint: disable=redefined-builtin
|
|
11
|
+
if six.PY2:
|
|
12
|
+
import traceback2 as traceback
|
|
13
|
+
traceback_modname = "traceback2"
|
|
14
|
+
else:
|
|
15
|
+
import traceback
|
|
16
|
+
traceback_modname = "traceback"
|
|
17
|
+
|
|
18
|
+
from behave.model_core import FileLocation, Status
|
|
19
|
+
from behave.model import Feature, Scenario, ScenarioOutline, Step
|
|
20
|
+
from behave.model import Table, Row
|
|
21
|
+
from behave.matchers import NoMatch
|
|
22
|
+
from behave.runner import Context
|
|
23
|
+
from behave.capture import CaptureController
|
|
24
|
+
from behave.configuration import Configuration
|
|
25
|
+
from behave.compat.collections import OrderedDict
|
|
26
|
+
from behave import step_registry
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# -- CONVENIENCE-ALIAS:
|
|
30
|
+
_text = six.text_type
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class TestFeatureRun(unittest.TestCase):
|
|
34
|
+
# pylint: disable=invalid-name
|
|
35
|
+
|
|
36
|
+
def setUp(self):
|
|
37
|
+
self.runner = Mock()
|
|
38
|
+
self.runner.aborted = False
|
|
39
|
+
self.runner.feature.tags = []
|
|
40
|
+
self.config = self.runner.config = Mock()
|
|
41
|
+
self.context = self.runner.context = Mock()
|
|
42
|
+
self.formatters = self.runner.formatters = [Mock()]
|
|
43
|
+
self.run_hook = self.runner.run_hook = Mock()
|
|
44
|
+
|
|
45
|
+
def test_formatter_feature_called(self):
|
|
46
|
+
feature = Feature('foo.feature', 1, u'Feature', u'foo',
|
|
47
|
+
background=Mock())
|
|
48
|
+
|
|
49
|
+
feature.run(self.runner)
|
|
50
|
+
|
|
51
|
+
self.formatters[0].feature.assert_called_with(feature)
|
|
52
|
+
|
|
53
|
+
def test_formatter_background_called_when_feature_has_background(self):
|
|
54
|
+
feature = Feature('foo.feature', 1, u'Feature', u'foo',
|
|
55
|
+
background=Mock())
|
|
56
|
+
|
|
57
|
+
feature.run(self.runner)
|
|
58
|
+
|
|
59
|
+
self.formatters[0].background.assert_called_with(feature.background)
|
|
60
|
+
|
|
61
|
+
def test_formatter_background_not_called_when_feature_has_no_background(self):
|
|
62
|
+
feature = Feature('foo.feature', 1, u'Feature', u'foo')
|
|
63
|
+
|
|
64
|
+
feature.run(self.runner)
|
|
65
|
+
|
|
66
|
+
assert not self.formatters[0].background.called
|
|
67
|
+
|
|
68
|
+
def test_run_runs_scenarios(self):
|
|
69
|
+
scenarios = [Mock(), Mock()]
|
|
70
|
+
for scenario in scenarios:
|
|
71
|
+
scenario.tags = []
|
|
72
|
+
scenario.run.return_value = False
|
|
73
|
+
|
|
74
|
+
self.config.tags.check.return_value = True # pylint: disable=no-member
|
|
75
|
+
self.config.name = []
|
|
76
|
+
|
|
77
|
+
feature = Feature('foo.feature', 1, u'Feature', u'foo',
|
|
78
|
+
scenarios=scenarios)
|
|
79
|
+
|
|
80
|
+
feature.run(self.runner)
|
|
81
|
+
|
|
82
|
+
for scenario in scenarios:
|
|
83
|
+
scenario.run.assert_called_with(self.runner)
|
|
84
|
+
|
|
85
|
+
def test_run_runs_named_scenarios(self):
|
|
86
|
+
scenarios = [Mock(Scenario), Mock(Scenario)]
|
|
87
|
+
scenarios[0].name = 'first scenario'
|
|
88
|
+
scenarios[1].name = 'second scenario'
|
|
89
|
+
scenarios[0].tags = []
|
|
90
|
+
scenarios[1].tags = []
|
|
91
|
+
# -- FAKE-CHECK:
|
|
92
|
+
scenarios[0].should_run_with_name_select.return_value = True
|
|
93
|
+
scenarios[1].should_run_with_name_select.return_value = False
|
|
94
|
+
|
|
95
|
+
for scenario in scenarios:
|
|
96
|
+
scenario.run.return_value = False
|
|
97
|
+
|
|
98
|
+
self.config.tags.check.return_value = True # pylint: disable=no-member
|
|
99
|
+
self.config.name = ['first', 'third']
|
|
100
|
+
self.config.name_re = Configuration.build_name_re(self.config.name)
|
|
101
|
+
|
|
102
|
+
feature = Feature('foo.feature', 1, u'Feature', u'foo',
|
|
103
|
+
scenarios=scenarios)
|
|
104
|
+
|
|
105
|
+
feature.run(self.runner)
|
|
106
|
+
|
|
107
|
+
scenarios[0].run.assert_called_with(self.runner)
|
|
108
|
+
assert not scenarios[1].run.called
|
|
109
|
+
scenarios[0].should_run_with_name_select.assert_called_with(self.config)
|
|
110
|
+
scenarios[1].should_run_with_name_select.assert_called_with(self.config)
|
|
111
|
+
|
|
112
|
+
def test_run_runs_named_scenarios_with_regexp(self):
|
|
113
|
+
scenarios = [Mock(), Mock()]
|
|
114
|
+
scenarios[0].name = 'first scenario'
|
|
115
|
+
scenarios[1].name = 'second scenario'
|
|
116
|
+
scenarios[0].tags = []
|
|
117
|
+
scenarios[1].tags = []
|
|
118
|
+
# -- FAKE-CHECK:
|
|
119
|
+
scenarios[0].should_run_with_name_select.return_value = False
|
|
120
|
+
scenarios[1].should_run_with_name_select.return_value = True
|
|
121
|
+
|
|
122
|
+
for scenario in scenarios:
|
|
123
|
+
scenario.run.return_value = False
|
|
124
|
+
|
|
125
|
+
self.config.tags.check.return_value = True # pylint: disable=no-member
|
|
126
|
+
self.config.name = ['third .*', 'second .*']
|
|
127
|
+
self.config.name_re = Configuration.build_name_re(self.config.name)
|
|
128
|
+
|
|
129
|
+
feature = Feature('foo.feature', 1, u'Feature', u'foo',
|
|
130
|
+
scenarios=scenarios)
|
|
131
|
+
|
|
132
|
+
feature.run(self.runner)
|
|
133
|
+
|
|
134
|
+
assert not scenarios[0].run.called
|
|
135
|
+
scenarios[1].run.assert_called_with(self.runner)
|
|
136
|
+
scenarios[0].should_run_with_name_select.assert_called_with(self.config)
|
|
137
|
+
scenarios[1].should_run_with_name_select.assert_called_with(self.config)
|
|
138
|
+
|
|
139
|
+
# @prepared
|
|
140
|
+
def test_run_exclude_named_scenarios_with_regexp(self):
|
|
141
|
+
# -- NOTE: Works here only because it is run against Mocks.
|
|
142
|
+
scenarios = [Mock(), Mock(), Mock()]
|
|
143
|
+
scenarios[0].name = "Alice in Florida"
|
|
144
|
+
scenarios[1].name = "Alice and Bob"
|
|
145
|
+
scenarios[2].name = "Bob in Paris"
|
|
146
|
+
scenarios[0].tags = []
|
|
147
|
+
scenarios[1].tags = []
|
|
148
|
+
scenarios[2].tags = []
|
|
149
|
+
# -- FAKE-CHECK:
|
|
150
|
+
scenarios[0].should_run_with_name_select.return_value = False
|
|
151
|
+
scenarios[1].should_run_with_name_select.return_value = False
|
|
152
|
+
scenarios[2].should_run_with_name_select.return_value = True
|
|
153
|
+
|
|
154
|
+
for scenario in scenarios:
|
|
155
|
+
scenario.run.return_value = False
|
|
156
|
+
|
|
157
|
+
self.config.tags.check.return_value = True # pylint: disable=no-member
|
|
158
|
+
self.config.name = ["(?!Alice)"] # Exclude all scenarios with "Alice"
|
|
159
|
+
self.config.name_re = Configuration.build_name_re(self.config.name)
|
|
160
|
+
|
|
161
|
+
feature = Feature('foo.feature', 1, u'Feature', u'foo',
|
|
162
|
+
scenarios=scenarios)
|
|
163
|
+
|
|
164
|
+
feature.run(self.runner)
|
|
165
|
+
|
|
166
|
+
assert not scenarios[0].run.called
|
|
167
|
+
scenarios[0].should_run_with_name_select.assert_called_with(self.config)
|
|
168
|
+
scenarios[1].should_run_with_name_select.assert_called_with(self.config)
|
|
169
|
+
scenarios[2].should_run_with_name_select.assert_called_with(self.config)
|
|
170
|
+
scenarios[0].run.assert_not_called()
|
|
171
|
+
scenarios[1].run.assert_not_called()
|
|
172
|
+
scenarios[2].run.assert_called_with(self.runner)
|
|
173
|
+
|
|
174
|
+
def test_feature_hooks_not_run_if_feature_not_being_run(self):
|
|
175
|
+
self.config.tags.check.return_value = False # pylint: disable=no-member
|
|
176
|
+
|
|
177
|
+
feature = Feature('foo.feature', 1, u'Feature', u'foo')
|
|
178
|
+
feature.run(self.runner)
|
|
179
|
+
assert not self.run_hook.called
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class TestScenarioRun(unittest.TestCase):
|
|
183
|
+
# pylint: disable=invalid-name
|
|
184
|
+
|
|
185
|
+
def setUp(self):
|
|
186
|
+
self.runner = Mock()
|
|
187
|
+
self.runner.aborted = False
|
|
188
|
+
self.runner.feature.tags = []
|
|
189
|
+
self.config = self.runner.config = Mock()
|
|
190
|
+
self.config.dry_run = False
|
|
191
|
+
self.context = self.runner.context = Mock()
|
|
192
|
+
self.formatters = self.runner.formatters = [Mock()]
|
|
193
|
+
self.run_hook = self.runner.run_hook = Mock()
|
|
194
|
+
|
|
195
|
+
def test_run_invokes_formatter_scenario_and_steps_correctly(self):
|
|
196
|
+
self.config.stdout_capture = False
|
|
197
|
+
self.config.log_capture = False
|
|
198
|
+
self.config.tags.check.return_value = True # pylint: disable=no-member
|
|
199
|
+
steps = [Mock(), Mock()]
|
|
200
|
+
scenario = Scenario('foo.feature', 17, u'Scenario', u'foo',
|
|
201
|
+
steps=steps)
|
|
202
|
+
|
|
203
|
+
scenario.run(self.runner)
|
|
204
|
+
|
|
205
|
+
self.formatters[0].scenario.assert_called_with(scenario)
|
|
206
|
+
for step in steps:
|
|
207
|
+
step.run.assert_called_with(self.runner)
|
|
208
|
+
|
|
209
|
+
if six.PY3:
|
|
210
|
+
stringio_target = 'io.StringIO'
|
|
211
|
+
else:
|
|
212
|
+
stringio_target = 'StringIO.StringIO'
|
|
213
|
+
|
|
214
|
+
def test_handles_stdout_and_log_capture(self):
|
|
215
|
+
self.config.stdout_capture = True
|
|
216
|
+
self.config.log_capture = True
|
|
217
|
+
self.config.tags.check.return_value = True # pylint: disable=no-member
|
|
218
|
+
|
|
219
|
+
steps = [Mock(), Mock()]
|
|
220
|
+
scenario = Scenario('foo.feature', 17, u'Scenario', u'foo',
|
|
221
|
+
steps=steps)
|
|
222
|
+
|
|
223
|
+
scenario.run(self.runner)
|
|
224
|
+
|
|
225
|
+
self.runner.setup_capture.assert_called_with()
|
|
226
|
+
self.runner.teardown_capture.assert_called_with()
|
|
227
|
+
|
|
228
|
+
def test_failed_step_causes_remaining_steps_to_be_skipped(self):
|
|
229
|
+
self.config.stdout_capture = False
|
|
230
|
+
self.config.log_capture = False
|
|
231
|
+
self.config.tags.check.return_value = True # pylint: disable=no-member
|
|
232
|
+
|
|
233
|
+
steps = [Mock(), Mock()]
|
|
234
|
+
scenario = Scenario('foo.feature', 17, u'Scenario', u'foo',
|
|
235
|
+
steps=steps)
|
|
236
|
+
steps[0].run.return_value = False
|
|
237
|
+
steps[1].step_type = "when"
|
|
238
|
+
steps[1].name = "step1"
|
|
239
|
+
|
|
240
|
+
def step1_function(context): # pylint: disable=unused-argument
|
|
241
|
+
pass
|
|
242
|
+
my_step_registry = step_registry.StepRegistry()
|
|
243
|
+
my_step_registry.add_step_definition("when", "step1", step1_function)
|
|
244
|
+
|
|
245
|
+
with patch("behave.step_registry.registry", my_step_registry):
|
|
246
|
+
assert scenario.run(self.runner)
|
|
247
|
+
eq_(steps[1].status, Status.skipped)
|
|
248
|
+
|
|
249
|
+
def test_failed_step_causes_context_failure_to_be_set(self):
|
|
250
|
+
self.config.stdout_capture = False
|
|
251
|
+
self.config.log_capture = False
|
|
252
|
+
self.config.tags.check.return_value = True # pylint: disable=no-member
|
|
253
|
+
|
|
254
|
+
steps = [
|
|
255
|
+
Mock(step_type="given", name="step0"),
|
|
256
|
+
Mock(step_type="then", name="step1"),
|
|
257
|
+
]
|
|
258
|
+
scenario = Scenario('foo.feature', 17, u'Scenario', u'foo',
|
|
259
|
+
steps=steps)
|
|
260
|
+
steps[0].run.return_value = False
|
|
261
|
+
|
|
262
|
+
assert scenario.run(self.runner)
|
|
263
|
+
# pylint: disable=protected-access
|
|
264
|
+
self.context._set_root_attribute.assert_called_with("failed", True)
|
|
265
|
+
|
|
266
|
+
def test_undefined_step_causes_failed_scenario_status(self):
|
|
267
|
+
self.config.stdout_capture = False
|
|
268
|
+
self.config.log_capture = False
|
|
269
|
+
self.config.tags.check.return_value = True # pylint: disable=no-member
|
|
270
|
+
|
|
271
|
+
passed_step = Mock()
|
|
272
|
+
undefined_step = Mock()
|
|
273
|
+
|
|
274
|
+
steps = [passed_step, undefined_step]
|
|
275
|
+
scenario = Scenario('foo.feature', 17, u'Scenario', u'foo',
|
|
276
|
+
steps=steps)
|
|
277
|
+
passed_step.run.return_value = True
|
|
278
|
+
passed_step.status = Status.passed
|
|
279
|
+
undefined_step.run.return_value = False
|
|
280
|
+
undefined_step.status = Status.undefined
|
|
281
|
+
|
|
282
|
+
assert scenario.run(self.runner)
|
|
283
|
+
eq_(undefined_step.status, Status.undefined)
|
|
284
|
+
eq_(scenario.status, Status.failed)
|
|
285
|
+
# pylint: disable=protected-access
|
|
286
|
+
self.context._set_root_attribute.assert_called_with("failed", True)
|
|
287
|
+
|
|
288
|
+
def test_skipped_steps_set_step_status_and_scenario_status_if_not_set(self):
|
|
289
|
+
self.config.stdout_capture = False
|
|
290
|
+
self.config.log_capture = False
|
|
291
|
+
self.config.tags.check.return_value = False # pylint: disable=no-member
|
|
292
|
+
|
|
293
|
+
steps = [Mock(), Mock()]
|
|
294
|
+
scenario = Scenario('foo.feature', 17, u'Scenario', u'foo',
|
|
295
|
+
steps=steps)
|
|
296
|
+
|
|
297
|
+
scenario.run(self.runner)
|
|
298
|
+
|
|
299
|
+
assert False not in [s.status == Status.skipped for s in steps]
|
|
300
|
+
eq_(scenario.status, Status.skipped)
|
|
301
|
+
|
|
302
|
+
def test_scenario_hooks_not_run_if_scenario_not_being_run(self):
|
|
303
|
+
self.config.tags.check.return_value = False # pylint: disable=no-member
|
|
304
|
+
|
|
305
|
+
scenario = Scenario('foo.feature', 17, u'Scenario', u'foo')
|
|
306
|
+
|
|
307
|
+
scenario.run(self.runner)
|
|
308
|
+
|
|
309
|
+
assert not self.run_hook.called
|
|
310
|
+
|
|
311
|
+
def test_should_run_with_name_select(self):
|
|
312
|
+
scenario_name = u"first scenario"
|
|
313
|
+
scenario = Scenario("foo.feature", 17, u"Scenario", scenario_name)
|
|
314
|
+
self.config.name = ['first .*', 'second .*']
|
|
315
|
+
self.config.name_re = Configuration.build_name_re(self.config.name)
|
|
316
|
+
|
|
317
|
+
assert scenario.should_run_with_name_select(self.config)
|
|
318
|
+
|
|
319
|
+
class TestScenarioOutline(unittest.TestCase):
|
|
320
|
+
# pylint: disable=invalid-name
|
|
321
|
+
|
|
322
|
+
def test_run_calls_run_on_each_generated_scenario(self):
|
|
323
|
+
# pylint: disable=protected-access
|
|
324
|
+
outline = ScenarioOutline('foo.feature', 17, u'Scenario Outline',
|
|
325
|
+
u'foo')
|
|
326
|
+
outline._scenarios = [Mock(), Mock()]
|
|
327
|
+
for scenario in outline._scenarios:
|
|
328
|
+
scenario.run.return_value = False
|
|
329
|
+
|
|
330
|
+
runner = Mock()
|
|
331
|
+
runner.context = Mock()
|
|
332
|
+
|
|
333
|
+
outline.run(runner)
|
|
334
|
+
|
|
335
|
+
for s in outline._scenarios:
|
|
336
|
+
s.run.assert_called_with(runner)
|
|
337
|
+
|
|
338
|
+
def test_run_stops_on_first_failure_if_requested(self):
|
|
339
|
+
# pylint: disable=protected-access
|
|
340
|
+
outline = ScenarioOutline('foo.feature', 17, u'Scenario Outline',
|
|
341
|
+
u'foo')
|
|
342
|
+
outline._scenarios = [Mock(), Mock()]
|
|
343
|
+
outline._scenarios[0].run.return_value = True
|
|
344
|
+
|
|
345
|
+
runner = Mock()
|
|
346
|
+
runner.context = Mock()
|
|
347
|
+
config = runner.config = Mock()
|
|
348
|
+
config.stop = True
|
|
349
|
+
|
|
350
|
+
outline.run(runner)
|
|
351
|
+
|
|
352
|
+
outline._scenarios[0].run.assert_called_with(runner)
|
|
353
|
+
assert not outline._scenarios[1].run.called
|
|
354
|
+
|
|
355
|
+
def test_run_sets_context_variable_for_outline(self):
|
|
356
|
+
# pylint: disable=protected-access
|
|
357
|
+
outline = ScenarioOutline('foo.feature', 17, u'Scenario Outline',
|
|
358
|
+
u'foo')
|
|
359
|
+
outline._scenarios = [Mock(), Mock(), Mock()]
|
|
360
|
+
for scenario in outline._scenarios:
|
|
361
|
+
scenario.run.return_value = False
|
|
362
|
+
|
|
363
|
+
runner = Mock()
|
|
364
|
+
context = runner.context = Mock()
|
|
365
|
+
config = runner.config = Mock()
|
|
366
|
+
config.stop = True
|
|
367
|
+
|
|
368
|
+
outline.run(runner)
|
|
369
|
+
|
|
370
|
+
eq_(context._set_root_attribute.call_args_list, [
|
|
371
|
+
(('active_outline', outline._scenarios[0]._row), {}),
|
|
372
|
+
(('active_outline', outline._scenarios[1]._row), {}),
|
|
373
|
+
(('active_outline', outline._scenarios[2]._row), {}),
|
|
374
|
+
(('active_outline', None), {}),
|
|
375
|
+
])
|
|
376
|
+
|
|
377
|
+
def test_run_should_pass_when_all_examples_pass(self):
|
|
378
|
+
# pylint: disable=protected-access
|
|
379
|
+
outline = ScenarioOutline('foo.feature', 17, u'Scenario Outline',
|
|
380
|
+
u'foo')
|
|
381
|
+
outline._scenarios = [Mock(), Mock(), Mock()]
|
|
382
|
+
for scenario in outline._scenarios:
|
|
383
|
+
scenario.run.return_value = False
|
|
384
|
+
|
|
385
|
+
runner = Mock()
|
|
386
|
+
context = runner.context = Mock()
|
|
387
|
+
config = runner.config = Mock()
|
|
388
|
+
config.stop = True
|
|
389
|
+
|
|
390
|
+
resultFailed = outline.run(runner)
|
|
391
|
+
eq_(resultFailed, False)
|
|
392
|
+
|
|
393
|
+
def test_run_should_fail_when_first_examples_fails(self):
|
|
394
|
+
outline = ScenarioOutline('foo.feature', 17, u'Scenario Outline',
|
|
395
|
+
u'foo')
|
|
396
|
+
failed = True
|
|
397
|
+
# pylint: disable=protected-access
|
|
398
|
+
outline._scenarios = [Mock(), Mock()]
|
|
399
|
+
outline._scenarios[0].run.return_value = failed
|
|
400
|
+
outline._scenarios[1].run.return_value = not failed
|
|
401
|
+
|
|
402
|
+
runner = Mock()
|
|
403
|
+
context = runner.context = Mock()
|
|
404
|
+
config = runner.config = Mock()
|
|
405
|
+
config.stop = True
|
|
406
|
+
|
|
407
|
+
resultFailed = outline.run(runner)
|
|
408
|
+
eq_(resultFailed, True)
|
|
409
|
+
|
|
410
|
+
def test_run_should_fail_when_last_examples_fails(self):
|
|
411
|
+
outline = ScenarioOutline('foo.feature', 17, u'Scenario Outline',
|
|
412
|
+
u'foo')
|
|
413
|
+
failed = True
|
|
414
|
+
# pylint: disable=protected-access
|
|
415
|
+
outline._scenarios = [Mock(), Mock()]
|
|
416
|
+
outline._scenarios[0].run.return_value = not failed
|
|
417
|
+
outline._scenarios[1].run.return_value = failed
|
|
418
|
+
|
|
419
|
+
runner = Mock()
|
|
420
|
+
context = runner.context = Mock()
|
|
421
|
+
config = runner.config = Mock()
|
|
422
|
+
config.stop = True
|
|
423
|
+
|
|
424
|
+
resultFailed = outline.run(runner)
|
|
425
|
+
eq_(resultFailed, True)
|
|
426
|
+
|
|
427
|
+
def test_run_should_fail_when_middle_examples_fails(self):
|
|
428
|
+
outline = ScenarioOutline('foo.feature', 17, u'Scenario Outline',
|
|
429
|
+
u'foo')
|
|
430
|
+
failed = True
|
|
431
|
+
# pylint: disable=protected-access
|
|
432
|
+
outline._scenarios = [Mock(), Mock(), Mock()]
|
|
433
|
+
outline._scenarios[0].run.return_value = not failed
|
|
434
|
+
outline._scenarios[1].run.return_value = failed
|
|
435
|
+
outline._scenarios[2].run.return_value = not failed
|
|
436
|
+
|
|
437
|
+
runner = Mock()
|
|
438
|
+
context = runner.context = Mock()
|
|
439
|
+
config = runner.config = Mock()
|
|
440
|
+
config.stop = True
|
|
441
|
+
|
|
442
|
+
resultFailed = outline.run(runner)
|
|
443
|
+
eq_(resultFailed, True)
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
def raiser(exception):
|
|
447
|
+
def func(*args, **kwargs): # pylint: disable=unused-argument
|
|
448
|
+
raise exception
|
|
449
|
+
return func
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
class TestStepRun(unittest.TestCase):
|
|
453
|
+
# pylint: disable=invalid-name
|
|
454
|
+
|
|
455
|
+
def setUp(self):
|
|
456
|
+
self.step_registry = Mock()
|
|
457
|
+
self.runner = Mock()
|
|
458
|
+
# self.capture_controller = self.runner.capture_controller = Mock()
|
|
459
|
+
self.capture_controller = CaptureController(self.runner.config)
|
|
460
|
+
self.runner.capture_controller = self.capture_controller
|
|
461
|
+
self.runner.step_registry = self.step_registry
|
|
462
|
+
self.config = self.runner.config = Mock()
|
|
463
|
+
self.config.outputs = [None]
|
|
464
|
+
self.context = self.runner.context = Mock()
|
|
465
|
+
print('context is %s' % self.context)
|
|
466
|
+
self.formatters = self.runner.formatters = [Mock()]
|
|
467
|
+
self.stdout_capture = self.capture_controller.stdout_capture = Mock()
|
|
468
|
+
self.stdout_capture.getvalue.return_value = ''
|
|
469
|
+
self.stderr_capture = self.capture_controller.stderr_capture = Mock()
|
|
470
|
+
self.stderr_capture.getvalue.return_value = ''
|
|
471
|
+
self.log_capture = self.capture_controller.log_capture = Mock()
|
|
472
|
+
self.log_capture.getvalue.return_value = ''
|
|
473
|
+
self.run_hook = self.runner.run_hook = Mock()
|
|
474
|
+
|
|
475
|
+
def test_run_appends_step_to_undefined_when_no_match_found(self):
|
|
476
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo')
|
|
477
|
+
self.runner.step_registry.find_match.return_value = None
|
|
478
|
+
self.runner.undefined_steps = []
|
|
479
|
+
assert not step.run(self.runner)
|
|
480
|
+
|
|
481
|
+
assert step in self.runner.undefined_steps
|
|
482
|
+
eq_(step.status, Status.undefined)
|
|
483
|
+
|
|
484
|
+
def test_run_reports_undefined_step_via_formatter_when_not_quiet(self):
|
|
485
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo')
|
|
486
|
+
self.runner.step_registry.find_match.return_value = None
|
|
487
|
+
assert not step.run(self.runner)
|
|
488
|
+
|
|
489
|
+
self.formatters[0].match.assert_called_with(NoMatch())
|
|
490
|
+
self.formatters[0].result.assert_called_with(step)
|
|
491
|
+
|
|
492
|
+
def test_run_with_no_match_does_not_touch_formatter_when_quiet(self):
|
|
493
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo')
|
|
494
|
+
self.runner.step_registry.find_match.return_value = None
|
|
495
|
+
assert not step.run(self.runner, quiet=True)
|
|
496
|
+
|
|
497
|
+
assert not self.formatters[0].match.called
|
|
498
|
+
assert not self.formatters[0].result.called
|
|
499
|
+
|
|
500
|
+
def test_run_when_not_quiet_reports_match_and_result(self):
|
|
501
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo')
|
|
502
|
+
match = Mock()
|
|
503
|
+
self.runner.step_registry.find_match.return_value = match
|
|
504
|
+
|
|
505
|
+
side_effects = (None, raiser(AssertionError('whee')),
|
|
506
|
+
raiser(Exception('whee')))
|
|
507
|
+
for side_effect in side_effects:
|
|
508
|
+
match.run.side_effect = side_effect
|
|
509
|
+
step.run(self.runner)
|
|
510
|
+
self.formatters[0].match.assert_called_with(match)
|
|
511
|
+
self.formatters[0].result.assert_called_with(step)
|
|
512
|
+
|
|
513
|
+
def test_run_when_quiet_reports_nothing(self):
|
|
514
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo')
|
|
515
|
+
match = Mock()
|
|
516
|
+
self.runner.step_registry.find_match.return_value = match
|
|
517
|
+
|
|
518
|
+
side_effects = (None, raiser(AssertionError('whee')),
|
|
519
|
+
raiser(Exception('whee')))
|
|
520
|
+
for side_effect in side_effects:
|
|
521
|
+
match.run.side_effect = side_effect
|
|
522
|
+
step.run(self.runner, quiet=True)
|
|
523
|
+
assert not self.formatters[0].match.called
|
|
524
|
+
assert not self.formatters[0].result.called
|
|
525
|
+
|
|
526
|
+
def test_run_runs_before_hook_then_match_then_after_hook(self):
|
|
527
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo')
|
|
528
|
+
match = Mock()
|
|
529
|
+
self.runner.step_registry.find_match.return_value = match
|
|
530
|
+
|
|
531
|
+
side_effects = (None, AssertionError('whee'), Exception('whee'))
|
|
532
|
+
for side_effect in side_effects:
|
|
533
|
+
# Make match.run() and runner.run_hook() the same mock so
|
|
534
|
+
# we can make sure things happen in the right order.
|
|
535
|
+
self.runner.run_hook = match.run = Mock()
|
|
536
|
+
|
|
537
|
+
def effect(thing):
|
|
538
|
+
# pylint: disable=unused-argument
|
|
539
|
+
def raiser_(*args, **kwargs):
|
|
540
|
+
match.run.side_effect = None
|
|
541
|
+
if thing:
|
|
542
|
+
raise thing
|
|
543
|
+
|
|
544
|
+
def nonraiser(*args, **kwargs):
|
|
545
|
+
match.run.side_effect = raiser_
|
|
546
|
+
|
|
547
|
+
return nonraiser
|
|
548
|
+
|
|
549
|
+
match.run.side_effect = effect(side_effect)
|
|
550
|
+
step.run(self.runner)
|
|
551
|
+
|
|
552
|
+
eq_(match.run.call_args_list, [
|
|
553
|
+
(('before_step', self.context, step), {}),
|
|
554
|
+
((self.context,), {}),
|
|
555
|
+
(('after_step', self.context, step), {}),
|
|
556
|
+
])
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
def test_run_sets_table_if_present(self):
|
|
560
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo',
|
|
561
|
+
table=Mock())
|
|
562
|
+
self.runner.step_registry.find_match.return_value = Mock()
|
|
563
|
+
step.run(self.runner)
|
|
564
|
+
eq_(self.context.table, step.table)
|
|
565
|
+
|
|
566
|
+
def test_run_sets_text_if_present(self):
|
|
567
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo',
|
|
568
|
+
text=Mock(name='text'))
|
|
569
|
+
self.runner.step_registry.find_match.return_value = Mock()
|
|
570
|
+
step.run(self.runner)
|
|
571
|
+
|
|
572
|
+
eq_(self.context.text, step.text)
|
|
573
|
+
|
|
574
|
+
def test_run_sets_status_to_passed_if_nothing_goes_wrong(self):
|
|
575
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo')
|
|
576
|
+
step.error_message = None
|
|
577
|
+
self.runner.step_registry.find_match.return_value = Mock()
|
|
578
|
+
step.run(self.runner)
|
|
579
|
+
|
|
580
|
+
eq_(step.status, Status.passed)
|
|
581
|
+
eq_(step.error_message, None)
|
|
582
|
+
|
|
583
|
+
def test_run_sets_status_to_failed_on_assertion_error(self):
|
|
584
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo')
|
|
585
|
+
self.runner.context = Context(self.runner)
|
|
586
|
+
self.runner.config.stdout_capture = True
|
|
587
|
+
self.runner.config.log_capture = False
|
|
588
|
+
self.runner.capture_controller = CaptureController(self.runner.config)
|
|
589
|
+
self.runner.capture_controller.setup_capture(self.runner.context)
|
|
590
|
+
step.error_message = None
|
|
591
|
+
match = Mock()
|
|
592
|
+
match.run.side_effect = raiser(AssertionError('whee'))
|
|
593
|
+
self.runner.step_registry.find_match.return_value = match
|
|
594
|
+
step.run(self.runner)
|
|
595
|
+
|
|
596
|
+
eq_(step.status, Status.failed)
|
|
597
|
+
assert step.error_message.startswith('Assertion Failed')
|
|
598
|
+
|
|
599
|
+
@patch('%s.format_exc' % traceback_modname)
|
|
600
|
+
def test_run_sets_status_to_failed_on_exception(self, format_exc):
|
|
601
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo')
|
|
602
|
+
step.error_message = None
|
|
603
|
+
match = Mock()
|
|
604
|
+
match.run.side_effect = raiser(Exception('whee'))
|
|
605
|
+
self.runner.step_registry.find_match.return_value = match
|
|
606
|
+
format_exc.return_value = 'something to do with an exception'
|
|
607
|
+
|
|
608
|
+
step.run(self.runner)
|
|
609
|
+
eq_(step.status, Status.failed)
|
|
610
|
+
eq_(step.error_message, format_exc.return_value)
|
|
611
|
+
|
|
612
|
+
@patch('time.time')
|
|
613
|
+
def test_run_calculates_duration(self, time_time):
|
|
614
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo')
|
|
615
|
+
match = Mock()
|
|
616
|
+
self.runner.step_registry.find_match.return_value = match
|
|
617
|
+
|
|
618
|
+
def time_time_1():
|
|
619
|
+
def time_time_2():
|
|
620
|
+
return 23
|
|
621
|
+
time_time.side_effect = time_time_2
|
|
622
|
+
return 17
|
|
623
|
+
|
|
624
|
+
side_effects = (None, raiser(AssertionError('whee')),
|
|
625
|
+
raiser(Exception('whee')))
|
|
626
|
+
for side_effect in side_effects:
|
|
627
|
+
match.run.side_effect = side_effect
|
|
628
|
+
time_time.side_effect = time_time_1
|
|
629
|
+
|
|
630
|
+
step.run(self.runner)
|
|
631
|
+
eq_(step.duration, 23 - 17)
|
|
632
|
+
|
|
633
|
+
def test_run_captures_stdout_and_logging(self):
|
|
634
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo')
|
|
635
|
+
match = Mock()
|
|
636
|
+
self.runner.step_registry.find_match.return_value = match
|
|
637
|
+
|
|
638
|
+
assert step.run(self.runner)
|
|
639
|
+
|
|
640
|
+
self.runner.start_capture.assert_called_with()
|
|
641
|
+
self.runner.stop_capture.assert_called_with()
|
|
642
|
+
|
|
643
|
+
def test_run_appends_any_captured_stdout_on_failure(self):
|
|
644
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo')
|
|
645
|
+
match = Mock()
|
|
646
|
+
self.runner.step_registry.find_match.return_value = match
|
|
647
|
+
self.stdout_capture.getvalue.return_value = 'frogs'
|
|
648
|
+
match.run.side_effect = raiser(Exception('halibut'))
|
|
649
|
+
|
|
650
|
+
assert not step.run(self.runner)
|
|
651
|
+
assert 'Captured stdout:' in step.error_message
|
|
652
|
+
assert 'frogs' in step.error_message
|
|
653
|
+
|
|
654
|
+
def test_run_appends_any_captured_logging_on_failure(self):
|
|
655
|
+
step = Step('foo.feature', 17, u'Given', 'given', u'foo')
|
|
656
|
+
match = Mock()
|
|
657
|
+
self.runner.step_registry.find_match.return_value = match
|
|
658
|
+
self.log_capture.getvalue.return_value = 'toads'
|
|
659
|
+
match.run.side_effect = raiser(AssertionError('kipper'))
|
|
660
|
+
|
|
661
|
+
assert not step.run(self.runner)
|
|
662
|
+
assert 'Captured logging:' in step.error_message
|
|
663
|
+
assert 'toads' in step.error_message
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
class TestTableModel(unittest.TestCase):
|
|
667
|
+
# pylint: disable=invalid-name
|
|
668
|
+
HEAD = [u'type of stuff', u'awesomeness', u'ridiculousness']
|
|
669
|
+
DATA = [
|
|
670
|
+
[u'fluffy', u'large', u'frequent'],
|
|
671
|
+
[u'lint', u'low', u'high'],
|
|
672
|
+
[u'green', u'variable', u'awkward'],
|
|
673
|
+
]
|
|
674
|
+
|
|
675
|
+
def setUp(self):
|
|
676
|
+
self.table = Table(self.HEAD, 0, self.DATA)
|
|
677
|
+
|
|
678
|
+
def test_equivalence(self):
|
|
679
|
+
t1 = self.table
|
|
680
|
+
self.setUp()
|
|
681
|
+
eq_(t1, self.table)
|
|
682
|
+
|
|
683
|
+
def test_table_iteration(self):
|
|
684
|
+
for i, row in enumerate(self.table):
|
|
685
|
+
for j, cell in enumerate(row):
|
|
686
|
+
eq_(cell, self.DATA[i][j])
|
|
687
|
+
|
|
688
|
+
def test_table_row_by_index(self):
|
|
689
|
+
for i in range(3):
|
|
690
|
+
eq_(self.table[i], Row(self.HEAD, self.DATA[i], 0))
|
|
691
|
+
|
|
692
|
+
def test_table_row_name(self):
|
|
693
|
+
eq_(self.table[0]['type of stuff'], 'fluffy')
|
|
694
|
+
eq_(self.table[1]['awesomeness'], 'low')
|
|
695
|
+
eq_(self.table[2]['ridiculousness'], 'awkward')
|
|
696
|
+
|
|
697
|
+
def test_table_row_index(self):
|
|
698
|
+
eq_(self.table[0][0], 'fluffy')
|
|
699
|
+
eq_(self.table[1][1], 'low')
|
|
700
|
+
eq_(self.table[2][2], 'awkward')
|
|
701
|
+
|
|
702
|
+
@raises(KeyError)
|
|
703
|
+
def test_table_row_keyerror(self):
|
|
704
|
+
self.table[0]['spam'] # pylint: disable=pointless-statement
|
|
705
|
+
|
|
706
|
+
def test_table_row_items(self):
|
|
707
|
+
eq_(list(self.table[0].items()), list(zip(self.HEAD, self.DATA[0])))
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
class TestModelRow(unittest.TestCase):
|
|
711
|
+
# pylint: disable=invalid-name, bad-whitespace
|
|
712
|
+
HEAD = [u'name', u'sex', u'age']
|
|
713
|
+
DATA = [u'Alice', u'female', u'12']
|
|
714
|
+
|
|
715
|
+
def setUp(self):
|
|
716
|
+
self.row = Row(self.HEAD, self.DATA, 0)
|
|
717
|
+
|
|
718
|
+
def test_len(self):
|
|
719
|
+
eq_(len(self.row), 3)
|
|
720
|
+
|
|
721
|
+
def test_getitem_with_valid_colname(self):
|
|
722
|
+
# pylint: disable=bad-whitespace
|
|
723
|
+
eq_(self.row['name'], u'Alice')
|
|
724
|
+
eq_(self.row['sex'], u'female')
|
|
725
|
+
eq_(self.row['age'], u'12')
|
|
726
|
+
|
|
727
|
+
@raises(KeyError)
|
|
728
|
+
def test_getitem_with_unknown_colname(self):
|
|
729
|
+
self.row['__UNKNOWN_COLUMN__'] # pylint: disable=pointless-statement
|
|
730
|
+
|
|
731
|
+
def test_getitem_with_valid_index(self):
|
|
732
|
+
eq_(self.row[0], u'Alice')
|
|
733
|
+
eq_(self.row[1], u'female')
|
|
734
|
+
eq_(self.row[2], u'12')
|
|
735
|
+
|
|
736
|
+
@raises(IndexError)
|
|
737
|
+
def test_getitem_with_invalid_index(self):
|
|
738
|
+
colsize = len(self.row)
|
|
739
|
+
eq_(colsize, 3)
|
|
740
|
+
self.row[colsize] # pylint: disable=pointless-statement
|
|
741
|
+
|
|
742
|
+
def test_get_with_valid_colname(self):
|
|
743
|
+
# pylint: disable=bad-whitespace
|
|
744
|
+
eq_(self.row.get('name'), u'Alice')
|
|
745
|
+
eq_(self.row.get('sex'), u'female')
|
|
746
|
+
eq_(self.row.get('age'), u'12')
|
|
747
|
+
|
|
748
|
+
def test_getitem_with_unknown_colname_should_return_default(self):
|
|
749
|
+
eq_(self.row.get('__UNKNOWN_COLUMN__', 'XXX'), u'XXX')
|
|
750
|
+
|
|
751
|
+
def test_as_dict(self):
|
|
752
|
+
data1 = self.row.as_dict()
|
|
753
|
+
data2 = dict(self.row.as_dict())
|
|
754
|
+
assert isinstance(data1, dict)
|
|
755
|
+
assert isinstance(data2, dict)
|
|
756
|
+
assert isinstance(data1, OrderedDict)
|
|
757
|
+
# -- REQUIRES: Python2.7 or ordereddict installed.
|
|
758
|
+
# assert not isinstance(data2, OrderedDict)
|
|
759
|
+
eq_(data1, data2)
|
|
760
|
+
# pylint: disable=bad-whitespace
|
|
761
|
+
eq_(data1['name'], u'Alice')
|
|
762
|
+
eq_(data1['sex'], u'female')
|
|
763
|
+
eq_(data1['age'], u'12')
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
class TestFileLocation(unittest.TestCase):
|
|
767
|
+
# pylint: disable=invalid-name
|
|
768
|
+
ordered_locations1 = [
|
|
769
|
+
FileLocation("features/alice.feature", 1),
|
|
770
|
+
FileLocation("features/alice.feature", 5),
|
|
771
|
+
FileLocation("features/alice.feature", 10),
|
|
772
|
+
FileLocation("features/alice.feature", 11),
|
|
773
|
+
FileLocation("features/alice.feature", 100),
|
|
774
|
+
]
|
|
775
|
+
ordered_locations2 = [
|
|
776
|
+
FileLocation("features/alice.feature", 1),
|
|
777
|
+
FileLocation("features/alice.feature", 10),
|
|
778
|
+
FileLocation("features/bob.feature", 5),
|
|
779
|
+
FileLocation("features/charly.feature", None),
|
|
780
|
+
FileLocation("features/charly.feature", 0),
|
|
781
|
+
FileLocation("features/charly.feature", 100),
|
|
782
|
+
]
|
|
783
|
+
same_locations = [
|
|
784
|
+
(FileLocation("alice.feature"),
|
|
785
|
+
FileLocation("alice.feature", None),
|
|
786
|
+
),
|
|
787
|
+
(FileLocation("alice.feature", 10),
|
|
788
|
+
FileLocation("alice.feature", 10),
|
|
789
|
+
),
|
|
790
|
+
(FileLocation("features/bob.feature", 11),
|
|
791
|
+
FileLocation("features/bob.feature", 11),
|
|
792
|
+
),
|
|
793
|
+
]
|
|
794
|
+
|
|
795
|
+
def test_compare_equal(self):
|
|
796
|
+
for value1, value2 in self.same_locations:
|
|
797
|
+
eq_(value1, value2)
|
|
798
|
+
|
|
799
|
+
def test_compare_equal_with_string(self):
|
|
800
|
+
for location in self.ordered_locations2:
|
|
801
|
+
eq_(location, location.filename)
|
|
802
|
+
eq_(location.filename, location)
|
|
803
|
+
|
|
804
|
+
def test_compare_not_equal(self):
|
|
805
|
+
for value1, value2 in self.same_locations:
|
|
806
|
+
assert not(value1 != value2) # pylint: disable=unneeded-not, superfluous-parens
|
|
807
|
+
|
|
808
|
+
for locations in [self.ordered_locations1, self.ordered_locations2]:
|
|
809
|
+
for value1, value2 in zip(locations, locations[1:]):
|
|
810
|
+
assert value1 != value2
|
|
811
|
+
|
|
812
|
+
def test_compare_less_than(self):
|
|
813
|
+
for locations in [self.ordered_locations1, self.ordered_locations2]:
|
|
814
|
+
for value1, value2 in zip(locations, locations[1:]):
|
|
815
|
+
assert value1 < value2, "FAILED: %s < %s" % (_text(value1), _text(value2))
|
|
816
|
+
assert value1 != value2
|
|
817
|
+
|
|
818
|
+
def test_compare_less_than_with_string(self):
|
|
819
|
+
locations = self.ordered_locations2
|
|
820
|
+
for value1, value2 in zip(locations, locations[1:]):
|
|
821
|
+
if value1.filename == value2.filename:
|
|
822
|
+
continue
|
|
823
|
+
assert value1 < value2.filename, \
|
|
824
|
+
"FAILED: %s < %s" % (_text(value1), _text(value2.filename))
|
|
825
|
+
assert value1.filename < value2, \
|
|
826
|
+
"FAILED: %s < %s" % (_text(value1.filename), _text(value2))
|
|
827
|
+
|
|
828
|
+
def test_compare_greater_than(self):
|
|
829
|
+
for locations in [self.ordered_locations1, self.ordered_locations2]:
|
|
830
|
+
for value1, value2 in zip(locations, locations[1:]):
|
|
831
|
+
assert value2 > value1, "FAILED: %s > %s" % (_text(value2), _text(value1))
|
|
832
|
+
assert value2 != value1
|
|
833
|
+
|
|
834
|
+
def test_compare_less_or_equal(self):
|
|
835
|
+
for value1, value2 in self.same_locations:
|
|
836
|
+
assert value1 <= value2, "FAILED: %s <= %s" % (_text(value1), _text(value2))
|
|
837
|
+
assert value1 == value2
|
|
838
|
+
|
|
839
|
+
for locations in [self.ordered_locations1, self.ordered_locations2]:
|
|
840
|
+
for value1, value2 in zip(locations, locations[1:]):
|
|
841
|
+
assert value1 <= value2, "FAILED: %s <= %s" % (_text(value1), _text(value2))
|
|
842
|
+
assert value1 != value2
|
|
843
|
+
|
|
844
|
+
def test_compare_greater_or_equal(self):
|
|
845
|
+
for value1, value2 in self.same_locations:
|
|
846
|
+
assert value2 >= value1, "FAILED: %s >= %s" % (_text(value2), _text(value1))
|
|
847
|
+
assert value2 == value1
|
|
848
|
+
|
|
849
|
+
for locations in [self.ordered_locations1, self.ordered_locations2]:
|
|
850
|
+
for value1, value2 in zip(locations, locations[1:]):
|
|
851
|
+
assert value2 >= value1, "FAILED: %s >= %s" % (_text(value2), _text(value1))
|
|
852
|
+
assert value2 != value1
|
|
853
|
+
|
|
854
|
+
def test_filename_should_be_same_as_self(self):
|
|
855
|
+
for location in self.ordered_locations2:
|
|
856
|
+
assert location == location.filename
|
|
857
|
+
assert location.filename == location
|
|
858
|
+
|
|
859
|
+
def test_string_conversion(self):
|
|
860
|
+
for location in self.ordered_locations2:
|
|
861
|
+
expected = u"%s:%s" % (location.filename, location.line)
|
|
862
|
+
if location.line is None:
|
|
863
|
+
expected = location.filename
|
|
864
|
+
assert six.text_type(location) == expected
|
|
865
|
+
|
|
866
|
+
def test_repr_conversion(self):
|
|
867
|
+
for location in self.ordered_locations2:
|
|
868
|
+
expected = u'<FileLocation: filename="%s", line=%s>' % \
|
|
869
|
+
(location.filename, location.line)
|
|
870
|
+
actual = repr(location)
|
|
871
|
+
assert actual == expected, "FAILED: %s == %s" % (actual, expected)
|