aslakhellesoy-cucumber 0.1.99.23 → 0.1.100.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/History.txt +2 -6
  2. data/Manifest.txt +8 -2
  3. data/examples/i18n/et/features/jagamine.feature +9 -0
  4. data/examples/jbehave/README.textile +4 -1
  5. data/examples/jbehave/features/trading.feature +4 -0
  6. data/examples/jbehave/pom.xml +5 -0
  7. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/scenarios/TraderSteps.java +6 -1
  8. data/examples/selenium/features/step_definitons/search_steps.rb +13 -0
  9. data/examples/selenium/features/support/env.rb +19 -0
  10. data/examples/selenium_webrat/Rakefile +6 -0
  11. data/examples/selenium_webrat/features/search.feature +9 -0
  12. data/examples/selenium_webrat/features/step_definitons/search_steps.rb +13 -0
  13. data/examples/selenium_webrat/features/support/env.rb +41 -0
  14. data/examples/self_test/features/background/failing_background.feature +1 -0
  15. data/examples/self_test/features/step_definitions/sample_steps.rb +1 -1
  16. data/examples/self_test/features/support/tag_count_formatter.rb +1 -1
  17. data/features/background.feature +9 -11
  18. data/features/cucumber_cli.feature +24 -1
  19. data/features/cucumber_cli_outlines.feature +10 -19
  20. data/features/report_called_undefined_steps.feature +2 -0
  21. data/gem_tasks/rspec.rake +2 -0
  22. data/lib/cucumber.rb +7 -15
  23. data/lib/cucumber/ast.rb +3 -3
  24. data/lib/cucumber/ast/background.rb +28 -66
  25. data/lib/cucumber/ast/examples.rb +15 -3
  26. data/lib/cucumber/ast/feature.rb +20 -24
  27. data/lib/cucumber/ast/feature_element.rb +46 -0
  28. data/lib/cucumber/ast/features.rb +2 -21
  29. data/lib/cucumber/ast/outline_table.rb +46 -14
  30. data/lib/cucumber/ast/py_string.rb +8 -3
  31. data/lib/cucumber/ast/scenario.rb +34 -73
  32. data/lib/cucumber/ast/scenario_outline.rb +40 -42
  33. data/lib/cucumber/ast/step.rb +53 -89
  34. data/lib/cucumber/ast/step_collection.rb +66 -0
  35. data/lib/cucumber/ast/step_invocation.rb +106 -0
  36. data/lib/cucumber/ast/table.rb +38 -19
  37. data/lib/cucumber/ast/tags.rb +4 -11
  38. data/lib/cucumber/ast/visitor.rb +31 -19
  39. data/lib/cucumber/broadcaster.rb +1 -1
  40. data/lib/cucumber/cli/configuration.rb +24 -16
  41. data/lib/cucumber/cli/language_help_formatter.rb +4 -4
  42. data/lib/cucumber/cli/main.rb +5 -4
  43. data/lib/cucumber/core_ext/proc.rb +2 -2
  44. data/lib/cucumber/formatter/ansicolor.rb +0 -1
  45. data/lib/cucumber/formatter/console.rb +18 -34
  46. data/lib/cucumber/formatter/html.rb +13 -10
  47. data/lib/cucumber/formatter/pretty.rb +48 -36
  48. data/lib/cucumber/formatter/profile.rb +6 -6
  49. data/lib/cucumber/formatter/progress.rb +12 -20
  50. data/lib/cucumber/formatter/rerun.rb +5 -5
  51. data/lib/cucumber/jbehave.rb +21 -26
  52. data/lib/cucumber/parser/feature.rb +26 -29
  53. data/lib/cucumber/parser/feature.tt +17 -12
  54. data/lib/cucumber/parser/treetop_ext.rb +13 -13
  55. data/lib/cucumber/platform.rb +0 -1
  56. data/lib/cucumber/rails/world.rb +2 -2
  57. data/lib/cucumber/rake/task.rb +0 -1
  58. data/lib/cucumber/step_definition.rb +21 -12
  59. data/lib/cucumber/step_match.rb +49 -0
  60. data/lib/cucumber/step_mother.rb +98 -80
  61. data/lib/cucumber/version.rb +2 -2
  62. data/lib/cucumber/world.rb +42 -0
  63. data/rails_generators/cucumber/templates/paths.rb +1 -1
  64. data/rails_generators/cucumber/templates/webrat_steps.rb +17 -17
  65. data/rails_generators/feature/feature_generator.rb +4 -0
  66. data/rails_generators/feature/templates/steps.erb +0 -4
  67. data/spec/cucumber/ast/background_spec.rb +32 -41
  68. data/spec/cucumber/ast/feature_factory.rb +10 -1
  69. data/spec/cucumber/ast/feature_spec.rb +7 -30
  70. data/spec/cucumber/ast/scenario_outline_spec.rb +3 -0
  71. data/spec/cucumber/ast/scenario_spec.rb +8 -25
  72. data/spec/cucumber/ast/step_collection_spec.rb +8 -0
  73. data/spec/cucumber/ast/step_spec.rb +37 -29
  74. data/spec/cucumber/ast/tags_spec.rb +2 -18
  75. data/spec/cucumber/cli/configuration_spec.rb +7 -0
  76. data/spec/cucumber/cli/main_spec.rb +1 -1
  77. data/spec/cucumber/parser/feature_parser_spec.rb +6 -5
  78. data/spec/cucumber/step_definition_spec.rb +5 -5
  79. data/spec/cucumber/step_mother_spec.rb +6 -6
  80. data/spec/cucumber/world/pending_spec.rb +1 -1
  81. metadata +17 -5
  82. data/lib/cucumber/ast/filter.rb +0 -22
  83. data/lib/cucumber/ast/steps.rb +0 -13
