Skip to content

Commit

Permalink
Use LocationQuery to compute line of the tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vincent-psarga committed Nov 18, 2019
1 parent 77ae4dc commit 45359f2
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 29 deletions.
41 changes: 28 additions & 13 deletions lib/cucumber/core/compiler.rb
Expand Up @@ -18,8 +18,8 @@ def initialize(receiver)
@receiver = receiver
end

def pickle(pickle)
test_case = create_test_case(pickle)
def pickle(pickle, location_query)
test_case = create_test_case(pickle, location_query)
test_case.describe_to(receiver)
end

Expand All @@ -30,35 +30,50 @@ def done

private

def create_test_case(pickle)
def create_test_case(pickle, location_query)
uri = pickle.uri
test_steps = pickle.steps.map { |step| create_test_step(step, uri) }
lines = pickle.locations.map { |location| location.line }.sort.reverse
tags = pickle.tags.map { |tag| Test::Tag.new(Test::Location.new(uri, tag.location.line), tag.name) }
test_steps = pickle.steps.map { |step| create_test_step(step, uri, location_query) }

lines = location_query.pickle_locations(pickle).map do |location|
location.line
end.sort.reverse

tags = pickle.tags.map do |tag|
Test::Tag.new(
Test::Location.new(uri, location_query.pickle_tag_location(tag).line),
tag.name
)
end

Test::Case.new(pickle.name, test_steps, Test::Location.new(uri, lines), tags, pickle.language)
end

def create_test_step(pickle_step, uri)
lines = pickle_step.locations.map { |location| location.line }.sort.reverse
multiline_arg = create_multiline_arg(pickle_step, uri)
def create_test_step(pickle_step, uri, location_query)
lines = location_query.pickle_step_locations(pickle_step).map do |location|
location.line
end.sort.reverse

multiline_arg = create_multiline_arg(pickle_step, uri, location_query)
Test::Step.new(pickle_step.text, Test::Location.new(uri, lines), multiline_arg)
end

def create_multiline_arg(pickle_step, uri)
def create_multiline_arg(pickle_step, uri, location_query)
argumentLocation = location_query.pickle_step_argument_location(pickle_step)
line = argumentLocation ? argumentLocation.line : 0

if pickle_step.argument
if pickle_step.argument.doc_string
doc_string = pickle_step.argument.doc_string
Test::DocString.new(
doc_string.content,
doc_string.contentType,
Test::Location.new(uri, doc_string.location.line)
Test::Location.new(uri, line)
)
elsif pickle_step.argument.data_table
data_table = pickle_step.argument.data_table
first_cell = data_table.rows.first.cells.first
Test::DataTable.new(
data_table.rows.map { |row| row.cells.map { |cell| cell.value } },
Test::Location.new(uri, first_cell.location.line)
Test::Location.new(uri, line)
)
end
else
Expand Down
34 changes: 20 additions & 14 deletions lib/cucumber/core/gherkin/location_query.rb
Expand Up @@ -19,23 +19,29 @@ def pickles
end

def pickle_locations(pickle)
scenario = scenario_by_id[pickle.sourceIds[0]]
table_row = table_row_by_id[pickle.sourceIds[1]]
locations = []

locations << scenario.location if scenario
locations << table_row.location if table_row
locations
[
scenario_by_id[pickle.sourceIds[0]],
table_row_by_id[pickle.sourceIds[1]]
].compact.map(&:location)
end

def pickle_step_locations(pickle_step)
scenario_step = scenario_step_by_id[pickle_step.sourceIds[0]]
table_row = table_row_by_id[pickle_step.sourceIds[1]]
locations = []
[
scenario_step_by_id[pickle_step.sourceIds[0]],
table_row_by_id[pickle_step.sourceIds[1]]
].compact.map(&:location)
end

locations << scenario_step.location if scenario_step
locations << table_row.location if table_row
locations
def pickle_step_argument_location(pickle_step)
scenario_step = scenario_step_by_id[pickle_step.sourceIds[0]]
if scenario_step
case scenario_step.argument
when :doc_string
return scenario_step.doc_string.location
when :data_table
return scenario_step.data_table.location
end
end
end

def pickle_tag_location(pickle_tag)
Expand All @@ -54,7 +60,7 @@ def process_gherkin_document(document)
def process_children(children)
children.each do |children|
process_scenario(children.scenario) if children.scenario
process_children(children.rule.children) if children.rule
process_children(children.rule.children) if children.respond_to?(:rule) && children.rule
end
end

Expand Down
5 changes: 4 additions & 1 deletion lib/cucumber/core/gherkin/parser.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
require 'gherkin'
require 'cucumber/core/gherkin/location_query'

module Cucumber
module Core
Expand All @@ -13,15 +14,17 @@ class Parser
def initialize(receiver, event_bus)
@receiver = receiver
@event_bus = event_bus
@location_query = LocationQuery.new
end

def document(document)
messages = ::Gherkin.from_source(document.uri, document.body, gherkin_options(document))
messages.each do |message|
@location_query.process(message)
if !message.gherkinDocument.nil?
event_bus.gherkin_source_parsed(message.gherkinDocument)
elsif !message.pickle.nil?
receiver.pickle(message.pickle)
receiver.pickle(message.pickle, @location_query)
elsif !message.attachment.nil?
# Parse error
raise Core::Gherkin::ParseError.new("#{document.uri}: #{message.attachment.data}")
Expand Down
45 changes: 45 additions & 0 deletions spec/cucumber/core/gherkin/location_query_spec.rb
Expand Up @@ -98,6 +98,51 @@ module Gherkin
end
end

describe 'pickle_step_argument_location' do
let(:pickle_step) { pickle.steps.first }

context 'when there is a docstring argument' do
let(:content) {
<<-FEATURE
Feature: my simple feature
Scenario: A scenario
Given a passed step
"""
This is my DocString
"""
FEATURE
}

it 'returns the location of the doc string' do
expect(subject.pickle_step_argument_location(pickle_step).line).to eq(5)
end
end

context 'when there is a datatable argument' do
let(:content) {
<<-FEATURE
Feature: my simple feature
Scenario: A scenario
Given a passed step
| name | value |
| plic | ploc |
FEATURE
}

it 'returns the location of the datatable' do
expect(subject.pickle_step_argument_location(pickle_step).line).to eq(5)
end
end

context 'when there is no argument' do
it 'returns nil' do
expect(subject.pickle_step_argument_location(pickle_step)).to be_nil
end
end
end

describe 'pickle_tag_location' do
let(:content) {
<<-FEATURE
Expand Down
4 changes: 3 additions & 1 deletion spec/cucumber/core/gherkin/parser_spec.rb
Expand Up @@ -69,7 +69,9 @@ def self.source(&block)
end

it "the pickles have the correct language" do
expect( receiver ).to receive(:pickle).with(pickle_with_language('ja'))
expect( receiver )
.to receive(:pickle)
.with(pickle_with_language('ja'), kind_of(LocationQuery))
parse
end
end
Expand Down

0 comments on commit 45359f2

Please sign in to comment.