gherkin 2.1.5-universal-dotnet → 2.2.0-universal-dotnet
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/History.txt +16 -0
- data/README.rdoc +1 -0
- data/Rakefile +1 -1
- data/VERSION.yml +2 -2
- data/features/json_formatter.feature +3 -11
- data/features/json_parser.feature +2 -5
- data/features/step_definitions/json_lexer_steps.rb +1 -1
- data/features/step_definitions/pretty_formatter_steps.rb +1 -1
- data/features/support/env.rb +2 -1
- data/java/src/main/java/gherkin/lexer/{.gitignore → i18n/.gitignore} +0 -0
- data/json-simple-1.1.dll +0 -0
- data/lib/gherkin.rb +1 -1
- data/lib/gherkin/formatter/filter_formatter.rb +52 -61
- data/lib/gherkin/formatter/json_formatter.rb +26 -94
- data/lib/gherkin/formatter/line_filter.rb +3 -3
- data/lib/gherkin/formatter/model.rb +156 -19
- data/lib/gherkin/formatter/pretty_formatter.rb +25 -25
- data/lib/gherkin/formatter/regexp_filter.rb +5 -1
- data/lib/gherkin/formatter/tag_count_formatter.rb +15 -12
- data/lib/gherkin/formatter/tag_filter.rb +19 -0
- data/lib/gherkin/json_parser.rb +49 -65
- data/lib/gherkin/lexer/i18n_lexer.rb +40 -0
- data/lib/gherkin/listener/formatter_listener.rb +11 -18
- data/lib/gherkin/parser/parser.rb +4 -5
- data/lib/gherkin/tools/stats_listener.rb +1 -1
- data/ragel/lexer.c.rl.erb +3 -1
- data/ragel/lexer.java.rl.erb +4 -4
- data/ragel/lexer.rb.rl.erb +3 -1
- data/spec/gherkin/fixtures/complex.json +2 -3
- data/spec/gherkin/formatter/model_spec.rb +1 -1
- data/spec/gherkin/formatter/pretty_formatter_spec.rb +11 -8
- data/spec/gherkin/i18n_spec.rb +3 -3
- data/spec/gherkin/java_lexer_spec.rb +1 -1
- data/spec/gherkin/json.rb +5 -0
- data/spec/gherkin/json_parser_spec.rb +49 -73
- data/spec/gherkin/lexer/i18n_lexer_spec.rb +33 -0
- data/spec/gherkin/sexp_recorder.rb +0 -2
- data/spec/spec_helper.rb +1 -0
- data/tasks/bench.rake +2 -2
- data/tasks/compile.rake +1 -1
- data/tasks/ikvm.rake +3 -1
- data/tasks/ragel_task.rb +1 -1
- data/tasks/release.rake +13 -1
- data/tasks/rspec.rake +0 -1
- metadata +17 -13
- data/lib/gherkin/i18n_lexer.rb +0 -38
- data/spec/gherkin/i18n_lexer_spec.rb +0 -26
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'gherkin/i18n'
|
2
|
+
require 'gherkin/native'
|
3
|
+
|
4
|
+
module Gherkin
|
5
|
+
module Lexer
|
6
|
+
I18nLexerNotFound = Class.new(LoadError)
|
7
|
+
LexingError = Class.new(StandardError)
|
8
|
+
|
9
|
+
# The main entry point to lexing Gherkin source.
|
10
|
+
class I18nLexer
|
11
|
+
native_impl('gherkin')
|
12
|
+
|
13
|
+
LANGUAGE_PATTERN = /^\s*#\s*language\s*:\s*([a-zA-Z\-]+)/ #:nodoc:
|
14
|
+
attr_reader :i18n_language
|
15
|
+
|
16
|
+
def initialize(listener, force_ruby=false)
|
17
|
+
@listener = listener
|
18
|
+
@force_ruby = force_ruby
|
19
|
+
end
|
20
|
+
|
21
|
+
def scan(source)
|
22
|
+
create_delegate(source).scan(source)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def create_delegate(source)
|
28
|
+
@i18n_language = lang(source)
|
29
|
+
@i18n_language.lexer(@listener, @force_ruby)
|
30
|
+
end
|
31
|
+
|
32
|
+
def lang(source)
|
33
|
+
line_one = source.split(/\n/)[0]
|
34
|
+
match = LANGUAGE_PATTERN.match(line_one)
|
35
|
+
I18n.get(match ? match[1] : 'en')
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -16,10 +16,6 @@ module Gherkin
|
|
16
16
|
@table = nil
|
17
17
|
end
|
18
18
|
|
19
|
-
def location(feature_uri)
|
20
|
-
@feature_uri = feature_uri
|
21
|
-
end
|
22
|
-
|
23
19
|
def comment(value, line)
|
24
20
|
@comments << Formatter::Model::Comment.new(value, line)
|
25
21
|
end
|
@@ -29,31 +25,31 @@ module Gherkin
|
|
29
25
|
end
|
30
26
|
|
31
27
|
def feature(keyword, name, description, line)
|
32
|
-
@formatter.feature(
|
28
|
+
@formatter.feature(Formatter::Model::Feature.new(grab_comments!, grab_tags!, keyword, name, description, line))
|
33
29
|
end
|
34
30
|
|
35
31
|
def background(keyword, name, description, line)
|
36
|
-
@formatter.background(
|
32
|
+
@formatter.background(Formatter::Model::Background.new(grab_comments!, keyword, name, description, line))
|
37
33
|
end
|
38
34
|
|
39
35
|
def scenario(keyword, name, description, line)
|
40
36
|
replay_step_or_examples
|
41
|
-
@formatter.scenario(
|
37
|
+
@formatter.scenario(Formatter::Model::Scenario.new(grab_comments!, grab_tags!, keyword, name, description, line))
|
42
38
|
end
|
43
39
|
|
44
40
|
def scenario_outline(keyword, name, description, line)
|
45
41
|
replay_step_or_examples
|
46
|
-
@formatter.scenario_outline(
|
42
|
+
@formatter.scenario_outline(Formatter::Model::ScenarioOutline.new(grab_comments!, grab_tags!, keyword, name, description, line))
|
47
43
|
end
|
48
44
|
|
49
45
|
def examples(keyword, name, description, line)
|
50
46
|
replay_step_or_examples
|
51
|
-
@examples_statement =
|
47
|
+
@examples_statement = Formatter::Model::Examples.new(grab_comments!, grab_tags!, keyword, name, description, line)
|
52
48
|
end
|
53
49
|
|
54
50
|
def step(keyword, name, line)
|
55
51
|
replay_step_or_examples
|
56
|
-
@step_statement =
|
52
|
+
@step_statement = Formatter::Model::Step.new(grab_comments!, keyword, name, nil, line)
|
57
53
|
end
|
58
54
|
|
59
55
|
def row(cells, line)
|
@@ -76,10 +72,6 @@ module Gherkin
|
|
76
72
|
|
77
73
|
private
|
78
74
|
|
79
|
-
def statement(comments, tags, keyword, name, description, line)
|
80
|
-
Formatter::Model::Statement.new(comments, tags, keyword, name, description, line)
|
81
|
-
end
|
82
|
-
|
83
75
|
def grab_comments!
|
84
76
|
comments = @comments
|
85
77
|
@comments = []
|
@@ -92,7 +84,7 @@ module Gherkin
|
|
92
84
|
tags
|
93
85
|
end
|
94
86
|
|
95
|
-
def
|
87
|
+
def grab_rows!
|
96
88
|
table = @table
|
97
89
|
@table = nil
|
98
90
|
table
|
@@ -106,12 +98,13 @@ module Gherkin
|
|
106
98
|
|
107
99
|
def replay_step_or_examples
|
108
100
|
if(@step_statement)
|
109
|
-
multiline_arg = grab_py_string! ||
|
110
|
-
@formatter.step(@step_statement
|
101
|
+
@step_statement.multiline_arg = grab_py_string! || grab_rows!
|
102
|
+
@formatter.step(@step_statement)
|
111
103
|
@step_statement = nil
|
112
104
|
end
|
113
105
|
if(@examples_statement)
|
114
|
-
@
|
106
|
+
@examples_statement.rows = grab_rows!
|
107
|
+
@formatter.examples(@examples_statement)
|
115
108
|
@examples_statement = nil
|
116
109
|
end
|
117
110
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'gherkin/i18n'
|
2
|
-
require 'gherkin/i18n_lexer'
|
2
|
+
require 'gherkin/lexer/i18n_lexer'
|
3
3
|
require 'gherkin/native'
|
4
4
|
require 'gherkin/listener/formatter_listener'
|
5
5
|
|
@@ -22,13 +22,12 @@ module Gherkin
|
|
22
22
|
@machine_name = machine_name
|
23
23
|
@machines = []
|
24
24
|
push_machine(@machine_name)
|
25
|
-
@lexer = I18nLexer.new(self, force_ruby)
|
25
|
+
@lexer = Gherkin::Lexer::I18nLexer.new(self, force_ruby)
|
26
26
|
end
|
27
27
|
|
28
28
|
def parse(gherkin, feature_uri, line_offset)
|
29
|
-
@feature_uri
|
29
|
+
@formatter.uri(feature_uri)
|
30
30
|
@line_offset = line_offset
|
31
|
-
@listener.location(feature_uri)
|
32
31
|
@lexer.scan(gherkin)
|
33
32
|
end
|
34
33
|
|
@@ -148,7 +147,7 @@ module Gherkin
|
|
148
147
|
@rows = []
|
149
148
|
end
|
150
149
|
|
151
|
-
def
|
150
|
+
def uri(uri)
|
152
151
|
end
|
153
152
|
|
154
153
|
def row(row, line_number)
|
data/ragel/lexer.c.rl.erb
CHANGED
@@ -57,6 +57,7 @@ typedef struct lexer_state {
|
|
57
57
|
} lexer_state;
|
58
58
|
|
59
59
|
static VALUE mGherkin;
|
60
|
+
static VALUE mGherkinLexer;
|
60
61
|
static VALUE mCLexer;
|
61
62
|
static VALUE cI18nLexer;
|
62
63
|
static VALUE rb_eGherkinLexingError;
|
@@ -442,7 +443,8 @@ static VALUE CLexer_scan(VALUE self, VALUE input)
|
|
442
443
|
void Init_gherkin_lexer_<%= @i18n.underscored_iso_code %>()
|
443
444
|
{
|
444
445
|
mGherkin = rb_define_module("Gherkin");
|
445
|
-
|
446
|
+
mGherkinLexer = rb_define_module_under(mGherkin, "Lexer");
|
447
|
+
rb_eGherkinLexingError = rb_const_get(mGherkinLexer, rb_intern("LexingError"));
|
446
448
|
|
447
449
|
mCLexer = rb_define_module_under(mGherkin, "CLexer");
|
448
450
|
cI18nLexer = rb_define_class_under(mCLexer, "<%= @i18n.underscored_iso_code.capitalize %>", rb_cObject);
|
data/ragel/lexer.java.rl.erb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
package gherkin.lexer;
|
1
|
+
package gherkin.lexer.i18n;
|
2
2
|
|
3
3
|
import java.io.UnsupportedEncodingException;
|
4
4
|
import java.util.List;
|
5
5
|
import java.util.ArrayList;
|
6
6
|
import java.util.regex.Pattern;
|
7
7
|
import java.util.regex.Matcher;
|
8
|
-
import gherkin.Lexer;
|
9
|
-
import gherkin.Listener;
|
10
|
-
import gherkin.LexingError;
|
8
|
+
import gherkin.lexer.Lexer;
|
9
|
+
import gherkin.lexer.Listener;
|
10
|
+
import gherkin.lexer.LexingError;
|
11
11
|
|
12
12
|
public class <%= @i18n.underscored_iso_code.upcase %> implements Lexer {
|
13
13
|
%%{
|
data/ragel/lexer.rb.rl.erb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'gherkin/lexer/i18n_lexer'
|
2
|
+
|
1
3
|
module Gherkin
|
2
4
|
module RbLexer
|
3
5
|
class <%= @i18n.underscored_iso_code.capitalize %> #:nodoc:
|
@@ -113,7 +115,7 @@ module Gherkin
|
|
113
115
|
action end_feature {
|
114
116
|
if cs < lexer_first_final
|
115
117
|
content = current_line_content(data, p)
|
116
|
-
raise LexingError.new("Lexing error on line %d: '%s'. See http://wiki.github.com/aslakhellesoy/gherkin/lexingerror for more information." % [@line_number, content])
|
118
|
+
raise Gherkin::Lexer::LexingError.new("Lexing error on line %d: '%s'. See http://wiki.github.com/aslakhellesoy/gherkin/lexingerror for more information." % [@line_number, content])
|
117
119
|
else
|
118
120
|
@listener.eof
|
119
121
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
{
|
2
|
-
"type": "feature",
|
3
2
|
"name": "Feature Text",
|
4
3
|
"keyword": "Feature",
|
5
4
|
"description": "In order to test multiline forms",
|
@@ -41,11 +40,11 @@
|
|
41
40
|
}
|
42
41
|
],
|
43
42
|
"examples": [
|
44
|
-
{
|
43
|
+
{
|
45
44
|
"name": "Sweet Example",
|
46
45
|
"keyword": "Examples",
|
47
46
|
"description": "",
|
48
|
-
"
|
47
|
+
"rows" : [
|
49
48
|
{"cells" :
|
50
49
|
[ "Fill","In" ]
|
51
50
|
},
|
@@ -35,14 +35,15 @@ module Gherkin
|
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should print comments when scenario is longer" do
|
38
|
-
@l.
|
38
|
+
@l.uri("features/foo.feature")
|
39
|
+
@l.feature(Model::Feature.new([], [], "Feature", "Hello", "World", 1))
|
39
40
|
@l.steps([
|
40
41
|
['Given ', 'some stuff'],
|
41
42
|
['When ', 'foo']
|
42
43
|
])
|
43
|
-
@l.scenario(Model::
|
44
|
-
@l.step(Model::
|
45
|
-
@l.step(Model::
|
44
|
+
@l.scenario(Model::Scenario.new([], [], "Scenario", "The scenario", "", 4))
|
45
|
+
@l.step(Model::Step.new([], "Given ", "some stuff", "", 5, nil, result('passed', nil, nil, "features/step_definitions/bar.rb:56")))
|
46
|
+
@l.step(Model::Step.new([], "When ", "foo", "", 6, nil, result('passed', nil, nil, "features/step_definitions/bar.rb:96")))
|
46
47
|
|
47
48
|
assert_io(%{Feature: Hello
|
48
49
|
World
|
@@ -54,12 +55,13 @@ module Gherkin
|
|
54
55
|
end
|
55
56
|
|
56
57
|
it "should print comments when step is longer" do
|
57
|
-
@l.
|
58
|
+
@l.uri("features/foo.feature")
|
59
|
+
@l.feature(Model::Feature.new([], [], "Feature", "Hello", "World", 1))
|
58
60
|
@l.steps([
|
59
61
|
['Given ', 'some stuff that is longer']
|
60
62
|
])
|
61
|
-
@l.scenario(Model::
|
62
|
-
@l.step(Model::
|
63
|
+
@l.scenario(Model::Scenario.new([], [], "Scenario", "The scenario", "", 4))
|
64
|
+
@l.step(Model::Step.new([], "Given ", "some stuff that is longer", "", 5, nil, result('passed', nil, nil, "features/step_definitions/bar.rb:56")))
|
63
65
|
|
64
66
|
assert_io(%{Feature: Hello
|
65
67
|
World
|
@@ -70,7 +72,8 @@ module Gherkin
|
|
70
72
|
end
|
71
73
|
|
72
74
|
it "should highlight arguments for regular steps" do
|
73
|
-
|
75
|
+
step = Model::Step.new([], "Given ", "I have 999 cukes in my belly", "", 3, nil, result('passed', nil, [Gherkin::Formatter::Argument.new(7, '999')], nil))
|
76
|
+
@l.step(step)
|
74
77
|
assert_io(" Given I have 999 cukes in my belly\n")
|
75
78
|
end
|
76
79
|
|
data/spec/gherkin/i18n_spec.rb
CHANGED
@@ -13,7 +13,7 @@ module Gherkin
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should recognize keywords in the language of the lexer" do
|
16
|
-
lexer = Gherkin::I18nLexer.new(@listener, false)
|
16
|
+
lexer = Gherkin::Lexer::I18nLexer.new(@listener, false)
|
17
17
|
scan_file(lexer, "i18n_no.feature")
|
18
18
|
@listener.to_sexp.should == [
|
19
19
|
[:comment, "#language:no", 1],
|
@@ -27,7 +27,7 @@ module Gherkin
|
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should parse languages without a space after keywords" do
|
30
|
-
lexer = Gherkin::I18nLexer.new(@listener, false)
|
30
|
+
lexer = Gherkin::Lexer::I18nLexer.new(@listener, false)
|
31
31
|
scan_file(lexer, "i18n_zh-CN.feature")
|
32
32
|
@listener.to_sexp.should == [
|
33
33
|
[:comment, "#language:zh-CN", 1],
|
@@ -42,7 +42,7 @@ module Gherkin
|
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should parse languages with spaces after some keywords but not others" do
|
45
|
-
lexer = Gherkin::I18nLexer.new(@listener, false)
|
45
|
+
lexer = Gherkin::Lexer::I18nLexer.new(@listener, false)
|
46
46
|
scan_file(lexer, "i18n_fr.feature")
|
47
47
|
@listener.to_sexp.should == [
|
48
48
|
[:comment, "#language:fr", 1],
|
@@ -1,91 +1,67 @@
|
|
1
1
|
#encoding: utf-8
|
2
|
+
require 'ap'
|
2
3
|
require 'spec_helper'
|
3
4
|
require 'gherkin/json_parser'
|
5
|
+
require 'gherkin/formatter/json_formatter'
|
4
6
|
|
5
7
|
module Gherkin
|
6
8
|
describe JSONParser do
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
def check_json(json)
|
11
|
+
io = StringIO.new
|
12
|
+
f = Formatter::JSONFormatter.new(io)
|
13
|
+
p = JSONParser.new(f)
|
14
|
+
p.parse(json, 'unknown.json')
|
15
|
+
expected = JSON.parse(json)
|
16
|
+
actual = JSON.parse(io.string)
|
12
17
|
|
13
|
-
|
14
|
-
it "should scan empty features" do
|
15
|
-
@parser.parse_with_listener('{}', @listener)
|
16
|
-
@listener.to_sexp.should == [
|
17
|
-
[:location, "unknown.json"],
|
18
|
-
[:eof]
|
19
|
-
]
|
20
|
-
end
|
18
|
+
actual.should == expected
|
21
19
|
end
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
]
|
31
|
-
end
|
21
|
+
it "should parse a barely empty feature" do
|
22
|
+
check_json(%{{
|
23
|
+
"keyword": "Feature",
|
24
|
+
"name": "One",
|
25
|
+
"description": "",
|
26
|
+
"line" : 3
|
27
|
+
}})
|
32
28
|
end
|
33
29
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
30
|
+
it "should parse feature with tags and one scenario" do
|
31
|
+
check_json(%{{
|
32
|
+
"tags": [
|
33
|
+
{
|
34
|
+
"name": "@foo",
|
35
|
+
"line": 22
|
36
|
+
}
|
37
|
+
],
|
38
|
+
"keyword": "Feature",
|
39
|
+
"name": "One",
|
40
|
+
"description": "",
|
41
|
+
"line": 3,
|
42
|
+
"elements": [
|
43
|
+
{
|
44
|
+
"type": "scenario",
|
45
|
+
"steps": [
|
46
|
+
{
|
47
|
+
"name": "Hello",
|
48
|
+
"multiline_arg": {
|
49
|
+
"type": "table",
|
50
|
+
"value": [
|
51
|
+
{
|
52
|
+
"cells": ["foo", "bar"]
|
53
|
+
}
|
54
|
+
]
|
55
|
+
}
|
56
|
+
}
|
57
|
+
]
|
58
|
+
}
|
41
59
|
]
|
42
|
-
|
60
|
+
}})
|
43
61
|
end
|
44
62
|
|
45
|
-
|
46
|
-
|
47
|
-
@parser.parse_with_listener(fixture("complex.json"), @listener)
|
48
|
-
@listener.to_sexp.should == [
|
49
|
-
[:location, "unknown.json"],
|
50
|
-
[:tag, "@tag1", nil],
|
51
|
-
[:tag, "@tag2", nil],
|
52
|
-
[:feature, "Feature", "Feature Text","In order to test multiline forms", nil],
|
53
|
-
[:background, "Background", "", "", nil],
|
54
|
-
[:step, "Given ", "this is a background step", nil],
|
55
|
-
[:step, "When ", "this is another one", 412],
|
56
|
-
[:tag, "@foo", nil],
|
57
|
-
[:scenario_outline, "Scenario Outline", "An Scenario Outline","", nil],
|
58
|
-
[:step, "Given ", "A step with a table", nil],
|
59
|
-
[:row, %w{a row for a step}, nil],
|
60
|
-
[:tag, "@exampletag", nil],
|
61
|
-
[:examples, "Examples", "Sweet Example", "", nil],
|
62
|
-
[:row, %w{Fill In}, nil],
|
63
|
-
[:row, %w{The Blanks}, nil],
|
64
|
-
[:tag, "@tag3", nil],
|
65
|
-
[:tag, "@tag4", nil],
|
66
|
-
[:scenario, "Scenario", "Reading a Scenario", "", nil],
|
67
|
-
[:step, "Given ", "there is a step", nil],
|
68
|
-
[:step, "But ", "not another step", nil],
|
69
|
-
[:tag, "@tag3", nil],
|
70
|
-
[:scenario, "Scenario", "Reading a second scenario", "With two lines of text", nil],
|
71
|
-
[:step, "Given ", "a third step with a table", nil],
|
72
|
-
[:row, %w{a b}, 987],
|
73
|
-
[:row, %w{c d}, nil],
|
74
|
-
[:row, %w{e f}, nil],
|
75
|
-
[:step, "Given ", "I am still testing things", nil],
|
76
|
-
[:row, %w{g h}, nil],
|
77
|
-
[:row, %w{e r}, nil],
|
78
|
-
[:row, %w{k i}, nil],
|
79
|
-
[:row, ['n', ''], nil],
|
80
|
-
[:step, "Given ", "I am done testing these tables", nil],
|
81
|
-
[:step, "Given ", "I am happy", nil],
|
82
|
-
[:scenario, "Scenario", "Hammerzeit", "", nil],
|
83
|
-
[:step, "Given ", "All work and no play", nil],
|
84
|
-
[:py_string, "Makes Homer something something\nAnd something else", 777],
|
85
|
-
[:step, "Given ", "crazy", nil],
|
86
|
-
[:eof]
|
87
|
-
]
|
88
|
-
end
|
63
|
+
it "shoud parse a complex feature" do
|
64
|
+
check_json(fixture("complex.json"))
|
89
65
|
end
|
90
66
|
end
|
91
67
|
end
|