@@ -5,13 +5,13 @@ module Cucumber
5
5
  super(step_mother)
6
6
  @io = io
7
7
  @file_names = []
8
- @file_lines = Hash.new{|h,k| h[k] = []}
8
+ @file_colon_lines = Hash.new{|h,k| h[k] = []}
9
9
  end
10
10
 
11
11
  def visit_features(features)
12
12
  super
13
13
  files = @file_names.uniq.map do |file|
14
- lines = @file_lines[file]
14
+ lines = @file_colon_lines[file]
15
15
  "#{file}:#{lines.join(':')}"
16
16
  end
17
17
  @io.puts files.join(' ')
@@ -21,13 +21,13 @@ module Cucumber
21
21
  @rerun = false
22
22
  super
23
23
  if @rerun
24
- file, line = *feature_element.file_line.split(':')
25
- @file_lines[file] << line
24
+ file, line = *feature_element.file_colon_line.split(':')
25
+ @file_colon_lines[file] << line
26
26
  @file_names << file
27
27
  end
28
28
  end
29
29
 
30
- def visit_step_name(keyword, step_name, status, step_definition, source_indent)
30
+ def visit_step_name(keyword, step_match, status, source_indent)
31
31
  @rerun = true if [:failed].index(status)
32
32
  end
33
33
  end
@@ -23,65 +23,60 @@ if defined?(JRUBY_VERSION)
23
23
  def initialize(jbehave_steps, jbehave_candidate_step)
24
24
  @jbehave_steps = jbehave_steps
25
25
  @jbehave_candidate_step = jbehave_candidate_step
26
+ @regexp = Regexp.new(jbehave_candidate_step.pattern.pattern)
26
27
  end
27
-
28
- def match(step_name)
29
- full_text = "Given #{step_name}" # JBehave doesn't distinguish GWT internally :-)
30
- @jbehave_candidate_step.matches(full_text)
28
+
29
+ def step_match(name_to_match, name_to_report)
30
+ if(match = name_to_match.match(@regexp))
31
+ StepMatch.new(self, name_to_match, name_to_report, match.captures)
32
+ else
33
+ nil
34
+ end
31
35
  end
