-
-
Notifications
You must be signed in to change notification settings - Fork 696
/
parser_message_stream.rb
96 lines (87 loc) · 3.04 KB
/
parser_message_stream.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
require 'cucumber/messages'
require 'gherkin/parser'
require 'gherkin/token_matcher'
require 'gherkin/pickles/compiler'
module Gherkin
module Stream
class ParserMessageStream
def initialize(paths, sources, options)
@paths = paths
@sources = sources
@options = options
id_generator = options[:id_generator] || Cucumber::Messages::IdGenerator::UUID.new
@parser = Parser.new(AstBuilder.new(id_generator))
@compiler = Pickles::Compiler.new(id_generator)
end
def messages
enumerated = false
Enumerator.new do |y|
raise DoubleIterationException, "Messages have already been enumerated" if enumerated
enumerated = true
sources.each do |source|
y.yield(Cucumber::Messages::Envelope.new(source: source)) if @options[:include_source]
begin
gherkin_document = nil
if @options[:include_gherkin_document]
gherkin_document = build_gherkin_document(source)
y.yield(Cucumber::Messages::Envelope.new(gherkin_document: gherkin_document))
end
if @options[:include_pickles]
gherkin_document ||= build_gherkin_document(source)
pickles = @compiler.compile(gherkin_document, source)
pickles.each do |pickle|
y.yield(Cucumber::Messages::Envelope.new(pickle: pickle))
end
end
rescue CompositeParserException => err
yield_parse_errors(y, err.errors, source.uri)
rescue ParserException => err
yield_parse_errors(y, [err], source.uri)
end
end
end
end
private
def yield_parse_errors(y, errors, uri)
errors.each do |err|
parse_error = Cucumber::Messages::ParseError.new(
source: Cucumber::Messages::SourceReference.new(
uri: uri,
location: Cucumber::Messages::Location.new(
line: err.location[:line],
column: err.location[:column]
)
),
message: err.message
)
y.yield(Cucumber::Messages::Envelope.new(parse_error: parse_error))
end
end
def sources
Enumerator.new do |y|
@paths.each do |path|
source = Cucumber::Messages::Source.new(
uri: path,
data: File.open(path, 'r:UTF-8', &:read),
media_type: 'text/x.cucumber.gherkin+plain'
)
y.yield(source)
end
@sources.each do |source|
y.yield(source)
end
end
end
def build_gherkin_document(source)
if @options[:default_dialect]
token_matcher = TokenMatcher.new(@options[:default_dialect])
gd = @parser.parse(source.data, token_matcher)
else
gd = @parser.parse(source.data)
end
gd[:uri] = source.uri
Cucumber::Messages::GherkinDocument.new(gd)
end
end
end
end