aslakhellesoy-cucumber 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest.txt +22 -10
- data/README.textile +147 -17
- data/README.txt +41 -0
- data/config/hoe.rb +1 -1
- data/examples/calculator/features/addition.feature +7 -7
- data/examples/calculator/features/division.feature +3 -4
- data/examples/calculator/features/steps/{addition_steps.rb → calculator_steps.rb} +0 -1
- data/examples/calculator/lib/calculator.rb +2 -4
- data/examples/{pure_ruby → calculator_ruby_features}/Rakefile +0 -0
- data/examples/{pure_ruby → calculator_ruby_features}/features/addition.rb +2 -2
- data/examples/{pure_ruby/features/steps/addition_steps.rb → calculator_ruby_features/features/steps/calculator_steps.rb} +0 -0
- data/examples/java/src/cucumber/demo/Hello.java +1 -1
- data/examples/{simple_norwegian → norwegian_calculator}/Rakefile +0 -0
- data/examples/{simple_norwegian/features/steps/matte_steg.rb.rb → norwegian_calculator/features/kalkulator_steps.rb} +2 -2
- data/examples/{simple_norwegian → norwegian_calculator}/features/summering.feature +4 -4
- data/examples/{web → watir}/Rakefile +0 -0
- data/examples/{web → watir}/features/search.feature +1 -1
- data/examples/{web → watir}/features/steps/stories_steps.rb +4 -4
- data/gem_tasks/gemspec.rake +6 -0
- data/generators/cucumber/cucumber_generator.rb +20 -0
- data/generators/cucumber/templates/common_webrat.rb +30 -0
- data/generators/cucumber/templates/cucumber.rake +7 -0
- data/generators/cucumber/templates/env.rb +6 -0
- data/generators/feature/feature_generator.rb +17 -0
- data/generators/feature/templates/feature.erb +27 -0
- data/generators/feature/templates/steps.erb +22 -0
- data/lib/cucumber.rb +9 -1
- data/lib/cucumber/cli.rb +13 -8
- data/lib/cucumber/executor.rb +0 -4
- data/lib/cucumber/formatters/html_formatter.rb +1 -0
- data/lib/cucumber/formatters/pretty_formatter.rb +15 -5
- data/lib/cucumber/languages.yml +1 -1
- data/lib/cucumber/rails/rspec.rb +12 -0
- data/lib/cucumber/rails/world.rb +18 -16
- data/lib/cucumber/rake/task.rb +17 -14
- data/lib/cucumber/step_methods.rb +3 -1
- data/lib/cucumber/tree/scenario.rb +6 -0
- data/lib/cucumber/tree/step.rb +8 -0
- data/lib/cucumber/treetop_parser/feature.treetop.erb +10 -6
- data/lib/cucumber/treetop_parser/feature_en.rb +132 -81
- data/lib/cucumber/treetop_parser/feature_fr.rb +136 -85
- data/lib/cucumber/treetop_parser/feature_no.rb +132 -81
- data/lib/cucumber/treetop_parser/feature_pt.rb +132 -81
- data/lib/cucumber/version.rb +1 -1
- data/spec/cucumber/treetop_parser/feature_parser_spec.rb +40 -0
- data/spec/cucumber/treetop_parser/spaces.feature +10 -0
- metadata +25 -12
@@ -3,13 +3,13 @@ require 'spec'
|
|
3
3
|
case PLATFORM
|
4
4
|
when /darwin/
|
5
5
|
require 'safariwatir'
|
6
|
-
Browser = Watir::Safari
|
6
|
+
Watir::Browser = Watir::Safari
|
7
7
|
when /win32|mingw/
|
8
8
|
require 'watir'
|
9
|
-
Browser = Watir::IE
|
9
|
+
Watir::Browser = Watir::IE
|
10
10
|
when /java/
|
11
11
|
require 'celerity'
|
12
|
-
Browser = Celerity::Browser
|
12
|
+
Watir::Browser = Celerity::Browser
|
13
13
|
else
|
14
14
|
raise "This platform is not supported (#{PLATFORM})"
|
15
15
|
end
|
@@ -30,7 +30,7 @@ class GoogleSearch
|
|
30
30
|
end
|
31
31
|
|
32
32
|
Before do
|
33
|
-
@b = Browser.new
|
33
|
+
@b = Watir::Browser.new
|
34
34
|
end
|
35
35
|
|
36
36
|
After do
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# This generator bootstraps a Rails project for use with Cucumber
|
2
|
+
class CucumberGenerator < Rails::Generator::Base
|
3
|
+
def manifest
|
4
|
+
record do |m|
|
5
|
+
m.directory 'features/steps'
|
6
|
+
m.file 'env.rb', 'features/steps/env.rb'
|
7
|
+
m.file 'common_webrat.rb', 'features/steps/common_webrat.rb'
|
8
|
+
|
9
|
+
m.directory 'lib/tasks'
|
10
|
+
m.file 'cucumber.rake', 'lib/tasks/cucumber.rake'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
def banner
|
17
|
+
"Usage: #{$0} cucumber"
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Commonly used webrat steps
|
2
|
+
# http://github.com/brynary/webrat
|
3
|
+
|
4
|
+
When /I press "(.*)"/ do |button|
|
5
|
+
clicks_button(button)
|
6
|
+
end
|
7
|
+
|
8
|
+
When /I follow "(.*)"/ do |link|
|
9
|
+
clicks_link(link)
|
10
|
+
end
|
11
|
+
|
12
|
+
When /I fill in "(.*)" for "(.*)"/ do |value, field|
|
13
|
+
fills_in(field, :with => value)
|
14
|
+
end
|
15
|
+
|
16
|
+
When /I check "(.*)"/ do |field|
|
17
|
+
checks(field)
|
18
|
+
end
|
19
|
+
|
20
|
+
When /I go to "(.*)"/ do |path|
|
21
|
+
visits(path)
|
22
|
+
end
|
23
|
+
|
24
|
+
Then /I should see "(.*)"/ do |text|
|
25
|
+
response.body.should =~ /#{text}/m
|
26
|
+
end
|
27
|
+
|
28
|
+
Then /I should not see "(.*)"/ do |text|
|
29
|
+
response.body.should_not =~ /#{text}/m
|
30
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
# Sets up the Rails environment for Cucumber
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
|
4
|
+
require 'cucumber/rails/world'
|
5
|
+
# Comment out the next line if you're not using RSpec's matchers (should / should_not) in your steps.
|
6
|
+
require 'cucumber/rails/rspec'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This generator bootstraps a Rails project for use with Cucumber
|
2
|
+
class FeatureGenerator < Rails::Generator::NamedBase
|
3
|
+
def manifest
|
4
|
+
record do |m|
|
5
|
+
m.directory 'features/steps'
|
6
|
+
m.template 'feature.erb', "features/manage_#{plural_name}.feature"
|
7
|
+
m.template 'steps.erb', "features/steps/#{singular_name}_steps.rb"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def banner
|
14
|
+
"Usage: #{$0} cucumber"
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Feature: Manage <%= plural_name %>
|
2
|
+
In order to keep track of <%= plural_name %>
|
3
|
+
A <%= singular_name %> mechanic
|
4
|
+
Should be able to manage several <%= plural_name %>
|
5
|
+
|
6
|
+
Scenario: Register new <%= singular_name %>
|
7
|
+
Given I am on the new <%= singular_name %> page
|
8
|
+
<% keyword = 'When' -%>
|
9
|
+
<% args.each do |arg| -%>
|
10
|
+
<%= keyword %> I fill in "My <%= singular_name %> <%= arg %>" for "<%= arg.humanize %>"
|
11
|
+
<% keyword = 'And' -%>
|
12
|
+
<% end -%>
|
13
|
+
And I press "Create"
|
14
|
+
<% keyword = 'Then' -%>
|
15
|
+
<% args.each do |arg| -%>
|
16
|
+
<%= keyword %> I should see "My <%= singular_name %> <%= arg %>"
|
17
|
+
<% keyword = 'And' -%>
|
18
|
+
<% end -%>
|
19
|
+
|
20
|
+
Scenario: Delete <%= singular_name %>
|
21
|
+
Given there are 4 <%= plural_name %>
|
22
|
+
When I delete the first <%= singular_name %>
|
23
|
+
Then there should be 3 <%= plural_name %> left
|
24
|
+
|
25
|
+
| initial | after |
|
26
|
+
| 100 | 99 |
|
27
|
+
| 1 | 0 |
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Given /I am on the new <%= singular_name %> page/ do
|
2
|
+
visits "/<%= plural_name %>/new"
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /there are (\d+) <%= plural_name %>/ do |n|
|
6
|
+
<%= class_name %>.transaction do
|
7
|
+
<%= class_name %>.destroy_all
|
8
|
+
n.to_i.times do |n|
|
9
|
+
<%= class_name %>.create! :name => "<%= class_name %> #{n}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
When /I delete the first <%= singular_name %>/ do
|
15
|
+
visits <%= plural_name %>_url
|
16
|
+
clicks_link "Destroy"
|
17
|
+
end
|
18
|
+
|
19
|
+
Then /there should be (\d+) <%= plural_name %> left/ do |n|
|
20
|
+
<%= class_name %>.count.should == n.to_i
|
21
|
+
response.should have_tag("table tr", n.to_i + 1) # There is a header row too
|
22
|
+
end
|
data/lib/cucumber.rb
CHANGED
@@ -17,8 +17,16 @@ module Cucumber
|
|
17
17
|
attr_reader :language
|
18
18
|
|
19
19
|
def load_language(lang)
|
20
|
+
@language = config[lang]
|
21
|
+
end
|
22
|
+
|
23
|
+
def languages
|
24
|
+
config.keys.sort
|
25
|
+
end
|
26
|
+
|
27
|
+
def config
|
20
28
|
require 'yaml'
|
21
|
-
@
|
29
|
+
@config ||= YAML.load_file(File.dirname(__FILE__) + '/cucumber/languages.yml')
|
22
30
|
end
|
23
31
|
end
|
24
32
|
end
|
data/lib/cucumber/cli.rb
CHANGED
@@ -21,6 +21,12 @@ module Cucumber
|
|
21
21
|
cli
|
22
22
|
end
|
23
23
|
end
|
24
|
+
|
25
|
+
FORMATS = {
|
26
|
+
'progress' => Formatters::ProgressFormatter,
|
27
|
+
'html' => Formatters::HtmlFormatter,
|
28
|
+
'pretty' => Formatters::PrettyFormatter
|
29
|
+
}
|
24
30
|
|
25
31
|
def initialize(args)
|
26
32
|
@args = args.dup
|
@@ -37,13 +43,15 @@ module Cucumber
|
|
37
43
|
@options[:require] ||= []
|
38
44
|
@options[:require] << v
|
39
45
|
end
|
40
|
-
opts.on("-l LINE", "--line
|
46
|
+
opts.on("-l LINE", "--line LINE", "Only execute the scenario at the given line") do |v|
|
41
47
|
@options[:line] = v
|
42
48
|
end
|
43
|
-
opts.on("-a LANG", "--language LANG", "Specify language for features (Default: #{@options[:lang]})"
|
49
|
+
opts.on("-a LANG", "--language LANG", "Specify language for features (Default: #{@options[:lang]})",
|
50
|
+
"Available languages: #{Cucumber.languages.join(", ")}") do |v|
|
44
51
|
@options[:lang] = v
|
45
52
|
end
|
46
|
-
opts.on("-f FORMAT", "--format FORMAT", "How to format features (Default: #{@options[:format]})"
|
53
|
+
opts.on("-f FORMAT", "--format FORMAT", "How to format features (Default: #{@options[:format]})",
|
54
|
+
"Available formats: #{FORMATS.keys.sort.join(", ")}") do |v|
|
47
55
|
@options[:format] = v
|
48
56
|
end
|
49
57
|
opts.on("-d", "--dry-run", "Invokes formatters without executing the steps.") do
|
@@ -80,6 +88,7 @@ module Cucumber
|
|
80
88
|
|
81
89
|
# Requires files - typically step files and ruby feature files.
|
82
90
|
def require_files
|
91
|
+
ARGV.clear # Shut up RSpec
|
83
92
|
require "cucumber/treetop_parser/feature_#{@options[:lang]}"
|
84
93
|
require "cucumber/treetop_parser/feature_parser"
|
85
94
|
|
@@ -106,11 +115,7 @@ module Cucumber
|
|
106
115
|
end
|
107
116
|
|
108
117
|
def formatter
|
109
|
-
klass =
|
110
|
-
'progress' => Formatters::ProgressFormatter,
|
111
|
-
'html' => Formatters::HtmlFormatter,
|
112
|
-
'pretty' => Formatters::PrettyFormatter,
|
113
|
-
}[@options[:format]]
|
118
|
+
klass = FORMATS[@options[:format]]
|
114
119
|
klass.new(STDOUT)
|
115
120
|
end
|
116
121
|
|
data/lib/cucumber/executor.rb
CHANGED
@@ -49,10 +49,6 @@ module Cucumber
|
|
49
49
|
@formatter.header_executing(header) if @formatter.respond_to?(:header_executing)
|
50
50
|
end
|
51
51
|
|
52
|
-
def visit_narrative(narrative)
|
53
|
-
@formatter.narrative_executing(narrative) if @formatter.respond_to?(:narrative_executing)
|
54
|
-
end
|
55
|
-
|
56
52
|
def visit_scenario(scenario)
|
57
53
|
if @line.nil? || scenario.at_line?(@line)
|
58
54
|
@error = nil
|
@@ -103,16 +103,26 @@ module Cucumber
|
|
103
103
|
@io.puts failed("#{@failed.length} steps failed") unless @failed.empty?
|
104
104
|
@io.puts skipped("#{@skipped.length} steps skipped") unless @skipped.empty?
|
105
105
|
@io.puts pending("#{@pending.length} steps pending") unless @pending.empty?
|
106
|
-
|
106
|
+
@io.print reset
|
107
|
+
print_snippets
|
108
|
+
end
|
109
|
+
|
110
|
+
def print_snippets
|
107
111
|
unless @pending.empty?
|
108
112
|
@io.puts "\nYou can use these snippets to implement pending steps:\n\n"
|
109
113
|
|
110
|
-
|
111
|
-
|
114
|
+
prev_keyword = nil
|
115
|
+
snippets = @pending.map do |step|
|
116
|
+
next if step.row?
|
117
|
+
snippet = "#{step.actual_keyword} /#{step.name}/ do\nend\n\n"
|
118
|
+
prev_keyword = step.keyword
|
119
|
+
snippet
|
120
|
+
end.compact.uniq
|
121
|
+
|
122
|
+
snippets.each do |snippet|
|
123
|
+
@io.puts snippet
|
112
124
|
end
|
113
125
|
end
|
114
|
-
|
115
|
-
@io.print reset
|
116
126
|
end
|
117
127
|
end
|
118
128
|
end
|
data/lib/cucumber/languages.yml
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require 'spec/rails'
|
3
|
+
|
4
|
+
# Hack to stop RSpec from dumping the summary
|
5
|
+
Spec::Runner::Options.class_eval do
|
6
|
+
def examples_should_be_run?
|
7
|
+
false
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
ActionController::Integration::Session.send(:include, Spec::Matchers)
|
12
|
+
ActionController::Integration::Session.send(:include, Spec::Rails::Matchers)
|
data/lib/cucumber/rails/world.rb
CHANGED
@@ -8,8 +8,6 @@ else
|
|
8
8
|
require 'action_controller/integration'
|
9
9
|
end
|
10
10
|
require 'test/unit/testresult'
|
11
|
-
require 'spec'
|
12
|
-
require 'spec/rails'
|
13
11
|
|
14
12
|
# These allow exceptions to come through as opposed to being caught and hvaing non-helpful responses returned.
|
15
13
|
ActionController::Base.class_eval do
|
@@ -26,18 +24,9 @@ end
|
|
26
24
|
# So that Test::Unit doesn't launch at the end - makes it think it has already been run.
|
27
25
|
Test::Unit.run = true
|
28
26
|
|
29
|
-
|
30
|
-
Spec::Runner::Options.class_eval do
|
31
|
-
def examples_should_be_run?
|
32
|
-
false
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
ActionController::Integration::Session.send(:include, Spec::Matchers)
|
37
|
-
ActionController::Integration::Session.send(:include, Spec::Rails::Matchers)
|
38
|
-
|
39
|
-
module Cucumber
|
27
|
+
module Cucumber #:nodoc:
|
40
28
|
module Rails
|
29
|
+
# All scenarios will execute in the context of a new instance of World.
|
41
30
|
class World < ActionController::IntegrationTest
|
42
31
|
if defined?(ActiveRecord::Base)
|
43
32
|
self.use_transactional_fixtures = true
|
@@ -58,12 +47,25 @@ end
|
|
58
47
|
|
59
48
|
if defined?(ActiveRecord::Base)
|
60
49
|
Before do
|
61
|
-
ActiveRecord::Base
|
50
|
+
if defined?(ActiveRecord::Base)
|
51
|
+
if ActiveRecord::Base.connection.respond_to?(:increment_open_transactions)
|
52
|
+
ActiveRecord::Base.connection.increment_open_transactions
|
53
|
+
else
|
54
|
+
ActiveRecord::Base.send :increment_open_transactions
|
55
|
+
end
|
56
|
+
end
|
62
57
|
ActiveRecord::Base.connection.begin_db_transaction
|
58
|
+
ActionMailer::Base.deliveries = [] if defined?(ActionMailer::Base)
|
63
59
|
end
|
64
60
|
|
65
61
|
After do
|
66
|
-
ActiveRecord::Base
|
67
|
-
|
62
|
+
if defined?(ActiveRecord::Base)
|
63
|
+
ActiveRecord::Base.connection.rollback_db_transaction
|
64
|
+
if ActiveRecord::Base.connection.respond_to?(:decrement_open_transactions)
|
65
|
+
ActiveRecord::Base.connection.decrement_open_transactions
|
66
|
+
else
|
67
|
+
ActiveRecord::Base.send :decrement_open_transactions
|
68
|
+
end
|
69
|
+
end
|
68
70
|
end
|
69
71
|
end
|
data/lib/cucumber/rake/task.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module Cucumber
|
2
2
|
module Rake
|
3
3
|
# Defines a task for running features.
|
4
|
-
# TODO: Base on http://github.com/dchelimsky/rspec/tree/master/lib/spec/rake/spectask.rb
|
5
4
|
class Task
|
6
5
|
LIB = File.expand_path(File.dirname(__FILE__) + '/../..')
|
7
6
|
BINARY = File.expand_path(File.dirname(__FILE__) + '/../../../bin/cucumber')
|
@@ -12,11 +11,14 @@ module Cucumber
|
|
12
11
|
attr_accessor :feature_list
|
13
12
|
attr_accessor :feature_pattern
|
14
13
|
attr_accessor :cucumber_opts
|
14
|
+
attr_accessor :rcov
|
15
|
+
attr_accessor :rcov_opts
|
15
16
|
|
16
17
|
# Define a task
|
17
18
|
def initialize(task_name = "features", desc = "Run Features")
|
18
19
|
@task_name, @desc = task_name, desc
|
19
|
-
@libs = [
|
20
|
+
@libs = []
|
21
|
+
@rcov_opts = %w{--rails --exclude osx\/objc,gems\/}
|
20
22
|
|
21
23
|
yield self if block_given?
|
22
24
|
|
@@ -28,27 +30,28 @@ module Cucumber
|
|
28
30
|
def define_tasks
|
29
31
|
desc @desc
|
30
32
|
task @task_name do
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
args << '"%s"' % BINARY
|
35
|
-
args << (ENV['CUCUMBER_OPTS'] || cucumber_opts)
|
33
|
+
lib_args = ['"%s"' % ([LIB] + libs).join(File::PATH_SEPARATOR)]
|
34
|
+
cucumber_bin = ['"%s"' % BINARY]
|
35
|
+
cuc_opts = [(ENV['CUCUMBER_OPTS'] || cucumber_opts)]
|
36
36
|
|
37
37
|
step_files.each do |step_file|
|
38
|
-
|
39
|
-
|
38
|
+
cuc_opts << '--require'
|
39
|
+
cuc_opts << step_file
|
40
|
+
end
|
41
|
+
|
42
|
+
if rcov
|
43
|
+
args = (['-I'] + lib_args + ['-S', 'rcov'] + rcov_opts + cucumber_bin + ['--'] + cuc_opts + feature_files).flatten
|
44
|
+
else
|
45
|
+
args = (['-I'] + lib_args + cucumber_bin + cuc_opts + feature_files).flatten
|
40
46
|
end
|
41
|
-
args << feature_files
|
42
|
-
args.flatten!
|
43
|
-
args.compact!
|
44
47
|
ruby(args.join(" ")) # ruby(*args) is broken on Windows
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
48
51
|
|
49
52
|
def feature_files # :nodoc:
|
50
|
-
if ENV['
|
51
|
-
FileList[ ENV['
|
53
|
+
if ENV['FEATURE']
|
54
|
+
FileList[ ENV['FEATURE'] ]
|
52
55
|
else
|
53
56
|
result = []
|
54
57
|
result += feature_list.to_a if feature_list
|