Skip to content

Commit

Permalink
Merge pull request #244 from enkessler/abstract_gherkin
Browse files Browse the repository at this point in the history
Add Gherkin abstraction layer
  • Loading branch information
leoc authored Nov 2, 2022
2 parents 8272ef9 + 9ae2dd5 commit ae3210c
Show file tree
Hide file tree
Showing 14 changed files with 92 additions and 69 deletions.
5 changes: 5 additions & 0 deletions examples/specific_language.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# language: en-au

Pretty much: A feature that specifies a language
Awww, look mate: This is a language specific feature
* a step
14 changes: 4 additions & 10 deletions lib/turnip/builder.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
require "gherkin"
require "cuke_modeler"
require 'turnip/node/feature'

module Turnip
class Builder
def self.build(feature_file)
messages = Gherkin.from_paths(
[feature_file],
include_source: false,
include_gherkin_document: true,
include_pickles: false
)
result = messages.first&.gherkin_document&.to_hash
feature_file = CukeModeler::FeatureFile.new(feature_file)

return nil if result.nil? || result[:feature].nil?
Node::Feature.new(result[:feature])
return nil unless feature_file.feature
Node::Feature.new(feature_file.feature)
end
end
end
12 changes: 6 additions & 6 deletions lib/turnip/node/example.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ class Example < Base
include HasTags

def keyword
@raw[:keyword]
@raw.keyword
end

def name
@raw[:name]
@raw.name
end

def description
@raw[:description]
@raw.description
end

#
Expand All @@ -42,7 +42,7 @@ def description
# @return [Array]
#
def header
@header ||= @raw[:table_header][:cells].map { |c| c[:value] }
@header ||= @raw.parameter_row.cells.map { |c| c.value }
end

#
Expand All @@ -56,8 +56,8 @@ def header
# @return [Array]
#
def rows
@rows ||= @raw[:table_body].map do |row|
row[:cells].map { |c| c[:value] }
@rows ||= @raw.argument_rows.map do |row|
row.cells.map { |c| c.value }
end
end
end
Expand Down
21 changes: 12 additions & 9 deletions lib/turnip/node/feature.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,25 @@ class Feature < ScenarioGroupDefinition
include HasTags

def language
@raw[:language]
@raw.language
end

def children
@children ||= @raw[:children].map do |child|
unless child[:background].nil?
next Background.new(child[:background])
@children ||= @raw.children.map do |child|
if child.is_a?(CukeModeler::Background)
next Background.new(child)
end

unless child[:scenario].nil?
klass = child.dig(:scenario, :examples).nil? ? Scenario : ScenarioOutline
next klass.new(child[:scenario])
if child.is_a?(CukeModeler::Scenario)
next Scenario.new(child)
end

unless child[:rule].nil?
next Rule.new(child[:rule])
if child.is_a?(CukeModeler::Outline)
next ScenarioOutline.new(child)
end

if child.is_a?(CukeModeler::Rule)
next Rule.new(child)
end
end.compact
end
Expand Down
2 changes: 1 addition & 1 deletion lib/turnip/node/location.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module HasLocation
# @return [Location]
#
def location
@location ||= Location.new(@raw[:location][:line], @raw[:location][:column])
@location ||= Location.new(@raw.source_line, @raw.source_column)
end

def line
Expand Down
15 changes: 9 additions & 6 deletions lib/turnip/node/rule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@ module Node
#
class Rule < ScenarioGroupDefinition
def children
@children ||= @raw[:children].map do |child|
unless child[:background].nil?
next Background.new(child[:background])
@children ||= @raw.children.map do |child|
if child.is_a?(CukeModeler::Background)
next Background.new(child)
end

unless child[:scenario].nil?
klass = child.dig(:scenario, :examples).nil? ? Scenario : ScenarioOutline
next klass.new(child[:scenario])
if child.is_a?(CukeModeler::Scenario)
next Scenario.new(child)
end

if child.is_a?(CukeModeler::Outline)
next ScenarioOutline.new(child)
end
end.compact
end
Expand Down
8 changes: 4 additions & 4 deletions lib/turnip/node/scenario_definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ module Turnip
module Node
class ScenarioDefinition < Base
def name
@raw[:name]
@raw.name
end

def keyword
@raw[:keyword]
@raw.keyword
end

def description
@raw[:description]
@raw.description
end

def steps
@steps ||= @raw[:steps].map do |step|
@steps ||= @raw.steps.map do |step|
Step.new(step)
end
end
Expand Down
6 changes: 3 additions & 3 deletions lib/turnip/node/scenario_group_definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ module Turnip
module Node
class ScenarioGroupDefinition < Base
def name
@raw[:name]
@raw.name
end

def keyword
@raw[:keyword]
@raw.keyword
end

def description
@raw[:description]
@raw.description
end

