Skip to content

Commit

Permalink
Update to use gherkin version 6.
Browse files Browse the repository at this point in the history
  • Loading branch information
brasmusson committed Sep 28, 2018
1 parent 12d04cd commit 1cd5969
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 71 deletions.
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
source "https://rubygems.org"
gemspec

gem 'gherkin', path: ENV['GHERKIN_RUBY'] if ENV['GHERKIN_RUBY']

gem 'cucumber-messages', path: ENV['CUCUMBER_MESSAGES_RUBY'] if ENV['CUCUMBER_MESSAGES_RUBY']
2 changes: 1 addition & 1 deletion cucumber-core.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Gem::Specification.new do |s|
s.license = "MIT"
s.required_ruby_version = '>= 2.2' # Keep in sync with .travis.yml

s.add_dependency 'gherkin', '~> 5.1'
s.add_dependency 'gherkin', '~> 6.0'
s.add_dependency 'cucumber-tag_expressions', '~> 1.1.0'
s.add_dependency 'backports', '>= 3.8.0'

Expand Down
50 changes: 24 additions & 26 deletions lib/cucumber/core/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ def initialize(receiver)
@receiver = receiver
end

def pickles(pickles, uri)
pickles.each do |pickle|
test_case = create_test_case(pickle, uri)
test_case.describe_to(receiver)
end
def pickle(pickle)
test_case = create_test_case(pickle)
test_case.describe_to(receiver)
end

def done
Expand All @@ -32,37 +30,37 @@ def done

private

def create_test_case(pickle, uri)
def create_test_case(pickle)
uri = pickle[:uri]
test_steps = pickle[:steps].map { |step| create_test_step(step, uri) }
lines = pickle[:locations].map { |location| location[:line] }
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::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] }
multiline_arg = create_multiline_arg(pickle_step[:arguments], uri)
lines = pickle_step[:locations].map { |location| location[:line] }.sort.reverse
multiline_arg = create_multiline_arg(pickle_step, uri)
Test::Step.new(pickle_step[:text], Test::Location.new(uri, lines), multiline_arg)
end

def create_multiline_arg(pickle_step_arguments, uri)
if pickle_step_arguments.empty?
Test::EmptyMultilineArgument.new
def create_multiline_arg(pickle_step, uri)
if !pickle_step[:doc_string].nil?
argument = pickle_step[:doc_string]
Test::DocString.new(
argument[:content],
argument[:content_type],
Test::Location.new(uri, argument[:location][:line])
)
elsif !pickle_step[:data_table].nil?
argument = pickle_step[:data_table]
first_cell = argument[:rows].first[:cells].first
Test::DataTable.new(
argument[:rows].map { |row| row[:cells].map { |cell| cell[:value] } },
Test::Location.new(uri, first_cell[:location][:line])
)
else
argument = pickle_step_arguments.first
if argument[:content]
Test::DocString.new(
argument[:content],
argument[:content_type],
Test::Location.new(uri, argument[:location][:line])
)
else
first_cell = argument[:rows].first[:cells].first
Test::DataTable.new(
argument[:rows].map { |row| row[:cells].map { |cell| cell[:value] } },
Test::Location.new(uri, first_cell[:location][:line])
)
end
Test::EmptyMultilineArgument.new
end
end
end
Expand Down
5 changes: 1 addition & 4 deletions lib/cucumber/core/events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ module Core
module Events

# Signals that a gherkin source has been parsed
class GherkinSourceParsed < Event.new(:uri, :gherkin_document)
# The uri of the file
attr_reader :uri

class GherkinSourceParsed < Event.new(:gherkin_document)
# @return [GherkinDocument] the GherkinDocument Ast Node
attr_reader :gherkin_document

Expand Down
36 changes: 14 additions & 22 deletions lib/cucumber/core/gherkin/parser.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
# frozen_string_literal: true
require 'gherkin/parser'
require 'gherkin/token_scanner'
require 'gherkin/errors'
require 'gherkin/pickles/compiler'
require 'gherkin/gherkin'

module Cucumber
module Core
Expand All @@ -19,31 +16,26 @@ def initialize(receiver, event_bus)
end

def document(document)
parser = ::Gherkin::Parser.new
scanner = ::Gherkin::TokenScanner.new(document.body)
token_matcher = ::Gherkin::TokenMatcher.new(document.language)
compiler = ::Gherkin::Pickles::Compiler.new

begin
result = parser.parse(scanner, token_matcher)
event_bus.gherkin_source_parsed(document.uri, result.dup)
pickles = compiler.compile(result)

receiver.pickles(pickles, document.uri)
rescue *PARSER_ERRORS => e
raise Core::Gherkin::ParseError.new("#{document.uri}: #{e.message}")
messages = ::Gherkin::Gherkin.from_source(document.uri, document.body, {default_dialect: document.language, include_source: false})
messages.each do |message|
if !message.gherkinDocument.nil?
event_bus.gherkin_source_parsed(message.gherkinDocument.to_hash)
elsif !message.pickle.nil?
receiver.pickle(message.pickle.to_hash)
elsif !message.attachment.nil?
raise message.attachment.data
else
raise "Unknown message: #{message.to_hash}"
end
end
rescue RuntimeError => e
raise Core::Gherkin::ParseError.new("#{document.uri}: #{e.message}")
end

def done
receiver.done
self
end

private

PARSER_ERRORS = ::Gherkin::ParserError

end
end
end
Expand Down
28 changes: 10 additions & 18 deletions spec/cucumber/core/gherkin/parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,17 @@ def parse
let(:path) { 'path_to/the.feature' }

it "issues a gherkin_source_parsed event" do
allow( receiver ).to receive(:pickles)
expect( event_bus ).to receive(:gherkin_source_parsed)
parse
end

it "passes on the uri" do
expect( receiver ).to receive(:pickles).with(anything, path)
parse
end
end

context "for empty files" do
let(:source) { Gherkin::Document.new(path, '') }
let(:path) { 'path_to/the.feature' }

it "passes on an empty list of pickles" do
expect( receiver ).to receive(:pickles).with([], anything)
it "passes on no pickles" do
expect( receiver ).not_to receive(:pickle)
parse
end
end
Expand All @@ -63,25 +57,23 @@ def self.source(&block)
let(:source) { gherkin(&block) }
end

RSpec::Matchers.define :pickles_with_language do |language|
match { |actual| actual.each { |pickle| pickle[:language] == language } }
RSpec::Matchers.define :pickle_with_language do |language|
match { |actual| actual[:language] == language }
end

context "when the Gherkin has a language header" do
source do
feature(language: 'ja', keyword: '機能')
feature(language: 'ja', keyword: '機能') do
scenario(keyword: 'シナリオ')
end
end

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

RSpec::Matchers.define :a_list_of_one_pickle do
match { |actual| actual.length == 1 }
end

context "when the Gherkin produces one pickle" do
source do
feature do
Expand All @@ -91,8 +83,8 @@ def self.source(&block)
end
end

it "passes on a list with the pickle" do
expect( receiver ).to receive(:pickles).with(a_list_of_one_pickle, anything)
it "passes on the pickle" do
expect( receiver ).to receive(:pickle)
parse
end
end
Expand Down

0 comments on commit 1cd5969

Please sign in to comment.