Skip to content

Commit

Permalink
Much better support for line numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
aslakhellesoy committed Jan 23, 2009
1 parent b70c731 commit f259c35
Show file tree
Hide file tree
Showing 14 changed files with 87 additions and 57 deletions.
46 changes: 20 additions & 26 deletions features/cucumber_cli_outlines.feature
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,35 @@ Feature: Cucumber command line
Developers should be able to execute requirements as tests

Scenario: Run scenario outline steps only
When I run cucumber -q features/outline_sample.feature:3
Then it should pass with
"""
Feature: Outline Sample
Scenario Outline: Test state
Given <state> without a table
|state |
1 scenario
"""

Scenario: Run single scenario outline table row with missing step definition
When I run cucumber -q features/outline_sample.feature:7
Then it should pass with
Then it should fail with
"""
Feature: Outline Sample
Scenario Outline: Test state
Given <state> without a table
Given <other_state> without a table
|state |
|missing|
Examples:
| state | other_state |
| missing | passing |
| passing | passing |
| failing | passing |
FAIL (RuntimeError)
./features/step_definitions/sample_steps.rb:2:in `flunker'
./features/step_definitions/sample_steps.rb:16:in `/^failing without a table$/'
features/outline_sample.feature:12:in `Given failing without a table'
2 scenarios
1 step pending (1 with no step definition)
3 scenarios
1 step failed
2 steps skipped
1 step undefined
2 steps passed
"""

Scenario: Run single failing scenario outline table row
When I run cucumber features/outline_sample.feature:5
When I run cucumber features/outline_sample.feature:12
Then it should fail with
"""
Feature: Outline Sample
Expand All @@ -44,19 +42,15 @@ Feature: Cucumber command line
Examples:
| state | other_state |
| missing | passing |
| passing | passing |
| failing | passing |
FAIL (RuntimeError)
./features/step_definitions/sample_steps.rb:2:in `flunker'
./features/step_definitions/sample_steps.rb:16:in `/^failing without a table$/'
features/outline_sample.feature:12:in `Given failing without a table'
3 scenarios
1 scenario
1 step failed
2 steps skipped
1 step undefined
2 steps passed
1 step skipped
"""

Expand Down
6 changes: 5 additions & 1 deletion lib/cucumber/ast/examples.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Cucumber
module Ast
class Examples
def initialize(keyword, name, outline_table)
def initialize(line, keyword, name, outline_table)
@keyword, @name, @outline_table = keyword, name, outline_table
end

Expand All @@ -10,6 +10,10 @@ def accept(visitor)
@outline_table.accept(visitor, nil)
end

def at_lines?(*lines)
lines.empty? || lines.index(@line) || @outline_table.at_lines?(*lines)
end

def to_sexp
[:examples, @keyword, @name, @outline_table.to_sexp]
end
Expand Down
6 changes: 4 additions & 2 deletions lib/cucumber/ast/feature.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ module Ast
# Represents the root node of a parsed feature.
class Feature
attr_accessor :file
attr_writer :lines, :features
attr_writer :features, :lines

def initialize(comment, tags, name, feature_elements)
@comment, @tags, @name, @feature_elements = comment, tags, name, feature_elements
feature_elements.each{|feature_element| feature_element.feature = self}
@lines = []
end

def accept(visitor)
visitor.current_feature_lines = @lines
visitor.visit_comment(@comment)
visitor.visit_tags(@tags)
visitor.visit_feature_name(@name)
@feature_elements.each do |feature_element|
visitor.visit_feature_element(feature_element) if @lines.nil? || feature_element.at_any_line?(@lines)
visitor.visit_feature_element(feature_element) if feature_element.at_lines?(*@lines)
end
end

Expand Down
13 changes: 13 additions & 0 deletions lib/cucumber/ast/outline_table.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ def initialize(raw, scenario_outline)
@cells_class = ExampleCells
end

def accept(visitor, status)
rows.each_with_index do |row, n|
should_visit = n == 0 ||
row.at_lines?(*visitor.current_feature_lines) ||
@scenario_outline.at_header_or_step_lines?(*visitor.current_feature_lines)

if should_visit
visitor.visit_table_row(row, status)
end
end
nil
end

def execute_row(cells, visitor, &proc)
@scenario_outline.execute_row(cells, visitor, &proc)
end
Expand Down
14 changes: 4 additions & 10 deletions lib/cucumber/ast/scenario.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,12 @@ def text_length
@keyword.jlength + @name.jlength
end

