bryanl-gherkin 2.11.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitattributes +2 -0
- data/.mailmap +2 -0
- data/.rbenv-gemsets +1 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/.travis.yml +16 -0
- data/.yardopts +5 -0
- data/Gemfile +5 -0
- data/History.md +788 -0
- data/LICENSE +20 -0
- data/README.md +272 -0
- data/Rakefile +26 -0
- data/build_native_gems.sh +7 -0
- data/cucumber.yml +4 -0
- data/examples/parse_and_output_json.rb +19 -0
- data/features/.cucumber/stepdefs.json +244 -0
- data/features/escaped_pipes.feature +8 -0
- data/features/feature_parser.feature +237 -0
- data/features/json_formatter.feature +498 -0
- data/features/json_parser.feature +331 -0
- data/features/native_lexer.feature +19 -0
- data/features/parser_with_native_lexer.feature +205 -0
- data/features/pretty_formatter.feature +16 -0
- data/features/step_definitions/eyeball_steps.rb +3 -0
- data/features/step_definitions/gherkin_steps.rb +29 -0
- data/features/step_definitions/json_formatter_steps.rb +30 -0
- data/features/step_definitions/json_parser_steps.rb +20 -0
- data/features/step_definitions/pretty_formatter_steps.rb +85 -0
- data/features/steps_parser.feature +46 -0
- data/features/support/env.rb +42 -0
- data/gherkin.gemspec +77 -0
- data/install_mingw_os_x.sh +7 -0
- data/js/.npmignore +1 -0
- data/js/lib/gherkin/lexer/.npmignore +0 -0
- data/lib/gherkin.rb +2 -0
- data/lib/gherkin/c_lexer.rb +17 -0
- data/lib/gherkin/formatter/ansi_escapes.rb +97 -0
- data/lib/gherkin/formatter/argument.rb +16 -0
- data/lib/gherkin/formatter/escaping.rb +15 -0
- data/lib/gherkin/formatter/filter_formatter.rb +146 -0
- data/lib/gherkin/formatter/hashable.rb +19 -0
- data/lib/gherkin/formatter/json_formatter.rb +122 -0
- data/lib/gherkin/formatter/line_filter.rb +26 -0
- data/lib/gherkin/formatter/model.rb +281 -0
- data/lib/gherkin/formatter/pretty_formatter.rb +244 -0
- data/lib/gherkin/formatter/regexp_filter.rb +21 -0
- data/lib/gherkin/formatter/step_printer.rb +21 -0
- data/lib/gherkin/formatter/tag_count_formatter.rb +47 -0
- data/lib/gherkin/formatter/tag_filter.rb +19 -0
- data/lib/gherkin/i18n.rb +180 -0
- data/lib/gherkin/i18n.yml +613 -0
- data/lib/gherkin/js_lexer.rb +20 -0
- data/lib/gherkin/json_parser.rb +177 -0
- data/lib/gherkin/lexer/i18n_lexer.rb +46 -0
- data/lib/gherkin/listener/event.rb +45 -0
- data/lib/gherkin/listener/formatter_listener.rb +143 -0
- data/lib/gherkin/native.rb +7 -0
- data/lib/gherkin/native/java.rb +72 -0
- data/lib/gherkin/native/null.rb +5 -0
- data/lib/gherkin/native/therubyracer.rb +39 -0
- data/lib/gherkin/parser/meta.txt +5 -0
- data/lib/gherkin/parser/parser.rb +164 -0
- data/lib/gherkin/parser/root.txt +11 -0
- data/lib/gherkin/parser/steps.txt +4 -0
- data/lib/gherkin/rb_lexer.rb +8 -0
- data/lib/gherkin/rb_lexer/README.rdoc +8 -0
- data/lib/gherkin/rb_lexer/ar.rb +1165 -0
- data/lib/gherkin/rb_lexer/bg.rb +1377 -0
- data/lib/gherkin/rb_lexer/bm.rb +1081 -0
- data/lib/gherkin/rb_lexer/ca.rb +1305 -0
- data/lib/gherkin/rb_lexer/cs.rb +1157 -0
- data/lib/gherkin/rb_lexer/cy_gb.rb +1027 -0
- data/lib/gherkin/rb_lexer/da.rb +1043 -0
- data/lib/gherkin/rb_lexer/de.rb +1151 -0
- data/lib/gherkin/rb_lexer/en.rb +1151 -0
- data/lib/gherkin/rb_lexer/en_au.rb +971 -0
- data/lib/gherkin/rb_lexer/en_lol.rb +929 -0
- data/lib/gherkin/rb_lexer/en_pirate.rb +1205 -0
- data/lib/gherkin/rb_lexer/en_scouse.rb +1357 -0
- data/lib/gherkin/rb_lexer/en_tx.rb +1011 -0
- data/lib/gherkin/rb_lexer/eo.rb +990 -0
- data/lib/gherkin/rb_lexer/es.rb +1135 -0
- data/lib/gherkin/rb_lexer/et.rb +985 -0
- data/lib/gherkin/rb_lexer/fi.rb +964 -0
- data/lib/gherkin/rb_lexer/fr.rb +1223 -0
- data/lib/gherkin/rb_lexer/he.rb +1113 -0
- data/lib/gherkin/rb_lexer/hr.rb +1061 -0
- data/lib/gherkin/rb_lexer/hu.rb +1113 -0
- data/lib/gherkin/rb_lexer/id.rb +958 -0
- data/lib/gherkin/rb_lexer/is.rb +1115 -0
- data/lib/gherkin/rb_lexer/it.rb +1081 -0
- data/lib/gherkin/rb_lexer/ja.rb +1413 -0
- data/lib/gherkin/rb_lexer/ko.rb +1097 -0
- data/lib/gherkin/rb_lexer/lt.rb +1040 -0
- data/lib/gherkin/rb_lexer/lu.rb +1127 -0
- data/lib/gherkin/rb_lexer/lv.rb +1161 -0
- data/lib/gherkin/rb_lexer/nl.rb +1110 -0
- data/lib/gherkin/rb_lexer/no.rb +1055 -0
- data/lib/gherkin/rb_lexer/pl.rb +1452 -0
- data/lib/gherkin/rb_lexer/pt.rb +1425 -0
- data/lib/gherkin/rb_lexer/ro.rb +1159 -0
- data/lib/gherkin/rb_lexer/ru.rb +1749 -0
- data/lib/gherkin/rb_lexer/sk.rb +1041 -0
- data/lib/gherkin/rb_lexer/sr_cyrl.rb +1798 -0
- data/lib/gherkin/rb_lexer/sr_latn.rb +1289 -0
- data/lib/gherkin/rb_lexer/sv.rb +1065 -0
- data/lib/gherkin/rb_lexer/tr.rb +1087 -0
- data/lib/gherkin/rb_lexer/uk.rb +1641 -0
- data/lib/gherkin/rb_lexer/uz.rb +1371 -0
- data/lib/gherkin/rb_lexer/vi.rb +1193 -0
- data/lib/gherkin/rb_lexer/zh_cn.rb +1053 -0
- data/lib/gherkin/rb_lexer/zh_tw.rb +1047 -0
- data/lib/gherkin/rubify.rb +24 -0
- data/lib/gherkin/tag_expression.rb +62 -0
- data/ragel/lexer.c.rl.erb +454 -0
- data/ragel/lexer.java.rl.erb +219 -0
- data/ragel/lexer.js.rl.erb +227 -0
- data/ragel/lexer.rb.rl.erb +174 -0
- data/ragel/lexer_common.rl.erb +50 -0
- data/spec/gherkin/c_lexer_spec.rb +22 -0
- data/spec/gherkin/fixtures/1.feature +8 -0
- data/spec/gherkin/fixtures/comments_in_table.feature +9 -0
- data/spec/gherkin/fixtures/complex.feature +45 -0
- data/spec/gherkin/fixtures/complex.json +139 -0
- data/spec/gherkin/fixtures/complex_for_filtering.feature +60 -0
- data/spec/gherkin/fixtures/complex_with_tags.feature +61 -0
- data/spec/gherkin/fixtures/dos_line_endings.feature +45 -0
- data/spec/gherkin/fixtures/examples_with_only_header.feature +14 -0
- data/spec/gherkin/fixtures/hantu_pisang.feature +35 -0
- data/spec/gherkin/fixtures/i18n_fr.feature +14 -0
- data/spec/gherkin/fixtures/i18n_fr2.feature +8 -0
- data/spec/gherkin/fixtures/i18n_no.feature +7 -0
- data/spec/gherkin/fixtures/i18n_pt1.feature +44 -0
- data/spec/gherkin/fixtures/i18n_pt2.feature +4 -0
- data/spec/gherkin/fixtures/i18n_pt3.feature +4 -0
- data/spec/gherkin/fixtures/i18n_pt4.feature +4 -0
- data/spec/gherkin/fixtures/i18n_zh-CN.feature +9 -0
- data/spec/gherkin/fixtures/issue_145.feature +22 -0
- data/spec/gherkin/fixtures/scenario_outline_with_tags.feature +13 -0
- data/spec/gherkin/fixtures/scenario_without_steps.feature +5 -0
- data/spec/gherkin/fixtures/simple_with_comments.feature +7 -0
- data/spec/gherkin/fixtures/simple_with_tags.feature +11 -0
- data/spec/gherkin/fixtures/with_bom.feature +3 -0
- data/spec/gherkin/formatter/ansi_escapes_spec.rb +32 -0
- data/spec/gherkin/formatter/filter_formatter_spec.rb +204 -0
- data/spec/gherkin/formatter/json_formatter_spec.rb +92 -0
- data/spec/gherkin/formatter/model_spec.rb +28 -0
- data/spec/gherkin/formatter/pretty_formatter_spec.rb +177 -0
- data/spec/gherkin/formatter/spaces.feature +9 -0
- data/spec/gherkin/formatter/step_printer_spec.rb +55 -0
- data/spec/gherkin/formatter/tabs.feature +9 -0
- data/spec/gherkin/formatter/tag_count_formatter_spec.rb +30 -0
- data/spec/gherkin/i18n_spec.rb +241 -0
- data/spec/gherkin/java_lexer_spec.rb +20 -0
- data/spec/gherkin/js_lexer_spec.rb +23 -0
- data/spec/gherkin/json_parser_spec.rb +176 -0
- data/spec/gherkin/lexer/i18n_lexer_spec.rb +43 -0
- data/spec/gherkin/output_stream_string_io.rb +20 -0
- data/spec/gherkin/parser/parser_spec.rb +16 -0
- data/spec/gherkin/rb_lexer_spec.rb +20 -0
- data/spec/gherkin/sexp_recorder.rb +59 -0
- data/spec/gherkin/shared/bom_group.rb +20 -0
- data/spec/gherkin/shared/doc_string_group.rb +163 -0
- data/spec/gherkin/shared/lexer_group.rb +591 -0
- data/spec/gherkin/shared/row_group.rb +125 -0
- data/spec/gherkin/shared/tags_group.rb +54 -0
- data/spec/gherkin/tag_expression_spec.rb +142 -0
- data/spec/spec_helper.rb +75 -0
- data/tasks/bench.rake +184 -0
- data/tasks/bench/feature_builder.rb +49 -0
- data/tasks/bench/null_listener.rb +4 -0
- data/tasks/compile.rake +120 -0
- data/tasks/cucumber.rake +22 -0
- data/tasks/gems.rake +31 -0
- data/tasks/ikvm.rake +124 -0
- data/tasks/ragel_task.rb +100 -0
- data/tasks/release.rake +49 -0
- data/tasks/rspec.rake +8 -0
- data/tasks/yard.rake +7 -0
- data/tasks/yard/default/layout/html/bubble_32x32.png +0 -0
- data/tasks/yard/default/layout/html/bubble_48x48.png +0 -0
- data/tasks/yard/default/layout/html/footer.erb +5 -0
- data/tasks/yard/default/layout/html/index.erb +1 -0
- data/tasks/yard/default/layout/html/layout.erb +25 -0
- data/tasks/yard/default/layout/html/logo.erb +1 -0
- data/tasks/yard/default/layout/html/setup.rb +4 -0
- metadata +473 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'gherkin/native'
|
2
|
+
require 'gherkin/formatter/hashable'
|
3
|
+
|
4
|
+
module Gherkin
|
5
|
+
module Formatter
|
6
|
+
class Argument < Hashable
|
7
|
+
native_impl('gherkin')
|
8
|
+
attr_reader :offset, :val
|
9
|
+
|
10
|
+
# Creates a new Argument that starts at character offset +offset+ with value +val+
|
11
|
+
def initialize(offset, val)
|
12
|
+
@offset, @val = offset, val
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Gherkin
|
2
|
+
module Formatter
|
3
|
+
module Escaping
|
4
|
+
# Escapes a pipes and backslashes:
|
5
|
+
#
|
6
|
+
# * | becomes \|
|
7
|
+
# * \ becomes \\
|
8
|
+
#
|
9
|
+
# This is used in the pretty formatter.
|
10
|
+
def escape_cell(s)
|
11
|
+
s.gsub(/\\(?!\|)/, "\\\\\\\\").gsub(/\n/, "\\n").gsub(/\|/, "\\|")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'gherkin/tag_expression'
|
2
|
+
require 'gherkin/formatter/regexp_filter'
|
3
|
+
require 'gherkin/formatter/line_filter'
|
4
|
+
require 'gherkin/formatter/tag_filter'
|
5
|
+
require 'gherkin/formatter/model'
|
6
|
+
require 'gherkin/native'
|
7
|
+
|
8
|
+
module Gherkin
|
9
|
+
module Formatter
|
10
|
+
class FilterFormatter
|
11
|
+
native_impl('gherkin')
|
12
|
+
|
13
|
+
def initialize(formatter, filters)
|
14
|
+
@formatter = formatter
|
15
|
+
@filter = detect_filter(filters)
|
16
|
+
|
17
|
+
@feature_tags = []
|
18
|
+
@feature_element_tags = []
|
19
|
+
@examples_tags = []
|
20
|
+
|
21
|
+
@feature_events = []
|
22
|
+
@background_events = []
|
23
|
+
@feature_element_events = []
|
24
|
+
@examples_events = []
|
25
|
+
end
|
26
|
+
|
27
|
+
def uri(uri)
|
28
|
+
@formatter.uri(uri)
|
29
|
+
end
|
30
|
+
|
31
|
+
def feature(feature)
|
32
|
+
@feature_tags = feature.tags
|
33
|
+
@feature_name = feature.name
|
34
|
+
@feature_events = [feature]
|
35
|
+
end
|
36
|
+
|
37
|
+
def background(background)
|
38
|
+
@feature_element_name = background.name
|
39
|
+
@feature_element_range = background.line_range
|
40
|
+
@background_events = [background]
|
41
|
+
end
|
42
|
+
|
43
|
+
def scenario(scenario)
|
44
|
+
replay!
|
45
|
+
@feature_element_tags = scenario.tags
|
46
|
+
@feature_element_name = scenario.name
|
47
|
+
@feature_element_range = scenario.line_range
|
48
|
+
@feature_element_events = [scenario]
|
49
|
+
end
|
50
|
+
|
51
|
+
def scenario_outline(scenario_outline)
|
52
|
+
replay!
|
53
|
+
@feature_element_tags = scenario_outline.tags
|
54
|
+
@feature_element_name = scenario_outline.name
|
55
|
+
@feature_element_range = scenario_outline.line_range
|
56
|
+
@feature_element_events = [scenario_outline]
|
57
|
+
end
|
58
|
+
|
59
|
+
def examples(examples)
|
60
|
+
replay!
|
61
|
+
@examples_tags = examples.tags
|
62
|
+
@examples_name = examples.name
|
63
|
+
|
64
|
+
table_body_range = case(examples.rows.length)
|
65
|
+
when 0 then examples.line_range.last..examples.line_range.last
|
66
|
+
when 1 then examples.rows[0].line..examples.rows[0].line
|
67
|
+
else examples.rows[1].line..examples.rows[-1].line
|
68
|
+
end
|
69
|
+
|
70
|
+
@examples_range = examples.line_range.first..table_body_range.last
|
71
|
+
if(@filter.eval([], [], [table_body_range]))
|
72
|
+
examples.rows = @filter.filter_table_body_rows(examples.rows)
|
73
|
+
end
|
74
|
+
@examples_events = [examples]
|
75
|
+
end
|
76
|
+
|
77
|
+
def step(step)
|
78
|
+
if @feature_element_events.any?
|
79
|
+
@feature_element_events << step
|
80
|
+
else
|
81
|
+
@background_events << step
|
82
|
+
end
|
83
|
+
|
84
|
+
@feature_element_range = @feature_element_range.first..step.line_range.last
|
85
|
+
end
|
86
|
+
|
87
|
+
def eof
|
88
|
+
replay!
|
89
|
+
@formatter.eof
|
90
|
+
end
|
91
|
+
|
92
|
+
def done
|
93
|
+
@formatter.done
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def detect_filter(filters)
|
99
|
+
raise "Inconsistent filters: #{filters.inspect}. Only one type [line,name,tag] can be used at once." if filters.map{|filter| filter.class}.uniq.length > 1
|
100
|
+
case(filters[0])
|
101
|
+
when Fixnum
|
102
|
+
LineFilter.new(filters)
|
103
|
+
when Regexp
|
104
|
+
RegexpFilter.new(filters)
|
105
|
+
when String
|
106
|
+
TagFilter.new(filters)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def replay!
|
111
|
+
feature_element_ok = @filter.eval(
|
112
|
+
(@feature_tags + @feature_element_tags),
|
113
|
+
[@feature_name, @feature_element_name].compact,
|
114
|
+
[@feature_element_range].compact
|
115
|
+
)
|
116
|
+
examples_ok = @filter.eval(
|
117
|
+
(@feature_tags + @feature_element_tags + @examples_tags),
|
118
|
+
[@feature_name, @feature_element_name, @examples_name].compact,
|
119
|
+
[@feature_element_range, @examples_range].compact
|
120
|
+
)
|
121
|
+
|
122
|
+
if feature_element_ok || examples_ok
|
123
|
+
replay_events!(@feature_events)
|
124
|
+
replay_events!(@background_events)
|
125
|
+
replay_events!(@feature_element_events)
|
126
|
+
|
127
|
+
if examples_ok
|
128
|
+
replay_events!(@examples_events)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
@examples_events.clear
|
133
|
+
@examples_tags.clear
|
134
|
+
@examples_name = nil
|
135
|
+
@examples_range = nil
|
136
|
+
end
|
137
|
+
|
138
|
+
def replay_events!(events)
|
139
|
+
events.each do |event|
|
140
|
+
event.replay(@formatter)
|
141
|
+
end
|
142
|
+
events.clear
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Gherkin
|
2
|
+
module Formatter
|
3
|
+
class Hashable
|
4
|
+
def to_hash
|
5
|
+
instance_variables.inject({}) do |hash, ivar|
|
6
|
+
value = instance_variable_get(ivar)
|
7
|
+
value = value.to_hash if value.respond_to?(:to_hash)
|
8
|
+
if Array === value
|
9
|
+
value = value.map do |e|
|
10
|
+
e.respond_to?(:to_hash) ? e.to_hash : e
|
11
|
+
end
|
12
|
+
end
|
13
|
+
hash[ivar[1..-1]] = value unless [[], nil].index(value)
|
14
|
+
hash
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'gherkin/formatter/model'
|
3
|
+
require 'gherkin/native'
|
4
|
+
require 'base64'
|
5
|
+
|
6
|
+
module Gherkin
|
7
|
+
module Formatter
|
8
|
+
# This class doesn't really generate JSON - instead it populates an Array that can easily
|
9
|
+
# be turned into JSON.
|
10
|
+
class JSONFormatter
|
11
|
+
native_impl('gherkin')
|
12
|
+
|
13
|
+
include Base64
|
14
|
+
|
15
|
+
def initialize(io)
|
16
|
+
raise "Must be writeable" unless io.respond_to?(:write)
|
17
|
+
@io = io
|
18
|
+
@feature_hashes = []
|
19
|
+
@current_step_or_hook = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def done
|
23
|
+
@io.write(@feature_hashes.to_json)
|
24
|
+
end
|
25
|
+
|
26
|
+
def uri(uri)
|
27
|
+
@uri = uri
|
28
|
+
end
|
29
|
+
|
30
|
+
def feature(feature)
|
31
|
+
@feature_hash = feature.to_hash
|
32
|
+
@feature_hash['uri'] = @uri
|
33
|
+
@feature_hashes << @feature_hash
|
34
|
+
end
|
35
|
+
|
36
|
+
def background(background)
|
37
|
+
feature_elements << background.to_hash
|
38
|
+
end
|
39
|
+
|
40
|
+
def scenario(scenario)
|
41
|
+
feature_elements << scenario.to_hash
|
42
|
+
end
|
43
|
+
|
44
|
+
def scenario_outline(scenario_outline)
|
45
|
+
feature_elements << scenario_outline.to_hash
|
46
|
+
end
|
47
|
+
|
48
|
+
def examples(examples)
|
49
|
+
all_examples << examples.to_hash
|
50
|
+
end
|
51
|
+
|
52
|
+
def step(step)
|
53
|
+
@current_step_or_hook = step.to_hash
|
54
|
+
steps << @current_step_or_hook
|
55
|
+
end
|
56
|
+
|
57
|
+
def match(match)
|
58
|
+
@current_step_or_hook['match'] = match.to_hash
|
59
|
+
end
|
60
|
+
|
61
|
+
def result(result)
|
62
|
+
@current_step_or_hook['result'] = result.to_hash
|
63
|
+
end
|
64
|
+
|
65
|
+
def before(match, result)
|
66
|
+
add_hook(match, result, "before")
|
67
|
+
end
|
68
|
+
|
69
|
+
def after(match, result)
|
70
|
+
add_hook(match, result, "after")
|
71
|
+
end
|
72
|
+
|
73
|
+
def embedding(mime_type, data)
|
74
|
+
embeddings << {'mime_type' => mime_type, 'data' => encode64s(data)}
|
75
|
+
end
|
76
|
+
|
77
|
+
def write(text)
|
78
|
+
output << text
|
79
|
+
end
|
80
|
+
|
81
|
+
def eof
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def add_hook(match, result, hook)
|
87
|
+
hooks = feature_element[hook] ||= []
|
88
|
+
hooks << {'match' => match.to_hash, 'result' => result.to_hash}
|
89
|
+
end
|
90
|
+
|
91
|
+
def feature_elements
|
92
|
+
@feature_hash['elements'] ||= []
|
93
|
+
end
|
94
|
+
|
95
|
+
def feature_element
|
96
|
+
feature_elements[-1]
|
97
|
+
end
|
98
|
+
|
99
|
+
def all_examples
|
100
|
+
feature_element['examples'] ||= []
|
101
|
+
end
|
102
|
+
|
103
|
+
def steps
|
104
|
+
feature_element['steps'] ||= []
|
105
|
+
end
|
106
|
+
|
107
|
+
def embeddings
|
108
|
+
@current_step_or_hook['embeddings'] ||= []
|
109
|
+
end
|
110
|
+
|
111
|
+
def output
|
112
|
+
@current_step_or_hook['output'] ||= []
|
113
|
+
end
|
114
|
+
|
115
|
+
def encode64s(data)
|
116
|
+
# Strip newlines
|
117
|
+
Base64.encode64(data).gsub(/\n/, '')
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Gherkin
|
2
|
+
module Formatter
|
3
|
+
class LineFilter
|
4
|
+
def initialize(lines)
|
5
|
+
@lines = lines
|
6
|
+
end
|
7
|
+
|
8
|
+
def eval(tags, names, ranges)
|
9
|
+
ranges.detect do |range|
|
10
|
+
@lines.detect do |line|
|
11
|
+
range.include?(line)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def filter_table_body_rows(rows)
|
17
|
+
body = rows.to_a[1..-1].select do |row|
|
18
|
+
@lines.detect do |line|
|
19
|
+
row.line == line
|
20
|
+
end
|
21
|
+
end
|
22
|
+
[rows[0]] + body
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,281 @@
|
|
1
|
+
require 'gherkin/native'
|
2
|
+
require 'gherkin/formatter/hashable'
|
3
|
+
|
4
|
+
module Gherkin
|
5
|
+
module Formatter
|
6
|
+
module Model
|
7
|
+
class BasicStatement < Hashable
|
8
|
+
attr_reader :comments, :keyword, :name, :line
|
9
|
+
|
10
|
+
def initialize(comments, keyword, name, line)
|
11
|
+
@comments, @keyword, @name, @line = comments, keyword, name, line
|
12
|
+
end
|
13
|
+
|
14
|
+
def line_range
|
15
|
+
first = @comments.any? ? @comments[0].line : first_non_comment_line
|
16
|
+
first..line
|
17
|
+
end
|
18
|
+
|
19
|
+
def first_non_comment_line
|
20
|
+
@line
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class DescribedStatement < BasicStatement
|
25
|
+
attr_reader :description
|
26
|
+
|
27
|
+
def initialize(comments, keyword, name, description, line)
|
28
|
+
super(comments, keyword, name, line)
|
29
|
+
@description = description
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class TagStatement < DescribedStatement
|
34
|
+
attr_reader :tags, :id
|
35
|
+
|
36
|
+
def initialize(comments, tags, keyword, name, description, line, id)
|
37
|
+
super(comments, keyword, name, description, line)
|
38
|
+
@tags = tags
|
39
|
+
@id = id
|
40
|
+
end
|
41
|
+
|
42
|
+
def first_non_comment_line
|
43
|
+
@tags.any? ? @tags[0].line : @line
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Feature < TagStatement
|
48
|
+
native_impl('gherkin')
|
49
|
+
|
50
|
+
def replay(formatter)
|
51
|
+
formatter.feature(self)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Background < DescribedStatement
|
56
|
+
native_impl('gherkin')
|
57
|
+
|
58
|
+
def initialize(comments, keyword, name, description, line)
|
59
|
+
super(comments, keyword, name, description, line)
|
60
|
+
@type = "background"
|
61
|
+
end
|
62
|
+
|
63
|
+
def replay(formatter)
|
64
|
+
formatter.background(self)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Scenario < TagStatement
|
69
|
+
native_impl('gherkin')
|
70
|
+
|
71
|
+
def initialize(comments, tags, keyword, name, description, line, id)
|
72
|
+
super(comments, tags, keyword, name, description, line, id)
|
73
|
+
@type = "scenario"
|
74
|
+
end
|
75
|
+
|
76
|
+
def replay(formatter)
|
77
|
+
formatter.scenario(self)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class ScenarioOutline < TagStatement
|
82
|
+
native_impl('gherkin')
|
83
|
+
|
84
|
+
def initialize(comments, tags, keyword, name, description, line, id)
|
85
|
+
super(comments, tags, keyword, name, description, line, id)
|
86
|
+
@type = "scenario_outline"
|
87
|
+
end
|
88
|
+
|
89
|
+
def replay(formatter)
|
90
|
+
formatter.scenario_outline(self)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class Examples < TagStatement
|
95
|
+
native_impl('gherkin')
|
96
|
+
|
97
|
+
attr_accessor :rows # needs to remain mutable for filters
|
98
|
+
|
99
|
+
def initialize(comments, tags, keyword, name, description, line, id, rows)
|
100
|
+
super(comments, tags, keyword, name, description, line, id)
|
101
|
+
@rows = rows
|
102
|
+
end
|
103
|
+
|
104
|
+
def replay(formatter)
|
105
|
+
formatter.examples(self)
|
106
|
+
end
|
107
|
+
|
108
|
+
class Builder
|
109
|
+
def initialize(*args)
|
110
|
+
@args = *args
|
111
|
+
@rows = nil
|
112
|
+
end
|
113
|
+
|
114
|
+
def row(comments, cells, line, id)
|
115
|
+
@rows ||= []
|
116
|
+
@rows << ExamplesTableRow.new(comments, cells, line, id)
|
117
|
+
end
|
118
|
+
|
119
|
+
def replay(formatter)
|
120
|
+
build.replay(formatter)
|
121
|
+
end
|
122
|
+
|
123
|
+
def build
|
124
|
+
Examples.new(*(@args << @rows))
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
class Step < BasicStatement
|
130
|
+
native_impl('gherkin')
|
131
|
+
|
132
|
+
attr_reader :rows, :doc_string
|
133
|
+
|
134
|
+
def initialize(comments, keyword, name, line, rows, doc_string)
|
135
|
+
super(comments, keyword, name, line)
|
136
|
+
@rows, @doc_string = rows, doc_string
|
137
|
+
end
|
138
|
+
|
139
|
+
def line_range
|
140
|
+
range = super
|
141
|
+
if(rows)
|
142
|
+
range = range.first..rows[-1].line
|
143
|
+
elsif(doc_string)
|
144
|
+
range = range.first..doc_string.line_range.last
|
145
|
+
end
|
146
|
+
range
|
147
|
+
end
|
148
|
+
|
149
|
+
def replay(formatter)
|
150
|
+
formatter.step(self)
|
151
|
+
end
|
152
|
+
|
153
|
+
def outline_args
|
154
|
+
offset = 0
|
155
|
+
name.scan(/<[^<]*>/).map do |val|
|
156
|
+
offset = name.index(val, offset)
|
157
|
+
Argument.new(offset, val)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
class Builder
|
162
|
+
def initialize(*args)
|
163
|
+
@args = *args
|
164
|
+
@rows = nil
|
165
|
+
@doc_string = nil
|
166
|
+
end
|
167
|
+
|
168
|
+
def row(comments, cells, line, id)
|
169
|
+
@rows ||= []
|
170
|
+
@rows << DataTableRow.new(comments, cells, line)
|
171
|
+
end
|
172
|
+
|
173
|
+
def doc_string(string, content_type, line)
|
174
|
+
@doc_string = Formatter::Model::DocString.new(string, content_type, line)
|
175
|
+
end
|
176
|
+
|
177
|
+
def replay(formatter)
|
178
|
+
build.replay(formatter)
|
179
|
+
end
|
180
|
+
|
181
|
+
def build
|
182
|
+
Step.new(*(@args << @rows << @doc_string))
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
class Comment < Hashable
|
188
|
+
native_impl('gherkin')
|
189
|
+
|
190
|
+
attr_reader :value, :line
|
191
|
+
|
192
|
+
def initialize(value, line)
|
193
|
+
@value, @line = value, line
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
class Tag < Hashable
|
198
|
+
native_impl('gherkin')
|
199
|
+
|
200
|
+
attr_reader :name, :line
|
201
|
+
|
202
|
+
def initialize(name, line)
|
203
|
+
@name, @line = name, line
|
204
|
+
end
|
205
|
+
|
206
|
+
def eql?(tag)
|
207
|
+
@name.eql?(tag.name)
|
208
|
+
end
|
209
|
+
|
210
|
+
def hash
|
211
|
+
@name.hash
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
class DocString < Hashable
|
216
|
+
native_impl('gherkin')
|
217
|
+
|
218
|
+
attr_reader :value, :content_type, :line
|
219
|
+
|
220
|
+
def initialize(value, content_type, line)
|
221
|
+
@value, @content_type, @line = value, content_type, line
|
222
|
+
end
|
223
|
+
|
224
|
+
def line_range
|
225
|
+
line_count = value.split(/\r?\n/).length
|
226
|
+
line..(line+line_count+1)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
class Row < Hashable
|
231
|
+
attr_reader :comments, :cells, :line
|
232
|
+
|
233
|
+
def initialize(comments, cells, line)
|
234
|
+
@comments, @cells, @line = comments, cells, line
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
class DataTableRow < Row
|
239
|
+
native_impl('gherkin')
|
240
|
+
end
|
241
|
+
|
242
|
+
class ExamplesTableRow < Row
|
243
|
+
native_impl('gherkin')
|
244
|
+
attr_reader :id
|
245
|
+
|
246
|
+
def initialize(comments, cells, line, id)
|
247
|
+
super(comments, cells, line)
|
248
|
+
@id = id
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
class Match < Hashable
|
253
|
+
native_impl('gherkin')
|
254
|
+
|
255
|
+
attr_reader :arguments, :location
|
256
|
+
|
257
|
+
def initialize(arguments, location)
|
258
|
+
@arguments, @location = arguments, location
|
259
|
+
end
|
260
|
+
|
261
|
+
def replay(formatter)
|
262
|
+
formatter.match(self)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
class Result < Hashable
|
267
|
+
native_impl('gherkin')
|
268
|
+
|
269
|
+
attr_reader :status, :duration, :error_message
|
270
|
+
|
271
|
+
def initialize(status, duration, error_message)
|
272
|
+
@status, @duration, @error_message = status, duration, error_message
|
273
|
+
end
|
274
|
+
|
275
|
+
def replay(formatter)
|
276
|
+
formatter.result(self)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|