32
-
36
+
33
37
  def file_colon_line
34
38
  @jbehave_steps.java_class.name
35
39
  end
36
40
 
37
41
  def format_args(step_name, format)
38
- java_pattern = @jbehave_candidate_step.pattern.pattern
39
- regexp = Regexp.new(java_pattern)
40
- step_name.gzub(regexp, format)
42
+ step_name.gzub(@regexp, format)
41
43
  end
42
44
 
43
- def matched_args(step_name)
44
- java_pattern = @jbehave_candidate_step.pattern.pattern
45
- regexp = Regexp.new(java_pattern)
46
- step_name.match(regexp).captures
47
- end
45
+ def invoke(world, args, step_name)
46
+ step = @jbehave_candidate_step.createFrom("Given #{step_name}") # JBehave doesn't care about the adverb.
47
+ step = @jbehave_candidate_step.__send__(:createStep, "Given #{step_name}", args) # JBehave doesn't care about the adverb.
48
48
 
49
- def execute(step_name, world, *args)
50
- step = @jbehave_candidate_step.createFrom("Given #{step_name}")
51
49
  result = step.perform
52
- result.describeTo(JBehave::REPORTER)
50
+ result.describeTo(Reporter)
53
51
  end
54
52
  end
55
53
 
56
- class JBehaveException < Exception
57
- end
58
-
59
54
  # Implements the org.jbehave.scenario.reporters.ScenarioReporter methods
60
55
  class Reporter
61
- def successful(step_text)
56
+ def self.successful(step_text)
62
57
  # noop
63
58
  end
64
59
 
65
- def failed(step, java_exception)
60
+ def self.failed(step, java_exception)
66
61
  raise java_exception_to_ruby_exception(java_exception)
67
62
  end
68
63
 
69
64
  private
70
65
 
71
- def java_exception_to_ruby_exception(java_exception)
66
+ def self.java_exception_to_ruby_exception(java_exception)
72
67
  # OK, this is a little funky - JRuby weirdness
73
68
  ruby_exception = org.jruby.NativeException.new(JRuby.runtime, JBehaveException, java_exception)
74
69
  ruby_exception.set_backtrace([]) # work around backtrace bug in jruby
75
-
76
- exception = JBehaveException.new(java_exception.getMessage)
70
+ exception = JBehaveException.new("#{java_exception.getClass.getName}: #{java_exception.getMessage}")
77
71
  bt = ruby_exception.backtrace
78
72
  Exception.cucumber_strip_backtrace!(bt, nil, nil)
79
73
  exception.set_backtrace(bt)
80
74
  exception
81
75
  end
82
76
  end
83
-
84
- REPORTER = Reporter.new
77
+
78
+ class JBehaveException < Exception
79
+ end
85
80
 
86
81
  def self.snippet_text(step_keyword, step_name)
87
82
  camel = step_name.gsub(/(\s.)/) {$1.upcase.strip}
@@ -45,7 +45,7 @@ module Cucumber
45
45
  elements[5]
46
46
  end
47
47
 
48
- def background
48
+ def bg
49
49
  elements[6]
50
50
  end
51
51
 
@@ -57,11 +57,14 @@ module Cucumber
57
57
 
58
58
  module Feature2
59
59
  def build
60
- if background.respond_to?(:build)
61
- Ast::Feature.new(comment.build, tags.build, header.text_value, feature_elements.build, background.build)
62
- else
63
- Ast::Feature.new(comment.build, tags.build, header.text_value, feature_elements.build)
64
- end
60
+ background = bg.respond_to?(:build) ? bg.build : nil
61
+ Ast::Feature.new(
62
+ background,
63
+ comment.build,
64
+ tags.build,
65
+ header.text_value,
66
+ feature_elements.build(background)
67
+ )
65
68
  end
