cucumber 0.8.6 → 0.8.7

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.
Files changed (180) hide show
  1. data/.rspec +1 -1
  2. data/Caliper.yml +4 -0
  3. data/History.txt +1557 -0
  4. data/LICENSE +1 -1
  5. data/README.rdoc +26 -0
  6. data/Rakefile +51 -5
  7. data/VERSION.yml +5 -0
  8. data/bin/cucumber +1 -7
  9. data/cucumber.gemspec +77 -3
  10. data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +1 -1
  11. data/examples/i18n/he/features/step_definitons/calculator_steps.rb +1 -1
  12. data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +7 -4
  13. data/examples/i18n/ro/features/suma.feature +11 -0
  14. data/examples/i18n/ru/features/division.feature +2 -2
  15. data/examples/i18n/tr/features/step_definitons/hesap_makinesi_adimlari.rb +3 -3
  16. data/examples/sinatra/features/support/env.rb +5 -2
  17. data/examples/v8/features/fibonacci.feature +1 -1
  18. data/examples/watir/features/step_definitions/search_steps.rb +1 -1
  19. data/features/announce.feature +164 -0
  20. data/features/around_hooks.feature +232 -0
  21. data/features/background.feature +95 -284
  22. data/features/bug_371.feature +32 -0
  23. data/features/bug_464.feature +16 -0
  24. data/features/bug_475.feature +42 -0
  25. data/features/bug_585_tab_indentation.feature +22 -0
  26. data/features/bug_600.feature +67 -0
  27. data/features/call_steps_from_stepdefs.feature +154 -0
  28. data/features/cucumber_cli.feature +591 -0
  29. data/features/cucumber_cli_outlines.feature +117 -0
  30. data/features/custom_formatter.feature +73 -3
  31. data/features/default_snippets.feature +42 -0
  32. data/features/diffing.feature +25 -0
  33. data/features/drb_server_integration.feature +174 -0
  34. data/features/exception_in_after_block.feature +127 -0
  35. data/features/exception_in_after_step_block.feature +104 -0
  36. data/features/exception_in_before_block.feature +98 -0
  37. data/features/exclude_files.feature +20 -0
  38. data/features/expand.feature +60 -0
  39. data/features/html_formatter.feature +8 -0
  40. data/features/html_formatter/a.html +582 -0
  41. data/features/json_formatter.feature +245 -160
  42. data/features/junit_formatter.feature +88 -0
  43. data/features/language_from_header.feature +30 -0
  44. data/features/language_help.feature +78 -0
  45. data/features/listener_debugger_formatter.feature +42 -0
  46. data/features/multiline_names.feature +44 -0
  47. data/features/negative_tagged_hooks.feature +60 -0
  48. data/features/post_configuration_hook.feature +37 -0
  49. data/features/profiles.feature +126 -0
  50. data/features/rake_task.feature +152 -0
  51. data/features/report_called_undefined_steps.feature +34 -0
  52. data/features/rerun_formatter.feature +45 -0
  53. data/features/simplest.feature +11 -0
  54. data/features/snippet.feature +23 -0
  55. data/features/snippets_when_using_star_keyword.feature +36 -0
  56. data/features/step_definitions/cucumber_steps.rb +153 -7
  57. data/features/step_definitions/extra_steps.rb +2 -0
  58. data/features/step_definitions/simplest_steps.rb +3 -0
  59. data/features/step_definitions/wire_steps.rb +32 -0
  60. data/features/support/env.rb +140 -18
  61. data/features/support/env.rb.simplest +7 -0
  62. data/features/support/fake_wire_server.rb +77 -0
  63. data/features/table_diffing.feature +45 -0
  64. data/features/table_mapping.feature +34 -0
  65. data/features/tag_logic.feature +258 -0
  66. data/features/transform.feature +245 -0
  67. data/features/unicode_table.feature +35 -0
  68. data/features/usage_and_stepdefs_formatter.feature +169 -0
  69. data/features/wire_protocol.feature +332 -0
  70. data/features/wire_protocol_table_diffing.feature +119 -0
  71. data/features/wire_protocol_tags.feature +87 -0
  72. data/features/wire_protocol_timeouts.feature +63 -0
  73. data/features/work_in_progress.feature +156 -0
  74. data/fixtures/json/features/pystring.feature +8 -0
  75. data/fixtures/junit/features/pending.feature +1 -3
  76. data/fixtures/self_test/features/background/background_tagged_before_on_outline.feature +12 -0
  77. data/fixtures/self_test/features/background/background_with_name.feature +7 -0
  78. data/fixtures/self_test/features/background/failing_background.feature +12 -0
  79. data/fixtures/self_test/features/background/failing_background_after_success.feature +11 -0
  80. data/fixtures/self_test/features/background/multiline_args_background.feature +32 -0
  81. data/fixtures/self_test/features/background/passing_background.feature +10 -0
  82. data/fixtures/self_test/features/background/pending_background.feature +10 -0
  83. data/fixtures/self_test/features/background/scenario_outline_failing_background.feature +16 -0
  84. data/fixtures/self_test/features/background/scenario_outline_passing_background.feature +16 -0
  85. data/fixtures/self_test/features/support/env.rb +0 -8
  86. data/fixtures/tickets/features.html +1 -1
  87. data/gem_tasks/examples.rake +1 -1
  88. data/gem_tasks/features.rake +14 -0
  89. data/gem_tasks/sdoc.rake +12 -0
  90. data/lib/cucumber.rb +0 -12
  91. data/lib/cucumber/ast.rb +1 -1
  92. data/lib/cucumber/ast/background.rb +5 -21
  93. data/lib/cucumber/ast/examples.rb +4 -12
  94. data/lib/cucumber/ast/feature.rb +5 -13
  95. data/lib/cucumber/ast/feature_element.rb +4 -9
  96. data/lib/cucumber/ast/outline_table.rb +4 -4
  97. data/lib/cucumber/ast/py_string.rb +80 -0
  98. data/lib/cucumber/ast/scenario.rb +5 -7
  99. data/lib/cucumber/ast/scenario_outline.rb +15 -23
  100. data/lib/cucumber/ast/step.rb +0 -5
  101. data/lib/cucumber/ast/step_invocation.rb +15 -21
  102. data/lib/cucumber/ast/table.rb +8 -14
  103. data/lib/cucumber/ast/tree_walker.rb +48 -10
  104. data/lib/cucumber/cli/configuration.rb +8 -33
  105. data/lib/cucumber/cli/main.rb +35 -20
  106. data/lib/cucumber/cli/options.rb +7 -8
  107. data/lib/cucumber/cli/profile_loader.rb +0 -2
  108. data/lib/cucumber/core_ext/proc.rb +1 -2
  109. data/lib/cucumber/feature_file.rb +15 -47
  110. data/lib/cucumber/formatter/ansicolor.rb +5 -3
  111. data/lib/cucumber/formatter/color_io.rb +23 -0
  112. data/lib/cucumber/formatter/console.rb +23 -27
  113. data/lib/cucumber/formatter/cucumber.css +17 -34
  114. data/lib/cucumber/formatter/cucumber.sass +182 -173
  115. data/lib/cucumber/formatter/html.rb +11 -46
  116. data/lib/cucumber/formatter/io.rb +4 -2
  117. data/lib/cucumber/formatter/json.rb +152 -15
  118. data/lib/cucumber/formatter/json_pretty.rb +6 -5
  119. data/lib/cucumber/formatter/junit.rb +22 -28
  120. data/lib/cucumber/formatter/pdf.rb +6 -6
  121. data/lib/cucumber/formatter/pretty.rb +5 -5
  122. data/lib/cucumber/formatter/rerun.rb +11 -22
  123. data/lib/cucumber/formatter/tag_cloud.rb +35 -0
  124. data/lib/cucumber/formatter/unicode.rb +20 -41
  125. data/lib/cucumber/js_support/js_dsl.js +4 -4
  126. data/lib/cucumber/js_support/js_language.rb +5 -9
  127. data/lib/cucumber/js_support/js_snippets.rb +2 -2
  128. data/lib/cucumber/language_support.rb +2 -2
  129. data/lib/cucumber/parser/gherkin_builder.rb +30 -35
  130. data/lib/cucumber/platform.rb +8 -8
  131. data/lib/cucumber/py_support/py_language.rb +2 -2
  132. data/lib/cucumber/rake/task.rb +31 -74
  133. data/lib/cucumber/rb_support/rb_dsl.rb +0 -1
  134. data/lib/cucumber/rb_support/rb_language.rb +8 -10
  135. data/lib/cucumber/rb_support/rb_step_definition.rb +0 -8
  136. data/lib/cucumber/rb_support/rb_transform.rb +0 -17
  137. data/lib/cucumber/rb_support/rb_world.rb +18 -26
  138. data/lib/cucumber/rspec/doubles.rb +3 -3
  139. data/lib/cucumber/step_match.rb +2 -6
  140. data/lib/cucumber/step_mother.rb +427 -6
  141. data/lib/cucumber/wire_support/configuration.rb +1 -4
  142. data/lib/cucumber/wire_support/wire_language.rb +10 -3
  143. data/spec/cucumber/ast/background_spec.rb +6 -68
  144. data/spec/cucumber/ast/feature_factory.rb +4 -5
  145. data/spec/cucumber/ast/feature_spec.rb +4 -4
  146. data/spec/cucumber/ast/outline_table_spec.rb +1 -1
  147. data/spec/cucumber/ast/py_string_spec.rb +40 -0
  148. data/spec/cucumber/ast/scenario_outline_spec.rb +11 -15
  149. data/spec/cucumber/ast/scenario_spec.rb +4 -4
  150. data/spec/cucumber/ast/step_spec.rb +3 -3
  151. data/spec/cucumber/ast/table_spec.rb +2 -38
  152. data/spec/cucumber/ast/tree_walker_spec.rb +2 -2
  153. data/spec/cucumber/broadcaster_spec.rb +1 -1
  154. data/spec/cucumber/cli/configuration_spec.rb +6 -32
  155. data/spec/cucumber/cli/drb_client_spec.rb +3 -2
  156. data/spec/cucumber/cli/main_spec.rb +43 -43
  157. data/spec/cucumber/cli/options_spec.rb +1 -28
  158. data/spec/cucumber/cli/profile_loader_spec.rb +1 -1
  159. data/spec/cucumber/core_ext/proc_spec.rb +1 -1
  160. data/spec/cucumber/formatter/ansicolor_spec.rb +1 -1
  161. data/spec/cucumber/formatter/color_io_spec.rb +29 -0
  162. data/spec/cucumber/formatter/duration_spec.rb +1 -1
  163. data/spec/cucumber/formatter/html_spec.rb +5 -3
  164. data/spec/cucumber/formatter/junit_spec.rb +2 -16
  165. data/spec/cucumber/formatter/progress_spec.rb +1 -1
  166. data/spec/cucumber/formatter/spec_helper.rb +12 -11
  167. data/spec/cucumber/rb_support/rb_language_spec.rb +28 -241
  168. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +28 -33
  169. data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +1 -1
  170. data/spec/cucumber/step_match_spec.rb +9 -11
  171. data/spec/cucumber/step_mother_spec.rb +302 -0
  172. data/spec/cucumber/wire_support/configuration_spec.rb +1 -1
  173. data/spec/cucumber/wire_support/connection_spec.rb +1 -1
  174. data/spec/cucumber/wire_support/wire_exception_spec.rb +1 -1
  175. data/spec/cucumber/wire_support/wire_language_spec.rb +1 -1
  176. data/spec/cucumber/wire_support/wire_packet_spec.rb +1 -1
  177. data/spec/cucumber/wire_support/wire_step_definition_spec.rb +1 -1
  178. data/spec/cucumber/world/pending_spec.rb +2 -2
  179. data/spec/spec_helper.rb +20 -13
  180. metadata +78 -4
