cucumber 0.8.5 → 0.8.6
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/.rspec +1 -1
- data/LICENSE +1 -1
- data/Rakefile +5 -51
- data/bin/cucumber +7 -1
- data/cucumber.gemspec +463 -679
- data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +1 -1
- data/examples/i18n/he/features/step_definitons/calculator_steps.rb +1 -1
- data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +4 -7
- data/examples/i18n/ru/features/division.feature +2 -2
- data/examples/i18n/tr/features/step_definitons/hesap_makinesi_adimlari.rb +3 -3
- data/examples/sinatra/features/support/env.rb +2 -5
- data/examples/v8/features/fibonacci.feature +1 -1
- data/examples/watir/features/step_definitions/search_steps.rb +1 -1
- data/features/background.feature +284 -95
- data/features/custom_formatter.feature +3 -73
- data/features/json_formatter.feature +160 -245
- data/features/step_definitions/cucumber_steps.rb +7 -153
- data/features/support/env.rb +18 -140
- data/fixtures/junit/features/pending.feature +3 -1
- data/fixtures/self_test/features/support/env.rb +8 -0
- data/fixtures/tickets/features.html +1 -1
- data/gem_tasks/examples.rake +1 -1
- data/lib/cucumber.rb +12 -0
- data/lib/cucumber/ast.rb +1 -1
- data/lib/cucumber/ast/background.rb +21 -5
- data/lib/cucumber/ast/examples.rb +12 -4
- data/lib/cucumber/ast/feature.rb +13 -5
- data/lib/cucumber/ast/feature_element.rb +9 -4
- data/lib/cucumber/ast/outline_table.rb +4 -4
- data/lib/cucumber/ast/scenario.rb +7 -5
- data/lib/cucumber/ast/scenario_outline.rb +23 -15
- data/lib/cucumber/ast/step.rb +5 -0
- data/lib/cucumber/ast/step_invocation.rb +21 -15
- data/lib/cucumber/ast/table.rb +14 -8
- data/lib/cucumber/ast/tree_walker.rb +10 -48
- data/lib/cucumber/cli/configuration.rb +33 -8
- data/lib/cucumber/cli/main.rb +20 -35
- data/lib/cucumber/cli/options.rb +8 -7
- data/lib/cucumber/cli/profile_loader.rb +2 -0
- data/lib/cucumber/core_ext/proc.rb +2 -1
- data/lib/cucumber/feature_file.rb +47 -15
- data/lib/cucumber/formatter/ansicolor.rb +3 -5
- data/lib/cucumber/formatter/console.rb +27 -23
- data/lib/cucumber/formatter/cucumber.css +34 -17
- data/lib/cucumber/formatter/cucumber.sass +173 -182
- data/lib/cucumber/formatter/html.rb +46 -11
- data/lib/cucumber/formatter/io.rb +2 -4
- data/lib/cucumber/formatter/json.rb +15 -152
- data/lib/cucumber/formatter/json_pretty.rb +5 -6
- data/lib/cucumber/formatter/junit.rb +28 -22
- data/lib/cucumber/formatter/pdf.rb +6 -6
- data/lib/cucumber/formatter/pretty.rb +5 -5
- data/lib/cucumber/formatter/rerun.rb +22 -11
- data/lib/cucumber/formatter/unicode.rb +41 -20
- data/lib/cucumber/js_support/js_dsl.js +4 -4
- data/lib/cucumber/js_support/js_language.rb +9 -5
- data/lib/cucumber/js_support/js_snippets.rb +2 -2
- data/lib/cucumber/language_support.rb +2 -2
- data/lib/cucumber/parser/gherkin_builder.rb +35 -30
- data/lib/cucumber/platform.rb +8 -8
- data/lib/cucumber/py_support/py_language.rb +2 -2
- data/lib/cucumber/rake/task.rb +80 -31
- data/lib/cucumber/rb_support/rb_dsl.rb +1 -0
- data/lib/cucumber/rb_support/rb_language.rb +10 -8
- data/lib/cucumber/rb_support/rb_step_definition.rb +8 -0
- data/lib/cucumber/rb_support/rb_transform.rb +17 -0
- data/lib/cucumber/rb_support/rb_world.rb +26 -18
- data/lib/cucumber/rspec/doubles.rb +3 -3
- data/lib/cucumber/step_match.rb +6 -2
- data/lib/cucumber/step_mother.rb +6 -427
- data/lib/cucumber/wire_support/configuration.rb +4 -1
- data/lib/cucumber/wire_support/wire_language.rb +3 -10
- data/spec/cucumber/ast/background_spec.rb +68 -6
- data/spec/cucumber/ast/feature_factory.rb +5 -4
- data/spec/cucumber/ast/feature_spec.rb +4 -4
- data/spec/cucumber/ast/outline_table_spec.rb +1 -1
- data/spec/cucumber/ast/scenario_outline_spec.rb +15 -11
- data/spec/cucumber/ast/scenario_spec.rb +4 -4
- data/spec/cucumber/ast/step_spec.rb +3 -3
- data/spec/cucumber/ast/table_spec.rb +38 -2
- data/spec/cucumber/ast/tree_walker_spec.rb +2 -2
- data/spec/cucumber/broadcaster_spec.rb +1 -1
- data/spec/cucumber/cli/configuration_spec.rb +32 -6
- data/spec/cucumber/cli/drb_client_spec.rb +2 -3
- data/spec/cucumber/cli/main_spec.rb +43 -43
- data/spec/cucumber/cli/options_spec.rb +28 -1
- data/spec/cucumber/cli/profile_loader_spec.rb +1 -1
- data/spec/cucumber/core_ext/proc_spec.rb +1 -1
- data/spec/cucumber/formatter/ansicolor_spec.rb +1 -1
- data/spec/cucumber/formatter/duration_spec.rb +1 -1
- data/spec/cucumber/formatter/html_spec.rb +3 -5
- data/spec/cucumber/formatter/junit_spec.rb +16 -2
- data/spec/cucumber/formatter/progress_spec.rb +1 -1
- data/spec/cucumber/formatter/spec_helper.rb +11 -12
- data/spec/cucumber/rb_support/rb_language_spec.rb +241 -28
- data/spec/cucumber/rb_support/rb_step_definition_spec.rb +33 -28
- data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +1 -1
- data/spec/cucumber/step_match_spec.rb +11 -9
- data/spec/cucumber/wire_support/configuration_spec.rb +1 -1
- data/spec/cucumber/wire_support/connection_spec.rb +1 -1
- data/spec/cucumber/wire_support/wire_exception_spec.rb +1 -1
- data/spec/cucumber/wire_support/wire_language_spec.rb +1 -1
- data/spec/cucumber/wire_support/wire_packet_spec.rb +1 -1
- data/spec/cucumber/wire_support/wire_step_definition_spec.rb +1 -1
- data/spec/cucumber/world/pending_spec.rb +2 -2
- data/spec/spec_helper.rb +13 -20
- metadata +11 -222
- data/.gitignore +0 -20
- data/Caliper.yml +0 -4
- data/History.txt +0 -1552
- data/README.rdoc +0 -26
- data/VERSION.yml +0 -5
- data/examples/i18n/ro/features/suma.feature +0 -11
- data/features/announce.feature +0 -164
- data/features/around_hooks.feature +0 -232
- data/features/bug_371.feature +0 -32
- data/features/bug_464.feature +0 -16
- data/features/bug_475.feature +0 -42
- data/features/bug_585_tab_indentation.feature +0 -22
- data/features/bug_600.feature +0 -67
- data/features/call_steps_from_stepdefs.feature +0 -154
- data/features/cucumber_cli.feature +0 -591
- data/features/cucumber_cli_outlines.feature +0 -117
- data/features/default_snippets.feature +0 -42
- data/features/diffing.feature +0 -25
- data/features/drb_server_integration.feature +0 -174
- data/features/exception_in_after_block.feature +0 -127
- data/features/exception_in_after_step_block.feature +0 -104
- data/features/exception_in_before_block.feature +0 -98
- data/features/exclude_files.feature +0 -20
- data/features/expand.feature +0 -60
- data/features/html_formatter.feature +0 -8
- data/features/html_formatter/a.html +0 -582
- data/features/junit_formatter.feature +0 -88
- data/features/language_from_header.feature +0 -30
- data/features/language_help.feature +0 -78
- data/features/listener_debugger_formatter.feature +0 -42
- data/features/multiline_names.feature +0 -44
- data/features/negative_tagged_hooks.feature +0 -60
- data/features/post_configuration_hook.feature +0 -37
- data/features/profiles.feature +0 -126
- data/features/rake_task.feature +0 -152
- data/features/report_called_undefined_steps.feature +0 -34
- data/features/rerun_formatter.feature +0 -45
- data/features/simplest.feature +0 -11
- data/features/snippet.feature +0 -23
- data/features/snippets_when_using_star_keyword.feature +0 -36
- data/features/step_definitions/extra_steps.rb +0 -2
- data/features/step_definitions/simplest_steps.rb +0 -3
- data/features/step_definitions/wire_steps.rb +0 -32
- data/features/support/env.rb.simplest +0 -7
- data/features/support/fake_wire_server.rb +0 -77
- data/features/table_diffing.feature +0 -45
- data/features/table_mapping.feature +0 -34
- data/features/tag_logic.feature +0 -258
- data/features/transform.feature +0 -245
- data/features/unicode_table.feature +0 -35
- data/features/usage_and_stepdefs_formatter.feature +0 -169
- data/features/wire_protocol.feature +0 -332
- data/features/wire_protocol_table_diffing.feature +0 -119
- data/features/wire_protocol_tags.feature +0 -87
- data/features/wire_protocol_timeouts.feature +0 -63
- data/features/work_in_progress.feature +0 -156
- data/fixtures/json/features/pystring.feature +0 -8
- data/fixtures/self_test/features/background/background_tagged_before_on_outline.feature +0 -12
- data/fixtures/self_test/features/background/background_with_name.feature +0 -7
- data/fixtures/self_test/features/background/failing_background.feature +0 -12
- data/fixtures/self_test/features/background/failing_background_after_success.feature +0 -11
- data/fixtures/self_test/features/background/multiline_args_background.feature +0 -32
- data/fixtures/self_test/features/background/passing_background.feature +0 -10
- data/fixtures/self_test/features/background/pending_background.feature +0 -10
- data/fixtures/self_test/features/background/scenario_outline_failing_background.feature +0 -16
- data/fixtures/self_test/features/background/scenario_outline_passing_background.feature +0 -16
- data/gem_tasks/features.rake +0 -14
- data/gem_tasks/sdoc.rake +0 -12
- data/lib/cucumber/ast/py_string.rb +0 -80
- data/lib/cucumber/formatter/color_io.rb +0 -23
- data/lib/cucumber/formatter/tag_cloud.rb +0 -35
- data/spec/cucumber/ast/py_string_spec.rb +0 -40
- data/spec/cucumber/formatter/color_io_spec.rb +0 -29
- data/spec/cucumber/step_mother_spec.rb +0 -302
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
require
|
|
2
|
-
|
|
1
|
+
require 'spec_helper'
|
|
3
2
|
|
|
4
3
|
module Cucumber
|
|
5
4
|
module Cli
|
|
@@ -30,7 +29,7 @@ module Cucumber
|
|
|
30
29
|
|
|
31
30
|
it "returns raises an error when it can't connect to the server" do
|
|
32
31
|
DRbObject.stub!(:new_with_uri).and_raise(DRb::DRbConnError)
|
|
33
|
-
|
|
32
|
+
lambda { DRbClient.run(@args, @error_stream, @out_stream) }.should raise_error(DRbClientError, "No DRb server is running.")
|
|
34
33
|
end
|
|
35
34
|
|
|
36
35
|
it "returns the result from the DRb server call" do
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
require
|
|
1
|
+
require 'spec_helper'
|
|
2
2
|
require 'yaml'
|
|
3
|
+
require 'cucumber/parser/gherkin_builder'
|
|
4
|
+
require 'gherkin/formatter/model'
|
|
3
5
|
|
|
4
6
|
module Cucumber
|
|
5
7
|
module Cli
|
|
@@ -11,11 +13,41 @@ module Cucumber
|
|
|
11
13
|
File.stub!(:exist?).and_return(false) # When Configuration checks for cucumber.yml
|
|
12
14
|
Dir.stub!(:[]).and_return([]) # to prevent cucumber's features dir to being laoded
|
|
13
15
|
end
|
|
16
|
+
|
|
17
|
+
let(:args) { [] }
|
|
18
|
+
let(:out_stream) { nil }
|
|
19
|
+
let(:err_stream) { nil }
|
|
20
|
+
subject { Main.new(args, out_stream, err_stream)}
|
|
21
|
+
|
|
22
|
+
describe "#execute!" do
|
|
23
|
+
context "passed an existing runtime" do
|
|
24
|
+
let(:existing_runtime) { double('runtime').as_null_object }
|
|
25
|
+
|
|
26
|
+
def do_execute
|
|
27
|
+
subject.execute!(existing_runtime)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "configures that runtime" do
|
|
31
|
+
expected_configuration = double('Configuration', :drb? => false).as_null_object
|
|
32
|
+
Configuration.stub!(:new => expected_configuration)
|
|
33
|
+
existing_runtime.should_receive(:configure).with(expected_configuration)
|
|
34
|
+
do_execute
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "uses that runtime for running and reporting results" do
|
|
38
|
+
expected_results = double('results', :failure? => true)
|
|
39
|
+
existing_runtime.should_receive(:run!)
|
|
40
|
+
existing_runtime.stub!(:results).and_return(expected_results)
|
|
41
|
+
do_execute.should == expected_results.failure?
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
14
45
|
|
|
15
46
|
describe "verbose mode" do
|
|
16
47
|
|
|
17
48
|
before(:each) do
|
|
18
|
-
|
|
49
|
+
b = Cucumber::Parser::GherkinBuilder.new
|
|
50
|
+
@empty_feature = b.feature(Gherkin::Formatter::Model::Feature.new([], [], "Feature", "Foo", "", 99))
|
|
19
51
|
end
|
|
20
52
|
|
|
21
53
|
it "should show feature files parsed" do
|
|
@@ -24,7 +56,7 @@ module Cucumber
|
|
|
24
56
|
|
|
25
57
|
Cucumber::FeatureFile.stub!(:new).and_return(mock("feature file", :parse => @empty_feature))
|
|
26
58
|
|
|
27
|
-
@cli.execute!
|
|
59
|
+
@cli.execute!
|
|
28
60
|
|
|
29
61
|
@out.string.should include('example.feature')
|
|
30
62
|
end
|
|
@@ -32,9 +64,7 @@ module Cucumber
|
|
|
32
64
|
end
|
|
33
65
|
|
|
34
66
|
describe "--format with class" do
|
|
35
|
-
|
|
36
|
-
describe "in module" do
|
|
37
|
-
|
|
67
|
+
describe "in module" do
|
|
38
68
|
it "should resolve each module until it gets Formatter class" do
|
|
39
69
|
cli = Main.new(%w{--format ZooModule::MonkeyFormatterClass}, nil)
|
|
40
70
|
mock_module = mock('module')
|
|
@@ -46,42 +76,11 @@ module Cucumber
|
|
|
46
76
|
Object.should_receive(:const_get).with('ZooModule').and_return(mock_module)
|
|
47
77
|
mock_module.should_receive(:const_get).with('MonkeyFormatterClass').and_return(mock('formatter class', :new => f))
|
|
48
78
|
|
|
49
|
-
cli.execute!
|
|
79
|
+
cli.execute!
|
|
50
80
|
end
|
|
51
|
-
|
|
52
81
|
end
|
|
53
82
|
end
|
|
54
83
|
|
|
55
|
-
describe "setup step sequence" do
|
|
56
|
-
|
|
57
|
-
it "should load files and execute hooks in order" do
|
|
58
|
-
Configuration.stub!(:new).and_return(configuration = mock('configuration').as_null_object)
|
|
59
|
-
step_mother = mock('step mother').as_null_object
|
|
60
|
-
configuration.stub!(:drb?).and_return false
|
|
61
|
-
cli = Main.new(%w{--verbose example.feature}, @out)
|
|
62
|
-
cli.stub!(:require)
|
|
63
|
-
|
|
64
|
-
configuration.stub!(:support_to_load).and_return(['support'])
|
|
65
|
-
configuration.stub!(:step_defs_to_load).and_return(['step defs'])
|
|
66
|
-
|
|
67
|
-
# Support must be loaded first to ensure post configuration hook can
|
|
68
|
-
# run before anything else.
|
|
69
|
-
step_mother.should_receive(:load_code_files).with(['support']).ordered
|
|
70
|
-
# The post configuration hook/s (if any) need to be run next to enable
|
|
71
|
-
# extensions to do their thing before features are loaded
|
|
72
|
-
step_mother.should_receive(:after_configuration).with(configuration).ordered
|
|
73
|
-
# Feature files must be loaded before step definitions are required.
|
|
74
|
-
# This is because i18n step methods are only aliased when
|
|
75
|
-
# features are loaded. If we swap the order, the requires
|
|
76
|
-
# will fail.
|
|
77
|
-
step_mother.should_receive(:load_plain_text_features).ordered
|
|
78
|
-
step_mother.should_receive(:load_code_files).with(['step defs']).ordered
|
|
79
|
-
|
|
80
|
-
cli.execute!(step_mother)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
end
|
|
84
|
-
|
|
85
84
|
[ProfilesNotDefinedError, YmlLoadError, ProfileNotFound].each do |exception_klass|
|
|
86
85
|
|
|
87
86
|
it "rescues #{exception_klass}, prints the message to the error stream and returns true" do
|
|
@@ -89,7 +88,7 @@ module Cucumber
|
|
|
89
88
|
configuration.stub!(:parse!).and_raise(exception_klass.new("error message"))
|
|
90
89
|
|
|
91
90
|
main = Main.new('', out = StringIO.new, error = StringIO.new)
|
|
92
|
-
main.execute
|
|
91
|
+
main.execute!.should be_true
|
|
93
92
|
error.string.should == "error message\n"
|
|
94
93
|
end
|
|
95
94
|
end
|
|
@@ -103,30 +102,31 @@ module Cucumber
|
|
|
103
102
|
|
|
104
103
|
@cli = Main.new(@args, @out, @err)
|
|
105
104
|
@step_mother = mock('StepMother').as_null_object
|
|
105
|
+
StepMother.stub!(:new).and_return(@step_mother)
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
it "delegates the execution to the DRB client passing the args and streams" do
|
|
109
109
|
@configuration.stub :drb_port => 1450
|
|
110
110
|
DRbClient.should_receive(:run).with(@args, @err, @out, 1450).and_return(true)
|
|
111
|
-
@cli.execute!
|
|
111
|
+
@cli.execute!
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
it "returns the result from the DRbClient" do
|
|
115
115
|
DRbClient.stub!(:run).and_return('foo')
|
|
116
|
-
@cli.execute
|
|
116
|
+
@cli.execute!.should == 'foo'
|
|
117
117
|
end
|
|
118
118
|
|
|
119
119
|
it "ceases execution if the DrbClient is able to perform the execution" do
|
|
120
120
|
DRbClient.stub!(:run).and_return(true)
|
|
121
121
|
@configuration.should_not_receive(:build_formatter_broadcaster)
|
|
122
|
-
@cli.execute!
|
|
122
|
+
@cli.execute!
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
context "when the DrbClient is unable to perfrom the execution" do
|
|
126
126
|
before { DRbClient.stub!(:run).and_raise(DRbClientError.new('error message.')) }
|
|
127
127
|
|
|
128
128
|
it "alerts the user that execution will be performed locally" do
|
|
129
|
-
@cli.execute!
|
|
129
|
+
@cli.execute!
|
|
130
130
|
@err.string.should include("WARNING: error message. Running features locally:")
|
|
131
131
|
end
|
|
132
132
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
require
|
|
1
|
+
require 'spec_helper'
|
|
2
2
|
require 'yaml'
|
|
3
|
+
require 'cucumber/cli/options'
|
|
3
4
|
|
|
4
5
|
module Cucumber
|
|
5
6
|
module Cli
|
|
@@ -111,6 +112,13 @@ module Cli
|
|
|
111
112
|
end
|
|
112
113
|
end
|
|
113
114
|
|
|
115
|
+
context '-l LINES or --lines LINES' do
|
|
116
|
+
it "adds line numbers to args" do
|
|
117
|
+
options.parse!(%w{-l24 FILE})
|
|
118
|
+
options.instance_variable_get(:@args).should == ['FILE:24']
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
114
122
|
context '-p PROFILE or --profile PROFILE' do
|
|
115
123
|
|
|
116
124
|
it "notifies the user that an individual profile is being used" do
|
|
@@ -324,6 +332,25 @@ module Cli
|
|
|
324
332
|
|
|
325
333
|
end
|
|
326
334
|
|
|
335
|
+
describe "dry-run" do
|
|
336
|
+
it "should have the default value for snippets" do
|
|
337
|
+
given_cucumber_yml_defined_as({'foo' => %w[--dry-run]})
|
|
338
|
+
options.parse!(%w{--dry-run})
|
|
339
|
+
options[:snippets].should == true
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
it "should set snippets to false when no-snippets provided after dry-run" do
|
|
343
|
+
given_cucumber_yml_defined_as({'foo' => %w[--dry-run --no-snippets]})
|
|
344
|
+
options.parse!(%w{--dry-run --no-snippets})
|
|
345
|
+
options[:snippets].should == false
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
it "should set snippets to false when no-snippets provided before dry-run" do
|
|
349
|
+
given_cucumber_yml_defined_as({'foo' => %w[--no-snippet --dry-run]})
|
|
350
|
+
options.parse!(%w{--no-snippets --dry-run})
|
|
351
|
+
options[:snippets].should == false
|
|
352
|
+
end
|
|
353
|
+
end
|
|
327
354
|
end
|
|
328
355
|
|
|
329
356
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'cucumber/formatter/spec_helper'
|
|
3
3
|
require 'cucumber/formatter/html'
|
|
4
4
|
require 'nokogiri'
|
|
5
5
|
require 'cucumber/rb_support/rb_language'
|
|
@@ -11,9 +11,7 @@ module Cucumber
|
|
|
11
11
|
extend SpecHelperDsl
|
|
12
12
|
include SpecHelper
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
matcher.define :have_css_node do |css, regexp|
|
|
14
|
+
RSpec::Matchers.define :have_css_node do |css, regexp|
|
|
17
15
|
match do |doc|
|
|
18
16
|
nodes = doc.css(css)
|
|
19
17
|
nodes.detect{ |node| node.text =~ regexp }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'cucumber/formatter/spec_helper'
|
|
3
3
|
|
|
4
4
|
require 'cucumber/formatter/junit'
|
|
5
5
|
require 'nokogiri'
|
|
@@ -51,6 +51,19 @@ module Cucumber::Formatter
|
|
|
51
51
|
|
|
52
52
|
it { @doc.to_s.should =~ /One passing scenario, one failing scenario/ }
|
|
53
53
|
end
|
|
54
|
+
|
|
55
|
+
describe "with a scenario in a subdirectory" do
|
|
56
|
+
define_feature %{
|
|
57
|
+
Feature: One passing scenario, one failing scenario
|
|
58
|
+
|
|
59
|
+
Scenario: Passing
|
|
60
|
+
Given a passing scenario
|
|
61
|
+
}, File.join('features', 'some', 'path', 'spec.feature')
|
|
62
|
+
|
|
63
|
+
it 'writes the filename including the subdirectory' do
|
|
64
|
+
@formatter.written_files.keys.first.should == File.join('', 'TEST-some_path_spec.xml')
|
|
65
|
+
end
|
|
66
|
+
end
|
|
54
67
|
|
|
55
68
|
describe "with a scenario outline table" do
|
|
56
69
|
define_steps do
|
|
@@ -81,6 +94,7 @@ module Cucumber::Formatter
|
|
|
81
94
|
it { @doc.to_s.should =~ /Big Mac/ }
|
|
82
95
|
it { @doc.to_s.should_not =~ /Things/ }
|
|
83
96
|
it { @doc.to_s.should_not =~ /Good|Evil/ }
|
|
97
|
+
it { @doc.to_s.should_not =~ /type="skipped"/}
|
|
84
98
|
end
|
|
85
99
|
|
|
86
100
|
describe "with a regular data table scenario" do
|
|
@@ -2,10 +2,11 @@ module Cucumber
|
|
|
2
2
|
module Formatter
|
|
3
3
|
|
|
4
4
|
module SpecHelperDsl
|
|
5
|
-
attr_reader :feature_content, :step_defs
|
|
5
|
+
attr_reader :feature_content, :step_defs, :feature_filename
|
|
6
6
|
|
|
7
|
-
def define_feature(string)
|
|
7
|
+
def define_feature(string, feature_file = 'spec.feature')
|
|
8
8
|
@feature_content = string
|
|
9
|
+
@feature_filename = feature_file
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
def define_steps(&block)
|
|
@@ -21,33 +22,31 @@ module Cucumber
|
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
def step_mother
|
|
24
|
-
@step_mother ||=
|
|
25
|
+
@step_mother ||= Runtime.new
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
def load_features(content)
|
|
28
|
-
feature_file = FeatureFile.new(
|
|
29
|
+
feature_file = FeatureFile.new(self.class.feature_filename, content)
|
|
29
30
|
features = Ast::Features.new
|
|
30
|
-
|
|
31
|
+
filters = []
|
|
32
|
+
feature = feature_file.parse(filters, {})
|
|
31
33
|
features.add_feature(feature) if feature
|
|
32
34
|
features
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
def run(features)
|
|
36
|
-
|
|
38
|
+
configuration = Cucumber::Configuration.default
|
|
39
|
+
tree_walker = Cucumber::Ast::TreeWalker.new(step_mother, [@formatter], configuration)
|
|
37
40
|
tree_walker.visit_features(features)
|
|
38
41
|
end
|
|
39
42
|
|
|
40
43
|
def define_steps
|
|
41
44
|
return unless step_defs = self.class.step_defs
|
|
42
|
-
rb =
|
|
43
|
-
dsl = Object.new
|
|
45
|
+
rb = step_mother.load_programming_language('rb')
|
|
46
|
+
dsl = Object.new
|
|
44
47
|
dsl.extend RbSupport::RbDsl
|
|
45
48
|
dsl.instance_exec &step_defs
|
|
46
49
|
end
|
|
47
|
-
|
|
48
|
-
def options
|
|
49
|
-
@options ||= mock(Cucumber::Cli::Options, :filters => [], :[] => nil)
|
|
50
|
-
end
|
|
51
50
|
end
|
|
52
51
|
end
|
|
53
52
|
end
|
|
@@ -1,69 +1,282 @@
|
|
|
1
|
-
require
|
|
2
|
-
|
|
1
|
+
require 'spec_helper'
|
|
3
2
|
require 'cucumber/step_mother'
|
|
4
3
|
require 'cucumber/rb_support/rb_language'
|
|
5
4
|
|
|
6
5
|
module Cucumber
|
|
7
6
|
module RbSupport
|
|
8
7
|
describe RbStepDefinition do
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
let(:user_interface) { double('user interface') }
|
|
9
|
+
let(:rb) { support_code.load_programming_language('rb')}
|
|
10
|
+
let(:support_code) do
|
|
11
|
+
Cucumber::Runtime::SupportCode.new(user_interface, {})
|
|
12
|
+
end
|
|
13
|
+
let(:dsl) do
|
|
14
|
+
rb
|
|
15
|
+
Object.new.extend(RbSupport::RbDsl)
|
|
12
16
|
end
|
|
13
17
|
|
|
14
18
|
def unindented(s)
|
|
15
19
|
s.split("\n")[1..-2].join("\n").indent(-10)
|
|
16
20
|
end
|
|
21
|
+
|
|
22
|
+
describe "snippets" do
|
|
17
23
|
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
it "should recognise numbers in name and make according regexp" do
|
|
25
|
+
rb.snippet_text('Given', 'Cloud 9 yeah', nil).should == unindented(%{
|
|
20
26
|
Given /^Cloud (\\d+) yeah$/ do |arg1|
|
|
21
27
|
pending # express the regexp above with the code you wish you had
|
|
22
28
|
end
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
})
|
|
30
|
+
end
|
|
25
31
|
|
|
26
|
-
|
|
27
|
-
|
|
32
|
+
it "should recognise a mix of ints, strings and why not a table too" do
|
|
33
|
+
rb.snippet_text('Given', 'I have 9 "awesome" cukes in 37 "boxes"', Cucumber::Ast::Table).should == unindented(%{
|
|
28
34
|
Given /^I have (\\d+) "([^"]*)" cukes in (\\d+) "([^"]*)"$/ do |arg1, arg2, arg3, arg4, table|
|
|
29
35
|
# table is a Cucumber::Ast::Table
|
|
30
36
|
pending # express the regexp above with the code you wish you had
|
|
31
37
|
end
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
})
|
|
39
|
+
end
|
|
34
40
|
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
it "should recognise quotes in name and make according regexp" do
|
|
42
|
+
rb.snippet_text('Given', 'A "first" arg', nil).should == unindented(%{
|
|
37
43
|
Given /^A "([^"]*)" arg$/ do |arg1|
|
|
38
44
|
pending # express the regexp above with the code you wish you had
|
|
39
45
|
end
|
|
40
|
-
|
|
41
|
-
|
|
46
|
+
})
|
|
47
|
+
end
|
|
42
48
|
|
|
43
|
-
|
|
44
|
-
|
|
49
|
+
it "should recognise several quoted words in name and make according regexp and args" do
|
|
50
|
+
rb.snippet_text('Given', 'A "first" and "second" arg', nil).should == unindented(%{
|
|
45
51
|
Given /^A "([^"]*)" and "([^"]*)" arg$/ do |arg1, arg2|
|
|
46
52
|
pending # express the regexp above with the code you wish you had
|
|
47
53
|
end
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
})
|
|
55
|
+
end
|
|
50
56
|
|
|
51
|
-
|
|
52
|
-
|
|
57
|
+
it "should not use quote group when there are no quotes" do
|
|
58
|
+
rb.snippet_text('Given', 'A first arg', nil).should == unindented(%{
|
|
53
59
|
Given /^A first arg$/ do
|
|
54
60
|
pending # express the regexp above with the code you wish you had
|
|
55
61
|
end
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
})
|
|
63
|
+
end
|
|
58
64
|
|
|
59
|
-
|
|
60
|
-
|
|
65
|
+
it "should be helpful with tables" do
|
|
66
|
+
rb.snippet_text('Given', 'A "first" arg', Cucumber::Ast::Table).should == unindented(%{
|
|
61
67
|
Given /^A "([^"]*)" arg$/ do |arg1, table|
|
|
62
68
|
# table is a Cucumber::Ast::Table
|
|
63
69
|
pending # express the regexp above with the code you wish you had
|
|
64
70
|
end
|
|
65
|
-
|
|
71
|
+
})
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe "#load_code_file" do
|
|
77
|
+
after do
|
|
78
|
+
FileUtils.rm_rf('tmp.rb')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def a_file_called(name)
|
|
82
|
+
File.open('tmp.rb', 'w') do |f|
|
|
83
|
+
f.puts yield
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "re-loads the file when called multiple times" do
|
|
88
|
+
a_file_called('tmp.rb') do
|
|
89
|
+
"$foo = 1"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
rb.load_code_file('tmp.rb')
|
|
93
|
+
$foo.should == 1
|
|
94
|
+
|
|
95
|
+
a_file_called('tmp.rb') do
|
|
96
|
+
"$foo = 2"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
rb.load_code_file('tmp.rb')
|
|
100
|
+
$foo.should == 2
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
describe "Handling the World" do
|
|
105
|
+
|
|
106
|
+
it "should raise an error if the world is nil" do
|
|
107
|
+
dsl.World {}
|
|
108
|
+
|
|
109
|
+
begin
|
|
110
|
+
rb.before(nil)
|
|
111
|
+
raise "Should fail"
|
|
112
|
+
rescue RbSupport::NilWorld => e
|
|
113
|
+
e.message.should == "World procs should never return nil"
|
|
114
|
+
e.backtrace.length.should == 1
|
|
115
|
+
e.backtrace[0].should =~ /spec\/cucumber\/rb_support\/rb_language_spec\.rb\:\d+\:in `World'/
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
module ModuleOne
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
module ModuleTwo
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
class ClassOne
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "should implicitly extend world with modules" do
|
|
129
|
+
dsl.World(ModuleOne, ModuleTwo)
|
|
130
|
+
rb.before(mock('scenario').as_null_object)
|
|
131
|
+
class << rb.current_world
|
|
132
|
+
included_modules.inspect.should =~ /ModuleOne/ # Workaround for RSpec/Ruby 1.9 issue with namespaces
|
|
133
|
+
included_modules.inspect.should =~ /ModuleTwo/
|
|
134
|
+
end
|
|
135
|
+
rb.current_world.class.should == Object
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "should raise error when we try to register more than one World proc" do
|
|
139
|
+
expected_error = %{You can only pass a proc to #World once, but it's happening
|
|
140
|
+
in 2 places:
|
|
141
|
+
|
|
142
|
+
spec/cucumber/rb_support/rb_language_spec.rb:\\d+:in `World'
|
|
143
|
+
spec/cucumber/rb_support/rb_language_spec.rb:\\d+:in `World'
|
|
144
|
+
|
|
145
|
+
Use Ruby modules instead to extend your worlds. See the Cucumber::RbSupport::RbDsl#World RDoc
|
|
146
|
+
or http://wiki.github.com/cucumber/cucumber/a-whole-new-world.
|
|
147
|
+
|
|
148
|
+
}
|
|
149
|
+
dsl.World { Hash.new }
|
|
150
|
+
lambda do
|
|
151
|
+
dsl.World { Array.new }
|
|
152
|
+
end.should raise_error(RbSupport::MultipleWorld, /#{expected_error}/)
|
|
153
|
+
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
describe "step argument transformations" do
|
|
158
|
+
|
|
159
|
+
describe "without capture groups" do
|
|
160
|
+
it "complains when registering with a with no transform block" do
|
|
161
|
+
lambda do
|
|
162
|
+
dsl.Transform('^abc$')
|
|
163
|
+
end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "complains when registering with a zero-arg transform block" do
|
|
167
|
+
lambda do
|
|
168
|
+
dsl.Transform('^abc$') {42}
|
|
169
|
+
end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "complains when registering with a splat-arg transform block" do
|
|
173
|
+
lambda do
|
|
174
|
+
dsl.Transform('^abc$') {|*splat| 42 }
|
|
175
|
+
end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "complains when transforming with an arity mismatch" do
|
|
179
|
+
lambda do
|
|
180
|
+
dsl.Transform('^abc$') {|one, two| 42 }
|
|
181
|
+
rb.execute_transforms(['abc'])
|
|
182
|
+
end.should raise_error(Cucumber::ArityMismatchError)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
it "allows registering a regexp pattern that yields the step_arg matched" do
|
|
186
|
+
dsl.Transform(/^ab*c$/) {|arg| 42}
|
|
187
|
+
rb.execute_transforms(['ab']).should == ['ab']
|
|
188
|
+
rb.execute_transforms(['ac']).should == [42]
|
|
189
|
+
rb.execute_transforms(['abc']).should == [42]
|
|
190
|
+
rb.execute_transforms(['abbc']).should == [42]
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
describe "with capture groups" do
|
|
195
|
+
it "complains when registering with a with no transform block" do
|
|
196
|
+
lambda do
|
|
197
|
+
dsl.Transform('^a(.)c$')
|
|
198
|
+
end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it "complains when registering with a zero-arg transform block" do
|
|
202
|
+
lambda do
|
|
203
|
+
dsl.Transform('^a(.)c$') { 42 }
|
|
204
|
+
end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
it "complains when registering with a splat-arg transform block" do
|
|
208
|
+
lambda do
|
|
209
|
+
dsl.Transform('^a(.)c$') {|*splat| 42 }
|
|
210
|
+
end.should raise_error(Cucumber::RbSupport::RbTransform::MissingProc)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
it "complains when transforming with an arity mismatch" do
|
|
214
|
+
lambda do
|
|
215
|
+
dsl.Transform('^a(.)c$') {|one, two| 42 }
|
|
216
|
+
rb.execute_transforms(['abc'])
|
|
217
|
+
end.should raise_error(Cucumber::ArityMismatchError)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
it "allows registering a regexp pattern that yields capture groups" do
|
|
221
|
+
dsl.Transform(/^shape: (.+), color: (.+)$/) do |shape, color|
|
|
222
|
+
{shape.to_sym => color.to_sym}
|
|
223
|
+
end
|
|
224
|
+
rb.execute_transforms(['shape: circle, color: blue']).should == [{:circle => :blue}]
|
|
225
|
+
rb.execute_transforms(['shape: square, color: red']).should == [{:square => :red}]
|
|
226
|
+
rb.execute_transforms(['not shape: square, not color: red']).should == ['not shape: square, not color: red']
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
it "allows registering a string pattern" do
|
|
231
|
+
dsl.Transform('^ab*c$') {|arg| 42}
|
|
232
|
+
rb.execute_transforms(['ab']).should == ['ab']
|
|
233
|
+
rb.execute_transforms(['ac']).should == [42]
|
|
234
|
+
rb.execute_transforms(['abc']).should == [42]
|
|
235
|
+
rb.execute_transforms(['abbc']).should == [42]
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it "gives match priority to transforms defined last" do
|
|
239
|
+
dsl.Transform(/^transform_me$/) {|arg| :foo }
|
|
240
|
+
dsl.Transform(/^transform_me$/) {|arg| :bar }
|
|
241
|
+
dsl.Transform(/^transform_me$/) {|arg| :baz }
|
|
242
|
+
rb.execute_transforms(['transform_me']).should == [:baz]
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
it "allows registering a transform which returns nil" do
|
|
246
|
+
dsl.Transform('^ac$') {|arg| nil}
|
|
247
|
+
rb.execute_transforms(['ab']).should == ['ab']
|
|
248
|
+
rb.execute_transforms(['ac']).should == [nil]
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
describe "hooks" do
|
|
253
|
+
|
|
254
|
+
it "should find before hooks" do
|
|
255
|
+
fish = dsl.Before('@fish'){}
|
|
256
|
+
meat = dsl.Before('@meat'){}
|
|
257
|
+
|
|
258
|
+
scenario = mock('Scenario')
|
|
259
|
+
scenario.should_receive(:accept_hook?).with(fish).and_return(true)
|
|
260
|
+
scenario.should_receive(:accept_hook?).with(meat).and_return(false)
|
|
261
|
+
|
|
262
|
+
rb.hooks_for(:before, scenario).should == [fish]
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
it "should find around hooks" do
|
|
266
|
+
a = dsl.Around do |scenario, block|
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
b = dsl.Around('@tag') do |scenario, block|
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
scenario = mock('Scenario')
|
|
273
|
+
scenario.should_receive(:accept_hook?).with(a).and_return(true)
|
|
274
|
+
scenario.should_receive(:accept_hook?).with(b).and_return(false)
|
|
275
|
+
|
|
276
|
+
rb.hooks_for(:around, scenario).should == [a]
|
|
277
|
+
end
|
|
66
278
|
end
|
|
279
|
+
|
|
67
280
|
end
|
|
68
281
|
end
|
|
69
282
|
end
|