def backgrounds
Expand Down
35 changes: 19 additions & 16 deletions lib/turnip/node/scenario_outline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ScenarioOutline < ScenarioDefinition
include HasTags

def examples
@examples ||= @raw[:examples].map do |raw|
@examples ||= @raw.examples.map do |raw|
Example.new(raw)
end
end
Expand Down Expand Up @@ -57,27 +57,27 @@ def to_scenarios
header = example.header

example.rows.map do |row|
metadata = convert_metadata_to_scenario(header, row)
scenario = convert_metadata_to_scenario(header, row)

#
# Replace <placeholder> using Example values
#
metadata[:steps].each do |step|
step[:text] = substitute(step[:text], header, row)
scenario.steps.each do |step|
step.text = substitute(step.text, header, row)

case
when step[:doc_string]
step[:doc_string][:content] = substitute(step[:doc_string][:content], header, row)
when step[:data_table]
step[:data_table][:rows].map do |table_row|
table_row[:cells].map do |cell|
cell[:value] = substitute(cell[:value], header, row)
when step.block&.is_a?(CukeModeler::DocString)
step.block.content = substitute(step.block.content, header, row)
when step.block&.is_a?(CukeModeler::Table)
step.block.rows.map do |table_row|
table_row.cells.map do |cell|
cell.value = substitute(cell.value, header, row)
end
end
end
end

Scenario.new(metadata)
Scenario.new(scenario)
end
end.flatten.compact
end
Expand Down Expand Up @@ -117,11 +117,14 @@ def to_scenarios
#
def convert_metadata_to_scenario(header, row)
# deep copy
Marshal.load(Marshal.dump(raw)).tap do |new_raw|
new_raw.delete(:examples)
new_raw[:name] = substitute(new_raw[:name], header, row)
new_raw[:type] = :Scenario
new_raw[:keyword] = 'Scenario'
original = Marshal.load(Marshal.dump(raw))

CukeModeler::Scenario.new.tap do |scenario|
scenario.name = substitute(original.name, header, row)
scenario.keyword = 'Scenario' # TODO: Do we need to worry about dialects other than English?
scenario.steps = original.steps
scenario.source_line = original.source_line
scenario.source_column = original.source_column
end
end

Expand Down
21 changes: 11 additions & 10 deletions lib/turnip/node/step.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ module Node
#
class Step < Base
def keyword
@raw[:keyword]
# TODO: Do we want to keep the whitespace?
@raw.keyword + ' '
end

def text
@raw[:text]
@raw.text
end

#
Expand All @@ -32,10 +33,10 @@ def description

def argument
@argument ||= case
when @raw[:doc_string]
doc_string(@raw[:doc_string])
when @raw[:data_table]
data_table(@raw[:data_table])
when @raw.block&.is_a?(CukeModeler::DocString)
doc_string(@raw.block)
when @raw.block&.is_a?(CukeModeler::Table)
data_table(@raw.block)
end
end

Expand All @@ -46,13 +47,13 @@ def to_s
private

def doc_string(doc)
doc[:content]
doc.content
end

def data_table(table)
rows = table[:rows].map do |row|
row[:cells].map do |cell|
cell[:value]
rows = table.rows.map do |row|
row.cells.map do |cell|
cell.value
end
end
Turnip::Table.new(rows)
Expand Down
4 changes: 2 additions & 2 deletions lib/turnip/node/tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module Node
#
class Tag < Base
def name
@name ||= @raw[:name].gsub(/^@/, '')
@name ||= @raw.name.gsub(/^@/, '')
end
end

Expand All @@ -22,7 +22,7 @@ module HasTags
# @return [Array] Array of Tag
#
def tags
@tags ||= @raw.fetch(:tags, []).map do |tag|
@tags ||= @raw.tags.map do |tag|
Tag.new(tag)
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/integration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
end

it "prints out failures and successes" do
@result.should include('45 examples, 4 failures, 5 pending')
@result.should include('46 examples, 4 failures, 6 pending')
end

it "includes features in backtraces" do
Expand Down
14 changes: 14 additions & 0 deletions spec/nodes/feature_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require 'spec_helper'

describe Turnip::Node::Feature do
let(:feature) { Turnip::Builder.build(feature_file) }

context 'a file that specifies a language' do
let(:feature_file) { File.expand_path('../../examples/specific_language.feature', __dir__) }

it 'extracts the language' do
feature.language.should eq 'en-au'
end

end
end
2 changes: 1 addition & 1 deletion turnip.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Gem::Specification.new do |s|
s.require_paths = ["lib"]

s.add_runtime_dependency "rspec", [">=3.0", "<4.0"]
s.add_runtime_dependency "cucumber-gherkin", "~> 14.0"
s.add_runtime_dependency "cuke_modeler", "~> 3.15"
s.add_development_dependency "rake"
s.add_development_dependency "pry"
s.add_development_dependency "pry-byebug"
Expand Down

0 comments on commit ae3210c

Please sign in to comment.