benhamill-gherkin 2.3.5
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/.gitignore +11 -0
- data/.mailmap +2 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +7 -0
- data/History.txt +363 -0
- data/LICENSE +20 -0
- data/README.rdoc +149 -0
- data/Rakefile +19 -0
- data/VERSION +1 -0
- data/build_native_gems.sh +8 -0
- data/cucumber.yml +3 -0
- data/features/escaped_pipes.feature +8 -0
- data/features/feature_parser.feature +237 -0
- data/features/json_formatter.feature +377 -0
- data/features/json_parser.feature +318 -0
- data/features/native_lexer.feature +19 -0
- data/features/parser_with_native_lexer.feature +205 -0
- data/features/pretty_formatter.feature +15 -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 +28 -0
- data/features/step_definitions/json_parser_steps.rb +20 -0
- data/features/step_definitions/pretty_formatter_steps.rb +84 -0
- data/features/steps_parser.feature +46 -0
- data/features/support/env.rb +38 -0
- data/gherkin.gemspec +61 -0
- data/ikvm/.gitignore +3 -0
- data/java/.gitignore +5 -0
- data/java/src/main/java/gherkin/lexer/i18n/.gitignore +1 -0
- data/java/src/main/resources/gherkin/.gitignore +1 -0
- data/js/lib/gherkin/lexer/i18n/ar.js +1094 -0
- data/js/lib/gherkin/lexer/i18n/bg.js +1308 -0
- data/js/lib/gherkin/lexer/i18n/ca.js +1236 -0
- data/js/lib/gherkin/lexer/i18n/cs.js +1090 -0
- data/js/lib/gherkin/lexer/i18n/cy_gb.js +958 -0
- data/js/lib/gherkin/lexer/i18n/da.js +974 -0
- data/js/lib/gherkin/lexer/i18n/de.js +1082 -0
- data/js/lib/gherkin/lexer/i18n/en.js +965 -0
- data/js/lib/gherkin/lexer/i18n/en_au.js +902 -0
- data/js/lib/gherkin/lexer/i18n/en_lol.js +859 -0
- data/js/lib/gherkin/lexer/i18n/en_pirate.js +1136 -0
- data/js/lib/gherkin/lexer/i18n/en_scouse.js +1289 -0
- data/js/lib/gherkin/lexer/i18n/en_tx.js +942 -0
- data/js/lib/gherkin/lexer/i18n/eo.js +916 -0
- data/js/lib/gherkin/lexer/i18n/es.js +1049 -0
- data/js/lib/gherkin/lexer/i18n/et.js +915 -0
- data/js/lib/gherkin/lexer/i18n/fi.js +894 -0
- data/js/lib/gherkin/lexer/i18n/fr.js +1116 -0
- data/js/lib/gherkin/lexer/i18n/he.js +1044 -0
- data/js/lib/gherkin/lexer/i18n/hr.js +994 -0
- data/js/lib/gherkin/lexer/i18n/hu.js +1043 -0
- data/js/lib/gherkin/lexer/i18n/id.js +884 -0
- data/js/lib/gherkin/lexer/i18n/it.js +1007 -0
- data/js/lib/gherkin/lexer/i18n/ja.js +1344 -0
- data/js/lib/gherkin/lexer/i18n/ko.js +1028 -0
- data/js/lib/gherkin/lexer/i18n/lt.js +972 -0
- data/js/lib/gherkin/lexer/i18n/lu.js +1057 -0
- data/js/lib/gherkin/lexer/i18n/lv.js +1092 -0
- data/js/lib/gherkin/lexer/i18n/nl.js +1036 -0
- data/js/lib/gherkin/lexer/i18n/no.js +986 -0
- data/js/lib/gherkin/lexer/i18n/pl.js +1140 -0
- data/js/lib/gherkin/lexer/i18n/pt.js +1000 -0
- data/js/lib/gherkin/lexer/i18n/ro.js +1089 -0
- data/js/lib/gherkin/lexer/i18n/ru.js +1560 -0
- data/js/lib/gherkin/lexer/i18n/sk.js +972 -0
- data/js/lib/gherkin/lexer/i18n/sr_cyrl.js +1728 -0
- data/js/lib/gherkin/lexer/i18n/sr_latn.js +1220 -0
- data/js/lib/gherkin/lexer/i18n/sv.js +997 -0
- data/js/lib/gherkin/lexer/i18n/tr.js +1014 -0
- data/js/lib/gherkin/lexer/i18n/uk.js +1572 -0
- data/js/lib/gherkin/lexer/i18n/uz.js +1302 -0
- data/js/lib/gherkin/lexer/i18n/vi.js +1124 -0
- data/js/lib/gherkin/lexer/i18n/zh_cn.js +902 -0
- data/js/lib/gherkin/lexer/i18n/zh_tw.js +940 -0
- data/lib/.gitignore +4 -0
- data/lib/gherkin.rb +2 -0
- data/lib/gherkin/c_lexer.rb +17 -0
- data/lib/gherkin/formatter/ansi_escapes.rb +95 -0
- data/lib/gherkin/formatter/argument.rb +16 -0
- data/lib/gherkin/formatter/escaping.rb +15 -0
- data/lib/gherkin/formatter/filter_formatter.rb +136 -0
- data/lib/gherkin/formatter/hashable.rb +19 -0
- data/lib/gherkin/formatter/json_formatter.rb +102 -0
- data/lib/gherkin/formatter/line_filter.rb +26 -0
- data/lib/gherkin/formatter/model.rb +236 -0
- data/lib/gherkin/formatter/pretty_formatter.rb +243 -0
- data/lib/gherkin/formatter/regexp_filter.rb +21 -0
- data/lib/gherkin/formatter/step_printer.rb +17 -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 +175 -0
- data/lib/gherkin/i18n.yml +588 -0
- data/lib/gherkin/json_parser.rb +137 -0
- data/lib/gherkin/lexer/i18n_lexer.rb +47 -0
- data/lib/gherkin/listener/event.rb +45 -0
- data/lib/gherkin/listener/formatter_listener.rb +113 -0
- data/lib/gherkin/native.rb +7 -0
- data/lib/gherkin/native/ikvm.rb +55 -0
- data/lib/gherkin/native/java.rb +55 -0
- data/lib/gherkin/native/null.rb +9 -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/.gitignore +1 -0
- data/lib/gherkin/rb_lexer/README.rdoc +8 -0
- data/lib/gherkin/rubify.rb +24 -0
- data/lib/gherkin/tag_expression.rb +62 -0
- data/lib/gherkin/version.rb +3 -0
- data/ragel/i18n/.gitignore +1 -0
- data/ragel/lexer.c.rl.erb +439 -0
- data/ragel/lexer.java.rl.erb +208 -0
- data/ragel/lexer.rb.rl.erb +167 -0
- data/ragel/lexer_common.rl.erb +50 -0
- data/spec/gherkin/c_lexer_spec.rb +21 -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 +143 -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/hantu_pisang.feature +35 -0
- data/spec/gherkin/fixtures/i18n_fr.feature +14 -0
- data/spec/gherkin/fixtures/i18n_no.feature +7 -0
- data/spec/gherkin/fixtures/i18n_zh-CN.feature +9 -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 +19 -0
- data/spec/gherkin/formatter/filter_formatter_spec.rb +165 -0
- data/spec/gherkin/formatter/model_spec.rb +28 -0
- data/spec/gherkin/formatter/pretty_formatter_spec.rb +158 -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 +152 -0
- data/spec/gherkin/java_lexer_spec.rb +20 -0
- data/spec/gherkin/java_libs.rb +20 -0
- data/spec/gherkin/json_parser_spec.rb +113 -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 +19 -0
- data/spec/gherkin/sexp_recorder.rb +56 -0
- data/spec/gherkin/shared/lexer_group.rb +593 -0
- data/spec/gherkin/shared/py_string_group.rb +153 -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 +137 -0
- data/spec/spec_helper.rb +69 -0
- data/tasks/bench.rake +184 -0
- data/tasks/bench/feature_builder.rb +49 -0
- data/tasks/bench/generated/.gitignore +1 -0
- data/tasks/bench/null_listener.rb +4 -0
- data/tasks/compile.rake +102 -0
- data/tasks/cucumber.rake +20 -0
- data/tasks/gems.rake +35 -0
- data/tasks/ikvm.rake +79 -0
- data/tasks/ragel_task.rb +70 -0
- data/tasks/rdoc.rake +9 -0
- data/tasks/release.rake +30 -0
- data/tasks/rspec.rake +8 -0
- metadata +609 -0
data/lib/.gitignore
ADDED
data/lib/gherkin.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'rbconfig'
|
|
2
|
+
|
|
3
|
+
module Gherkin
|
|
4
|
+
module CLexer
|
|
5
|
+
def self.[](i18n_underscored_iso_code)
|
|
6
|
+
begin
|
|
7
|
+
prefix = Config::CONFIG['arch'] =~ /mswin|mingw/ ? "#{Config::CONFIG['MAJOR']}.#{Config::CONFIG['MINOR']}/" : ''
|
|
8
|
+
lib = "#{prefix}gherkin_lexer_#{i18n_underscored_iso_code}"
|
|
9
|
+
require lib
|
|
10
|
+
const_get(i18n_underscored_iso_code.capitalize)
|
|
11
|
+
rescue LoadError => e
|
|
12
|
+
e.message << %{\nCouldn't load #{lib}\nThe $LOAD_PATH was:\n#{$LOAD_PATH.join("\n")}}
|
|
13
|
+
raise e
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
module Gherkin
|
|
2
|
+
module Formatter
|
|
3
|
+
# Defines aliases for ANSI coloured output. Default colours can be overridden by defining
|
|
4
|
+
# a <tt>GHERKIN_COLORS</tt> variable in your shell, very much like how you can
|
|
5
|
+
# tweak the familiar POSIX command <tt>ls</tt> with
|
|
6
|
+
# <a href="http://mipsisrisc.com/rambling/2008/06/27/lscolorsls_colors-now-with-linux-support/">$LSCOLORS/$LS_COLORS</a>
|
|
7
|
+
#
|
|
8
|
+
# The colours that you can change are:
|
|
9
|
+
#
|
|
10
|
+
# <tt>undefined</tt>:: defaults to <tt>yellow</tt>
|
|
11
|
+
# <tt>pending</tt>:: defaults to <tt>yellow</tt>
|
|
12
|
+
# <tt>pending_arg</tt>:: defaults to <tt>yellow,bold</tt>
|
|
13
|
+
# <tt>executing</tt>:: defaults to <tt>grey</tt>
|
|
14
|
+
# <tt>executing_arg</tt>:: defaults to <tt>grey,bold</tt>
|
|
15
|
+
# <tt>failed</tt>:: defaults to <tt>red</tt>
|
|
16
|
+
# <tt>failed_arg</tt>:: defaults to <tt>red,bold</tt>
|
|
17
|
+
# <tt>passed</tt>:: defaults to <tt>green</tt>
|
|
18
|
+
# <tt>passed_arg</tt>:: defaults to <tt>green,bold</tt>
|
|
19
|
+
# <tt>outline</tt>:: defaults to <tt>cyan</tt>
|
|
20
|
+
# <tt>outline_arg</tt>:: defaults to <tt>cyan,bold</tt>
|
|
21
|
+
# <tt>skipped</tt>:: defaults to <tt>cyan</tt>
|
|
22
|
+
# <tt>skipped_arg</tt>:: defaults to <tt>cyan,bold</tt>
|
|
23
|
+
# <tt>comment</tt>:: defaults to <tt>grey</tt>
|
|
24
|
+
# <tt>tag</tt>:: defaults to <tt>cyan</tt>
|
|
25
|
+
#
|
|
26
|
+
# For instance, if your shell has a black background and a green font (like the
|
|
27
|
+
# "Homebrew" settings for OS X' Terminal.app), you may want to override passed
|
|
28
|
+
# steps to be white instead of green. Examples:
|
|
29
|
+
#
|
|
30
|
+
# export GHERKIN_COLORS="passed=white"
|
|
31
|
+
# export GHERKIN_COLORS="passed=white,bold:passed_arg=white,bold,underline"
|
|
32
|
+
#
|
|
33
|
+
# (If you're on Windows, use SET instead of export).
|
|
34
|
+
# To see what colours and effects are available, just run this in your shell:
|
|
35
|
+
#
|
|
36
|
+
# ruby -e "require 'rubygems'; require 'term/ansicolor'; puts Term::ANSIColor.attributes"
|
|
37
|
+
#
|
|
38
|
+
# Although not listed, you can also use <tt>grey</tt>
|
|
39
|
+
module AnsiEscapes
|
|
40
|
+
COLORS = {
|
|
41
|
+
'black' => "\e[30m",
|
|
42
|
+
'red' => "\e[31m",
|
|
43
|
+
'green' => "\e[32m",
|
|
44
|
+
'yellow' => "\e[33m",
|
|
45
|
+
'blue' => "\e[34m",
|
|
46
|
+
'magenta' => "\e[35m",
|
|
47
|
+
'cyan' => "\e[36m",
|
|
48
|
+
'white' => "\e[37m",
|
|
49
|
+
'grey' => "\e[90m",
|
|
50
|
+
'bold' => "\e[1m"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
ALIASES = Hash.new do |h,k|
|
|
54
|
+
if k.to_s =~ /(.*)_arg/
|
|
55
|
+
h[$1] + ',bold'
|
|
56
|
+
end
|
|
57
|
+
end.merge({
|
|
58
|
+
'undefined' => 'yellow',
|
|
59
|
+
'pending' => 'yellow',
|
|
60
|
+
'executing' => 'grey',
|
|
61
|
+
'failed' => 'red',
|
|
62
|
+
'passed' => 'green',
|
|
63
|
+
'outline' => 'cyan',
|
|
64
|
+
'skipped' => 'cyan',
|
|
65
|
+
'comments' => 'grey',
|
|
66
|
+
'tag' => 'cyan'
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
if ENV['GHERKIN_COLORS'] # Example: export GHERKIN_COLORS="passed=red:failed=yellow"
|
|
70
|
+
ENV['GHERKIN_COLORS'].split(':').each do |pair|
|
|
71
|
+
a = pair.split('=')
|
|
72
|
+
ALIASES[a[0]] = a[1]
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
ALIASES.keys.each do |key|
|
|
77
|
+
define_method(key) do
|
|
78
|
+
ALIASES[key].split(',').map{|color| COLORS[color]}.join('')
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
define_method("#{key}_arg") do
|
|
82
|
+
ALIASES["#{key}_arg"].split(',').map{|color| COLORS[color]}.join('')
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def reset
|
|
87
|
+
"\e[0m"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def up(n)
|
|
91
|
+
"\e[#{n}A"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -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,136 @@
|
|
|
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 = examples.rows[1].line..examples.rows[-1].line
|
|
65
|
+
@examples_range = examples.line_range.first..table_body_range.last
|
|
66
|
+
if(@filter.eval([], [], [table_body_range]))
|
|
67
|
+
examples.rows = @filter.filter_table_body_rows(examples.rows)
|
|
68
|
+
end
|
|
69
|
+
@examples_events = [examples]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def step(step)
|
|
73
|
+
if @feature_element_events.any?
|
|
74
|
+
@feature_element_events << step
|
|
75
|
+
else
|
|
76
|
+
@background_events << step
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
@feature_element_range = @feature_element_range.first..step.line_range.last
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def eof
|
|
83
|
+
replay!
|
|
84
|
+
@formatter.eof
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
def detect_filter(filters)
|
|
90
|
+
raise "Inconsistent filters: #{filters.inspect}" if filters.map{|filter| filter.class}.uniq.length > 1
|
|
91
|
+
case(filters[0])
|
|
92
|
+
when Fixnum
|
|
93
|
+
LineFilter.new(filters)
|
|
94
|
+
when Regexp
|
|
95
|
+
RegexpFilter.new(filters)
|
|
96
|
+
when String
|
|
97
|
+
TagFilter.new(filters)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def replay!
|
|
102
|
+
feature_element_ok = @filter.eval(
|
|
103
|
+
(@feature_tags + @feature_element_tags),
|
|
104
|
+
[@feature_name, @feature_element_name].compact,
|
|
105
|
+
[@feature_element_range].compact
|
|
106
|
+
)
|
|
107
|
+
examples_ok = @filter.eval(
|
|
108
|
+
(@feature_tags + @feature_element_tags + @examples_tags),
|
|
109
|
+
[@feature_name, @feature_element_name, @examples_name].compact,
|
|
110
|
+
[@feature_element_range, @examples_range].compact
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
if feature_element_ok || examples_ok
|
|
114
|
+
replay_events!(@feature_events)
|
|
115
|
+
replay_events!(@background_events)
|
|
116
|
+
replay_events!(@feature_element_events)
|
|
117
|
+
|
|
118
|
+
if examples_ok
|
|
119
|
+
replay_events!(@examples_events)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
@examples_events.clear
|
|
124
|
+
@examples_tags.clear
|
|
125
|
+
@examples_name = nil
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def replay_events!(events)
|
|
129
|
+
events.each do |event|
|
|
130
|
+
event.replay(@formatter)
|
|
131
|
+
end
|
|
132
|
+
events.clear
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
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,102 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'gherkin/formatter/model'
|
|
3
|
+
require 'gherkin/native'
|
|
4
|
+
require 'base64'
|
|
5
|
+
|
|
6
|
+
module Gherkin
|
|
7
|
+
module Formatter
|
|
8
|
+
class JSONFormatter
|
|
9
|
+
native_impl('gherkin')
|
|
10
|
+
|
|
11
|
+
include Base64
|
|
12
|
+
attr_reader :gherkin_object
|
|
13
|
+
|
|
14
|
+
# Creates a new instance that writes the resulting JSON to +io+.
|
|
15
|
+
# If +io+ is nil, the JSON will not be written, but instead a Ruby
|
|
16
|
+
# object can be retrieved with #gherkin_object
|
|
17
|
+
def initialize(io)
|
|
18
|
+
@io = io
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def uri(uri)
|
|
22
|
+
# We're ignoring the uri - we don't want it as part of the JSON
|
|
23
|
+
# (The pretty formatter uses it just for visual niceness - comments)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def feature(feature)
|
|
27
|
+
@gherkin_object = feature.to_hash
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def steps(steps)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def background(background)
|
|
34
|
+
feature_elements << background.to_hash
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def scenario(scenario)
|
|
38
|
+
feature_elements << scenario.to_hash
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def scenario_outline(scenario_outline)
|
|
42
|
+
feature_elements << scenario_outline.to_hash
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def examples(examples)
|
|
46
|
+
all_examples << examples.to_hash
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def step(step)
|
|
50
|
+
current_steps << step.to_hash
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def match(match)
|
|
54
|
+
last_step['match'] = match.to_hash
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def result(result)
|
|
58
|
+
last_step['result'] = result.to_hash
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def embedding(mime_type, data)
|
|
62
|
+
embeddings << {'mime_type' => mime_type, 'data' => encode64s(data)}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def eof
|
|
66
|
+
@io.write(@gherkin_object.to_json) if @io
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
def feature_elements
|
|
72
|
+
@gherkin_object['elements'] ||= []
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def feature_element
|
|
76
|
+
feature_elements[-1]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def all_examples
|
|
80
|
+
feature_element['examples'] ||= []
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def current_steps
|
|
84
|
+
feature_element['steps'] ||= []
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def last_step
|
|
88
|
+
current_steps[-1]
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def embeddings
|
|
92
|
+
last_step['embeddings'] ||= []
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def encode64s(data)
|
|
96
|
+
# Strip newlines
|
|
97
|
+
Base64.encode64(data).gsub(/\n/, '')
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
@@ -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
|