cucumber 0.3.101 → 0.3.102

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.
Files changed (62) hide show
  1. data/History.txt +31 -2
  2. data/Manifest.txt +7 -4
  3. data/config/hoe.rb +2 -2
  4. data/examples/pure_java/README.textile +2 -2
  5. data/examples/self_test/features/step_definitions/sample_steps.rb +0 -12
  6. data/examples/self_test/features/support/env.rb +0 -6
  7. data/features/cucumber_cli.feature +11 -24
  8. data/features/custom_formatter.feature +38 -3
  9. data/features/default_snippets.feature +42 -0
  10. data/features/html_formatter/a.html +1 -1
  11. data/features/negative_tagged_hooks.feature +61 -0
  12. data/features/step_definitions/cucumber_steps.rb +1 -1
  13. data/features/support/env.rb +1 -1
  14. data/features/transform.feature +88 -12
  15. data/features/usage.feature +0 -6
  16. data/lib/cucumber/ast/feature.rb +4 -0
  17. data/lib/cucumber/ast/feature_element.rb +49 -42
  18. data/lib/cucumber/ast/step_invocation.rb +1 -1
  19. data/lib/cucumber/ast/tags.rb +25 -3
  20. data/lib/cucumber/cli/drb_client.rb +7 -1
  21. data/lib/cucumber/cli/main.rb +5 -3
  22. data/lib/cucumber/cli/options.rb +15 -24
  23. data/lib/cucumber/constantize.rb +8 -2
  24. data/lib/cucumber/core_ext/instance_exec.rb +2 -1
  25. data/lib/cucumber/core_ext/string.rb +12 -22
  26. data/lib/cucumber/filter.rb +2 -12
  27. data/lib/cucumber/formatter/console.rb +21 -21
  28. data/lib/cucumber/formatter/html.rb +1 -1
  29. data/lib/cucumber/formatter/pdf.rb +1 -1
  30. data/lib/cucumber/formatter/pretty.rb +1 -1
  31. data/lib/cucumber/language_support/language_methods.rb +19 -2
  32. data/lib/cucumber/language_support/step_definition_methods.rb +2 -25
  33. data/lib/cucumber/parser/feature.rb +13 -50
  34. data/lib/cucumber/parser/feature.tt +13 -47
  35. data/lib/cucumber/parser/natural_language.rb +1 -1
  36. data/lib/cucumber/rails/action_controller.rb +33 -0
  37. data/lib/cucumber/rails/active_record.rb +27 -0
  38. data/lib/cucumber/rails/rspec.rb +1 -1
  39. data/lib/cucumber/rails/test_unit.rb +9 -0
  40. data/lib/cucumber/rails/world.rb +7 -78
  41. data/lib/cucumber/rb_support/rb_dsl.rb +6 -4
  42. data/lib/cucumber/rb_support/rb_group.rb +11 -0
  43. data/lib/cucumber/rb_support/rb_language.rb +8 -2
  44. data/lib/cucumber/rb_support/rb_step_definition.rb +23 -8
  45. data/lib/cucumber/rb_support/rb_transform.rb +35 -0
  46. data/lib/cucumber/rb_support/rb_world.rb +7 -1
  47. data/lib/cucumber/step_match.rb +25 -6
  48. data/lib/cucumber/step_mother.rb +9 -32
  49. data/lib/cucumber/version.rb +1 -1
  50. data/rails_generators/cucumber/templates/cucumber_environment.rb +2 -2
  51. data/rails_generators/cucumber/templates/env.rb +1 -8
  52. data/spec/cucumber/ast/feature_element_spec.rb +24 -23
  53. data/spec/cucumber/ast/scenario_outline_spec.rb +1 -1
  54. data/spec/cucumber/cli/options_spec.rb +5 -14
  55. data/spec/cucumber/core_ext/string_spec.rb +11 -13
  56. data/spec/cucumber/parser/feature_parser_spec.rb +6 -6
  57. data/spec/cucumber/step_mother_spec.rb +41 -38
  58. metadata +11 -8
  59. data/examples/self_test/features/transform_sample.feature +0 -10
  60. data/spec/cucumber/rails/stubs/mini_rails.rb +0 -18
  61. data/spec/cucumber/rails/stubs/test_help.rb +0 -1
  62. data/spec/cucumber/rails/world_spec.rb +0 -16
@@ -116,14 +116,8 @@ Feature: Cucumber command line
116
116
  Given passing # features/sample.feature:12