@@ -0,0 +1,2 @@
1
+ Given /^missing$/ do
2
+ end
@@ -0,0 +1,3 @@
1
+ Given /^this step works$/ do
2
+ end
3
+
@@ -0,0 +1,32 @@
1
+ Given /^there is a wire server (running |)on port (\d+) which understands the following protocol:$/ do |running, port, table|
2
+ protocol = table.hashes
3
+ @server = FakeWireServer.new(port.to_i, protocol)
4
+ start_wire_server if running.strip == "running"
5
+ end
6
+
7
+ Given /^the wire server takes (.*) seconds to respond to the invoke message$/ do |timeout|
8
+ @server.delay_response(:invoke, timeout.to_f)
9
+ start_wire_server
10
+ end
11
+
12
+ module WireHelper
13
+ def start_wire_server
14
+ @wire_pid = fork do
15
+ @server.run
16
+ end
17
+ end
18
+
19
+ def stop_wire_server
20
+ return unless @wire_pid
21
+ Process.kill('KILL', @wire_pid)
22
+ Process.wait
23
+ end
24
+ end
25
+
26
+ Before('@wire') do
27
+ extend(WireHelper)
28
+ end
29
+
30
+ After('@wire') do
31
+ stop_wire_server
32
+ end
@@ -1,26 +1,148 @@
1
- ENV['FORCE_COLOR'] = 'true'
2
- require 'aruba/api'
3
- require 'aruba/cucumber'
1
+ require 'rubygems'
2
+ require 'tempfile'
3
+ begin
4
+ require 'rspec/expectations'
5
+ rescue LoadError
6
+ require 'spec/expectations'
7
+ end
8
+ require 'fileutils'
9
+ require 'forwardable'
10
+ require 'cucumber/formatter/unicode'
11
+
12
+ class CucumberWorld
13
+ extend Forwardable
14
+ def_delegators CucumberWorld, :fixtures_dir, :self_test_dir, :working_dir, :cucumber_lib_dir
15
+
16
+ def self.fixtures_dir(subdir=nil)
17
+ @fixtures_dir ||= File.expand_path(File.join(File.dirname(__FILE__), '../../fixtures'))
18
+ subdir ? File.join(@fixtures_dir, subdir) : @fixtures_dir
19
+ end
20
+
21
+ def self.self_test_dir
22
+ @self_test_dir ||= fixtures_dir('self_test')
23
+ end
24
+
25
+ def self.working_dir
26
+ @working_dir ||= fixtures_dir('self_test/tmp')
27
+ end
28
+
29
+ def cucumber_lib_dir
30
+ @cucumber_lib_dir ||= File.expand_path(File.join(File.dirname(__FILE__), '../../lib'))
31
+ end
32
+
33
+ def initialize
34
+ @current_dir = self_test_dir
35
+ end
36
+
37
+ private
38
+ attr_reader :last_exit_status, :last_stderr
39
+
40
+ # The last standard out, with the duration line taken out (unpredictable)
41
+ def last_stdout
42
+ strip_1_9_paths(strip_duration(@last_stdout))
43
+ end
44
+
45
+ def combined_output
46
+ last_stdout + "\n" + last_stderr
47
+ end
48
+
49
+ def strip_duration(s)
50
+ s.gsub(/^\d+m\d+\.\d+s\n/m, "")
51
+ end
52
+
53
+ def strip_1_9_paths(s)
54
+ s.gsub(/#{Dir.pwd}\/fixtures\/self_test\/tmp/m, ".").gsub(/#{Dir.pwd}\/fixtures\/self_test/m, ".")
55
+ end
56
+
57
+ def replace_duration(s, replacement)
58
+ s.gsub(/\d+m\d+\.\d+s/m, replacement)
59
+ end
4
60
 
5
- # Monkey patch aruba to filter out some stuff
6
- module Aruba::Api
7
- alias __all_stdout all_stdout
8
-
9
- def all_stdout
10
- unrandom(__all_stdout)
61
+ def replace_junit_duration(s, replacement)
62
+ s.gsub(/\d+\.\d\d+/m, replacement)
11
63
  end
12
64
 
13
- def unrandom(out)
14
- out = out.gsub(/#{Dir.pwd}\/tmp\/aruba/, '.') # Remove absolute paths
15
- out = out.gsub(/^\d+m\d+\.\d+s$/, '0m0.012s') # Make duration predictable
16
- out = out.gsub(/Coverage report generated for Cucumber Features to #{Dir.pwd}\/coverage.*\n$/, '') # Remove SimpleCov message
65
+ def strip_ruby186_extra_trace(s)
66
+ s.gsub(/^.*\.\/features\/step_definitions(.*)\n/, "")
17
67
  end
68
+
69
+ def create_file(file_name, file_content)
70
+ file_content.gsub!("CUCUMBER_LIB", "'#{cucumber_lib_dir}'") # Some files, such as Rakefiles need to use the lib dir
71
+ in_current_dir do
72
+ FileUtils.mkdir_p(File.dirname(file_name)) unless File.directory?(File.dirname(file_name))
73
+ File.open(file_name, 'w') { |f| f << file_content }
74
+ end
75
+ end
76
+
77
+ def set_env_var(variable, value)
78
+ @original_env_vars ||= {}
79
+ @original_env_vars[variable] = ENV[variable]
80
+ ENV[variable] = value
81
+ end
82
+
83
+ def background_jobs
84
+ @background_jobs ||= []
85
+ end
86
+
87
+ def in_current_dir(&block)
88
+ Dir.chdir(@current_dir, &block)
89
+ end
90
+
91
+ def run(command)
92
+ stderr_file = Tempfile.new('cucumber')
93
+ stderr_file.close
94
+ in_current_dir do
95
+ mode = Cucumber::RUBY_1_9 ? {:external_encoding=>"UTF-8"} : 'r'
96
+ IO.popen("#{command} 2> #{stderr_file.path}", mode) do |io|
97
+ @last_stdout = io.read
98
+ end
99
+
100
+ @last_exit_status = $?.exitstatus
101
+ end
102
+ @last_stderr = IO.read(stderr_file.path)
103
+ end
104
+
105
+ def run_spork_in_background(port = nil)
106
+ require 'spork'
107
+
108
+ pid = fork
109
+ in_current_dir do
110
+ if pid
111
+ background_jobs << pid
112
+ else
113
+ # STDOUT.close
114
+ # STDERR.close
115
+ port_arg = port ? "-p #{port}" : ''
116
+ cmd = "#{Cucumber::RUBY_BINARY} -I #{Cucumber::LIBDIR} #{Spork::BINARY} cuc #{port_arg}"
117
+ exec cmd
118
+ end
119
+ end
120
+ sleep 1.0
121
+ end
122
+
123
+ def terminate_background_jobs
124
+ background_jobs.each do |pid|
125
+ Process.kill(Signal.list['TERM'], pid)
126
+ end
127
+ end
128
+
129
+ def restore_original_env_vars
130
+ @original_env_vars.each { |variable, value| ENV[variable] = value } if @original_env_vars
131
+ end
132
+
133
+ end
134
+
135
+ World do
136
+ CucumberWorld.new
18
137
  end
19
138
 
20
139
  Before do
21
- # Make sure bin/cucumber runs with SimpleCov enabled
22
- # set_env('SIMPLECOV', 'true')
23
-
24
- # Set a longer timeout for aruba
25
- @aruba_timeout_seconds = 5
140
+ FileUtils.rm_rf CucumberWorld.working_dir
141
+ FileUtils.mkdir CucumberWorld.working_dir
142
+ end
143
+
144
+ After do
145
+ FileUtils.rm_rf CucumberWorld.working_dir unless ENV['KEEP_FILES']
146
+ terminate_background_jobs
147
+ restore_original_env_vars
26
148
  end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+
3
+ class SomeException < Exception; end
4
+
5
+ Before do
6
+ raise SomeException.new("I cannot even start this scenario")
7
+ end
@@ -0,0 +1,77 @@
1
+ require 'socket'
2
+ require 'json'
3
+
4
+ class FakeWireServer
5
+ def initialize(port, protocol_table)
6
+ @port, @protocol_table = port, protocol_table
7
+ @delays = {}
8
+ end
9
+
10
+ def run
11
+ @server = TCPServer.open(@port)
12
+ loop { handle_connections }
13
+ end
14
+
15
+ def delay_response(message, delay)
16
+ @delays[message] = delay
17
+ end
18
+
19
+ private
20
+
21
+ def handle_connections
22
+ Thread.start(@server.accept) { |socket| open_session_on socket }
23
+ end
24
+
25
+ def open_session_on(socket)
26
+ begin
27
+ SocketSession.new(socket, @protocol_table, @delays).start
28
+ rescue Exception => e
29
+ raise e
30
+ ensure
31
+ socket.close
32
+ end
33
+ end
34
+
35
+ class SocketSession
36
+ def initialize(socket, protocol, delays)
37
+ @socket = socket
38
+ @protocol = protocol
39
+ @delays = delays
40
+ end
41
+
42
+ def start
43
+ while message = @socket.gets
44
+ handle(message)
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def handle(data)
51
+ if protocol_entry = response_to(data.strip)
52
+ sleep delay(data)
53
+ send_response(protocol_entry['response'])
54
+ else
55
+ serialized_exception = { :message => "Not understood: #{data}", :backtrace => [] }
56
+ send_response(['fail', serialized_exception ].to_json)
57
+ end
58
+ rescue => e
59
+ send_response(['fail', { :message => e.message, :backtrace => e.backtrace, :exception => e.class } ].to_json)
60
+ end
61
+
62
+ def response_to(data)
63
+ @protocol.detect do |entry|
64
+ JSON.parse(entry['request']) == JSON.parse(data)
65
+ end
66
+ end
67
+
68
+ def send_response(response)
69
+ @socket.puts response + "\n"
70
+ end
71
+
72
+ def delay(data)
73
+ message = JSON.parse(data.strip)[0]
74
+ @delays[message.to_sym] || 0
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,45 @@
1
+ Feature: Table diffing
2
+ In order to more easily compare data in tables
3
+ step definition writers should be able to diff
4
+ a table with expected data and see the diff inline
5
+
6
+ Scenario: Extra row
7
+ Given a standard Cucumber project directory structure
8
+ And a file named "features/tables.feature" with:
9
+ """
10
+ Feature: Tables
11
+ Scenario: Extra row
12
+ Then the table should be:
13
+ | x | y |
14
+ | a | b |
15
+ """
16
+ And a file named "features/step_definitions/table_steps.rb" with:
17
+ """
18
+ Then /the table should be:/ do |expected| x=1
19
+ expected.diff!(table(%{
20
+ | x | y |
21
+ | a | c |
22
+ }))
23
+ end
24
+ """
25
+ When I run cucumber -i features/tables.feature
26
+ Then it should fail with
27
+ """
28
+ Feature: Tables
29
+
30
+ Scenario: Extra row # features/tables.feature:2
31
+ Then the table should be: # features/step_definitions/table_steps.rb:1
32
+ | x | y |
33
+ | a | b |
34
+ | a | c |
35
+ Tables were not identical (Cucumber::Ast::Table::Different)
36
+ ./features/step_definitions/table_steps.rb:2:in `/the table should be:/'
37
+ features/tables.feature:3:in `Then the table should be:'
38
+
39
+ Failing Scenarios:
40
+ cucumber features/tables.feature:2 # Scenario: Extra row
41
+
42
+ 1 scenario (1 failed)
43
+ 1 step (1 failed)
44
+
45
+ """
@@ -0,0 +1,34 @@
1
+ Feature: Table mapping
2
+ Scenario: Mapping table shouldn't change output
3
+ Given a standard Cucumber project directory structure
4
+ And a file named "features/f.feature" with:
5
+ """
6
+ Feature: F
7
+ Scenario: S
8
+ Given a table:
9
+ | who |
10
+ | aslak |
11
+ """
12
+ And a file named "features/step_definitions/steps.rb" with:
13
+ """
14
+ Given(/a table:/) { |table| table.map_headers!(/who/i => 'Who')
15
+ table.map_column!('Who') { |who| "Cuke" }
16
+ table.hashes[0]['Who'] = "Joe"
17
+ table.hashes.should == [{"Who"=>"Joe"}]
18
+ }
19
+ """
20
+ When I run cucumber features/f.feature
21
+ Then STDERR should be empty
22
+ And it should pass with
23
+ """
24
+ Feature: F
25
+
26
+ Scenario: S # features/f.feature:2
27
+ Given a table: # features/step_definitions/steps.rb:1
28
+ | who |
29
+ | aslak |
30
+
31
+ 1 scenario (1 passed)
32
+ 1 step (1 passed)
33
+
34
+ """
@@ -0,0 +1,258 @@
1
+ Feature: Tag logic
2
+ In order to conveniently run subsets of features
3
+ As a Cuker
4
+ I want to select features using logical AND/OR of tags
5
+
6
+ Background:
7
+ Given a standard Cucumber project directory structure
8
+ And a file named "features/tagulicious.feature" with:
9
+ """
10
+ Feature: Sample
11
+
12
+ @one @three
13
+ Scenario: Example
14
+ Given passing
15
+
16
+ @one
17
+ Scenario: Another Example
18
+ Given passing
19
+
20
+ @three
21
+ Scenario: Yet another Example
22
+ Given passing
23
+
24
+ @ignore
25
+ Scenario: And yet another Example
26
+ """
27
+
28
+ Scenario: ANDing tags
29
+ When I run cucumber -q -t @one -t @three features/tagulicious.feature
30
+ Then it should pass
31
+ And the output should contain
32
+ """
33
+ Feature: Sample
34
+
35
+ @one @three
36
+ Scenario: Example
37
+ Given passing
38
+
39
+ 1 scenario (1 undefined)
40
+ 1 step (1 undefined)
41
+
42
+ """
43
+
44
+ Scenario: ORing tags
45
+ When I run cucumber -q -t @one,@three features/tagulicious.feature
46
+ Then it should pass
47
+ And the output should contain
48
+ """
49
+ Feature: Sample
50
+
51
+ @one @three
52
+ Scenario: Example
53
+ Given passing
54
+
55
+ @one
56
+ Scenario: Another Example
57
+ Given passing
58
+
59
+ @three
60
+ Scenario: Yet another Example
61
+ Given passing
62
+
63
+ 3 scenarios (3 undefined)
64
+ 3 steps (3 undefined)
65
+
66
+ """
67
+
68
+ Scenario: Before hooks ORing
69
+ Given a file named "features/support/hooks.rb" with:
70
+ """
71
+ Before('@one,@three') do
72
+ raise 'boom'
73
+ end
74
+ """
75
+ When I run cucumber -q features/tagulicious.feature
76
+ Then it should fail with
77
+ """
78
+ Feature: Sample
79
+
80
+ @one @three
81
+ Scenario: Example
82
+ boom (RuntimeError)
83
+ ./features/support/hooks.rb:2:in `Before'
84
+ Given passing
85
+
86
+ @one
87
+ Scenario: Another Example
88
+ boom (RuntimeError)
89
+ ./features/support/hooks.rb:2:in `Before'
90
+ Given passing
91
+
92
+ @three
93
+ Scenario: Yet another Example
94
+ boom (RuntimeError)
95
+ ./features/support/hooks.rb:2:in `Before'
96
+ Given passing
97
+
98
+ @ignore
99
+ Scenario: And yet another Example
100
+
101
+ Failing Scenarios:
102
+ cucumber features/tagulicious.feature:4 # Scenario: Example
103
+ cucumber features/tagulicious.feature:8 # Scenario: Another Example
104
+ cucumber features/tagulicious.feature:12 # Scenario: Yet another Example
105
+
106
+ 4 scenarios (3 failed, 1 passed)
107
+ 3 steps (3 undefined)
108
+
109
+ """
110
+
111
+ Scenario: Before hooks ANDing
112
+ Given a file named "features/support/hooks.rb" with:
113
+ """
114
+ Before('@one','@three') do
115
+ raise 'boom'
116
+ end
117
+ """
118
+ When I run cucumber -q features/tagulicious.feature
119
+ Then it should fail with
120
+ """
121
+ Feature: Sample
122
+
123
+ @one @three
124
+ Scenario: Example
125
+ boom (RuntimeError)
126
+ ./features/support/hooks.rb:2:in `Before'
127
+ Given passing
128
+
129
+ @one
130
+ Scenario: Another Example
131
+ Given passing
132
+
133
+ @three
134
+ Scenario: Yet another Example
135
+ Given passing
136
+
137
+ @ignore
138
+ Scenario: And yet another Example
139
+
140
+ Failing Scenarios:
141
+ cucumber features/tagulicious.feature:4 # Scenario: Example
142
+
143
+ 4 scenarios (1 failed, 2 undefined, 1 passed)
144
+ 3 steps (3 undefined)
145
+
146
+ """
147
+
148
+ Scenario: Before hooks ANDing with a bad hook matching nothing
149
+ Given a file named "features/support/hooks.rb" with:
150
+ """
151
+ Before('@one','@notused') do
152
+ raise 'boom'
153
+ end
154
+ """
155
+ When I run cucumber -q features/tagulicious.feature
156
+ Then it should pass with
157
+ """
158
+ Feature: Sample
159
+
160
+ @one @three
161
+ Scenario: Example
162
+ Given passing
163
+
164
+ @one
165
+ Scenario: Another Example
166
+ Given passing
167
+
168
+ @three
169
+ Scenario: Yet another Example
170
+ Given passing
171
+
172
+ @ignore
173
+ Scenario: And yet another Example
174
+
175
+ 4 scenarios (3 undefined, 1 passed)
176
+ 3 steps (3 undefined)
177
+
178
+ """
179
+
180
+ Scenario: After hooks ORing
181
+ Given a file named "features/support/hooks.rb" with:
182
+ """
183
+ After('@one,@three') do
184
+ raise 'boom'
185
+ end
186
+ """
187
+ When I run cucumber -q features/tagulicious.feature
188
+ Then it should fail with
189
+ """
190
+ Feature: Sample
191
+
192
+ @one @three
193
+ Scenario: Example
194
+ Given passing
195
+ boom (RuntimeError)
196
+ ./features/support/hooks.rb:2:in `After'
197
+
198
+ @one
199
+ Scenario: Another Example
200
+ Given passing
201
+ boom (RuntimeError)
202
+ ./features/support/hooks.rb:2:in `After'
203
+
204
+ @three
205
+ Scenario: Yet another Example
206
+ Given passing
207
+ boom (RuntimeError)
208
+ ./features/support/hooks.rb:2:in `After'
209
+
210
+ @ignore
211
+ Scenario: And yet another Example
212
+
213
+ Failing Scenarios:
214
+ cucumber features/tagulicious.feature:4 # Scenario: Example
215
+ cucumber features/tagulicious.feature:8 # Scenario: Another Example
216
+ cucumber features/tagulicious.feature:12 # Scenario: Yet another Example
217
+
218
+ 4 scenarios (3 failed, 1 passed)
219
+ 3 steps (3 undefined)
220
+
221
+ """
222
+
223
+ Scenario: After hooks ANDing
224
+ Given a file named "features/support/hooks.rb" with:
225
+ """
226
+ After('@one','@three') do
227
+ raise 'boom'
228
+ end
229
+ """
230
+ When I run cucumber -q features/tagulicious.feature
231
+ Then it should fail with
232
+ """
233
+ Feature: Sample
234
+
235
+ @one @three
236
+ Scenario: Example
237
+ Given passing
238
+ boom (RuntimeError)
239
+ ./features/support/hooks.rb:2:in `After'
240
+
241
+ @one
242
+ Scenario: Another Example
243
+ Given passing
244
+
245
+ @three
246
+ Scenario: Yet another Example
247
+ Given passing
248
+
249
+ @ignore
250
+ Scenario: And yet another Example
251
+
252
+ Failing Scenarios:
253
+ cucumber features/tagulicious.feature:4 # Scenario: Example
254
+
255
+ 4 scenarios (1 failed, 2 undefined, 1 passed)
256
+ 3 steps (3 undefined)
257
+
258
+ """