66
69
  end
67
70
 
@@ -311,7 +314,7 @@ module Cucumber
311
314
  if r1
312
315
  s2, i2 = [], index
313
316
  loop do
314
- if input.index(Regexp.new('[^@\\n\\t ]'), index) == index
317
+ if input.index(Regexp.new('[^@\\r\\n\\t ]'), index) == index
315
318
  r3 = (SyntaxNode).new(input, index...(index + 1))
316
319
  @index += 1
317
320
  else
@@ -548,8 +551,8 @@ module Cucumber
548
551
  end
549
552
 
550
553
  module FeatureElements0
551
- def build
552
- elements.map{|s| s.build}
554
+ def build(background)
555
+ elements.map{|s| s.build(background)}
553
556
  end
554
557
  end
555
558
 
@@ -611,6 +614,10 @@ module Cucumber
611
614
  elements[5]
612
615
  end
613
616
 
617
+ def white
618
+ elements[6]
619
+ end
620
+
614
621
  def steps
615
622
  elements[7]
616
623
  end
@@ -621,8 +628,9 @@ module Cucumber
621
628
  end
622
629
 
623
630
  module Scenario1
624
- def build
631
+ def build(background)
625
632
  Ast::Scenario.new(
633
+ background,
626
634
  comment.build,
627
635
  tags.build,
628
636
  scenario_keyword.line,
@@ -669,26 +677,14 @@ module Cucumber
669
677
  r7 = _nt_line_to_eol
670
678
  s0 << r7
671
679
  if r7
672
- i8 = index
673
- r9 = _nt_white
674
- if r9
675
- r8 = r9
676
- else
677
- r10 = _nt_eof
678
- if r10
679
- r8 = r10
680
- else
681
- self.index = i8
682
- r8 = nil
683
- end
684
- end
680
+ r8 = _nt_white
685
681
  s0 << r8
686
682
  if r8
687
- r11 = _nt_steps
688
- s0 << r11
689
- if r11
690
- r12 = _nt_white
691
- s0 << r12
683
+ r9 = _nt_steps
684
+ s0 << r9
685
+ if r9
686
+ r10 = _nt_white
687
+ s0 << r10
692
688
  end
693
689
  end
694
690
  end
@@ -750,8 +746,9 @@ module Cucumber
750
746
  end
751
747
 
752
748
  module ScenarioOutline1
753
- def build
749
+ def build(background)
754
750
  Ast::ScenarioOutline.new(
751
+ background,
755
752
  comment.build,
756
753
  tags.build,
757
754
  scenario_outline_keyword.line,
@@ -17,15 +17,18 @@ module Cucumber
17
17
  tags
18
18
  white
19
19
  header:(!(scenario_outline / scenario / background) .)*
20
- background:(background)?
20
+ bg:background?
21
21
  feature_elements
22
22
  comment? {
23
23
  def build
24
- if background.respond_to?(:build)
25
- Ast::Feature.new(comment.build, tags.build, header.text_value, feature_elements.build, background.build)
26
- else
27
- Ast::Feature.new(comment.build, tags.build, header.text_value, feature_elements.build)
28
- end
24
+ background = bg.respond_to?(:build) ? bg.build : nil
25
+ Ast::Feature.new(
26
+ background,
27
+ comment.build,
28
+ tags.build,
29
+ header.text_value,
30
+ feature_elements.build(background)
31
+ )
29
32
  end
30
33
  }
31
34
  end
@@ -40,7 +43,7 @@ module Cucumber
40
43
  end
41
44
 
42
45
  rule tag
43
- '@' tag_name:([^@\n\t ])+
46
+ '@' tag_name:([^@\r\n\t ])+
44
47
  end
45
48
 
46
49
  rule comment
@@ -70,16 +73,17 @@ module Cucumber
70
73
 
71
74
  rule feature_elements
72
75
  (scenario / scenario_outline)* {
73
- def build
74
- elements.map{|s| s.build}
76
+ def build(background)
77
+ elements.map{|s| s.build(background)}
75
78
  end
76
79
  }
77
80
  end
78
81
 
79
82
  rule scenario
80
- comment tags white scenario_keyword space* name:line_to_eol (white / eof) steps white {
81
- def build
83
+ comment tags white scenario_keyword space* name:line_to_eol white steps white {
84
+ def build(background)
82
85
  Ast::Scenario.new(
86
+ background,
83
87
  comment.build,
84
88
  tags.build,
85
89
  scenario_keyword.line,
@@ -93,8 +97,9 @@ module Cucumber
93
97
 
94
98
  rule scenario_outline
95
99
  comment tags white scenario_outline_keyword space* name:line_to_eol white steps examples_sections white {
96
- def build
100
+ def build(background)
97
101
  Ast::ScenarioOutline.new(
102
+ background,
98
103
  comment.build,
99
104
  tags.build,
100
105
  scenario_outline_keyword.line,
@@ -13,11 +13,11 @@ end
13
13
  module Cucumber
14
14
  module Parser
15
15
  module TreetopExt
16
- FILE_LINE_PATTERN = /^([\w\W]*?):([\d:]+)$/
16
+ FILE_COLON_LINE_PATTERN = /^([\w\W]*?):([\d:]+)$/
17
17
 
18
18
  # Parses a file and returns a Cucumber::Ast
19
19
  def parse_file(file)
20
- _, path, lines = *FILE_LINE_PATTERN.match(file)
20
+ _, path, lines = *FILE_COLON_LINE_PATTERN.match(file)
21
21
  if path
22
22
  lines = lines.split(':').map { |line| line.to_i }
23
23
  else
@@ -35,6 +35,17 @@ module Cucumber
35
35
  feature.lines = lines
36
36
  feature
37
37
  end
38
+
39
+ def parse_or_fail(s, file=nil, line_offset=0)
40
+ parse_tree = parse(s)
41
+ if parse_tree.nil?
42
+ raise Cucumber::Parser::SyntaxError.new(self, file, line_offset)
43
+ else
44
+ ast = parse_tree.build
45
+ ast.file = file
46
+ ast
47
+ end
48
+ end
38
49
  end
39
50
 
40
51
  class SyntaxError < StandardError
@@ -59,17 +70,6 @@ module Treetop
59
70
 
60
71
  class CompiledParser
61
72
  include Cucumber::Parser::TreetopExt
62
-
63
- def parse_or_fail(s, file=nil, line=0)
64
- parse_tree = parse(s)
65
- if parse_tree.nil?
66
- raise Cucumber::Parser::SyntaxError.new(self, file, line)
67
- else
68
- ast = parse_tree.build
69
- ast.file = file
70
- ast
71
- end
72
- end
73
73
  end
74
74
  end
75
75
  end
@@ -14,5 +14,4 @@ module Cucumber
14
14
  RAILS = defined?(Rails)
15
15
  RUBY_BINARY = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
16
16
  RUBY_1_9 = RUBY_VERSION =~ /^1\.9/
17
- EXCEPTION_STATUS = Hash.new(:failed)
18
17
  end
@@ -11,8 +11,8 @@ require 'test/unit/testresult'
11
11
 
12
12
  # These allow exceptions to come through as opposed to being caught and having non-helpful responses returned.
13
13
  ActionController::Base.class_eval do
14
- def perform_action_with_rescue
15
- perform_action_without_rescue
14
+ def rescue_action(exception)
15
+ raise exception
16
16
  end
17
17
  end
18
18
  ActionController::Dispatcher.class_eval do
@@ -14,7 +14,6 @@ module Cucumber
14
14
  # To further configure the task, you can pass a block:
15
15
  #
16
16
  # Cucumber::Rake::Task.new do |t|
17
- # t.libs << 'lib'
18
17
  # t.cucumber_opts = "--format progress"
19
18
  # end
20
19
  #
@@ -1,3 +1,4 @@
1
+ require 'cucumber/step_match'
1
2
  require 'cucumber/core_ext/string'
2
3
  require 'cucumber/core_ext/proc'
3
4
 
@@ -27,12 +28,30 @@ module Cucumber
27
28
  def initialize(pattern, &proc)
28
29
  raise MissingProc if proc.nil?
29
30
  if String === pattern
30
- p = pattern.gsub(/\$\w+/, '(.*)')
31
+ p = pattern.gsub(/\$\w+/, '(.*)') # Replace $var with (.*)
31
32
  pattern = Regexp.new("^#{p}$")
32
33
  end
33
34
  @regexp, @proc = pattern, proc
34
35
  end
35
36
 
37
+ def step_match(name_to_match, name_to_report)
38
+ if(match = name_to_match.match(@regexp))
39
+ StepMatch.new(self, name_to_match, name_to_report, match.captures)
40
+ else
41
+ nil
42
+ end
43
+ end
44
+
45
+ def invoke(world, args, step_name)
46
+ args = args.map{|arg| Ast::PyString === arg ? arg.to_s : arg}
47
+ begin
48
+ world.cucumber_instance_exec(true, @regexp.inspect, *args, &@proc)
49
+ rescue Cucumber::ArityMismatchError => e
50
+ e.backtrace.unshift(self.backtrace_line)
51
+ raise e
52
+ end
53
+ end
54
+
36
55
  #:stopdoc:
37
56
 
38
57
  def match(step_name)
@@ -65,17 +84,7 @@ module Cucumber
65
84
  step_name.match(@regexp).captures
66
85
  end
67
86
 
68
- def execute(step_name, world, *args)
69
- args = args.map{|arg| Ast::PyString === arg ? arg.to_s : arg}
70
- begin
71
- world.cucumber_instance_exec(true, @regexp.inspect, *args, &@proc)
72
- rescue Cucumber::ArityMismatchError => e
73
- e.backtrace.unshift(self.to_backtrace_line)
74
- raise e
75
- end
76
- end
77
-
78
- def to_backtrace_line
87
+ def backtrace_line
79
88
  "#{file_colon_line}:in `#{@regexp.inspect}'"
80
89
  end
81
90
 
@@ -0,0 +1,49 @@
1
+ module Cucumber
2
+ class StepMatch
3
+ attr_reader :step_definition
4
+ attr_reader :args
5
+
6
+ def initialize(step_definition, step_name, formatted_step_name, args)
7
+ @step_definition, @step_name, @formatted_step_name, @args = step_definition, step_name, formatted_step_name, args
8
+ end
9
+
10
+ def invoke(world, multiline_arg)
11
+ all_args = @args.dup
12
+ all_args << multiline_arg if multiline_arg
13
+ @step_definition.invoke(world, all_args, @step_name)
14
+ end
15
+
16
+ def format_args(format)
17
+ @formatted_step_name || @step_definition.format_args(@step_name, format)
18
+ end
19
+
20
+ def file_colon_line
21
+ @step_definition.file_colon_line
22
+ end
23
+
24
+ def backtrace_line
25
+ @step_definition.backtrace_line
26
+ end
27
+ end
28
+
29
+ class NoStepMatch
30
+ attr_reader :step_definition
31
+
32
+ def initialize(step)
33
+ @step = step
34
+ end
35
+
36
+ def format_args(format)
37
+ @step.name
38
+ end
39
+
40
+ def file_colon_line
41
+ raise "No file:line for #{@step}" unless @step.file_colon_line
42
+ @step.file_colon_line
43
+ end
44
+
45
+ def backtrace_line
46
+ @step.backtrace_line
47
+ end
48
+ end
49
+ end