117
117
  /^failing expectation$/ # features/step_definitions/sample_steps.rb:62
118
118
  Given failing expectation # features/failing_expectation.feature:4
119
- /^I should transform ('\d+' to an Integer)$/ # features/step_definitions/sample_steps.rb:83
120
- Then I should transform '10' to an Integer # features/transform_sample.feature:4
121
- /^I should transform ('\w+' to a Symbol)$/ # features/step_definitions/sample_steps.rb:87
122
- Then I should transform 'abc' to a Symbol # features/transform_sample.feature:7
123
119
  /^failing$/ # features/step_definitions/sample_steps.rb:8
124
120
  Given failing # features/sample.feature:18
125
- /^I should not transform ('\d+') to an Integer$/ # features/step_definitions/sample_steps.rb:91
126
- Then I should not transform '10' to an Integer # features/transform_sample.feature:10
127
121
  (::) UNUSED (::)
128
122
  /^unused$/ # features/step_definitions/sample_steps.rb:66
129
123
  /^another unused$/ # features/step_definitions/sample_steps.rb:69
@@ -26,6 +26,10 @@ module Cucumber
26
26
  end
27
27
  end
28
28
 
29
+ def source_tag_names
30
+ @tags.tag_names
31
+ end
32
+
29
33
  def accept_hook?(hook)
30
34
  @tags.accept_hook?(hook)
31
35
  end
@@ -1,61 +1,68 @@
1
1
  require 'enumerator'
2
+ require 'cucumber/ast/tags'
2
3
 
3
4
  module Cucumber
4
- module FeatureElement #:nodoc:
5
- attr_accessor :feature
5
+ module Ast
6
+ module FeatureElement #:nodoc:
7
+ attr_accessor :feature
6
8
 
7
- def attach_steps(steps)
8
- steps.each {|step| step.feature_element = self}
9
- end
9
+ def attach_steps(steps)
10
+ steps.each {|step| step.feature_element = self}
11
+ end
10
12
 
11
- def file_colon_line(line = @line)
12
- @feature.file_colon_line(line) if @feature
13
- end
13
+ def file_colon_line(line = @line)
14
+ @feature.file_colon_line(line) if @feature
15
+ end
14
16
 
15
- def text_length
16
- name_line_lengths.max
17
- end
17
+ def text_length
18
+ name_line_lengths.max
19
+ end
18
20
 
19
- def first_line_length
20
- name_line_lengths[0]
21
- end
21
+ def first_line_length
22
+ name_line_lengths[0]
23
+ end
22
24
 
23
- def name_line_lengths
24
- if @name.strip.empty?
25
- [@keyword.jlength]
26
- else
27
- @name.split("\n").enum_for(:each_with_index).map do |line, line_number|
28
- line_number == 0 ? @keyword.jlength + line.jlength : line.jlength + Ast::Step::INDENT - 1 # We -1 as names which are not keyword lines are missing a space between keyword and name
25
+ def name_line_lengths
26
+ if @name.strip.empty?
27
+ [@keyword.jlength]
28
+ else
29
+ @name.split("\n").enum_for(:each_with_index).map do |line, line_number|
30
+ line_number == 0 ? @keyword.jlength + line.jlength : line.jlength + Ast::Step::INDENT - 1 # We -1 as names which are not keyword lines are missing a space between keyword and name
31
+ end
29
32
  end
30
33
  end
31
- end
32
34
 
33
- def matches_scenario_names?(scenario_name_regexps)
34
- scenario_name_regexps.detect{|name| name =~ @name}
35
- end
35
+ def matches_scenario_names?(scenario_name_regexps)
36
+ scenario_name_regexps.detect{|name| name =~ @name}
37
+ end
36
38
 
37
- def backtrace_line(name = "#{@keyword} #{@name}", line = @line)
38
- @feature.backtrace_line(name, line) if @feature
39
- end
39
+ def backtrace_line(name = "#{@keyword} #{@name}", line = @line)
40
+ @feature.backtrace_line(name, line) if @feature
41
+ end
40
42
 
41
- def source_indent(text_length)
42
- max_line_length - text_length
43
- end
43
+ def source_indent(text_length)
44
+ max_line_length - text_length
45
+ end
44
46
 
45
- def max_line_length
46
- @steps.max_line_length(self)
47
- end
47
+ def max_line_length
48
+ @steps.max_line_length(self)
49
+ end
48
50
 
