dwaite-cucumber 0.3.101
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.
- data/History.txt +1067 -0
- data/License.txt +22 -0
- data/Manifest.txt +453 -0
- data/README.txt +4 -0
- data/Rakefile +9 -0
- data/bin/cucumber +17 -0
- data/config/hoe.rb +78 -0
- data/config/requirements.rb +15 -0
- data/cucumber.yml +2 -0
- data/examples/cs/README.textile +1 -0
- data/examples/cs/Rakefile +12 -0
- data/examples/cs/compile.bat +1 -0
- data/examples/cs/features/addition.feature +16 -0
- data/examples/cs/features/step_definitons/calculator_steps.rb +19 -0
- data/examples/cs/src/demo/Calculator.cs +20 -0
- data/examples/dos_line_endings/Rakefile +6 -0
- data/examples/dos_line_endings/features/dos_line_endings.feature +9 -0
- data/examples/i18n/README.textile +18 -0
- data/examples/i18n/Rakefile +32 -0
- data/examples/i18n/ar/Rakefile +6 -0
- data/examples/i18n/ar/features/addition.feature +17 -0
- data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/ar/lib/calculator.rb +11 -0
- data/examples/i18n/bg/Rakefile +6 -0
- data/examples/i18n/bg/features/addition.feature +12 -0
- data/examples/i18n/bg/features/consecutive_calculations.feature +19 -0
- data/examples/i18n/bg/features/division.feature +17 -0
- data/examples/i18n/bg/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/bg/features/support/env.rb +6 -0
- data/examples/i18n/bg/features/support/world.rb +8 -0
- data/examples/i18n/bg/lib/calculator.rb +24 -0
- data/examples/i18n/cat/Rakefile +6 -0
- data/examples/i18n/cat/features/step_definitons/calculator_steps.rb +21 -0
- data/examples/i18n/cat/features/suma.feature +17 -0
- data/examples/i18n/cat/lib/calculadora.rb +16 -0
- data/examples/i18n/da/Rakefile +6 -0
- data/examples/i18n/da/features/step_definitons/kalkulator_steps.rb +24 -0
- data/examples/i18n/da/features/summering.feature +18 -0
- data/examples/i18n/da/lib/kalkulator.rb +11 -0
- data/examples/i18n/de/Rakefile +6 -0
- data/examples/i18n/de/features/addition.feature +17 -0
- data/examples/i18n/de/features/division.feature +10 -0
- data/examples/i18n/de/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/de/lib/calculator.rb +14 -0
- data/examples/i18n/en/Rakefile +6 -0
- data/examples/i18n/en/features/addition.feature +17 -0
- data/examples/i18n/en/features/division.feature +10 -0
- data/examples/i18n/en/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/en/lib/calculator.rb +14 -0
- data/examples/i18n/en-lol/Rakefile +6 -0
- data/examples/i18n/en-lol/features/step_definitions/cucumbrz_steps.rb +16 -0
- data/examples/i18n/en-lol/features/stuffing.feature +8 -0
- data/examples/i18n/en-lol/features/support/env.rb +8 -0
- data/examples/i18n/en-lol/lib/basket.rb +12 -0
- data/examples/i18n/en-lol/lib/belly.rb +11 -0
- data/examples/i18n/es/Rakefile +6 -0
- data/examples/i18n/es/features/adicion.feature +17 -0
- data/examples/i18n/es/features/step_definitons/calculador_steps.rb +21 -0
- data/examples/i18n/es/lib/calculador.rb +14 -0
- data/examples/i18n/et/Rakefile +6 -0
- data/examples/i18n/et/features/jagamine.feature +10 -0
- data/examples/i18n/et/features/liitmine.feature +17 -0
- data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +24 -0
- data/examples/i18n/et/lib/kalkulaator.rb +14 -0
- data/examples/i18n/fi/Rakefile +6 -0
- data/examples/i18n/fi/features/jakolasku.feature +10 -0
- data/examples/i18n/fi/features/step_definitons/laskin_steps.rb +24 -0
- data/examples/i18n/fi/features/yhteenlasku.feature +17 -0
- data/examples/i18n/fi/lib/laskin.rb +14 -0
- data/examples/i18n/fr/Rakefile +6 -0
- data/examples/i18n/fr/features/addition.feature +18 -0
- data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +25 -0
- data/examples/i18n/fr/lib/calculatrice.rb +10 -0
- data/examples/i18n/he/Rakefile +6 -0
- data/examples/i18n/he/features/addition.feature +17 -0
- data/examples/i18n/he/features/division.feature +10 -0
- data/examples/i18n/he/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/he/lib/calculator.rb +14 -0
- data/examples/i18n/hu/Rakefile +6 -0
- data/examples/i18n/hu/features/addition.feature +17 -0
- data/examples/i18n/hu/features/division.feature +10 -0
- data/examples/i18n/hu/features/step_definitons/calculator_steps.rb +25 -0
- data/examples/i18n/hu/lib/calculator.rb +14 -0
- data/examples/i18n/id/Rakefile +6 -0
- data/examples/i18n/id/features/addition.feature +17 -0
- data/examples/i18n/id/features/division.feature +10 -0
- data/examples/i18n/id/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/id/lib/calculator.rb +14 -0
- data/examples/i18n/it/Rakefile +6 -0
- data/examples/i18n/it/features/somma.feature +11 -0
- data/examples/i18n/it/features/step_definitons/calcolatrice_steps.rb +24 -0
- data/examples/i18n/it/lib/calcolatrice.rb +11 -0
- data/examples/i18n/ja/Rakefile +6 -0
- data/examples/i18n/ja/features/addition.feature +17 -0
- data/examples/i18n/ja/features/division.feature +10 -0
- data/examples/i18n/ja/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/ja/lib/calculator.rb +14 -0
- data/examples/i18n/ko/Rakefile +6 -0
- data/examples/i18n/ko/features/addition.feature +17 -0
- data/examples/i18n/ko/features/division.feature +11 -0
- data/examples/i18n/ko/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/ko/lib/calculator.rb +14 -0
- data/examples/i18n/lt/Rakefile +6 -0
- data/examples/i18n/lt/features/addition.feature +17 -0
- data/examples/i18n/lt/features/division.feature +10 -0
- data/examples/i18n/lt/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/lt/lib/calculator.rb +14 -0
- data/examples/i18n/lv/Rakefile +6 -0
- data/examples/i18n/lv/features/addition.feature +17 -0
- data/examples/i18n/lv/features/division.feature +10 -0
- data/examples/i18n/lv/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/lv/lib/calculator.rb +14 -0
- data/examples/i18n/no/Rakefile +6 -0
- data/examples/i18n/no/features/step_definitons/kalkulator_steps.rb +17 -0
- data/examples/i18n/no/features/summering.feature +19 -0
- data/examples/i18n/no/features/support/env.rb +6 -0
- data/examples/i18n/no/lib/kalkulator.rb +11 -0
- data/examples/i18n/pl/Rakefile +6 -0
- data/examples/i18n/pl/features/addition.feature +17 -0
- data/examples/i18n/pl/features/division.feature +10 -0
- data/examples/i18n/pl/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/pl/features/support/env.rb +6 -0
- data/examples/i18n/pl/lib/calculator.rb +14 -0
- data/examples/i18n/pt/Rakefile +6 -0
- data/examples/i18n/pt/features/adicao.feature +11 -0
- data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +20 -0
- data/examples/i18n/pt/features/support/env.rb +6 -0
- data/examples/i18n/pt/lib/calculadora.rb +10 -0
- data/examples/i18n/ro/Rakefile +6 -0
- data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/ro/features/suma.feature +11 -0
- data/examples/i18n/ro/lib/calculator.rb +11 -0
- data/examples/i18n/ru/Rakefile +6 -0
- data/examples/i18n/ru/features/addition.feature +11 -0
- data/examples/i18n/ru/features/consecutive_calculations.feature +17 -0
- data/examples/i18n/ru/features/division.feature +16 -0
- data/examples/i18n/ru/features/step_definitons/calculator_steps.rb +19 -0
- data/examples/i18n/ru/features/support/env.rb +6 -0
- data/examples/i18n/ru/features/support/world.rb +8 -0
- data/examples/i18n/ru/lib/calculator.rb +24 -0
- data/examples/i18n/se/Rakefile +6 -0
- data/examples/i18n/se/features/step_definitons/kalkulator_steps.rb +24 -0
- data/examples/i18n/se/features/summering.feature +18 -0
- data/examples/i18n/se/lib/kalkulator.rb +11 -0
- data/examples/i18n/sk/Rakefile +6 -0
- data/examples/i18n/sk/features/addition.feature +17 -0
- data/examples/i18n/sk/features/division.feature +10 -0
- data/examples/i18n/sk/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/sk/lib/calculator.rb +14 -0
- data/examples/i18n/uz/Rakefile +6 -0
- data/examples/i18n/uz/features/addition.feature +10 -0
- data/examples/i18n/uz/features/consecutive_calculations.feature +17 -0
- data/examples/i18n/uz/features/division.feature +17 -0
- data/examples/i18n/uz/features/step_definitons/calculator_steps.rb +19 -0
- data/examples/i18n/uz/features/support/env.rb +6 -0
- data/examples/i18n/uz/features/support/world.rb +8 -0
- data/examples/i18n/uz/lib/calculator.rb +24 -0
- data/examples/i18n/zh-CN/Rakefile +6 -0
- data/examples/i18n/zh-CN/features/addition.feature +18 -0
- data/examples/i18n/zh-CN/features/step_definitons/calculator_steps.rb +26 -0
- data/examples/i18n/zh-CN/lib/calculator.rb +10 -0
- data/examples/i18n/zh-TW/Rakefile +6 -0
- data/examples/i18n/zh-TW/features/addition.feature +17 -0
- data/examples/i18n/zh-TW/features/division.feature +11 -0
- data/examples/i18n/zh-TW/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/zh-TW/lib/calculator.rb +14 -0
- data/examples/java/README.textile +18 -0
- data/examples/java/build.xml +33 -0
- data/examples/java/features/hello.feature +11 -0
- data/examples/java/features/step_definitons/hello_steps.rb +23 -0
- data/examples/java/features/step_definitons/tree_steps.rb +14 -0
- data/examples/java/features/tree.feature +9 -0
- data/examples/java/src/cucumber/demo/Hello.java +16 -0
- data/examples/junit/features/one_passing_one_failing.feature +8 -0
- data/examples/junit/features/pending.feature +5 -0
- data/examples/junit/features/step_definitions/steps.rb +11 -0
- data/examples/pure_java/README.textile +5 -0
- data/examples/python/features/fibonacci.feature +19 -0
- data/examples/python/features/step_definitions/fib_steps.py +3 -0
- data/examples/python/features/step_definitions/fib_steps.rb +7 -0
- data/examples/python/features/support/env.rb +21 -0
- data/examples/python/lib/fib.py +7 -0
- data/examples/selenium/Rakefile +6 -0
- data/examples/selenium/features/search.feature +9 -0
- data/examples/selenium/features/step_definitons/search_steps.rb +13 -0
- data/examples/selenium/features/support/env.rb +19 -0
- data/examples/selenium_webrat/Rakefile +6 -0
- data/examples/selenium_webrat/config.ru +0 -0
- data/examples/selenium_webrat/features/search.feature +9 -0
- data/examples/selenium_webrat/features/step_definitons/search_steps.rb +13 -0
- data/examples/selenium_webrat/features/support/env.rb +45 -0
- data/examples/self_test/README.textile +6 -0
- data/examples/self_test/Rakefile +6 -0
- data/examples/self_test/features/background/background_tagged_before_on_outline.feature +12 -0
- data/examples/self_test/features/background/background_with_name.feature +7 -0
- data/examples/self_test/features/background/failing_background.feature +12 -0
- data/examples/self_test/features/background/failing_background_after_success.feature +11 -0
- data/examples/self_test/features/background/multiline_args_background.feature +32 -0
- data/examples/self_test/features/background/passing_background.feature +10 -0
- data/examples/self_test/features/background/pending_background.feature +10 -0
- data/examples/self_test/features/background/scenario_outline_failing_background.feature +16 -0
- data/examples/self_test/features/background/scenario_outline_passing_background.feature +16 -0
- data/examples/self_test/features/call_undefined_step_from_step_def.feature +7 -0
- data/examples/self_test/features/failing_expectation.feature +4 -0
- data/examples/self_test/features/lots_of_undefined.feature +8 -0
- data/examples/self_test/features/multiline_name.feature +27 -0
- data/examples/self_test/features/outline_sample.feature +15 -0
- data/examples/self_test/features/sample.feature +21 -0
- data/examples/self_test/features/search_sample.feature +32 -0
- data/examples/self_test/features/step_definitions/sample_steps.rb +93 -0
- data/examples/self_test/features/support/env.rb +24 -0
- data/examples/self_test/features/tags_sample.feature +17 -0
- data/examples/self_test/features/tons_of_cukes.feature +52 -0
- data/examples/self_test/features/transform_sample.feature +10 -0
- data/examples/self_test/features/undefined_multiline_args.feature +12 -0
- data/examples/self_test/list-of-features.txt +1 -0
- data/examples/sinatra/README.textile +13 -0
- data/examples/sinatra/Rakefile +6 -0
- data/examples/sinatra/app.rb +14 -0
- data/examples/sinatra/features/add.feature +11 -0
- data/examples/sinatra/features/step_definitions/add_steps.rb +15 -0
- data/examples/sinatra/features/support/env.rb +32 -0
- data/examples/sinatra/views/add.erb +5 -0
- data/examples/sinatra/views/layout.erb +8 -0
- data/examples/steps_library/features/step_definitions/steps_lib1.rb +8 -0
- data/examples/steps_library/features/step_definitions/steps_lib2.rb +8 -0
- data/examples/test_unit/Rakefile +6 -0
- data/examples/test_unit/features/step_definitions/test_unit_steps.rb +23 -0
- data/examples/test_unit/features/test_unit.feature +9 -0
- data/examples/tickets/Rakefile +16 -0
- data/examples/tickets/features/172.feature +28 -0
- data/examples/tickets/features/177/1.feature +29 -0
- data/examples/tickets/features/177/2.feature +21 -0
- data/examples/tickets/features/177/3.feature +18 -0
- data/examples/tickets/features/180.feature +7 -0
- data/examples/tickets/features/229/tagged_hooks.feature +8 -0
- data/examples/tickets/features/229/tagged_hooks.rb +14 -0
- data/examples/tickets/features/236.feature +13 -0
- data/examples/tickets/features/241.feature +13 -0
- data/examples/tickets/features/246.feature +4 -0
- data/examples/tickets/features/248.feature +11 -0
- data/examples/tickets/features/270/back.feature +14 -0
- data/examples/tickets/features/270/back.steps.rb +14 -0
- data/examples/tickets/features/272/hooks.feature +26 -0
- data/examples/tickets/features/272/hooks_steps.rb +53 -0
- data/examples/tickets/features/279/py_string_indent.feature +25 -0
- data/examples/tickets/features/279/py_string_indent.steps.rb +12 -0
- data/examples/tickets/features/279/wrong.feature_ +11 -0
- data/examples/tickets/features/301/filter_background_tagged_hooks.feature +6 -0
- data/examples/tickets/features/301/filter_background_tagged_hooks_steps.rb +12 -0
- data/examples/tickets/features/306/only_background.feature +4 -0
- data/examples/tickets/features/lib/eatting_machine.rb +18 -0
- data/examples/tickets/features/lib/pantry.rb +20 -0
- data/examples/tickets/features/scenario_outline.feature +95 -0
- data/examples/tickets/features/step_definitons/246_steps.rb +3 -0
- data/examples/tickets/features/step_definitons/248_steps.rb +15 -0
- data/examples/tickets/features/step_definitons/scenario_outline_steps.rb +42 -0
- data/examples/tickets/features/step_definitons/tickets_steps.rb +81 -0
- data/examples/tickets/features/table_diffing.feature +13 -0
- data/examples/tickets/features/tickets.feature +28 -0
- data/examples/watir/README.textile +16 -0
- data/examples/watir/Rakefile +6 -0
- data/examples/watir/features/search.feature +12 -0
- data/examples/watir/features/step_definitons/search_steps.rb +26 -0
- data/examples/watir/features/support/env.rb +32 -0
- data/features/background.feature +311 -0
- data/features/bug_371.feature +32 -0
- data/features/cucumber_cli.feature +667 -0
- data/features/cucumber_cli_diff_disabled.feature +54 -0
- data/features/cucumber_cli_outlines.feature +109 -0
- data/features/custom_formatter.feature +11 -0
- data/features/drb_server_integration.feature +173 -0
- data/features/exception_in_after_block.feature +102 -0
- data/features/exception_in_after_step_block.feature +104 -0
- data/features/exception_in_before_block.feature +47 -0
- data/features/exclude_files.feature +20 -0
- data/features/expand.feature +49 -0
- data/features/html_formatter/a.html +183 -0
- data/features/html_formatter.feature +7 -0
- data/features/junit_formatter.feature +89 -0
- data/features/language_from_header.feature +30 -0
- data/features/multiline_names.feature +43 -0
- data/features/post_configuration_hook.feature +37 -0
- data/features/profiles.feature +112 -0
- data/features/rake_task.feature +178 -0
- data/features/report_called_undefined_steps.feature +35 -0
- data/features/snippet.feature +22 -0
- data/features/step_definitions/cucumber_steps.rb +154 -0
- data/features/step_definitions/extra_steps.rb +2 -0
- data/features/steps_formatter.feature +25 -0
- data/features/support/env.rb +139 -0
- data/features/table_diffing.feature +45 -0
- data/features/transform.feature +24 -0
- data/features/unicode_table.feature +35 -0
- data/features/usage.feature +132 -0
- data/features/work_in_progress.feature +158 -0
- data/gem_tasks/contributors.rake +12 -0
- data/gem_tasks/deployment.rake +11 -0
- data/gem_tasks/environment.rake +7 -0
- data/gem_tasks/features.rake +11 -0
- data/gem_tasks/fix_cr_lf.rake +10 -0
- data/gem_tasks/flog.rake +4 -0
- data/gem_tasks/gemspec.rake +10 -0
- data/gem_tasks/rspec.rake +45 -0
- data/gem_tasks/sass.rake +4 -0
- data/gem_tasks/sdoc.rake +7 -0
- data/lib/README.rdoc +12 -0
- data/lib/autotest/cucumber.rb +6 -0
- data/lib/autotest/cucumber_mixin.rb +125 -0
- data/lib/autotest/cucumber_rails.rb +6 -0
- data/lib/autotest/cucumber_rails_rspec.rb +6 -0
- data/lib/autotest/cucumber_rspec.rb +6 -0
- data/lib/autotest/discover.rb +9 -0
- data/lib/cucumber/ast/background.rb +63 -0
- data/lib/cucumber/ast/comment.rb +31 -0
- data/lib/cucumber/ast/examples.rb +32 -0
- data/lib/cucumber/ast/feature.rb +81 -0
- data/lib/cucumber/ast/feature_element.rb +61 -0
- data/lib/cucumber/ast/features.rb +40 -0
- data/lib/cucumber/ast/outline_table.rb +146 -0
- data/lib/cucumber/ast/py_string.rb +57 -0
- data/lib/cucumber/ast/scenario.rb +108 -0
- data/lib/cucumber/ast/scenario_outline.rb +96 -0
- data/lib/cucumber/ast/step.rb +116 -0
- data/lib/cucumber/ast/step_collection.rb +76 -0
- data/lib/cucumber/ast/step_invocation.rb +166 -0
- data/lib/cucumber/ast/table.rb +626 -0
- data/lib/cucumber/ast/tags.rb +44 -0
- data/lib/cucumber/ast/visitor.rb +115 -0
- data/lib/cucumber/ast.rb +29 -0
- data/lib/cucumber/broadcaster.rb +13 -0
- data/lib/cucumber/cli/configuration.rb +190 -0
- data/lib/cucumber/cli/drb_client.rb +26 -0
- data/lib/cucumber/cli/language_help_formatter.rb +61 -0
- data/lib/cucumber/cli/main.rb +116 -0
- data/lib/cucumber/cli/options.rb +394 -0
- data/lib/cucumber/cli/profile_loader.rb +70 -0
- data/lib/cucumber/constantize.rb +28 -0
- data/lib/cucumber/core_ext/instance_exec.rb +93 -0
- data/lib/cucumber/core_ext/proc.rb +29 -0
- data/lib/cucumber/core_ext/string.rb +48 -0
- data/lib/cucumber/feature_file.rb +54 -0
- data/lib/cucumber/filter.rb +52 -0
- data/lib/cucumber/formatter/ansicolor.rb +143 -0
- data/lib/cucumber/formatter/color_io.rb +23 -0
- data/lib/cucumber/formatter/console.rb +185 -0
- data/lib/cucumber/formatter/cucumber.css +132 -0
- data/lib/cucumber/formatter/cucumber.sass +139 -0
- data/lib/cucumber/formatter/duration.rb +13 -0
- data/lib/cucumber/formatter/html.rb +261 -0
- data/lib/cucumber/formatter/junit.rb +121 -0
- data/lib/cucumber/formatter/ordered_xml_markup.rb +24 -0
- data/lib/cucumber/formatter/pdf.rb +217 -0
- data/lib/cucumber/formatter/pretty.rb +222 -0
- data/lib/cucumber/formatter/profile.rb +78 -0
- data/lib/cucumber/formatter/progress.rb +67 -0
- data/lib/cucumber/formatter/rerun.rb +46 -0
- data/lib/cucumber/formatter/steps.rb +50 -0
- data/lib/cucumber/formatter/tag_cloud.rb +29 -0
- data/lib/cucumber/formatter/unicode.rb +35 -0
- data/lib/cucumber/formatter/usage.rb +86 -0
- data/lib/cucumber/formatters/unicode.rb +7 -0
- data/lib/cucumber/language_support/language_methods.rb +75 -0
- data/lib/cucumber/language_support/step_definition_methods.rb +46 -0
- data/lib/cucumber/language_support.rb +30 -0
- data/lib/cucumber/languages.yml +561 -0
- data/lib/cucumber/parser/feature.rb +1838 -0
- data/lib/cucumber/parser/feature.tt +351 -0
- data/lib/cucumber/parser/i18n.tt +42 -0
- data/lib/cucumber/parser/natural_language.rb +72 -0
- data/lib/cucumber/parser/table.rb +417 -0
- data/lib/cucumber/parser/table.tt +71 -0
- data/lib/cucumber/parser/treetop_ext.rb +53 -0
- data/lib/cucumber/parser.rb +6 -0
- data/lib/cucumber/platform.rb +27 -0
- data/lib/cucumber/py_support/py_dsl.py +8 -0
- data/lib/cucumber/py_support/py_language.py +2 -0
- data/lib/cucumber/py_support/py_language.rb +68 -0
- data/lib/cucumber/rails/rspec.rb +10 -0
- data/lib/cucumber/rails/world.rb +100 -0
- data/lib/cucumber/rake/task.rb +241 -0
- data/lib/cucumber/rb_support/rb_dsl.rb +100 -0
- data/lib/cucumber/rb_support/rb_hook.rb +18 -0
- data/lib/cucumber/rb_support/rb_language.rb +153 -0
- data/lib/cucumber/rb_support/rb_step_definition.rb +60 -0
- data/lib/cucumber/rb_support/rb_world.rb +93 -0
- data/lib/cucumber/rspec_neuter.rb +23 -0
- data/lib/cucumber/step_match.rb +61 -0
- data/lib/cucumber/step_mother.rb +307 -0
- data/lib/cucumber/version.rb +10 -0
- data/lib/cucumber/webrat/element_locator.rb +87 -0
- data/lib/cucumber/webrat/table_locator.rb +1 -0
- data/lib/cucumber.rb +10 -0
- data/rails_generators/cucumber/USAGE +11 -0
- data/rails_generators/cucumber/cucumber_generator.rb +70 -0
- data/rails_generators/cucumber/templates/cucumber +9 -0
- data/rails_generators/cucumber/templates/cucumber.rake +36 -0
- data/rails_generators/cucumber/templates/cucumber_environment.rb +26 -0
- data/rails_generators/cucumber/templates/env.rb +27 -0
- data/rails_generators/cucumber/templates/paths.rb +27 -0
- data/rails_generators/cucumber/templates/spork_env.rb +35 -0
- data/rails_generators/cucumber/templates/webrat_steps.rb +236 -0
- data/rails_generators/feature/USAGE +12 -0
- data/rails_generators/feature/feature_generator.rb +40 -0
- data/rails_generators/feature/templates/feature.erb +31 -0
- data/rails_generators/feature/templates/steps.erb +14 -0
- data/spec/cucumber/ast/background_spec.rb +60 -0
- data/spec/cucumber/ast/feature_element_spec.rb +40 -0
- data/spec/cucumber/ast/feature_factory.rb +62 -0
- data/spec/cucumber/ast/feature_spec.rb +44 -0
- data/spec/cucumber/ast/py_string_spec.rb +51 -0
- data/spec/cucumber/ast/scenario_outline_spec.rb +72 -0
- data/spec/cucumber/ast/scenario_spec.rb +43 -0
- data/spec/cucumber/ast/step_collection_spec.rb +17 -0
- data/spec/cucumber/ast/step_spec.rb +66 -0
- data/spec/cucumber/ast/table_spec.rb +394 -0
- data/spec/cucumber/broadcaster_spec.rb +15 -0
- data/spec/cucumber/cli/configuration_spec.rb +396 -0
- data/spec/cucumber/cli/drb_client_spec.rb +77 -0
- data/spec/cucumber/cli/main_spec.rb +172 -0
- data/spec/cucumber/cli/options_spec.rb +331 -0
- data/spec/cucumber/cli/profile_loader_spec.rb +10 -0
- data/spec/cucumber/core_ext/proc_spec.rb +68 -0
- data/spec/cucumber/core_ext/string_spec.rb +43 -0
- data/spec/cucumber/formatter/ansicolor_spec.rb +31 -0
- data/spec/cucumber/formatter/color_io_spec.rb +27 -0
- data/spec/cucumber/formatter/duration_spec.rb +22 -0
- data/spec/cucumber/formatter/html_spec.rb +18 -0
- data/spec/cucumber/formatter/progress_spec.rb +33 -0
- data/spec/cucumber/parser/feature_parser_spec.rb +396 -0
- data/spec/cucumber/parser/table_parser_spec.rb +52 -0
- data/spec/cucumber/rails/stubs/mini_rails.rb +18 -0
- data/spec/cucumber/rails/stubs/test_help.rb +1 -0
- data/spec/cucumber/rails/world_spec.rb +16 -0
- data/spec/cucumber/rb_support/rb_step_definition_spec.rb +123 -0
- data/spec/cucumber/sell_cucumbers.feature +19 -0
- data/spec/cucumber/step_mother_spec.rb +282 -0
- data/spec/cucumber/treetop_parser/empty_feature.feature +4 -0
- data/spec/cucumber/treetop_parser/empty_scenario.feature +9 -0
- data/spec/cucumber/treetop_parser/empty_scenario_outline.feature +3 -0
- data/spec/cucumber/treetop_parser/fit_scenario.feature +8 -0
- data/spec/cucumber/treetop_parser/given_scenario.feature +9 -0
- data/spec/cucumber/treetop_parser/invalid_scenario_outlines.feature +7 -0
- data/spec/cucumber/treetop_parser/multiline_steps.feature +17 -0
- data/spec/cucumber/treetop_parser/multiple_tables.feature +27 -0
- data/spec/cucumber/treetop_parser/scenario_outline.feature +16 -0
- data/spec/cucumber/treetop_parser/spaces.feature +12 -0
- data/spec/cucumber/treetop_parser/test_dos.feature +25 -0
- data/spec/cucumber/treetop_parser/with_comments.feature +23 -0
- data/spec/cucumber/treetop_parser/with_tags.feature +18 -0
- data/spec/cucumber/world/pending_spec.rb +46 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +18 -0
- metadata +561 -0
@@ -0,0 +1,626 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Ast
|
3
|
+
# Step Definitions that match a plain text Step with a multiline argument table
|
4
|
+
# will receive it as an instance of Table. A Table object holds the data of a
|
5
|
+
# table parsed from a feature file and lets you access and manipulate the data
|
6
|
+
# in different ways.
|
7
|
+
#
|
8
|
+
# For example:
|
9
|
+
#
|
10
|
+
# Given I have:
|
11
|
+
# | a | b |
|
12
|
+
# | c | d |
|
13
|
+
#
|
14
|
+
# And a matching StepDefinition:
|
15
|
+
#
|
16
|
+
# Given /I have:/ do |table|
|
17
|
+
# data = table.raw
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# This will store <tt>[['a', 'b'], ['c', 'd']]</tt> in the <tt>data</tt> variable.
|
21
|
+
#
|
22
|
+
class Table
|
23
|
+
include Enumerable
|
24
|
+
|
25
|
+
NULL_CONVERSIONS = Hash.new(lambda{ |cell_value| cell_value }).freeze
|
26
|
+
|
27
|
+
attr_accessor :file
|
28
|
+
|
29
|
+
def self.default_arg_name #:nodoc:
|
30
|
+
"table"
|
31
|
+
end
|
32
|
+
|
33
|
+
# Creates a new instance. +raw+ should be an Array of Array of String.
|
34
|
+
# You don't typically create your own Table objects - Cucumber will do
|
35
|
+
# it internally and pass them to your Step Definitions.
|
36
|
+
#
|
37
|
+
def initialize(raw, conversion_procs = NULL_CONVERSIONS.dup)
|
38
|
+
@cells_class = Cells
|
39
|
+
@cell_class = Cell
|
40
|
+
|
41
|
+
# Verify that it's square
|
42
|
+
transposed = raw.transpose
|
43
|
+
create_cell_matrix(raw)
|
44
|
+
@conversion_procs = conversion_procs
|
45
|
+
end
|
46
|
+
|
47
|
+
# Creates a copy of this table, inheriting any column mappings.
|
48
|
+
# registered with #map_headers!
|
49
|
+
#
|
50
|
+
def dup
|
51
|
+
self.class.new(raw.dup, @conversion_procs.dup)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns a new, transposed table. Example:
|
55
|
+
#
|
56
|
+
# | a | 7 | 4 |
|
57
|
+
# | b | 9 | 2 |
|
58
|
+
#
|
59
|
+
# Gets converted into the following:
|
60
|
+
#
|
61
|
+
# | a | b |
|
62
|
+
# | 7 | 9 |
|
63
|
+
# | 4 | 2 |
|
64
|
+
#
|
65
|
+
def transpose
|
66
|
+
self.class.new(raw.transpose, @conversion_procs.dup)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Converts this table into an Array of Hash where the keys of each
|
70
|
+
# Hash are the headers in the table. For example, a Table built from
|
71
|
+
# the following plain text:
|
72
|
+
#
|
73
|
+
# | a | b | sum |
|
74
|
+
# | 2 | 3 | 5 |
|
75
|
+
# | 7 | 9 | 16 |
|
76
|
+
#
|
77
|
+
# Gets converted into the following:
|
78
|
+
#
|
79
|
+
# [{'a' => '2', 'b' => '3', 'sum' => '5'}, {'a' => '7', 'b' => '9', 'sum' => '16'}]
|
80
|
+
#
|
81
|
+
# Use #map_column! to specify how values in a column are converted.
|
82
|
+
#
|
83
|
+
def hashes
|
84
|
+
@hashes ||= cells_rows[1..-1].map do |row|
|
85
|
+
row.to_hash
|
86
|
+
end.freeze
|
87
|
+
end
|
88
|
+
|
89
|
+
# Converts this table into a Hash where the first column is
|
90
|
+
# used as keys and the second column is used as values
|
91
|
+
#
|
92
|
+
# | a | 2 |
|
93
|
+
# | b | 3 |
|
94
|
+
#
|
95
|
+
# Gets converted into the following:
|
96
|
+
#
|
97
|
+
# {'a' => '2', 'b' => '3'}
|
98
|
+
#
|
99
|
+
# The table must be exactly two columns wide
|
100
|
+
#
|
101
|
+
def rows_hash
|
102
|
+
return @rows_hash if @rows_hash
|
103
|
+
verify_table_width(2)
|
104
|
+
@rows_hash = self.transpose.hashes[0].freeze
|
105
|
+
end
|
106
|
+
|
107
|
+
# Gets the raw data of this table. For example, a Table built from
|
108
|
+
# the following plain text:
|
109
|
+
#
|
110
|
+
# | a | b |
|
111
|
+
# | c | d |
|
112
|
+
#
|
113
|
+
# gets converted into the following:
|
114
|
+
#
|
115
|
+
# [['a', 'b], ['c', 'd']]
|
116
|
+
#
|
117
|
+
def raw
|
118
|
+
cell_matrix.map do |row|
|
119
|
+
row.map do |cell|
|
120
|
+
cell.value
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Same as #raw, but skips the first (header) row
|
126
|
+
def rows
|
127
|
+
raw[1..-1]
|
128
|
+
end
|
129
|
+
|
130
|
+
def each_cells_row(&proc) #:nodoc:
|
131
|
+
cells_rows.each(&proc)
|
132
|
+
end
|
133
|
+
|
134
|
+
def accept(visitor) #:nodoc:
|
135
|
+
return if $cucumber_interrupted
|
136
|
+
cells_rows.each do |row|
|
137
|
+
visitor.visit_table_row(row)
|
138
|
+
end
|
139
|
+
nil
|
140
|
+
end
|
141
|
+
|
142
|
+
# For testing only
|
143
|
+
def to_sexp #:nodoc:
|
144
|
+
[:table, *cells_rows.map{|row| row.to_sexp}]
|
145
|
+
end
|
146
|
+
|
147
|
+
# Redefines the table headers. This makes it possible to use
|
148
|
+
# prettier and more flexible header names in the features. The
|
149
|
+
# keys of +mappings+ are Strings or regular expressions
|
150
|
+
# (anything that responds to #=== will work) that may match
|
151
|
+
# column headings in the table. The values of +mappings+ are
|
152
|
+
# desired names for the columns.
|
153
|
+
#
|
154
|
+
# Example:
|
155
|
+
#
|
156
|
+
# | Phone Number | Address |
|
157
|
+
# | 123456 | xyz |
|
158
|
+
# | 345678 | abc |
|
159
|
+
#
|
160
|
+
# A StepDefinition receiving this table can then map the columns
|
161
|
+
# with both Regexp and String:
|
162
|
+
#
|
163
|
+
# table.map_headers!(/phone( number)?/i => :phone, 'Address' => :address)
|
164
|
+
# table.hashes
|
165
|
+
# # => [{:phone => '123456', :address => 'xyz'}, {:phone => '345678', :address => 'abc'}]
|
166
|
+
#
|
167
|
+
# You may also pass in a block if you wish to convert all of the headers:
|
168
|
+
#
|
169
|
+
# table.map_headers! { |header| header.downcase }
|
170
|
+
# table.hashes.keys
|
171
|
+
# # => ['phone number', 'address']
|
172
|
+
#
|
173
|
+
# When a block is passed in along with a hash then the mappings in the hash take precendence:
|
174
|
+
#
|
175
|
+
# table.map_headers!('Address' => 'ADDRESS') { |header| header.downcase }
|
176
|
+
# table.hashes.keys
|
177
|
+
# # => ['phone number', 'ADDRESS']
|
178
|
+
#
|
179
|
+
def map_headers!(mappings={}, &block)
|
180
|
+
header_cells = cell_matrix[0]
|
181
|
+
|
182
|
+
if block_given?
|
183
|
+
header_values = header_cells.map { |cell| cell.value } - mappings.keys
|
184
|
+
mappings = mappings.merge(Hash[*header_values.zip(header_values.map(&block)).flatten])
|
185
|
+
end
|
186
|
+
|
187
|
+
mappings.each_pair do |pre, post|
|
188
|
+
mapped_cells = header_cells.select{|cell| pre === cell.value}
|
189
|
+
raise "No headers matched #{pre.inspect}" if mapped_cells.empty?
|
190
|
+
raise "#{mapped_cells.length} headers matched #{pre.inspect}: #{mapped_cells.map{|c| c.value}.inspect}" if mapped_cells.length > 1
|
191
|
+
mapped_cells[0].value = post
|
192
|
+
if @conversion_procs.has_key?(pre)
|
193
|
+
@conversion_procs[post] = @conversion_procs.delete(pre)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# Returns a new Table where the headers are redefined. See #map_headers!
|
199
|
+
def map_headers(mappings={})
|
200
|
+
table = self.dup
|
201
|
+
table.map_headers!(mappings)
|
202
|
+
table
|
203
|
+
end
|
204
|
+
|
205
|
+
# Change how #hashes converts column values. The +column_name+ argument identifies the column
|
206
|
+
# and +conversion_proc+ performs the conversion for each cell in that column. If +strict+ is
|
207
|
+
# true, an error will be raised if the column named +column_name+ is not found. If +strict+
|
208
|
+
# is false, no error will be raised. Example:
|
209
|
+
#
|
210
|
+
# Given /^an expense report for (.*) with the following posts:$/ do |table|
|
211
|
+
# posts_table.map_column!('amount') { |a| a.to_i }
|
212
|
+
# posts_table.hashes.each do |post|
|
213
|
+
# # post['amount'] is a Fixnum, rather than a String
|
214
|
+
# end
|
215
|
+
# end
|
216
|
+
#
|
217
|
+
def map_column!(column_name, strict=true, &conversion_proc)
|
218
|
+
verify_column(column_name) if strict
|
219
|
+
@conversion_procs[column_name] = conversion_proc
|
220
|
+
end
|
221
|
+
|
222
|
+
# Compares +other_table+ to self. If +other_table+ contains columns
|
223
|
+
# and/or rows that are not in self, new columns/rows are added at the
|
224
|
+
# relevant positions, marking the cells in those rows/columns as
|
225
|
+
# <tt>surplus</tt>. Likewise, if +other_table+ lacks columns and/or
|
226
|
+
# rows that are present in self, these are marked as <tt>missing</tt>.
|
227
|
+
#
|
228
|
+
# <tt>surplus</tt> and <tt>missing</tt> cells are recognised by formatters
|
229
|
+
# and displayed so that it's easy to read the differences.
|
230
|
+
#
|
231
|
+
# Cells that are different, but <em>look</em> identical (for example the
|
232
|
+
# boolean true and the string "true") are converted to their Object#inspect
|
233
|
+
# representation and preceded with (i) - to make it easier to identify
|
234
|
+
# where the difference actually is.
|
235
|
+
#
|
236
|
+
# Since all tables that are passed to StepDefinitions always have String
|
237
|
+
# objects in their cells, you may want to use #map_column! before calling
|
238
|
+
# #diff!. You can use #map_column! on either of the tables.
|
239
|
+
#
|
240
|
+
# An exception is raised if there are missing rows or columns, or
|
241
|
+
# surplus rows. An error is <em>not</em> raised for surplus columns.
|
242
|
+
# Whether to raise or not raise can be changed by setting values in
|
243
|
+
# +options+ to true or false:
|
244
|
+
#
|
245
|
+
# * <tt>missing_row</tt> : Raise on missing rows (defaults to true)
|
246
|
+
# * <tt>surplus_row</tt> : Raise on surplus rows (defaults to true)
|
247
|
+
# * <tt>missing_col</tt> : Raise on missing columns (defaults to true)
|
248
|
+
# * <tt>surplus_col</tt> : Raise on surplus columns (defaults to false)
|
249
|
+
#
|
250
|
+
# The +other_table+ argument can be another Table, an Array of Array or
|
251
|
+
# an Array of Hash (similar to the structure returned by #hashes).
|
252
|
+
#
|
253
|
+
# Calling this method is particularly useful in <tt>Then</tt> steps that take
|
254
|
+
# a Table argument, if you want to compare that table to some actual values.
|
255
|
+
#
|
256
|
+
def diff!(other_table, options={})
|
257
|
+
options = {:missing_row => true, :surplus_row => true, :missing_col => true, :surplus_col => false}.merge(options)
|
258
|
+
|
259
|
+
other_table = ensure_table(other_table)
|
260
|
+
other_table.convert_columns!
|
261
|
+
ensure_green!
|
262
|
+
|
263
|
+
original_width = cell_matrix[0].length
|
264
|
+
other_table_cell_matrix = pad!(other_table.cell_matrix)
|
265
|
+
padded_width = cell_matrix[0].length
|
266
|
+
|
267
|
+
missing_col = cell_matrix[0].detect{|cell| cell.status == :undefined}
|
268
|
+
surplus_col = padded_width > original_width
|
269
|
+
|
270
|
+
require_diff_lcs
|
271
|
+
cell_matrix.extend(Diff::LCS)
|
272
|
+
convert_columns!
|
273
|
+
changes = cell_matrix.diff(other_table_cell_matrix).flatten
|
274
|
+
|
275
|
+
inserted = 0
|
276
|
+
missing = 0
|
277
|
+
|
278
|
+
row_indices = Array.new(other_table_cell_matrix.length) {|n| n}
|
279
|
+
|
280
|
+
last_change = nil
|
281
|
+
missing_row_pos = nil
|
282
|
+
insert_row_pos = nil
|
283
|
+
|
284
|
+
changes.each do |change|
|
285
|
+
if(change.action == '-')
|
286
|
+
missing_row_pos = change.position + inserted
|
287
|
+
cell_matrix[missing_row_pos].each{|cell| cell.status = :undefined}
|
288
|
+
row_indices.insert(missing_row_pos, nil)
|
289
|
+
missing += 1
|
290
|
+
else # '+'
|
291
|
+
insert_row_pos = change.position + missing
|
292
|
+
inserted_row = change.element
|
293
|
+
inserted_row.each{|cell| cell.status = :comment}
|
294
|
+
cell_matrix.insert(insert_row_pos, inserted_row)
|
295
|
+
row_indices[insert_row_pos] = nil
|
296
|
+
inspect_rows(cell_matrix[missing_row_pos], inserted_row) if last_change && last_change.action == '-'
|
297
|
+
inserted += 1
|
298
|
+
end
|
299
|
+
last_change = change
|
300
|
+
end
|
301
|
+
|
302
|
+
other_table_cell_matrix.each_with_index do |other_row, i|
|
303
|
+
row_index = row_indices.index(i)
|
304
|
+
row = cell_matrix[row_index] if row_index
|
305
|
+
if row
|
306
|
+
(original_width..padded_width).each do |col_index|
|
307
|
+
surplus_cell = other_row[col_index]
|
308
|
+
row[col_index].value = surplus_cell.value if row[col_index]
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
clear_cache!
|
314
|
+
should_raise =
|
315
|
+
missing_row_pos && options[:missing_row] ||
|
316
|
+
insert_row_pos && options[:surplus_row] ||
|
317
|
+
missing_col && options[:missing_col] ||
|
318
|
+
surplus_col && options[:surplus_col]
|
319
|
+
raise 'Tables were not identical' if should_raise
|
320
|
+
end
|
321
|
+
|
322
|
+
def to_hash(cells) #:nodoc:
|
323
|
+
hash = Hash.new do |hash, key|
|
324
|
+
hash[key.to_s] if key.is_a?(Symbol)
|
325
|
+
end
|
326
|
+
raw[0].each_with_index do |column_name, column_index|
|
327
|
+
value = @conversion_procs[column_name].call(cells.value(column_index))
|
328
|
+
hash[column_name] = value
|
329
|
+
end
|
330
|
+
hash
|
331
|
+
end
|
332
|
+
|
333
|
+
def index(cells) #:nodoc:
|
334
|
+
cells_rows.index(cells)
|
335
|
+
end
|
336
|
+
|
337
|
+
def verify_column(column_name) #:nodoc:
|
338
|
+
raise %{The column named "#{column_name}" does not exist} unless raw[0].include?(column_name)
|
339
|
+
end
|
340
|
+
|
341
|
+
def verify_table_width(width) #:nodoc:
|
342
|
+
raise %{The table must have exactly #{width} columns} unless raw[0].size == width
|
343
|
+
end
|
344
|
+
|
345
|
+
def arguments_replaced(arguments) #:nodoc:
|
346
|
+
raw_with_replaced_args = raw.map do |row|
|
347
|
+
row.map do |cell|
|
348
|
+
cell_with_replaced_args = cell
|
349
|
+
arguments.each do |name, value|
|
350
|
+
if cell_with_replaced_args && cell_with_replaced_args.include?(name)
|
351
|
+
cell_with_replaced_args = value ? cell_with_replaced_args.gsub(name, value) : nil
|
352
|
+
end
|
353
|
+
end
|
354
|
+
cell_with_replaced_args
|
355
|
+
end
|
356
|
+
end
|
357
|
+
Table.new(raw_with_replaced_args)
|
358
|
+
end
|
359
|
+
|
360
|
+
def has_text?(text) #:nodoc:
|
361
|
+
raw.flatten.compact.detect{|cell_value| cell_value.index(text)}
|
362
|
+
end
|
363
|
+
|
364
|
+
def cells_rows #:nodoc:
|
365
|
+
@rows ||= cell_matrix.map do |cell_row|
|
366
|
+
@cells_class.new(self, cell_row)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
def headers #:nodoc:
|
371
|
+
raw.first
|
372
|
+
end
|
373
|
+
|
374
|
+
def header_cell(col) #:nodoc:
|
375
|
+
cells_rows[0][col]
|
376
|
+
end
|
377
|
+
|
378
|
+
def cell_matrix #:nodoc:
|
379
|
+
@cell_matrix
|
380
|
+
end
|
381
|
+
|
382
|
+
def col_width(col) #:nodoc:
|
383
|
+
columns[col].__send__(:width)
|
384
|
+
end
|
385
|
+
|
386
|
+
def to_s(options = {}) #:nodoc:
|
387
|
+
options = {:color => true, :indent => 2, :prefixes => TO_S_PREFIXES}.merge(options)
|
388
|
+
io = StringIO.new
|
389
|
+
|
390
|
+
c = Term::ANSIColor.coloring?
|
391
|
+
Term::ANSIColor.coloring = options[:color]
|
392
|
+
f = Formatter::Pretty.new(nil, io, options)
|
393
|
+
f.instance_variable_set('@indent', options[:indent])
|
394
|
+
f.visit_multiline_arg(self)
|
395
|
+
Term::ANSIColor.coloring = c
|
396
|
+
|
397
|
+
io.rewind
|
398
|
+
s = "\n" + io.read + (" " * (options[:indent] - 2))
|
399
|
+
s
|
400
|
+
end
|
401
|
+
|
402
|
+
private
|
403
|
+
|
404
|
+
TO_S_PREFIXES = Hash.new(' ')
|
405
|
+
TO_S_PREFIXES[:comment] = ['(+) ']
|
406
|
+
TO_S_PREFIXES[:undefined] = ['(-) ']
|
407
|
+
|
408
|
+
protected
|
409
|
+
|
410
|
+
def inspect_rows(missing_row, inserted_row) #:nodoc:
|
411
|
+
missing_row.each_with_index do |missing_cell, col|
|
412
|
+
inserted_cell = inserted_row[col]
|
413
|
+
if(missing_cell.value != inserted_cell.value && (missing_cell.value.to_s == inserted_cell.value.to_s))
|
414
|
+
missing_cell.inspect!
|
415
|
+
inserted_cell.inspect!
|
416
|
+
end
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
def create_cell_matrix(raw) #:nodoc:
|
421
|
+
@cell_matrix = raw.map do |raw_row|
|
422
|
+
line = raw_row.line rescue -1
|
423
|
+
raw_row.map do |raw_cell|
|
424
|
+
new_cell(raw_cell, line)
|
425
|
+
end
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
def convert_columns! #:nodoc:
|
430
|
+
cell_matrix.transpose.each do |col|
|
431
|
+
conversion_proc = @conversion_procs[col[0].value]
|
432
|
+
col[1..-1].each do |cell|
|
433
|
+
cell.value = conversion_proc.call(cell.value)
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
def require_diff_lcs #:nodoc:
|
439
|
+
begin
|
440
|
+
require 'diff/lcs'
|
441
|
+
rescue LoadError => e
|
442
|
+
e.message << "\n Please gem install diff-lcs\n"
|
443
|
+
raise e
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
def clear_cache! #:nodoc:
|
448
|
+
@hashes = @rows_hash = @rows = @columns = nil
|
449
|
+
end
|
450
|
+
|
451
|
+
def columns #:nodoc:
|
452
|
+
@columns ||= cell_matrix.transpose.map do |cell_row|
|
453
|
+
@cells_class.new(self, cell_row)
|
454
|
+
end.freeze
|
455
|
+
end
|
456
|
+
|
457
|
+
def new_cell(raw_cell, line) #:nodoc:
|
458
|
+
@cell_class.new(raw_cell, self, line)
|
459
|
+
end
|
460
|
+
|
461
|
+
# Pads our own cell_matrix and returns a cell matrix of same
|
462
|
+
# column width that can be used for diffing
|
463
|
+
def pad!(other_cell_matrix) #:nodoc:
|
464
|
+
clear_cache!
|
465
|
+
cols = cell_matrix.transpose
|
466
|
+
unmapped_cols = other_cell_matrix.transpose
|
467
|
+
|
468
|
+
mapped_cols = []
|
469
|
+
|
470
|
+
cols.each_with_index do |col, col_index|
|
471
|
+
header = col[0]
|
472
|
+
candidate_cols, unmapped_cols = unmapped_cols.partition do |other_col|
|
473
|
+
other_col[0] == header
|
474
|
+
end
|
475
|
+
raise "More than one column has the header #{header}" if candidate_cols.size > 2
|
476
|
+
|
477
|
+
other_padded_col = if candidate_cols.size == 1
|
478
|
+
# Found a matching column
|
479
|
+
candidate_cols[0]
|
480
|
+
else
|
481
|
+
mark_as_missing(cols[col_index])
|
482
|
+
(0...other_cell_matrix.length).map do |row|
|
483
|
+
val = row == 0 ? header.value : nil
|
484
|
+
SurplusCell.new(val, self, -1)
|
485
|
+
end
|
486
|
+
end
|
487
|
+
mapped_cols.insert(col_index, other_padded_col)
|
488
|
+
end
|
489
|
+
|
490
|
+
unmapped_cols.each_with_index do |col, col_index|
|
491
|
+
empty_col = (0...cell_matrix.length).map do |row|
|
492
|
+
SurplusCell.new(nil, self, -1)
|
493
|
+
end
|
494
|
+
cols << empty_col
|
495
|
+
end
|
496
|
+
|
497
|
+
@cell_matrix = cols.transpose
|
498
|
+
(mapped_cols + unmapped_cols).transpose
|
499
|
+
end
|
500
|
+
|
501
|
+
def ensure_table(table_or_array) #:nodoc:
|
502
|
+
return table_or_array if Table === table_or_array
|
503
|
+
table_or_array = hashes_to_array(table_or_array) if Hash === table_or_array[0]
|
504
|
+
table_or_array = enumerable_to_array(table_or_array) unless Array == table_or_array[0]
|
505
|
+
Table.new(table_or_array)
|
506
|
+
end
|
507
|
+
|
508
|
+
def hashes_to_array(hashes) #:nodoc:
|
509
|
+
header = hashes[0].keys
|
510
|
+
[header] + hashes.map{|hash| header.map{|key| hash[key]}}
|
511
|
+
end
|
512
|
+
|
513
|
+
def enumerable_to_array(rows) #:nodoc:
|
514
|
+
rows.map{|row| row.map{|cell| cell}}
|
515
|
+
end
|
516
|
+
|
517
|
+
def ensure_green! #:nodoc:
|
518
|
+
each_cell{|cell| cell.status = :passed}
|
519
|
+
end
|
520
|
+
|
521
|
+
def each_cell(&proc) #:nodoc:
|
522
|
+
cell_matrix.each{|row| row.each(&proc)}
|
523
|
+
end
|
524
|
+
|
525
|
+
def mark_as_missing(col) #:nodoc:
|
526
|
+
col.each do |cell|
|
527
|
+
cell.status = :undefined
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
531
|
+
# Represents a row of cells or columns of cells
|
532
|
+
class Cells #:nodoc:
|
533
|
+
include Enumerable
|
534
|
+
attr_reader :exception
|
535
|
+
|
536
|
+
def initialize(table, cells)
|
537
|
+
@table, @cells = table, cells
|
538
|
+
end
|
539
|
+
|
540
|
+
def accept(visitor)
|
541
|
+
return if $cucumber_interrupted
|
542
|
+
each do |cell|
|
543
|
+
visitor.visit_table_cell(cell)
|
544
|
+
end
|
545
|
+
nil
|
546
|
+
end
|
547
|
+
|
548
|
+
# For testing only
|
549
|
+
def to_sexp #:nodoc:
|
550
|
+
[:row, line, *@cells.map{|cell| cell.to_sexp}]
|
551
|
+
end
|
552
|
+
|
553
|
+
def to_hash #:nodoc:
|
554
|
+
@to_hash ||= @table.to_hash(self).freeze
|
555
|
+
end
|
556
|
+
|
557
|
+
def value(n) #:nodoc:
|
558
|
+
self[n].value
|
559
|
+
end
|
560
|
+
|
561
|
+
def [](n)
|
562
|
+
@cells[n]
|
563
|
+
end
|
564
|
+
|
565
|
+
def line
|
566
|
+
@cells[0].line
|
567
|
+
end
|
568
|
+
|
569
|
+
def dom_id
|
570
|
+
"row_#{line}"
|
571
|
+
end
|
572
|
+
|
573
|
+
private
|
574
|
+
|
575
|
+
def index
|
576
|
+
@table.index(self)
|
577
|
+
end
|
578
|
+
|
579
|
+
def width
|
580
|
+
map{|cell| cell.value ? cell.value.to_s.jlength : 0}.max
|
581
|
+
end
|
582
|
+
|
583
|
+
def each(&proc)
|
584
|
+
@cells.each(&proc)
|
585
|
+
end
|
586
|
+
end
|
587
|
+
|
588
|
+
class Cell #:nodoc:
|
589
|
+
attr_reader :line, :table
|
590
|
+
attr_accessor :status, :value
|
591
|
+
|
592
|
+
def initialize(value, table, line)
|
593
|
+
@value, @table, @line = value, table, line
|
594
|
+
end
|
595
|
+
|
596
|
+
def accept(visitor)
|
597
|
+
return if $cucumber_interrupted
|
598
|
+
visitor.visit_table_cell_value(value, status)
|
599
|
+
end
|
600
|
+
|
601
|
+
def inspect!
|
602
|
+
@value = "(i) #{value.inspect}"
|
603
|
+
end
|
604
|
+
|
605
|
+
def ==(o)
|
606
|
+
SurplusCell === o || value == o.value
|
607
|
+
end
|
608
|
+
|
609
|
+
# For testing only
|
610
|
+
def to_sexp #:nodoc:
|
611
|
+
[:cell, @value]
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
class SurplusCell < Cell #:nodoc:
|
616
|
+
def status
|
617
|
+
:comment
|
618
|
+
end
|
619
|
+
|
620
|
+
def ==(o)
|
621
|
+
true
|
622
|
+
end
|
623
|
+
end
|
624
|
+
end
|
625
|
+
end
|
626
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Ast
|
3
|
+
# Holds the names of tags parsed from a feature file:
|
4
|
+
#
|
5
|
+
# @invoice @release_2
|
6
|
+
#
|
7
|
+
# This gets stored internally as <tt>["invoice", "release_2"]</tt>
|
8
|
+
#
|
9
|
+
class Tags #:nodoc:
|
10
|
+
def self.strip_prefix(tag_name)
|
11
|
+
tag_name =~ /^@(.*)/ ? $1 : tag_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(line, tag_names)
|
15
|
+
@line, @tag_names = line, tag_names
|
16
|
+
end
|
17
|
+
|
18
|
+
def accept(visitor)
|
19
|
+
return if $cucumber_interrupted
|
20
|
+
@tag_names.each do |tag_name|
|
21
|
+
visitor.visit_tag_name(tag_name)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def accept_hook?(hook)
|
26
|
+
hook.tag_names.empty? || (hook.tag_names.map{|tag| Ast::Tags.strip_prefix(tag)} & @tag_names).any?
|
27
|
+
end
|
28
|
+
|
29
|
+
def count(tag)
|
30
|
+
# See discussion:
|
31
|
+
# http://github.com/weplay/cucumber/commit/2dc592acdf3f7c1a0c333a8164649936bb82d983
|
32
|
+
if @tag_names.respond_to?(:count) && @tag_names.method(:count).arity > 0
|
33
|
+
@tag_names.count(tag) # 1.9
|
34
|
+
else
|
35
|
+
@tag_names.select{|t| t == tag}.length # 1.8
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_sexp
|
40
|
+
@tag_names.map{|tag_name| [:tag, tag_name]}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|