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.
Files changed (47) hide show
  1. data/Manifest.txt +22 -10
  2. data/README.textile +147 -17
  3. data/README.txt +41 -0
  4. data/config/hoe.rb +1 -1
  5. data/examples/calculator/features/addition.feature +7 -7
  6. data/examples/calculator/features/division.feature +3 -4
  7. data/examples/calculator/features/steps/{addition_steps.rb → calculator_steps.rb} +0 -1
  8. data/examples/calculator/lib/calculator.rb +2 -4
  9. data/examples/{pure_ruby → calculator_ruby_features}/Rakefile +0 -0
  10. data/examples/{pure_ruby → calculator_ruby_features}/features/addition.rb +2 -2
  11. data/examples/{pure_ruby/features/steps/addition_steps.rb → calculator_ruby_features/features/steps/calculator_steps.rb} +0 -0
  12. data/examples/java/src/cucumber/demo/Hello.java +1 -1
  13. data/examples/{simple_norwegian → norwegian_calculator}/Rakefile +0 -0
  14. data/examples/{simple_norwegian/features/steps/matte_steg.rb.rb → norwegian_calculator/features/kalkulator_steps.rb} +2 -2
  15. data/examples/{simple_norwegian → norwegian_calculator}/features/summering.feature +4 -4
  16. data/examples/{web → watir}/Rakefile +0 -0
  17. data/examples/{web → watir}/features/search.feature +1 -1
  18. data/examples/{web → watir}/features/steps/stories_steps.rb +4 -4
  19. data/gem_tasks/gemspec.rake +6 -0
  20. data/generators/cucumber/cucumber_generator.rb +20 -0
  21. data/generators/cucumber/templates/common_webrat.rb +30 -0
  22. data/generators/cucumber/templates/cucumber.rake +7 -0
  23. data/generators/cucumber/templates/env.rb +6 -0
  24. data/generators/feature/feature_generator.rb +17 -0
  25. data/generators/feature/templates/feature.erb +27 -0
  26. data/generators/feature/templates/steps.erb +22 -0
  27. data/lib/cucumber.rb +9 -1
  28. data/lib/cucumber/cli.rb +13 -8
  29. data/lib/cucumber/executor.rb +0 -4
  30. data/lib/cucumber/formatters/html_formatter.rb +1 -0
  31. data/lib/cucumber/formatters/pretty_formatter.rb +15 -5
  32. data/lib/cucumber/languages.yml +1 -1
  33. data/lib/cucumber/rails/rspec.rb +12 -0
  34. data/lib/cucumber/rails/world.rb +18 -16
  35. data/lib/cucumber/rake/task.rb +17 -14
  36. data/lib/cucumber/step_methods.rb +3 -1
  37. data/lib/cucumber/tree/scenario.rb +6 -0
  38. data/lib/cucumber/tree/step.rb +8 -0
  39. data/lib/cucumber/treetop_parser/feature.treetop.erb +10 -6
  40. data/lib/cucumber/treetop_parser/feature_en.rb +132 -81
  41. data/lib/cucumber/treetop_parser/feature_fr.rb +136 -85
  42. data/lib/cucumber/treetop_parser/feature_no.rb +132 -81
  43. data/lib/cucumber/treetop_parser/feature_pt.rb +132 -81
  44. data/lib/cucumber/version.rb +1 -1
  45. data/spec/cucumber/treetop_parser/feature_parser_spec.rb +40 -0
  46. data/spec/cucumber/treetop_parser/spaces.feature +10 -0
  47. 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,6 @@
1
+ namespace :gemspec do
2
+ desc 'Refresh cucumber.gemspec to include ALL files'
3
+ task :refresh => 'manifest:refresh' do
4
+ File.open('cucumber.gemspec', 'w') {|io| io.write($hoe.spec.to_ruby)}
5
+ end
6
+ end
@@ -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,7 @@
1
+ $:.unshift(RAILS_ROOT + '/vendor/plugins/cucumber/lib')
2
+ require 'cucumber/rake/task'
3
+
4
+ Cucumber::Rake::Task.new(:features) do |t|
5
+ t.cucumber_opts = "--format pretty"
6
+ end
7
+ task :features => 'db:test:prepare'
@@ -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
- @language = YAML.load_file(File.dirname(__FILE__) + '/cucumber/languages.yml')[lang]
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 LANG", "Only execute the scenario at the given line") do |v|
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]})") do |v|
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]})") do |v|
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
 
@@ -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
@@ -220,6 +220,7 @@ HTML
220
220
  @io.puts " <dt>Feature: #{header}</dt>"
221
221
  end
222
222
 
223
+ # TODO: Lose me
223
224
  def visit_narrative(narrative)
224
225
  @io.puts " <dd>"
225
226
  @io.puts " <p>"
@@ -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
- @pending.each do |step|
111
- @io.puts "#{step.keyword} /#{step.name}/ do\nend\n\n" unless step.row?
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
@@ -19,7 +19,7 @@
19
19
  scenario: Scenario
20
20
  given_scenario: SoitScenario
21
21
  given: Soit
22
- when: Quand
22
+ when: Lorsque
23
23
  then: Alors
24
24
  and: Et
25
25
  "pt":
@@ -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)
@@ -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
- # Hack to stop RSpec from dumping the summary
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.send :increment_open_transactions
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.connection.rollback_db_transaction
67
- ActiveRecord::Base.send :decrement_open_transactions
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
@@ -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 = [LIB]
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
- args = []
32
- args << '-I'
33
- args << '"%s"' % libs.join(File::PATH_SEPARATOR)
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
- args << '--require'
39
- args << step_file
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['STORY']
51
- FileList[ ENV['STORY'] ]
53
+ if ENV['FEATURE']
54
+ FileList[ ENV['FEATURE'] ]
52
55
  else
53
56
  result = []
54
57
  result += feature_list.to_a if feature_list