aslakhellesoy-cucumber 0.2.3.4 → 0.3.0
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 +11 -0
- data/Manifest.txt +3 -0
- data/config/hoe.rb +1 -1
- data/cucumber.yml +1 -1
- data/examples/self_test/features/background/passing_background.feature +2 -2
- data/examples/self_test/features/step_definitions/sample_steps.rb +10 -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/279/py_string_indent.steps.rb +1 -0
- data/examples/tickets/features/step_definitons/tickets_steps.rb +0 -7
- data/features/background.feature +1 -0
- data/features/rake_task.feature +132 -0
- data/features/step_definitions/cucumber_steps.rb +38 -19
- data/features/support/env.rb +61 -4
- data/gem_tasks/deployment.rake +1 -1
- data/lib/cucumber/ast/background.rb +11 -1
- data/lib/cucumber/ast/feature_element.rb +4 -0
- data/lib/cucumber/ast/outline_table.rb +8 -0
- data/lib/cucumber/ast/tags.rb +9 -1
- data/lib/cucumber/cli/configuration.rb +2 -2
- data/lib/cucumber/cli/main.rb +5 -1
- data/lib/cucumber/parser/feature.rb +2 -2
- data/lib/cucumber/parser/feature.tt +2 -2
- data/lib/cucumber/rake/task.rb +29 -6
- data/lib/cucumber/step_mother.rb +50 -15
- data/lib/cucumber/version.rb +3 -3
- data/spec/cucumber/cli/main_spec.rb +5 -1
- data/spec/cucumber/step_mother_spec.rb +11 -0
- metadata +5 -2
    
        data/History.txt
    CHANGED
    
    | @@ -13,7 +13,17 @@ The Visitor API (which is used for formatters) has also changed slightly. Howeve | |
| 13 13 | 
             
            do this in a backwards compatible way, so if you have custom formatters for Cucumber 0.2 they should
         | 
| 14 14 | 
             
            still work.
         | 
| 15 15 |  | 
| 16 | 
            +
            One of the most significant new features is Tagged Hooks: http://wiki.github.com/aslakhellesoy/cucumber/hooks
         | 
| 17 | 
            +
            This lets you associate Before and After blocks with specific scenarios.
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            We are also deprecating the step_list, step_pattern, feature_list, and feature_pattern accessors on
         | 
| 20 | 
            +
            Cucumber::Rake::Task. These accessors will be completely removed in version 0.4. For complex settings 
         | 
| 21 | 
            +
            please rely on cucumber profiles in your rake tasks:
         | 
| 22 | 
            +
            http://wiki.github.com/aslakhellesoy/cucumber/using-rake#profiles
         | 
| 23 | 
            +
             | 
| 16 24 | 
             
            === New features
         | 