49
- def accept_hook?(hook)
50
- @tags.accept_hook?(hook) || @feature.accept_hook?(hook)
51
- end
51
+ def accept_hook?(hook)
52
+ Tags.matches?(source_tag_names, hook.tag_names)
53
+ end
52
54
 
53
- def tag_count(tag)
54
- @feature.tag_count(tag) == 0 ? @tags.count(tag) : @feature.tag_count(tag)
55
- end
55
+ def source_tag_names
56
+ (@tags.tag_names + (@feature ? @feature.source_tag_names : [])).uniq
57
+ end
56
58
 
57
- def language
58
- @feature.language
59
+ def tag_count(tag)
60
+ @feature.tag_count(tag) == 0 ? @tags.count(tag) : @feature.tag_count(tag)
61
+ end
62
+
63
+ def language
64
+ @feature.language
65
+ end
59
66
  end
60
- end
67
+ end
61
68
  end
@@ -163,4 +163,4 @@ module Cucumber
163
163
  end
164
164
  end
165
165
  end
166
- end
166
+ end
@@ -7,10 +7,32 @@ module Cucumber
7
7
  # This gets stored internally as <tt>["invoice", "release_2"]</tt>
8
8
  #
9
9
  class Tags #:nodoc:
10
- def self.strip_prefix(tag_name)
11
- tag_name =~ /^@(.*)/ ? $1 : tag_name
10
+ class << self
11
+ EXCLUDE_PATTERN = /^~/
12
+
13
+ def matches?(source_tag_names, tag_names)
14
+ exclude_tag_names, include_tag_names = tag_names.partition{|tag_name| exclude_tag?(tag_name)}
15
+ exclude_tag_names.map!{|name| name[1..-1]}
16
+ !excluded?(source_tag_names, exclude_tag_names) && included?(source_tag_names, include_tag_names)
17
+ end
18
+
19
+ def exclude_tag?(tag_name)
20
+ tag_name =~ EXCLUDE_PATTERN
21
+ end
22
+
23
+ private
24
+
25
+ def excluded?(source_tag_names, query_tag_names)
26
+ source_tag_names.any? && (source_tag_names & query_tag_names).any?
27
+ end
28
+
29
+ def included?(source_tag_names, query_tag_names)
30
+ query_tag_names.empty? || (source_tag_names & query_tag_names).any?
31
+ end
12
32
  end
13
33
 
34
+ attr_reader :tag_names
35
+
14
36
  def initialize(line, tag_names)
15
37
  @line, @tag_names = line, tag_names
16
38
  end
@@ -23,7 +45,7 @@ module Cucumber
23
45
  end
24
46
 
25
47
  def accept_hook?(hook)
26
- hook.tag_names.empty? || (hook.tag_names.map{|tag| Ast::Tags.strip_prefix(tag)} & @tag_names).any?
48
+ self.class.matches?(@tag_names, hook.tag_names)
27
49
  end
28
50
 
29
51
  def count(tag)
@@ -13,7 +13,13 @@ module Cucumber
13
13
  port ||= ENV["CUCUMBER_DRB"] || DEFAULT_PORT
14
14
 
15
15
  # See http://redmine.ruby-lang.org/issues/show/496 as to why we specify localhost:0
16
- DRb.start_service("druby://localhost:0")
16
+ begin
17
+ DRb.start_service("druby://localhost:0")
18
+ rescue SocketError
19
+ # Ruby-1.8.7 on snow leopard doesn't like localhost:0 - but just :0
20
+ # seems to work just fine
21
+ DRb.start_service("druby://:0")
22
+ end
17
23
  feature_server = DRbObject.new_with_uri("druby://127.0.0.1:#{port}")
18
24
  cloned_args = [] # I have no idea why this is needed, but if the regular args are sent then DRb magically transforms it into a DRb object - not an array
19
25
  args.each { |arg| cloned_args << arg }
@@ -8,6 +8,7 @@ require 'cucumber/formatter/color_io'
8
8
  require 'cucumber/cli/language_help_formatter'
9
9
  require 'cucumber/cli/configuration'
10
10
  require 'cucumber/cli/drb_client'
11
+ require 'cucumber/ast/tags'
11
12
 
12
13
  module Cucumber
13
14
  module Cli
@@ -46,6 +47,7 @@ module Cucumber
46
47
  step_mother.after_configuration(configuration)
47
48
  features = step_mother.load_plain_text_features(configuration.feature_files)
48
49
  step_mother.load_code_files(configuration.step_defs_to_load)
