cucumber 2.0.0.beta.2 → 2.0.0.beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/History.md +25 -7
- data/cucumber.gemspec +1 -1
- data/features/docs/defining_steps/nested_steps.feature +0 -1
- data/features/docs/defining_steps/printing_messages.feature +1 -0
- data/features/docs/defining_steps/table_diffing.feature +9 -4
- data/features/docs/exception_in_after_step_hook.feature +1 -0
- data/features/docs/formatters/json_formatter.feature +51 -4
- data/features/docs/formatters/junit_formatter.feature +1 -0
- data/features/docs/gherkin/outlines.feature +4 -0
- data/features/docs/output_from_hooks.feature +128 -0
- data/features/docs/wire_protocol_table_diffing.feature +6 -2
- data/features/docs/writing_support_code/after_hooks.feature +56 -0
- data/lib/cucumber/cli/configuration.rb +0 -4
- data/lib/cucumber/cli/main.rb +0 -1
- data/lib/cucumber/cli/options.rb +0 -3
- data/lib/cucumber/formatter/console.rb +3 -1
- data/lib/cucumber/formatter/debug.rb +4 -0
- data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +26 -3
- data/lib/cucumber/formatter/html.rb +6 -2
- data/lib/cucumber/formatter/usage.rb +1 -58
- data/lib/cucumber/mappings.rb +25 -7
- data/lib/cucumber/multiline_argument.rb +40 -82
- data/lib/cucumber/multiline_argument/data_table.rb +719 -0
- data/lib/cucumber/multiline_argument/doc_string.rb +10 -0
- data/lib/cucumber/platform.rb +1 -1
- data/lib/cucumber/rb_support/rb_world.rb +2 -4
- data/lib/cucumber/reports/legacy_formatter.rb +69 -22
- data/lib/cucumber/runtime.rb +0 -39
- data/lib/cucumber/runtime/for_programming_languages.rb +12 -10
- data/lib/cucumber/runtime/support_code.rb +11 -4
- data/lib/cucumber/wire_support/wire_protocol/requests.rb +2 -2
- data/spec/cucumber/formatter/pretty_spec.rb +5 -5
- data/spec/cucumber/mappings_spec.rb +137 -8
- data/spec/cucumber/multiline_argument/data_table_spec.rb +508 -0
- data/spec/cucumber/rb_support/rb_step_definition_spec.rb +3 -3
- data/spec/cucumber/rb_support/snippet_spec.rb +1 -1
- data/spec/cucumber/runtime/for_programming_languages_spec.rb +16 -12
- metadata +13 -6
- data/lib/cucumber/runtime/features_loader.rb +0 -62
data/lib/cucumber/platform.rb
CHANGED
@@ -4,7 +4,7 @@ require 'rbconfig'
|
|
4
4
|
|
5
5
|
module Cucumber
|
6
6
|
unless defined?(Cucumber::VERSION)
|
7
|
-
VERSION = '2.0.0.beta.
|
7
|
+
VERSION = '2.0.0.beta.3'
|
8
8
|
BINARY = File.expand_path(File.dirname(__FILE__) + '/../../bin/cucumber')
|
9
9
|
LIBDIR = File.expand_path(File.dirname(__FILE__) + '/../../lib')
|
10
10
|
JRUBY = defined?(JRUBY_VERSION)
|
@@ -36,10 +36,8 @@ module Cucumber
|
|
36
36
|
# @param [String] name The name of the step
|
37
37
|
# @param [String,Cucumber::Ast::DocString,Cucumber::Ast::Table] multiline_argument
|
38
38
|
def step(name, raw_multiline_arg=nil)
|
39
|
-
|
40
|
-
|
41
|
-
core_multiline_arg = Core::Ast::MultilineArgument.from(raw_multiline_arg, location)
|
42
|
-
@__cucumber_runtime.invoke(name, MultilineArgument.from(core_multiline_arg), location)
|
39
|
+
location = Core::Ast::Location.of_caller
|
40
|
+
@__cucumber_runtime.invoke(name, MultilineArgument.from(raw_multiline_arg, location))
|
43
41
|
end
|
44
42
|
|
45
43
|
# Run a snippet of Gherkin
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
require 'delegate'
|
3
3
|
require 'cucumber/errors'
|
4
|
+
require 'cucumber/multiline_argument'
|
4
5
|
|
5
6
|
module Cucumber
|
6
7
|
module Reports
|
@@ -220,29 +221,41 @@ module Cucumber
|
|
220
221
|
def after_test_case(*args)
|
221
222
|
if current_test_step_source.step_result.nil?
|
222
223
|
switch_step_container
|
223
|
-
@delayed_messages = []
|
224
|
-
@delayed_embeddings = []
|
225
224
|
end
|
225
|
+
|
226
|
+
# messages and embedding should already have been handled, but just in case...
|
227
|
+
@delayed_messages.each { |message| formatter.puts(message) }
|
228
|
+
@delayed_embeddings.each { |embedding| embedding.send_to_formatter(formatter) }
|
229
|
+
@delayed_messages = []
|
230
|
+
@delayed_embeddings = []
|
231
|
+
|
226
232
|
@child.after_test_case
|
227
233
|
@previous_test_case_background = @current_test_case_background
|
228
234
|
@previous_test_case_scenario_outline = current_test_step_source.scenario_outline
|
229
235
|
end
|
230
236
|
|
231
237
|
def before_hook(location, result)
|
232
|
-
@before_hook_results << Legacy::Ast::HookResult.new(LegacyResultBuilder.new(result))
|
238
|
+
@before_hook_results << Legacy::Ast::HookResult.new(LegacyResultBuilder.new(result), @delayed_messages, @delayed_embeddings)
|
239
|
+
@delayed_messages = []
|
240
|
+
@delayed_embeddings = []
|
233
241
|
end
|
234
242
|
|
235
243
|
def after_hook(location, result)
|
236
244
|
# if the scenario has no steps, we can hit this before we've created the scenario printer
|
237
245
|
# ideally we should call switch_step_container in before_step_step
|
238
246
|
switch_step_container if !@child
|
239
|
-
@child.after_hook Legacy::Ast::HookResult.new(LegacyResultBuilder.new(result))
|
247
|
+
@child.after_hook Legacy::Ast::HookResult.new(LegacyResultBuilder.new(result), @delayed_messages, @delayed_embeddings)
|
248
|
+
@delayed_messages = []
|
249
|
+
@delayed_embeddings = []
|
240
250
|
end
|
241
251
|
|
242
252
|
def after_step_hook(hook, result)
|
243
253
|
line = StepBacktraceLine.new(current_test_step_source.step)
|
244
|
-
@child.after_step_hook LegacyResultBuilder.new(result).
|
245
|
-
append_to_exception_backtrace(line)
|
254
|
+
@child.after_step_hook Legacy::Ast::HookResult.new(LegacyResultBuilder.new(result).
|
255
|
+
append_to_exception_backtrace(line), @delayed_messages, @delayed_embeddings)
|
256
|
+
@delayed_messages = []
|
257
|
+
@delayed_embeddings = []
|
258
|
+
|
246
259
|
end
|
247
260
|
|
248
261
|
def background(node, *)
|
@@ -417,7 +430,7 @@ module Cucumber
|
|
417
430
|
end
|
418
431
|
|
419
432
|
def after_step_hook(result)
|
420
|
-
result.
|
433
|
+
result.accept formatter
|
421
434
|
end
|
422
435
|
|
423
436
|
def step_invocation(step_invocation, source)
|
@@ -485,7 +498,7 @@ module Cucumber
|
|
485
498
|
end
|
486
499
|
|
487
500
|
def after_step_hook(result)
|
488
|
-
result.
|
501
|
+
result.accept formatter
|
489
502
|
end
|
490
503
|
|
491
504
|
def after_test_case(*args)
|
@@ -726,7 +739,8 @@ module Cucumber
|
|
726
739
|
include PrintsAfterHooks
|
727
740
|
|
728
741
|
def after_step_hook(result)
|
729
|
-
@after_step_hook_result
|
742
|
+
@after_step_hook_result ||= []
|
743
|
+
@after_step_hook_result.push result
|
730
744
|
end
|
731
745
|
|
732
746
|
def after_test_case(*args)
|
@@ -791,7 +805,7 @@ module Cucumber
|
|
791
805
|
formatter.after_table_cell(value)
|
792
806
|
end
|
793
807
|
formatter.after_table_row(legacy_table_row)
|
794
|
-
@after_step_hook_result.
|
808
|
+
@after_step_hook_result.each { |result| result.accept formatter } if @after_step_hook_result
|
795
809
|
after_hook_results.accept(formatter)
|
796
810
|
@done = true
|
797
811
|
self
|
@@ -826,7 +840,7 @@ module Cucumber
|
|
826
840
|
def after
|
827
841
|
return if @done
|
828
842
|
@child.after if @child
|
829
|
-
@after_step_hook_result.
|
843
|
+
@after_step_hook_result.each { |result| result.accept formatter } if @after_step_hook_result
|
830
844
|
after_hook_results.accept(formatter)
|
831
845
|
@done = true
|
832
846
|
self
|
@@ -977,7 +991,7 @@ module Cucumber
|
|
977
991
|
|
978
992
|
class StepBacktraceLine < Struct.new(:step)
|
979
993
|
def to_s
|
980
|
-
|
994
|
+
step.backtrace_line
|
981
995
|
end
|
982
996
|
end
|
983
997
|
|
@@ -1057,13 +1071,15 @@ module Cucumber
|
|
1057
1071
|
end
|
1058
1072
|
|
1059
1073
|
class HookResult
|
1060
|
-
def initialize(result)
|
1061
|
-
@result = result
|
1074
|
+
def initialize(result, messages, embeddings)
|
1075
|
+
@result, @messages, @embeddings = result, messages, embeddings
|
1062
1076
|
@already_accepted = false
|
1063
1077
|
end
|
1064
1078
|
|
1065
1079
|
def accept(formatter)
|
1066
1080
|
unless @already_accepted
|
1081
|
+
@messages.each { |message| formatter.puts(message) }
|
1082
|
+
@embeddings.each { |embedding| embedding.send_to_formatter(formatter) }
|
1067
1083
|
@result.describe_exception_to(formatter)
|
1068
1084
|
@already_accepted = true
|
1069
1085
|
end
|
@@ -1179,9 +1195,9 @@ module Cucumber
|
|
1179
1195
|
end
|
1180
1196
|
|
1181
1197
|
class DataTableRow
|
1182
|
-
def initialize(row)
|
1183
|
-
@values = row
|
1184
|
-
@line =
|
1198
|
+
def initialize(row, line)
|
1199
|
+
@values = row
|
1200
|
+
@line = line
|
1185
1201
|
end
|
1186
1202
|
|
1187
1203
|
def dom_id
|
@@ -1210,6 +1226,18 @@ module Cucumber
|
|
1210
1226
|
private :values, :line
|
1211
1227
|
end
|
1212
1228
|
|
1229
|
+
class LegacyTableRow < DataTableRow
|
1230
|
+
def accept(formatter)
|
1231
|
+
formatter.before_table_row(self)
|
1232
|
+
values.each do |value|
|
1233
|
+
formatter.before_table_cell(value.value)
|
1234
|
+
formatter.table_cell_value(value.value, value.status)
|
1235
|
+
formatter.after_table_cell(value.value)
|
1236
|
+
end
|
1237
|
+
formatter.after_table_row(self)
|
1238
|
+
end
|
1239
|
+
end
|
1240
|
+
|
1213
1241
|
Tags = Struct.new(:tags) do
|
1214
1242
|
def accept(formatter)
|
1215
1243
|
formatter.before_tags tags
|
@@ -1268,6 +1296,10 @@ module Cucumber
|
|
1268
1296
|
@result = DataTable.new(node)
|
1269
1297
|
end
|
1270
1298
|
|
1299
|
+
def legacy_table(node)
|
1300
|
+
@result = LegacyTable.new(node)
|
1301
|
+
end
|
1302
|
+
|
1271
1303
|
def result
|
1272
1304
|
@result || Node.new(nil)
|
1273
1305
|
end
|
@@ -1281,16 +1313,31 @@ module Cucumber
|
|
1281
1313
|
end
|
1282
1314
|
end
|
1283
1315
|
|
1284
|
-
class DataTable <
|
1316
|
+
class DataTable < Cucumber::MultilineArgument::DataTable
|
1317
|
+
def node
|
1318
|
+
@ast_table
|
1319
|
+
end
|
1320
|
+
|
1285
1321
|
def accept(formatter)
|
1286
|
-
formatter.before_multiline_arg
|
1287
|
-
node.
|
1288
|
-
|
1322
|
+
formatter.before_multiline_arg self
|
1323
|
+
node.raw.each_with_index do |row, index|
|
1324
|
+
line = node.location.line + index
|
1325
|
+
Legacy::Ast::DataTableRow.new(row, line).accept(formatter)
|
1289
1326
|
end
|
1290
|
-
formatter.after_multiline_arg
|
1327
|
+
formatter.after_multiline_arg self
|
1291
1328
|
end
|
1292
1329
|
end
|
1330
|
+
end
|
1293
1331
|
|
1332
|
+
class LegacyTable < SimpleDelegator
|
1333
|
+
def accept(formatter)
|
1334
|
+
formatter.before_multiline_arg self
|
1335
|
+
cells_rows.each_with_index do |row, index|
|
1336
|
+
line = location.line + index
|
1337
|
+
Legacy::Ast::LegacyTableRow.new(row, line).accept(formatter)
|
1338
|
+
end
|
1339
|
+
formatter.after_multiline_arg self
|
1340
|
+
end
|
1294
1341
|
end
|
1295
1342
|
|
1296
1343
|
Features = Struct.new(:duration)
|
data/lib/cucumber/runtime.rb
CHANGED
@@ -35,7 +35,6 @@ module Cucumber
|
|
35
35
|
|
36
36
|
require 'cucumber/core'
|
37
37
|
require 'cucumber/runtime/user_interface'
|
38
|
-
require 'cucumber/runtime/features_loader'
|
39
38
|
require 'cucumber/runtime/results'
|
40
39
|
require 'cucumber/runtime/support_code'
|
41
40
|
require 'cucumber/runtime/tag_limits'
|
@@ -157,44 +156,6 @@ module Cucumber
|
|
157
156
|
@support_code.unknown_programming_language?
|
158
157
|
end
|
159
158
|
|
160
|
-
# TODO: this code is untested
|
161
|
-
def write_stepdefs_json
|
162
|
-
if(@configuration.dotcucumber)
|
163
|
-
stepdefs = []
|
164
|
-
@support_code.step_definitions.sort{|a,b| a.to_hash['source'] <=> a.to_hash['source']}.each do |stepdef|
|
165
|
-
stepdef_hash = stepdef.to_hash
|
166
|
-
steps = []
|
167
|
-
features.each do |feature|
|
168
|
-
feature.feature_elements.each do |feature_element|
|
169
|
-
feature_element.raw_steps.each do |step|
|
170
|
-
args = stepdef.arguments_from(step.name)
|
171
|
-
if(args)
|
172
|
-
steps << {
|
173
|
-
'name' => step.name,
|
174
|
-
'args' => args.map do |arg|
|
175
|
-
{
|
176
|
-
'offset' => arg.offset,
|
177
|
-
'val' => arg.val
|
178
|
-
}
|
179
|
-
end
|
180
|
-
}
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
stepdef_hash['file_colon_line'] = stepdef.file_colon_line
|
186
|
-
stepdef_hash['steps'] = steps.uniq.sort {|a,b| a['name'] <=> b['name']}
|
187
|
-
stepdefs << stepdef_hash
|
188
|
-
end
|
189
|
-
if !File.directory?(@configuration.dotcucumber)
|
190
|
-
FileUtils.mkdir_p(@configuration.dotcucumber)
|
191
|
-
end
|
192
|
-
File.open(File.join(@configuration.dotcucumber, 'stepdefs.json'), 'w') do |io|
|
193
|
-
io.write(MultiJson.dump(stepdefs, :pretty => true))
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
159
|
# Returns Ast::DocString for +string_without_triple_quotes+.
|
199
160
|
#
|
200
161
|
def doc_string(string_without_triple_quotes, content_type='', line_offset=0)
|
@@ -27,7 +27,7 @@ module Cucumber
|
|
27
27
|
:invoke,
|
28
28
|
:load_programming_language
|
29
29
|
|
30
|
-
# Returns a Cucumber::
|
30
|
+
# Returns a Cucumber::MultilineArgument::DataTable for +text_or_table+, which can either
|
31
31
|
# be a String:
|
32
32
|
#
|
33
33
|
# table(%{
|
@@ -45,21 +45,23 @@ module Cucumber
|
|
45
45
|
# ])
|
46
46
|
#
|
47
47
|
def table(text_or_table, file=nil, line_offset=0)
|
48
|
-
file
|
49
|
-
|
48
|
+
if !file
|
49
|
+
location = Core::Ast::Location.of_caller
|
50
|
+
else
|
51
|
+
location = Core::Ast::Location.new(file, line)
|
52
|
+
end
|
50
53
|
if Array === text_or_table
|
51
|
-
|
54
|
+
MultilineArgument::DataTable.new(text_or_table, location)
|
52
55
|
else
|
53
|
-
|
56
|
+
MultilineArgument::DataTable.parse(text_or_table, file, location)
|
54
57
|
end
|
55
58
|
end
|
56
59
|
|
57
|
-
# Returns
|
60
|
+
# Returns a Cucumber::MultilineArgument::DocString for +body+.
|
58
61
|
#
|
59
|
-
def doc_string(
|
60
|
-
|
61
|
-
|
62
|
-
Core::Ast::DocString.new(string_without_triple_quotes,content_type, location)
|
62
|
+
def doc_string(body, content_type='', line_offset=0)
|
63
|
+
location = Core::Ast::Location.of_caller
|
64
|
+
MultilineArgument.doc_string(body, content_type, location)
|
63
65
|
end
|
64
66
|
end
|
65
67
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'cucumber/constantize'
|
2
|
-
require 'cucumber/core/ast/multiline_argument'
|
3
2
|
require 'cucumber/runtime/for_programming_languages'
|
4
3
|
|
5
4
|
module Cucumber
|
@@ -8,6 +7,7 @@ module Cucumber
|
|
8
7
|
|
9
8
|
class SupportCode
|
10
9
|
|
10
|
+
# TODO: figure out a way to move this to the core. We'd need to have access to the mappings to pass those in.
|
11
11
|
require 'forwardable'
|
12
12
|
class StepInvoker
|
13
13
|
include Gherkin::Rubify
|
@@ -20,13 +20,20 @@ module Cucumber
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def step(step)
|
23
|
-
location =
|
24
|
-
|
25
|
-
@support_code.invoke(step.name, MultilineArgument.from(core_multiline_arg), location)
|
23
|
+
location = Core::Ast::Location.of_caller
|
24
|
+
@support_code.invoke(step.name, multiline_arg(step, location))
|
26
25
|
end
|
27
26
|
|
28
27
|
def eof
|
29
28
|
end
|
29
|
+
|
30
|
+
def multiline_arg(step, location)
|
31
|
+
if argument = step.doc_string
|
32
|
+
MultilineArgument.doc_string(argument.value, argument.content_type, location.on_line(argument.line_range))
|
33
|
+
else
|
34
|
+
MultilineArgument.from(step.rows, location)
|
35
|
+
end
|
36
|
+
end
|
30
37
|
end
|
31
38
|
|
32
39
|
include Constantize
|
@@ -69,7 +69,7 @@ module Cucumber
|
|
69
69
|
|
70
70
|
def handle_diff!(tables)
|
71
71
|
# TODO: figure out if / how we could get a location for a table from the wire (or make a null location)
|
72
|
-
location = Core::Ast::Location.new(
|
72
|
+
location = Core::Ast::Location.new(__FILE__, __LINE__)
|
73
73
|
table1 = table(tables[0], location)
|
74
74
|
table2 = table(tables[1], location)
|
75
75
|
table1.diff!(table2)
|
@@ -89,7 +89,7 @@ module Cucumber
|
|
89
89
|
private
|
90
90
|
|
91
91
|
def table(data, location)
|
92
|
-
Cucumber::MultilineArgument.
|
92
|
+
Cucumber::MultilineArgument.from_core(Core::Ast::DataTable.new(data, location))
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
@@ -531,14 +531,14 @@ OUTPUT
|
|
531
531
|
Given there are <Things> # spec.feature:4
|
532
532
|
Examples: Fruit
|
533
533
|
Scenario: | apples | # spec.feature:8
|
534
|
-
Given there are apples # spec.feature:
|
534
|
+
Given there are apples # spec.feature:8
|
535
535
|
Scenario: | bananas | # spec.feature:9
|
536
|
-
Given there are bananas # spec.feature:
|
536
|
+
Given there are bananas # spec.feature:9
|
537
537
|
Examples: Vegetables
|
538
538
|
Scenario: | broccoli | # spec.feature:12
|
539
|
-
Given there are broccoli # spec.feature:
|
539
|
+
Given there are broccoli # spec.feature:12
|
540
540
|
Scenario: | carrots | # spec.feature:13
|
541
|
-
Given there are carrots # spec.feature:
|
541
|
+
Given there are carrots # spec.feature:13
|
542
542
|
OUTPUT
|
543
543
|
lines.split("\n").each do |line|
|
544
544
|
expect(@out.string).to include line.strip
|
@@ -561,7 +561,7 @@ OUTPUT
|
|
561
561
|
lines = <<-OUTPUT
|
562
562
|
Examples:
|
563
563
|
Scenario: | Hominidae | Very long cell content | # spec.feature:8
|
564
|
-
Given there are Hominidae # spec.feature:
|
564
|
+
Given there are Hominidae # spec.feature:8
|
565
565
|
|
566
566
|
OUTPUT
|
567
567
|
lines.split("\n").each do |line|
|
@@ -10,7 +10,7 @@ module Cucumber
|
|
10
10
|
let(:ruby) { double.as_null_object }
|
11
11
|
let(:runtime) do
|
12
12
|
double(
|
13
|
-
load_programming_language: ruby,
|
13
|
+
load_programming_language: ruby,
|
14
14
|
step_match: double
|
15
15
|
)
|
16
16
|
end
|
@@ -18,16 +18,129 @@ module Cucumber
|
|
18
18
|
let(:report) { double.as_null_object }
|
19
19
|
|
20
20
|
it "responds to #source_tag_names" do
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
define_gherkin do
|
22
|
+
feature 'test', tags: '@foo @bar' do
|
23
|
+
scenario 'test', tags: '@baz' do
|
24
|
+
step 'passing'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
before do |scenario|
|
30
|
+
expect(scenario.source_tag_names).to eq %w(@foo @bar @baz)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#failed?" do
|
35
|
+
|
36
|
+
it "is true if the test case is in a failed state" do
|
37
|
+
define_gherkin do
|
38
|
+
feature do
|
39
|
+
scenario do
|
40
|
+
step 'failing'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
allow(runtime).to receive(:step_match) do |step_name|
|
46
|
+
if step_name == 'failing'
|
47
|
+
step_match = double
|
48
|
+
allow(step_match).to receive(:invoke) { fail }
|
49
|
+
step_match
|
50
|
+
else
|
51
|
+
raise Cucumber::Undefined
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
after do |test_case|
|
56
|
+
expect(test_case).to be_failed
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#scenario_outline" do
|
63
|
+
|
64
|
+
# TODO: is this actually desired behaviour?
|
65
|
+
it "throws a NoMethodError when the test case is from a scenario" do
|
66
|
+
define_gherkin do
|
67
|
+
feature do
|
68
|
+
scenario do
|
69
|
+
step 'passing'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
before do |test_case|
|
75
|
+
expect{ test_case.scenario_outline }.to raise_error(NoMethodError)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
it "points to self when the test case is from a scenario outline" do
|
80
|
+
define_gherkin do
|
81
|
+
feature do
|
82
|
+
scenario_outline 'outline' do
|
83
|
+
step 'passing'
|
84
|
+
|
85
|
+
examples 'examples' do
|
86
|
+
row 'a'
|
87
|
+
row '1'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
before do |test_case|
|
94
|
+
expect(test_case.scenario_outline).to_not be_nil
|
95
|
+
expect(test_case.scenario_outline.name).to eq "Scenario Outline: outline, examples (row 1)"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#outline?" do
|
102
|
+
|
103
|
+
it "returns false when the test case is from a scenario" do
|
104
|
+
define_gherkin do
|
105
|
+
feature do
|
106
|
+
scenario do
|
107
|
+
step 'passing'
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
before do |test_case|
|
113
|
+
expect(test_case).to_not be_an_outline
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
it "returns true when the test case is from a scenario" do
|
118
|
+
define_gherkin do
|
119
|
+
feature do
|
120
|
+
scenario_outline do
|
25
121
|
step 'passing'
|
122
|
+
|
123
|
+
examples 'examples' do
|
124
|
+
row 'a'
|
125
|
+
row '1'
|
126
|
+
end
|
26
127
|
end
|
27
128
|
end
|
28
129
|
end
|
29
|
-
]
|
30
130
|
|
131
|
+
before do |test_case|
|
132
|
+
expect(test_case).to be_an_outline
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
attr_accessor :gherkin_docs
|
138
|
+
|
139
|
+
def define_gherkin(&block)
|
140
|
+
self.gherkin_docs = [gherkin(&block)]
|
141
|
+
end
|
142
|
+
|
143
|
+
def before
|
31
144
|
# TODO: the complexity of this stubbing shows we need to clean up the interface
|
32
145
|
scenario_spy = nil
|
33
146
|
allow(ruby).to receive(:hooks_for) do |phase, scenario|
|
@@ -41,10 +154,26 @@ module Cucumber
|
|
41
154
|
[]
|
42
155
|
end
|
43
156
|
end
|
44
|
-
|
45
157
|
execute gherkin_docs, mappings, report
|
158
|
+
yield scenario_spy
|
159
|
+
end
|
46
160
|
|
47
|
-
|
161
|
+
def after
|
162
|
+
# TODO: the complexity of this stubbing shows we need to clean up the interface
|
163
|
+
scenario_spy = nil
|
164
|
+
allow(ruby).to receive(:hooks_for) do |phase, scenario|
|
165
|
+
if phase == :after
|
166
|
+
hook = double
|
167
|
+
expect(hook).to receive(:invoke) do |phase, scenario|
|
168
|
+
scenario_spy = scenario
|
169
|
+
end
|
170
|
+
[hook]
|
171
|
+
else
|
172
|
+
[]
|
173
|
+
end
|
174
|
+
end
|
175
|
+
execute gherkin_docs, mappings, report
|
176
|
+
yield scenario_spy
|
48
177
|
end
|
49
178
|
end
|
50
179
|
end
|