| 25 | 
            +
            * Use Hooks with @tags (#229 Aslak Hellesøy)
         | 
| 26 | 
            +
            * Rake task supports cucumber.yml profiles (#187 Ben Mabey)
         | 
| 17 27 | 
             
            * Field value steps for Webrat (Jack Chen)
         | 
| 18 28 | 
             
            * Added translation for Bulgarian (Krasimir Angelov)
         | 
| 19 29 | 
             
            * Updated translation for Polish (#273 Grzegorz Marszałek)
         | 
| @@ -26,6 +36,7 @@ still work. | |
| 26 36 | 
             
            * Support description string for Backgrounds (#271 Joseph Wilk)
         | 
| 27 37 |  | 
| 28 38 | 
             
            === Bugfixes
         | 
| 39 | 
            +
            * After methods not being executed when Background fails (#288 Luismi Cavallé)
         | 
| 29 40 | 
             
            * Fixed dependency on internal files in rspec breaks cucumber w/ rspec-1.2.4 (#291 Aslak Hellesøy)
         | 
| 30 41 | 
             
            * Fix color use when using autotest on Linux. (Hans de Graaff)
         | 
| 31 42 | 
             
            * Fixed incorrect calculation of pystring indentation (#279 Eugene Naydanov)
         | 
    
        data/Manifest.txt
    CHANGED
    
    | @@ -182,6 +182,8 @@ examples/tickets/features/177/1.feature | |
| 182 182 | 
             
            examples/tickets/features/177/2.feature
         | 
| 183 183 | 
             
            examples/tickets/features/177/3.feature
         | 
| 184 184 | 
             
            examples/tickets/features/180.feature
         | 
| 185 | 
            +
            examples/tickets/features/229/tagged_hooks.feature
         | 
| 186 | 
            +
            examples/tickets/features/229/tagged_hooks.rb
         | 
| 185 187 | 
             
            examples/tickets/features/236.feature
         | 
| 186 188 | 
             
            examples/tickets/features/241.feature
         | 
| 187 189 | 
             
            examples/tickets/features/246.feature
         | 
| @@ -209,6 +211,7 @@ features/cucumber_cli.feature | |
| 209 211 | 
             
            features/cucumber_cli_diff_disabled.feature
         | 
| 210 212 | 
             
            features/cucumber_cli_outlines.feature
         | 
| 211 213 | 
             
            features/custom_formatter.feature
         | 
| 214 | 
            +
            features/rake_task.feature
         | 
| 212 215 | 
             
            features/report_called_undefined_steps.feature
         | 
| 213 216 | 
             
            features/snippet.feature
         | 
| 214 217 | 
             
            features/step_definitions/cucumber_steps.rb
         | 
    
        data/config/hoe.rb
    CHANGED
    
    | @@ -53,7 +53,7 @@ $hoe = Hoe.new(GEM_NAME, VERS) do |p| | |
| 53 53 | 
             
              p.summary = DESCRIPTION
         | 
| 54 54 | 
             
              p.url = HOMEPATH
         | 
| 55 55 | 
             
              p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
         | 
| 56 | 
            -
              p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store', '**/*.class', '**/*.jar']  #An array of file patterns to delete on clean.
         | 
| 56 | 
            +
              p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store', '**/*.class', '**/*.jar', '**/tmp']  #An array of file patterns to delete on clean.
         | 
| 57 57 |  | 
| 58 58 | 
             
              # == Optional
         | 
| 59 59 | 
             
              p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
         | 
    
        data/cucumber.yml
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            default: --format progress features
         | 
| 1 | 
            +
            default: --format progress features --tags ~@pending
         | 
| @@ -68,3 +68,13 @@ end | |
| 68 68 |  | 
| 69 69 | 
             
            Given /^another unused$/ do
         | 
| 70 70 | 
             
            end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
            after_file = File.dirname(__FILE__) + '/../../tmp/after.txt'
         | 
| 73 | 
            +
             | 
| 74 | 
            +
            Before('@after_file') do
         | 
| 75 | 
            +
              FileUtils.rm(after_file) if File.exist?(after_file)
         | 
| 76 | 
            +
            end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
            After('@after_file') do
         | 
| 79 | 
            +
              FileUtils.touch(after_file)
         | 
| 80 | 
            +
            end
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            require 'spec/expectations'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Before('@i_am_so_special') do
         | 
| 4 | 
            +
              @something_special = 10
         | 
| 5 | 
            +
            end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            After('@i_am_so_special') do
         | 
| 8 | 
            +
              @something_special.should == 20
         | 
| 9 | 
            +
            end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            When /special me goes to town/ do
         | 
| 12 | 
            +
              @something_special.should == 10
         | 
| 13 | 
            +
              @something_special = 20
         | 
| 14 | 
            +
            end
         | 
    
        data/features/background.feature
    CHANGED
    
    | @@ -93,6 +93,7 @@ Feature: backgrounds | |
| 93 93 | 
             
                5 skipped steps
         | 
| 94 94 |  | 
| 95 95 | 
             
                """
         | 
| 96 | 
            +
                And "examples/self_test/tmp/after.txt" should exist
         | 
| 96 97 |  | 
| 97 98 | 
             
              Scenario: run a feature with scenario outlines that has a background that fails
         | 
| 98 99 | 
             
                When I run cucumber -q features/background/scenario_outline_failing_background.feature --require features
         | 
| @@ -0,0 +1,132 @@ | |
| 1 | 
            +
            Feature: Rake task
         | 
| 2 | 
            +
              In order to ease the development process
         | 
| 3 | 
            +
              As a developer and CI server administrator
         | 
| 4 | 
            +
              Cucumber features should be executable via Rake
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              Background:
         | 
| 7 | 
            +
                Given a standard Cucumber project directory structure
         | 
| 8 | 
            +
                And a file named "features/missing_step_definitions.feature" with:
         | 
| 9 | 
            +
                """
         | 
| 10 | 
            +
                Feature: Sample
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  Scenario: Wanted
         | 
| 13 | 
            +
                    Given I want to run this
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  Scenario: Unwanted
         | 
| 16 | 
            +
                    Given I don't want this ran
         | 
| 17 | 
            +
                """
         | 
| 18 | 
            +
             | 
| 19 | 
            +
             | 
| 20 | 
            +
              Scenario: rake task with a defined profile
         | 
| 21 | 
            +
                Given the following profile is defined:
         | 
| 22 | 
            +
                """
         | 
| 23 | 
            +
                foo: --quiet --no-color features/missing_step_definitions.feature:3
         | 
| 24 | 
            +
                """
         | 
| 25 | 
            +
                And a file named "Rakefile" with:
         | 
| 26 | 
            +
                """
         | 
| 27 | 
            +
                $LOAD_PATH.unshift(CUCUMBER_LIB)
         | 
| 28 | 
            +
                require 'cucumber/rake/task'
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                Cucumber::Rake::Task.new(:features) do |t|
         | 
| 31 | 
            +
                  t.profile = "foo"
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
                """
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                When I run rake features
         | 
| 36 | 
            +
                Then it should pass
         | 
| 37 | 
            +
                And the output should contain
         | 
| 38 | 
            +
                """
         | 
| 39 | 
            +
                Feature: Sample
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  Scenario: Wanted
         | 
| 42 | 
            +
                    Given I want to run this
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                1 scenario
         | 
| 45 | 
            +
                1 undefined step
         | 
| 46 | 
            +
                """
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              Scenario: rake task with a defined profile and cucumber_opts
         | 
| 49 | 
            +
                Given the following profile is defined:
         | 
| 50 | 
            +
                """
         | 
| 51 | 
            +
                bar: features/missing_step_definitions.feature:3
         | 
| 52 | 
            +
                """
         | 
| 53 | 
            +
                And a file named "Rakefile" with:
         | 
| 54 | 
            +
                """
         | 
| 55 | 
            +
                $LOAD_PATH.unshift(CUCUMBER_LIB)
         | 
| 56 | 
            +
                require 'cucumber/rake/task'
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                Cucumber::Rake::Task.new(:features) do |t|
         | 
| 59 | 
            +
                  t.profile = "bar"
         | 
| 60 | 
            +
                  t.cucumber_opts = "--quiet --no-color"
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
                """
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                When I run rake features
         | 
| 65 | 
            +
                Then it should pass
         | 
| 66 | 
            +
                And the output should contain
         | 
| 67 | 
            +
                """
         | 
| 68 | 
            +
                Feature: Sample
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  Scenario: Wanted
         | 
| 71 | 
            +
                    Given I want to run this
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                1 scenario
         | 
| 74 | 
            +
                1 undefined step
         | 
| 75 | 
            +
                """
         | 
| 76 | 
            +
             | 
| 77 | 
            +
              Scenario: rake task with a defined profile and feature list
         | 
| 78 | 
            +
                Given a file named "features/the_one_i_want_to_run.feature" with:
         | 
| 79 | 
            +
                """
         | 
| 80 | 
            +
                Feature: Desired
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  Scenario: Something
         | 
| 83 | 
            +
                    Given this is missing
         | 
| 84 | 
            +
                """
         | 
| 85 | 
            +
               Given the following profile is defined:
         | 
| 86 | 
            +
                """
         | 
| 87 | 
            +
                baz: --quiet --no-color
         | 
| 88 | 
            +
                """
         | 
| 89 | 
            +
                And a file named "Rakefile" with:
         | 
| 90 | 
            +
                """
         | 
| 91 | 
            +
                $LOAD_PATH.unshift(CUCUMBER_LIB)
         | 
| 92 | 
            +
                require 'cucumber/rake/task'
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                Cucumber::Rake::Task.new(:features) do |t|
         | 
| 95 | 
            +
                  t.profile = "baz"
         | 
| 96 | 
            +
                  t.feature_list = ['features/the_one_i_want_to_run.feature']
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
                """
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                When I run rake features
         | 
| 101 | 
            +
                Then it should pass
         | 
| 102 | 
            +
                And the output should contain
         | 
| 103 | 
            +
                """
         | 
| 104 | 
            +
                Feature: Desired
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                  Scenario: Something
         | 
| 107 | 
            +
                    Given this is missing
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                1 scenario
         | 
| 110 | 
            +
                1 undefined step
         | 
| 111 | 
            +
                """
         | 
| 112 | 
            +
             | 
| 113 | 
            +
              Scenario: deprecation warnings
         | 
| 114 | 
            +
                Given a file named "Rakefile" with:
         | 
| 115 | 
            +
                """
         | 
| 116 | 
            +
                $LOAD_PATH.unshift(CUCUMBER_LIB)
         | 
| 117 | 
            +
                require 'cucumber/rake/task'
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                Cucumber::Rake::Task.new(:features) do |t|
         | 
| 120 | 
            +
                  t.feature_list = ['features/missing_step_definitions.feature']
         | 
| 121 | 
            +
                end
         | 
| 122 | 
            +
                """
         | 
| 123 | 
            +
                When I run rake features
         | 
| 124 | 
            +
                Then it should pass
         | 
| 125 | 
            +
                And STDERR should match
         | 
| 126 | 
            +
                """
         | 
| 127 | 
            +
                Cucumber::Rake::Task#feature_list is deprecated and will be removed in 0.4.0.  Please use profiles for complex settings: http://wiki.github.com/aslakhellesoy/cucumber/using-rake#profiles
         | 
| 128 | 
            +
                """
         | 
| 129 | 
            +
             | 
| 130 | 
            +
             | 
| 131 | 
            +
             | 
| 132 | 
            +
             | 
| @@ -1,32 +1,46 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
            Given /^I am in (.*)$/ do |dir|
         | 
| 4 | 
            -
              @dir = dir
         | 
| 1 | 
            +
            Given /^I am in (.*)$/ do |example_dir_relative_path|
         | 
| 2 | 
            +
              @current_dir = examples_dir(example_dir_relative_path)
         | 
| 5 3 | 
             
            end
         | 
| 6 4 |  | 
| 7 | 
            -
             | 
| 8 | 
            -
              @ | 
| 9 | 
            -
               | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
              Dir.chdir(full_dir) do
         | 
| 13 | 
            -
                @full_cmd = "#{Cucumber::RUBY_BINARY} #{Cucumber::BINARY} --no-color #{cmd} 2> #{@stderr.path}"
         | 
| 14 | 
            -
                @out = `#{@full_cmd}`
         | 
| 15 | 
            -
                @status = $?.exitstatus
         | 
| 5 | 
            +
            Given /^a standard Cucumber project directory structure$/ do
         | 
| 6 | 
            +
              @current_dir = working_dir
         | 
| 7 | 
            +
              in_current_dir do
         | 
| 8 | 
            +
                FileUtils.mkdir_p 'features/support'
         | 
| 9 | 
            +
                FileUtils.mkdir 'features/step_definitions'
         | 
| 16 10 | 
             
              end
         | 
| 17 11 | 
             
            end
         | 
| 18 12 |  | 
| 19 | 
            -
             | 
| 20 | 
            -
               | 
| 13 | 
            +
            Given /^a file named "([^\"]*)" with:$/ do |file_name, file_content|
         | 
| 14 | 
            +
              create_file(file_name, file_content)
         | 
| 15 | 
            +
            end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            Given /^the following profiles? (?:are|is) defined:$/ do |profiles|
         | 
| 18 | 
            +
              create_file('cucumber.yml', profiles)
         | 
| 19 | 
            +
            end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            When /^I run cucumber (.*)$/ do |cucumber_opts|
         | 
| 22 | 
            +
              run "#{Cucumber::RUBY_BINARY} #{Cucumber::BINARY} --no-color #{cucumber_opts}"
         | 
| 23 | 
            +
            end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            When /^I run rake (.*)$/ do |rake_opts|
         | 
| 26 | 
            +
              run "rake #{rake_opts}"
         | 
| 27 | 
            +
            end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            Then /^it should (fail|pass)$/ do |success|
         | 
| 21 30 | 
             
              if success == 'fail'
         | 
| 22 | 
            -
                 | 
| 31 | 
            +
                last_exit_status.should_not == 0
         | 
| 23 32 | 
             
              else
         | 
| 24 | 
            -
                 | 
| 33 | 
            +
                last_exit_status.should == 0
         | 
| 25 34 | 
             
              end
         | 
| 26 35 | 
             
            end
         | 
| 27 36 |  | 
| 37 | 
            +
            Then /^it should (fail|pass) with$/ do |success, output|
         | 
| 38 | 
            +
              last_stdout.should == output
         | 
| 39 | 
            +
              Then("it should #{success}")
         | 
| 40 | 
            +
            end
         | 
| 41 | 
            +
             | 
| 28 42 | 
             
            Then /^the output should contain$/ do |text|
         | 
| 29 | 
            -
               | 
| 43 | 
            +
              last_stdout.should include(text)
         | 
| 30 44 | 
             
            end
         | 
| 31 45 |  | 
| 32 46 | 
             
            Then /^"(.*)" should contain$/ do |file, text|
         | 
| @@ -38,5 +52,10 @@ Then /^"(.*)" should match$/ do |file, text| | |
| 38 52 | 
             
            end
         | 
| 39 53 |  | 
| 40 54 | 
             
            Then /^STDERR should match$/ do |text|
         | 
| 41 | 
            -
               | 
| 55 | 
            +
              last_stderr.should =~ /#{text}/
         | 
| 56 | 
            +
            end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            Then /^"(.*)" should exist$/ do |file|
         | 
| 59 | 
            +
              File.exists?(file).should be_true
         | 
| 60 | 
            +
              FileUtils.rm(file)
         | 
| 42 61 | 
             
            end
         | 
    
        data/features/support/env.rb
    CHANGED
    
    | @@ -1,8 +1,65 @@ | |
| 1 1 | 
             
            require 'rubygems'
         | 
| 2 | 
            +
            require 'tempfile'
         | 
| 2 3 | 
             
            require 'spec/expectations'
         | 
| 3 4 | 
             
            require 'fileutils'
         | 
| 5 | 
            +
            require 'forwardable'
         | 
| 4 6 |  | 
| 5 | 
            -
             | 
| 6 | 
            -
               | 
| 7 | 
            -
               | 
| 8 | 
            -
             | 
| 7 | 
            +
            class CucumberWorld
         | 
| 8 | 
            +
              extend Forwardable
         | 
| 9 | 
            +
              def_delegators CucumberWorld, :examples_dir, :self_test_dir, :working_dir, :cucumber_lib_dir
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              def self.examples_dir(subdir=nil)
         | 
| 12 | 
            +
                @examples_dir ||= File.expand_path(File.join(File.dirname(__FILE__), '../../examples'))
         | 
| 13 | 
            +
                subdir ? File.join(@examples_dir, subdir) : @examples_dir
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              def self.self_test_dir
         | 
| 17 | 
            +
                @self_test_dir ||= examples_dir('self_test')
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              def self.working_dir
         | 
| 21 | 
            +
                @working_dir ||= examples_dir('self_test/tmp')
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              def cucumber_lib_dir
         | 
| 25 | 
            +
                @cucumber_lib_dir ||= File.expand_path(File.join(File.dirname(__FILE__), '../../lib'))
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              def initialize
         | 
| 29 | 
            +
                @current_dir = self_test_dir
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              private
         | 
| 33 | 
            +
              attr_reader :last_exit_status, :last_stdout, :last_stderr
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              def create_file(file_name, file_content)
         | 
| 36 | 
            +
                file_content.gsub!("CUCUMBER_LIB", "'#{cucumber_lib_dir}'") # Some files, such as Rakefiles need to use the lib dir
         | 
| 37 | 
            +
                in_current_dir do
         | 
| 38 | 
            +
                  File.open(file_name, 'w') { |f| f << file_content }
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              def in_current_dir(&block)
         | 
| 43 | 
            +
                Dir.chdir(@current_dir, &block)
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              def run(command)
         | 
| 47 | 
            +
                stderr_file = Tempfile.new('cucumber')
         | 
| 48 | 
            +
                stderr_file.close
         | 
| 49 | 
            +
                in_current_dir do
         | 
| 50 | 
            +
                  @last_stdout = `#{command} 2> #{stderr_file.path}`
         | 
| 51 | 
            +
                  @last_exit_status = $?.exitstatus
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
                @last_stderr = IO.read(stderr_file.path)
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            World do
         | 
| 59 | 
            +
              CucumberWorld.new
         | 
| 60 | 
            +
            end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            Before do
         | 
| 63 | 
            +
              FileUtils.rm_rf CucumberWorld.working_dir
         | 
| 64 | 
            +
              FileUtils.mkdir CucumberWorld.working_dir
         | 
| 65 | 
            +
            end
         | 
    
        data/gem_tasks/deployment.rake
    CHANGED
    
    
| @@ -24,9 +24,19 @@ module Cucumber | |
| 24 24 | 
             
                  def accept(visitor)
         | 
| 25 25 | 
             
                    visitor.visit_comment(@comment)
         | 
| 26 26 | 
             
                    visitor.visit_background_name(@keyword, @name, file_colon_line(@line), source_indent(text_length))
         | 
| 27 | 
            -
                    visitor.step_mother. | 
| 27 | 
            +
                    visitor.step_mother.before(self)
         | 
| 28 28 | 
             
                    visitor.visit_steps(@step_invocations)
         | 
| 29 29 | 
             
                    @failed = @step_invocations.detect{|step_invocation| step_invocation.exception}
         | 
| 30 | 
            +
                    visitor.step_mother.after(self) if @failed
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  def accept_hook?(hook)
         | 
| 34 | 
            +
                    # TODO: When background is involved - no tag based hook filtering is occurring with
         | 
| 35 | 
            +
                    # the current implementation. All hooks will be executed. This is because of the line
         | 
| 36 | 
            +
                    #   visitor.step_mother.before(self)
         | 
| 37 | 
            +
                    # in the #accept method above. Instead, we should really be passing the first scenario
         | 
| 38 | 
            +
                    # here. We currently don't have access to that, so a refactoring is in order to make that happen.
         | 
| 39 | 
            +
                    true
         | 
| 30 40 | 
             
                  end
         | 
| 31 41 |  | 
| 32 42 | 
             
                  def failed?
         | 
| @@ -15,6 +15,10 @@ module Cucumber | |
| 15 15 | 
             
                    nil
         | 
| 16 16 | 
             
                  end
         | 
| 17 17 |  | 
| 18 | 
            +
                  def accept_hook?(hook)
         | 
| 19 | 
            +
                    @scenario_outline.accept_hook?(hook)
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 18 22 | 
             
                  def skip_invoke!
         | 
| 19 23 | 
             
                    example_rows.each do |cells|
         | 
| 20 24 | 
             
                      cells.skip_invoke!
         | 
| @@ -62,6 +66,10 @@ module Cucumber | |
| 62 66 | 
             
                      end
         | 
| 63 67 | 
             
                    end
         | 
| 64 68 |  | 
| 69 | 
            +
                    def accept_hook?(hook)
         | 
| 70 | 
            +
                      @table.accept_hook?(hook)
         | 
| 71 | 
            +
                    end
         | 
| 72 | 
            +
             | 
| 65 73 | 
             
                    private
         | 
| 66 74 |  | 
| 67 75 | 
             
                    def header?
         | 
    
        data/lib/cucumber/ast/tags.rb
    CHANGED
    
    | @@ -7,6 +7,10 @@ module Cucumber | |
| 7 7 | 
             
                # This gets stored internally as <tt>["invoice", "release_2"]</tt>
         | 
| 8 8 | 
             
                #
         | 
| 9 9 | 
             
                class Tags
         | 
| 10 | 
            +
                  def self.strip_prefix(tag_name)
         | 
| 11 | 
            +
                    tag_name =~ /^@(.*)/ ? $1 : tag_name
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                
         | 
| 10 14 | 
             
                  def initialize(line, tag_names)
         | 
| 11 15 | 
             
                    @line, @tag_names = line, tag_names
         | 
| 12 16 | 
             
                  end
         | 
| @@ -16,7 +20,11 @@ module Cucumber | |
| 16 20 | 
             
                      visitor.visit_tag_name(tag_name)
         | 
| 17 21 | 
             
                    end
         | 
| 18 22 | 
             
                  end
         | 
| 19 | 
            -
             | 
| 23 | 
            +
             | 
| 24 | 
            +
                  def accept_hook?(hook)
         | 
| 25 | 
            +
                    hook.matches_tag_names?(@tag_names)
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 20 28 | 
             
                  def to_sexp
         | 
| 21 29 | 
             
                    @tag_names.map{|tag_name| [:tag, tag_name]}
         | 
| 22 30 | 
             
                  end
         | 
| @@ -187,8 +187,8 @@ module Cucumber | |
| 187 187 | 
             
                    excludes = excludes.map{|tag| tag[1..-1]}
         | 
| 188 188 |  | 
| 189 189 | 
             
                    # Strip @
         | 
| 190 | 
            -
                    includes = includes.map{|tag| tag | 
| 191 | 
            -
                    excludes = excludes.map{|tag| tag | 
| 190 | 
            +
                    includes = includes.map{|tag| Ast::Tags.strip_prefix(tag)}
         | 
| 191 | 
            +
                    excludes = excludes.map{|tag| Ast::Tags.strip_prefix(tag)}
         | 
| 192 192 | 
             
                    [includes, excludes]
         | 
| 193 193 | 
             
                  end
         | 
| 194 194 |  | 
    
        data/lib/cucumber/cli/main.rb
    CHANGED
    
    | @@ -92,7 +92,11 @@ module Cucumber | |
| 92 92 |  | 
| 93 93 | 
             
                  def enable_diffing
         | 
| 94 94 | 
             
                    if configuration.diff_enabled? && defined?(::Spec)
         | 
| 95 | 
            -
                       | 
| 95 | 
            +
                      begin
         | 
| 96 | 
            +
                        require 'spec/runner/differs/default' # RSpec >=1.2.4
         | 
| 97 | 
            +
                      rescue ::LoadError
         | 
| 98 | 
            +
                        require 'spec/expectations/differs/default' # RSpec <=1.2.3
         | 
| 99 | 
            +
                      end
         | 
| 96 100 | 
             
                      options = OpenStruct.new(:diff_format => :unified, :context_lines => 3)
         | 
| 97 101 | 
             
                      ::Spec::Expectations.differ = ::Spec::Expectations::Differs::Default.new(options)
         | 
| 98 102 | 
             
                    end
         | 
| @@ -216,7 +216,7 @@ module Cucumber | |
| 216 216 | 
             
                    end
         | 
| 217 217 |  | 
| 218 218 | 
             
                    def has_tags?(tags)
         | 
| 219 | 
            -
                      tag_names | 
| 219 | 
            +
                      (tag_names & tags).any?
         | 
| 220 220 | 
             
                    end
         | 
| 221 221 |  | 
| 222 222 | 
             
                    def build
         | 
| @@ -224,7 +224,7 @@ module Cucumber | |
| 224 224 | 
             
                    end
         | 
| 225 225 |  | 
| 226 226 | 
             
                    def tag_names
         | 
| 227 | 
            -
                      ts.elements.map{|e| e.tag.tag_name.text_value}
         | 
| 227 | 
            +
                      @tag_names ||= ts.elements.map{|e| e.tag.tag_name.text_value}
         | 
| 228 228 | 
             
                    end
         | 
| 229 229 | 
             
                  end
         | 
| 230 230 |  | 
| @@ -46,7 +46,7 @@ module Cucumber | |
| 46 46 | 
             
                      end
         | 
| 47 47 |  | 
| 48 48 | 
             
                      def has_tags?(tags)
         | 
| 49 | 
            -
                        tag_names | 
| 49 | 
            +
                        (tag_names & tags).any?
         | 
| 50 50 | 
             
                      end
         | 
| 51 51 |  | 
| 52 52 | 
             
                      def build
         | 
| @@ -54,7 +54,7 @@ module Cucumber | |
| 54 54 | 
             
                      end
         | 
| 55 55 |  | 
| 56 56 | 
             
                      def tag_names
         | 
| 57 | 
            -
                        ts.elements.map{|e| e.tag.tag_name.text_value}
         | 
| 57 | 
            +
                        @tag_names ||= ts.elements.map{|e| e.tag.tag_name.text_value}
         | 
| 58 58 | 
             
                      end
         | 
| 59 59 | 
             
                    }
         | 
| 60 60 | 
             
                  end
         | 
    
        data/lib/cucumber/rake/task.rb
    CHANGED
    
    | @@ -27,26 +27,45 @@ module Cucumber | |
| 27 27 | 
             
                class Task
         | 
| 28 28 | 
             
                  LIB    = File.expand_path(File.dirname(__FILE__) + '/../..') # :nodoc:
         | 
| 29 29 |  | 
| 30 | 
            +
                  # TODO: remove depreated accessors for 0.4.0
         | 
| 31 | 
            +
                  def self.deprecate_accessor(attribute) # :nodoc:
         | 
| 32 | 
            +
                    attr_reader attribute
         | 
| 33 | 
            +
                    class_eval <<-EOF, __FILE__, __LINE__ + 1
         | 
| 34 | 
            +
                      def #{attribute}=(value)
         | 
| 35 | 
            +
                        @#{attribute} = value
         | 
| 36 | 
            +
                        warn("Cucumber::Rake::Task##{attribute} is deprecated and will be removed in 0.4.0.  Please use profiles for complex settings: http://wiki.github.com/aslakhellesoy/cucumber/using-rake#profiles")
         | 
| 37 | 
            +
                      end
         | 
| 38 | 
            +
                    EOF
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 30 41 | 
             
                  # Directories to add to the Ruby $LOAD_PATH
         | 
| 31 42 | 
             
                  attr_accessor :libs
         | 
| 32 43 | 
             
                  # Name of the cucumber binary to use for running features. Defaults to Cucumber::BINARY
         | 
| 33 44 | 
             
                  attr_accessor :binary
         | 
| 34 45 | 
             
                  # Array of paths to specific step definition files to use
         | 
| 35 | 
            -
                   | 
| 46 | 
            +
                  deprecate_accessor :step_list
         | 
| 36 47 | 
             
                  # File pattern for finding step definitions. Defaults to 
         | 
| 37 48 | 
             
                  # 'features/**/*.rb'.
         | 
| 38 | 
            -
                   | 
| 49 | 
            +
                  deprecate_accessor :step_pattern
         | 
| 39 50 | 
             
                  # Array of paths to specific features to run. 
         | 
| 40 | 
            -
                   | 
| 51 | 
            +
                  deprecate_accessor :feature_list
         | 
| 41 52 | 
             
                  # File pattern for finding features to run. Defaults to 
         | 
| 42 | 
            -
                  # 'features/**/*.feature'. Can be  | 
| 43 | 
            -
                   | 
| 53 | 
            +
                  # 'features/**/*.feature'. Can be overridden by the FEATURE environment variable.
         | 
| 54 | 
            +
                  deprecate_accessor :feature_pattern
         | 
| 44 55 | 
             
                  # Extra options to pass to the cucumber binary. Can be overridden by the CUCUMBER_OPTS environment variable.
         | 
| 45 56 | 
             
                  attr_accessor :cucumber_opts
         | 
| 46 57 | 
             
                  # Run cucumber with RCov?
         | 
| 47 58 | 
             
                  attr_accessor :rcov
         | 
| 48 59 | 
             
                  # Extra options to pass to rcov
         | 
| 49 60 | 
             
                  attr_accessor :rcov_opts
         | 
| 61 | 
            +
                  # Define what profile to be used.  When used with cucumber_opts it is simply appended to it. Will be ignored when CUCUMBER_OPTS is used.
         | 
| 62 | 
            +
                  def profile=(profile)
         | 
| 63 | 
            +
                    @profile = profile
         | 
| 64 | 
            +
                    unless feature_list
         | 
| 65 | 
            +
                      @feature_list = [] # Don't use accessor to avoid deprecation warning.
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
                  attr_reader :profile
         | 
| 50 69 |  | 
| 51 70 | 
             
                  # Define a Rake
         | 
| 52 71 | 
             
                  def initialize(task_name = "features", desc = "Run Features with Cucumber")
         | 
| @@ -75,7 +94,7 @@ module Cucumber | |
| 75 94 | 
             
                  def arguments_for_ruby_execution(task_args = nil) # :nodoc:
         | 
| 76 95 | 
             
                    lib_args     = ['"%s"' % libs.join(File::PATH_SEPARATOR)]
         | 
| 77 96 | 
             
                    cucumber_bin = ['"%s"' % binary]
         | 
| 78 | 
            -
                    cuc_opts     = [(ENV['CUCUMBER_OPTS'] ||  | 
| 97 | 
            +
                    cuc_opts     = [(ENV['CUCUMBER_OPTS'] || cucumber_opts_with_profile)]
         | 
| 79 98 |  | 
| 80 99 | 
             
                    step_files(task_args).each do |step_file|
         | 
| 81 100 | 
             
                      cuc_opts << '--require'
         | 
| @@ -92,6 +111,10 @@ module Cucumber | |
| 92 111 | 
             
                    args
         | 
| 93 112 | 
             
                  end
         | 
| 94 113 |  | 
| 114 | 
            +
                  def cucumber_opts_with_profile # :nodoc:
         | 
| 115 | 
            +
                    @profile ? "#{cucumber_opts} --profile #{@profile}" : cucumber_opts
         | 
| 116 | 
            +
                  end
         | 
| 117 | 
            +
             | 
| 95 118 | 
             
                  def feature_files(task_args = nil) # :nodoc:
         | 
| 96 119 | 
             
                    if ENV['FEATURE']
         | 
| 97 120 | 
             
                      FileList[ ENV['FEATURE'] ]
         | 
    
        data/lib/cucumber/step_mother.rb
    CHANGED
    
    | @@ -67,6 +67,21 @@ module Cucumber | |
| 67 67 | 
             
              # so #register_step_definition (and more interestingly - its aliases) are
         | 
| 68 68 | 
             
              # available from the top-level.
         | 
| 69 69 | 
             
              module StepMother
         | 
| 70 | 
            +
                class Hook
         | 
| 71 | 
            +
                  def initialize(tag_names, proc)
         | 
| 72 | 
            +
                    @tag_names = tag_names.map{|tag| Ast::Tags.strip_prefix(tag)}
         | 
| 73 | 
            +
                    @proc = proc
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  def matches_tag_names?(tag_names)
         | 
| 77 | 
            +
                    @tag_names.empty? || (@tag_names & tag_names).any?
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                  def execute_in(world, scenario, location)
         | 
| 81 | 
            +
                    world.cucumber_instance_exec(false, location, scenario, &@proc)
         | 
| 82 | 
            +
                  end
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
             | 
| 70 85 | 
             
                class << self
         | 
| 71 86 | 
             
                  def alias_adverb(adverb)
         | 
| 72 87 | 
             
                    adverb = adverb.gsub(/\s/, '')
         | 
| @@ -114,12 +129,26 @@ module Cucumber | |
| 114 129 |  | 
| 115 130 | 
             
                # Registers a Before proc. You can call this method as many times as you
         | 
| 116 131 | 
             
                # want (typically from ruby scripts under <tt>support</tt>).
         | 
| 117 | 
            -
                def Before(&proc)
         | 
| 118 | 
            -
                  ( | 
| 132 | 
            +
                def Before(*tag_names, &proc)
         | 
| 133 | 
            +
                  register_hook(:before, tag_names, proc)
         | 
| 134 | 
            +
                end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                def After(*tag_names, &proc)
         | 
| 137 | 
            +
                  register_hook(:after, tag_names, proc)
         | 
| 119 138 | 
             
                end
         | 
| 120 139 |  | 
| 121 | 
            -
                def  | 
| 122 | 
            -
                   | 
| 140 | 
            +
                def register_hook(phase, tags, proc)
         | 
| 141 | 
            +
                  hook = Hook.new(tags, proc)
         | 
| 142 | 
            +
                  hooks[phase] << hook
         | 
| 143 | 
            +
                  hook
         | 
| 144 | 
            +
                end
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                def hooks
         | 
| 147 | 
            +
                  @hooks ||= Hash.new {|hash, phase| hash[phase] = []}
         | 
| 148 | 
            +
                end
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                def hooks_for(phase, scenario)
         | 
| 151 | 
            +
                  hooks[phase].select{|hook| scenario.accept_hook?(hook)}
         | 
| 123 152 | 
             
                end
         | 
| 124 153 |  | 
| 125 154 | 
             
                # Registers any number of +world_modules+ (Ruby Modules) and/or a Proc.
         | 
| @@ -197,16 +226,22 @@ module Cucumber | |
| 197 226 | 
             
                end
         | 
| 198 227 |  | 
| 199 228 | 
             
                def before_and_after(scenario, skip=false)
         | 
| 200 | 
            -
                  unless  | 
| 229 | 
            +
                  before(scenario) unless skip
         | 
| 230 | 
            +
                  yield
         | 
| 231 | 
            +
                  after(scenario) unless skip
         | 
| 232 | 
            +
                  scenario_visited(scenario)
         | 
| 233 | 
            +
                end
         | 
| 234 | 
            +
                
         | 
| 235 | 
            +
                def before(scenario)
         | 
| 236 | 
            +
                  unless current_world
         | 
| 201 237 | 
             
                    new_world!
         | 
| 202 238 | 
             
                    execute_before(scenario)
         | 
| 203 239 | 
             
                  end
         | 
| 204 | 
            -
             | 
| 205 | 
            -
             | 
| 206 | 
            -
             | 
| 207 | 
            -
             | 
| 208 | 
            -
             | 
| 209 | 
            -
                  end
         | 
| 240 | 
            +
                end
         | 
| 241 | 
            +
                
         | 
| 242 | 
            +
                def after(scenario)
         | 
| 243 | 
            +
                  execute_after(scenario)
         | 
| 244 | 
            +
                  nil_world!
         | 
| 210 245 | 
             
                end
         | 
| 211 246 |  | 
| 212 247 | 
             
                private
         | 
| @@ -268,14 +303,14 @@ module Cucumber | |
| 268 303 | 
             
                end
         | 
| 269 304 |  | 
| 270 305 | 
             
                def execute_before(scenario)
         | 
| 271 | 
            -
                  ( | 
| 272 | 
            -
                    @current_world | 
| 306 | 
            +
                  hooks_for(:before, scenario).each do |hook|
         | 
| 307 | 
            +
                    hook.execute_in(@current_world, scenario, 'Before')
         | 
| 273 308 | 
             
                  end
         | 
| 274 309 | 
             
                end
         | 
| 275 310 |  | 
| 276 311 | 
             
                def execute_after(scenario)
         | 
| 277 | 
            -
                  ( | 
| 278 | 
            -
                    @current_world | 
| 312 | 
            +
                  hooks_for(:after, scenario).each do |hook|
         | 
| 313 | 
            +
                    hook.execute_in(@current_world, scenario, 'After')
         | 
| 279 314 | 
             
                  end
         | 
| 280 315 | 
             
                end
         | 
| 281 316 |  | 
    
        data/lib/cucumber/version.rb
    CHANGED
    
    | @@ -1,9 +1,9 @@ | |
| 1 1 | 
             
            module Cucumber #:nodoc:
         | 
| 2 2 | 
             
              class VERSION #:nodoc:
         | 
| 3 3 | 
             
                MAJOR = 0
         | 
| 4 | 
            -
                MINOR =  | 
| 5 | 
            -
                TINY  =  | 
| 6 | 
            -
                PATCH =  | 
| 4 | 
            +
                MINOR = 3
         | 
| 5 | 
            +
                TINY  = 0
         | 
| 6 | 
            +
                PATCH = nil # Set to nil for official release
         | 
| 7 7 |  | 
| 8 8 | 
             
                STRING = [MAJOR, MINOR, TINY, PATCH].compact.join('.')
         | 
| 9 9 | 
             
              end
         | 
| @@ -1,6 +1,10 @@ | |
| 1 1 | 
             
            require File.dirname(__FILE__) + '/../../spec_helper'
         | 
| 2 2 | 
             
            require 'yaml'
         | 
| 3 | 
            -
             | 
| 3 | 
            +
            begin
         | 
| 4 | 
            +
              require 'spec/runner/differs/default' # RSpec >=1.2.4
         | 
| 5 | 
            +
            rescue ::LoadError
         | 
| 6 | 
            +
              require 'spec/expectations/differs/default' # RSpec <=1.2.3
         | 
| 7 | 
            +
            end
         | 
| 4 8 |  | 
| 5 9 | 
             
            module Cucumber
         | 
| 6 10 | 
             
            module Cli
         | 
| @@ -133,5 +133,16 @@ Use Ruby modules instead to extend your worlds. See the #World RDoc. | |
| 133 133 |  | 
| 134 134 | 
             
            })
         | 
| 135 135 | 
             
                end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                it "should find before hooks" do
         | 
| 138 | 
            +
                  fish = @step_mother.Before('@fish'){}
         | 
| 139 | 
            +
                  meat = @step_mother.Before('@meat'){}
         | 
| 140 | 
            +
                  
         | 
| 141 | 
            +
                  scenario = mock('Scenario')
         | 
| 142 | 
            +
                  scenario.should_receive(:accept_hook?).with(fish).and_return(true)
         | 
| 143 | 
            +
                  scenario.should_receive(:accept_hook?).with(meat).and_return(false)
         | 
| 144 | 
            +
                  
         | 
| 145 | 
            +
                  @step_mother.hooks_for(:before, scenario).should == [fish]
         | 
| 146 | 
            +
                end
         | 
| 136 147 | 
             
              end
         | 
| 137 148 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: aslakhellesoy-cucumber
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.3.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors: 
         | 
| 7 7 | 
             
            - "Aslak Helles\xC3\xB8y"
         | 
| @@ -9,7 +9,7 @@ autorequire: | |
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 11 |  | 
| 12 | 
            -
            date: 2009-04- | 
| 12 | 
            +
            date: 2009-04-14 00:00:00 -07:00
         | 
| 13 13 | 
             
            default_executable: cucumber
         | 
| 14 14 | 
             
            dependencies: 
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -269,6 +269,8 @@ files: | |
| 269 269 | 
             
            - examples/tickets/features/177/2.feature
         | 
| 270 270 | 
             
            - examples/tickets/features/177/3.feature
         | 
| 271 271 | 
             
            - examples/tickets/features/180.feature
         | 
| 272 | 
            +
            - examples/tickets/features/229/tagged_hooks.feature
         | 
| 273 | 
            +
            - examples/tickets/features/229/tagged_hooks.rb
         | 
| 272 274 | 
             
            - examples/tickets/features/236.feature
         | 
| 273 275 | 
             
            - examples/tickets/features/241.feature
         | 
| 274 276 | 
             
            - examples/tickets/features/246.feature
         | 
| @@ -296,6 +298,7 @@ files: | |
| 296 298 | 
             
            - features/cucumber_cli_diff_disabled.feature
         | 
| 297 299 | 
             
            - features/cucumber_cli_outlines.feature
         | 
| 298 300 | 
             
            - features/custom_formatter.feature
         | 
| 301 | 
            +
            - features/rake_task.feature
         | 
| 299 302 | 
             
            - features/report_called_undefined_steps.feature
         | 
| 300 303 | 
             
            - features/snippet.feature
         | 
| 301 304 | 
             
            - features/step_definitions/cucumber_steps.rb
         |