def at_any_line?(lines)
lines.each {|line| return true if at_line?(line)}
false
def at_lines?(*lines)
lines.empty? || lines.index(@line) || at_header_or_step_lines?(*lines)
end

def at_line?(line)
if @line == line
true
else
@steps.each {|step| return true if step.at_line?(line)}
false
end
def at_header_or_step_lines?(*lines)
@steps.detect {|step| step.at_lines?(*lines)}
end

def undefined?
Expand Down
13 changes: 9 additions & 4 deletions lib/cucumber/ast/scenario_outline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,20 @@ def initialize(comment, tags, line, keyword, name, steps, example_sections)
steps.each {|step| step.status = :outline}

@examples_array = example_sections.map do |example_section|
examples_keyword = example_section[0]
examples_name = example_section[1]
examples_matrix = example_section[2]
examples_line = example_section[0]
examples_keyword = example_section[1]
examples_name = example_section[2]
examples_matrix = example_section[3]

examples_table = OutlineTable.new(examples_matrix, self)
Examples.new(examples_keyword, examples_name, examples_table)
Examples.new(examples_line, examples_keyword, examples_name, examples_table)
end
end

def at_lines?(*lines)
super || @examples_array.detect { |examples| examples.at_lines?(*lines) }
end

def accept(visitor)
visitor.visit_comment(@comment)
visitor.visit_tags(@tags)
Expand Down
4 changes: 2 additions & 2 deletions lib/cucumber/ast/step.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ def to_sexp
[:step, @line, @gwt, @name, *@multiline_args.map{|arg| arg.to_sexp}]
end

def at_line?(line)
@line == line
def at_lines?(*lines)
lines.empty? || lines.index(@line)
end

def source_indent
Expand Down
20 changes: 14 additions & 6 deletions lib/cucumber/ast/table.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ def initialize(raw)
@cell_class = Cell
end

def at_lines?(*lines)
rows.detect { |row| row.at_lines?(*lines) }
end

def accept(visitor, status)
each do |row|
rows.each do |row|
visitor.visit_table_row(row, status)
end
nil
Expand Down Expand Up @@ -93,16 +97,16 @@ def arguments_replaced(arguments) #:nodoc:
Table.new(raw_with_replaced_args)
end

def at_lines?(*lines)
rows.detect{|row| row.at_lines?(*lines)}
end

private

def col_width(col)
columns[col].__send__(:width)
end

def each(&proc)
rows.each(&proc)
end

def rows
@rows ||= cell_matrix.map do |cell_row|
@cells_class.new(self, cell_row)
Expand Down Expand Up @@ -161,7 +165,11 @@ def [](n)
end

def line
@cells.line
@cells[0].line
end

def at_lines?(*lines)
lines.empty? || lines.index(line)
end

private
Expand Down
8 changes: 8 additions & 0 deletions lib/cucumber/ast/visitor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ def step_definition(step_name)
@step_mother.step_definition(step_name)
end

def current_feature_lines=(lines)
@current_feature_lines = lines
end

def current_feature_lines
@current_feature_lines || []
end

def visit_features(features)
features.accept(self)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/cucumber/parser/feature.rb
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,7 @@ def table

module Examples1
def build
[examples_keyword.text_value, "", table.raw]
[examples_keyword.line, examples_keyword.text_value, "", table.raw]
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/cucumber/parser/feature.tt
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ module Cucumber
rule examples
space* examples_keyword white table {
def build
[examples_keyword.text_value, "", table.raw]
[examples_keyword.line, examples_keyword.text_value, "", table.raw]
end
}
end
Expand Down
1 change: 1 addition & 0 deletions lib/cucumber/parser/file_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def parse_file(file)
lines = lines.split(':').map { |line| line.to_i }
else
path = file
lines = []
end
feature = parse_or_fail(IO.read(path), path)
feature.lines = lines
Expand Down
6 changes: 3 additions & 3 deletions spec/cucumber/ast/feature_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ module Ast

f.lines = [33]

s1.should_receive(:at_any_line?).and_return(false)
s2.should_receive(:at_any_line?).and_return(true)
s3.should_receive(:at_any_line?).and_return(false)
s1.should_receive(:at_lines?).and_return(false)
s2.should_receive(:at_lines?).and_return(true)
s3.should_receive(:at_lines?).and_return(false)

s2.should_receive(:accept)

Expand Down
3 changes: 2 additions & 1 deletion spec/cucumber/ast/scenario_outline_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ module Ast
Step.new(23, 'And', 'I should have <eat> cucumbers in my belly')
],
[
[
[
24,
'Examples:',
'First table',
[
Expand Down

0 comments on commit f259c35

Please sign in to comment.