50
+
49
51
  enable_diffing
50
52
 
51
53
  visitor = configuration.build_formatter_broadcaster(step_mother)
@@ -67,9 +69,9 @@ module Cucumber
67
69
 
68
70
  def exceeded_tag_limts?(features)
69
71
  exceeded = false
70
- configuration.options[:include_tags].each do |tag, limit|
71
- unless limit.nil?
72
- tag_count = features.tag_count(tag)
72
+ configuration.options[:tag_names].each do |tag_name, limit|
73
+ if !Ast::Tags.exclude_tag?(tag_name) && limit
74
+ tag_count = features.tag_count(tag_name)
73
75
  if tag_count > limit.to_i
74
76
  exceeded = true
75
77
  end
@@ -20,8 +20,8 @@ module Cucumber
20
20
  max = BUILTIN_FORMATS.keys.map{|s| s.length}.max
21
21
  FORMAT_HELP = (BUILTIN_FORMATS.keys.sort.map do |key|
22
22
  " #{key}#{' ' * (max - key.length)} : #{BUILTIN_FORMATS[key][1]}"
23
- end) + ["Use --format rerun --out features.txt to rerun failing",
24
- "failing features in a new run with cucumber @features.txt.",
23
+ end) + ["Use --format rerun --out features.txt to write out failing",
24
+ "features. You can rerun them with cucumber @features.txt.",
25
25
  "FORMAT can also be the fully qualified class name of",
26
26
  "your own custom formatter. If the class isn't loaded,",
27
27
  "Cucumber will attempt to require a file with a relative",
@@ -134,16 +134,14 @@ module Cucumber
134
134
  end
135
135
  opts.on("-t TAGS", "--tags TAGS",
136
136
  "Only execute the features or scenarios with the specified tags.",
137
- "TAGS must be comma-separated without spaces. They can be",
138
- "specified with or without the @ prefix. Example: --tags dev\n",
137
+ "TAGS must be comma-separated without spaces. Example: --tags @dev\n",
139
138
  "Negative tags: Prefix tags with ~ to exclude features or scenarios",
140
- "having that tag.\n",
139
+ "having that tag. Example: --tags ~@slow\n",
141
140
  "Limit WIP: Positive tags can be given a threshold to limit the",
142
- "number of occurrences. Example: --tags qa:3 will fail if there",
141
+ "number of occurrences. Example: --tags @qa:3 will fail if there",
143
142
  "are more than 3 occurrences of the @qa tag.") do |v|
144
- include_tags, exclude_tags = *parse_tags(v)
145
- @options[:include_tags].merge!(include_tags)
146
- @options[:exclude_tags].merge!(exclude_tags)
143
+ tag_names = parse_tags(v)
144
+ @options[:tag_names].merge!(tag_names)
147
145
  end
148
146
  opts.on("-n NAME", "--name NAME",
149
147
  "Only execute the feature elements which match part of the given name.",
@@ -276,22 +274,15 @@ module Cucumber
276
274
 
277
275
  def parse_tags(tag_string)
278
276
  tag_names = tag_string.split(",")
279
- excludes, includes = tag_names.partition{|tag| tag =~ /^~/}
280
- excludes = excludes.map{|tag| tag[1..-1]}
281
-
282
- # Strip @
283
- includes = includes.map{|tag| Ast::Tags.strip_prefix(tag)}
284
- excludes = excludes.map{|tag| Ast::Tags.strip_prefix(tag)}
285
- [parse_tag_limits(includes), parse_tag_limits(excludes)]
277
+ parse_tag_limits(tag_names)
286
278
  end
287
279
 
288
- def parse_tag_limits(includes)
289
- dict = {}
290
- includes.each do |tag|
280
+ def parse_tag_limits(tag_names)
281
+ tag_names.inject({}) do |dict, tag|
291
282
  tag, limit = tag.split(':')
292
283
  dict[tag] = limit.nil? ? limit : limit.to_i
284
+ dict
293
285
  end
294
- dict
295
286
  end
296
287
 
297
288
  def disable_profile_loading?
@@ -328,8 +319,9 @@ module Cucumber
328
319
  def reverse_merge(other_options)
329
320
  @options = other_options.options.merge(@options)
330
321
  @options[:require] += other_options[:require]
331
- @options[:include_tags].merge! other_options[:include_tags]
332
- @options[:exclude_tags].merge! other_options[:exclude_tags]
322
+ @options[:excludes] += other_options[:excludes]
323
+ @options[:name_regexps] += other_options[:name_regexps]
324
+ @options[:tag_names].merge! other_options[:tag_names]
333
325
  @options[:env_vars] = other_options[:env_vars].merge(@options[:env_vars])
334
326
  if @options[:paths].empty?
335
327
  @options[:paths] = other_options[:paths]
@@ -381,8 +373,7 @@ module Cucumber
381
373
  :dry_run => false,
382
374
  :formats => [],
383
375
  :excludes => [],
384
- :include_tags => {},
385
- :exclude_tags => {},
376
+ :tag_names => {},
386
377
  :name_regexps => [],
387
378
  :env_vars => {},
388
379
  :diff_enabled => true
@@ -1,7 +1,9 @@
1
1
  module Cucumber
2
2
  module Constantize #:nodoc:
3
3
  def constantize(camel_cased_word)
4
+ try = 0
4
5
  begin
6
+ try += 1
5
7
  names = camel_cased_word.split('::')
6
8
  names.shift if names.empty? || names.first.empty?
7
9
 
@@ -10,9 +12,13 @@ module Cucumber
10
12
  constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
11
13
  end
12
14
  constant
13
- rescue NameError
15
+ rescue NameError => e
14
16
  require underscore(camel_cased_word)
15
- retry
17
+ if try < 2
18
+ retry
19
+ else
20
+ raise e
21
+ end
16
22
  end
17
23
  end
18
24
 
@@ -8,6 +8,7 @@ module Cucumber
8
8
  end
9
9
 
10
10
  class Object #:nodoc:
11
+ # TODO: Move most of this stuff out to an InstanceExecutor class.
11
12
  def cucumber_instance_exec(check_arity, pseudo_method, *args, &block)
12
13
  cucumber_run_with_backtrace_filtering(pseudo_method) do
13
14
  if check_arity && !cucumber_compatible_arity?(args, block)
@@ -21,7 +22,7 @@ class Object #:nodoc:
21
22
  )
22
23
  end
23
24
  else
24
- instance_exec(*Cucumber::StepMother.transform_arguments(args), &block)
25
+ instance_exec(*args, &block)
25
26
  end
26
27
  end
27
28
  end
@@ -7,34 +7,24 @@ class String #:nodoc:
7
7
  end
8
8
  end
9
9
 
10
- # re.source.gsub(/\([^)]*\)/, '$var')
11
- # Cumulative #sub
12
- def subs(re, *args)
13
- args.inject(self) do |s,arg|
14
- s.sub(re, arg)
15
- end
16
- end
17
-
18
- # TODO: Use subs instead...
19
- def gzub(regexp, format=nil, &proc)
20
- md = match(regexp)
21
- raise "#{self.inspect} doesn't match #{regexp.inspect}" if md.nil?
22
-
10
+ # TODO: Move to StepMatch
11
+ # +groups+ is an array of 2-element arrays, where
12
+ # the 1st element is the value of a regexp match group,
13
+ # and the 2nd element is its start index.
14
+ def gzub(groups, format=nil, &proc)
23
15
  s = dup
24
- pos = 0
25
- md.captures.each_with_index do |m, n|
16
+ offset = 0
17
+ groups.each do |group|
26
18
  replacement = if block_given?
27
- proc.call(m)
19
+ proc.call(group.val)
28
20
  elsif Proc === format
29
- format.call(m)
21
+ format.call(group.val)
30
22
  else
31
- format % m
23
+ format % group.val
32
24
  end
33
25
 
34
- if md.offset(n+1)[0]
35
- s[md.offset(n+1)[0] + pos, m.length] = replacement
36
- pos += replacement.length - m.length
37
- end
26
+ s[group.start + offset, group.val.length] = replacement
27
+ offset += replacement.length - group.val.length
38
28
  end
39
29
  s
40
30
  end
@@ -4,8 +4,7 @@ module Cucumber
4
4
  def initialize(lines, options)
5
5
  @lines = lines
6
6
 
7
- @include_tags = options[:include_tags] ? options[:include_tags].keys : []
8
- @exclude_tags = options[:exclude_tags] ? options[:exclude_tags].keys : []
7
+ @tag_names = options[:tag_names] ? options[:tag_names].keys : []
9
8
  @name_regexps = options[:name_regexps] || []
10
9
  end
11
10
 
@@ -29,18 +28,9 @@ module Cucumber
29
28
  end
30
29
 
31
30
  def matches_tags?(syntax_node)
32
- !excluded_by_tags?(syntax_node) &&
33
- included_by_tags?(syntax_node)
31
+ syntax_node.matches_tags?(@tag_names)
34
32
  end
35
33
 
36
- def included_by_tags?(syntax_node)
37
- @include_tags.empty? || syntax_node.has_all_tags?(@include_tags)
38
- end
39
-
40
- def excluded_by_tags?(syntax_node)
41
- @exclude_tags.any? && syntax_node.has_tags?(@exclude_tags)
42
- end
43
-
44
34
  def outline_matches_names?(syntax_node)
45
35
  @name_regexps.nil? || @name_regexps.empty? || @name_regexps.detect{|name_regexp| syntax_node.outline_matches_name?(name_regexp)}
46
36
  end
@@ -92,6 +92,8 @@ module Cucumber
92
92
  return unless options[:snippets]
93
93
  undefined = step_mother.steps(:undefined)
94
94
  return if undefined.empty?
95
+
96
+ unknown_programming_language = step_mother.unknown_programming_language?
95
97
  snippets = undefined.map do |step|
96
98
  step_name = Undefined === step.exception ? step.exception.step_name : step.name
97
99
  step_multiline_class = step.multiline_arg ? step.multiline_arg.class : nil
@@ -101,8 +103,13 @@ module Cucumber
101
103
 
102
104
  text = "\nYou can implement step definitions for undefined steps with these snippets:\n\n"
103
105
  text += snippets.join("\n\n")
104
-
105
106
  @io.puts format_string(text, :undefined)
107
+
108
+ if unknown_programming_language
109
+ @io.puts format_string("\nIf you want snippets in a different programming language, just make sure a file\n" +
110
+ "with the appropriate file extension exists where cucumber looks for step definitions.", :failed)
111
+ end
112
+
106
113
  @io.puts
107
114
  @io.flush
108
115
  end
@@ -119,23 +126,25 @@ module Cucumber
119
126
  end
120
127
 
121
128
  def print_tag_limit_warnings(options)
122
- return unless tag_limit_breached?(options, @tag_occurences)
123
- @io.puts
124
- @io.puts format_string("Failed due to exceeding the tag limit", :failed)
125
- options[:include_tags].each do |tag_name, limit|
126
- tag_frequnecy = @tag_occurences[tag_name].size
127
- if limit && tag_frequnecy > limit
128
- @io.puts format_string("@#{tag_name} occurred:#{tag_frequnecy} limit:#{limit}", :failed)
129
- @tag_occurences[tag_name].each {|location| @io.puts format_string(" #{location}", :failed)}
130
- @io.flush
129
+ first_tag = true
130
+ options[:tag_names].each do |tag_name, limit|
131
+ unless Ast::Tags.exclude_tag?(tag_name)
132
+ tag_frequnecy = @tag_occurences[tag_name].size
133
+ if limit && tag_frequnecy > limit
134
+ @io.puts if first_tag
135
+ first_tag = false
136
+ @io.puts format_string("#{tag_name} occurred #{tag_frequnecy} times, but the limit was set to #{limit}", :failed)
137
+ @tag_occurences[tag_name].each {|location| @io.puts format_string(" #{location}", :failed)}
138
+ @io.flush
139
+ end
131
140
  end
132
141
  end
133
142
  end
134
143
 
135
144
  def record_tag_occurrences(feature_element, options)
136
145
  @tag_occurences ||= Hash.new{|k,v| k[v] = []}
137
- options[:include_tags].each do |tag_name, limit|
138
- if feature_element.tag_count(tag_name) > 0
146
+ options[:tag_names].each do |tag_name, limit|
147
+ if !Ast::Tags.exclude_tag?(tag_name) && feature_element.tag_count(tag_name) > 0
139
148
  @tag_occurences[tag_name] << feature_element.file_colon_line
140
149
  end
141
150
  end
@@ -171,15 +180,6 @@ module Cucumber
171
180
  raise "No format for #{key.inspect}: #{FORMATS.inspect}" if fmt.nil?
172
181
  fmt
173
182
  end
174
-
175
- def tag_limit_breached?(options, tag_occurences)
176
- return if tag_occurences.nil?
177
- tag_limit_breached = false
178
- options[:include_tags].each do |tag_name, limit|
179
- tag_limit_breached ||= limit && (tag_occurences[tag_name].size > limit)
180
- end
181
- tag_limit_breached
182
- end
183
183
  end
184
184
  end
185
185
  end