gherkin 2.0.1-universal-dotnet → 2.0.2-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 +12 -0
- data/VERSION.yml +1 -1
- data/features/json_formatter.feature +108 -48
- data/features/json_parser.feature +307 -0
- data/features/pretty_formatter.feature +9 -3
- data/features/step_definitions/json_lexer_steps.rb +20 -0
- data/features/step_definitions/pretty_formatter_steps.rb +44 -14
- data/lib/gherkin/cli/main.rb +1 -1
- data/lib/gherkin/formatter/json_formatter.rb +50 -13
- data/lib/gherkin/formatter/pretty_formatter.rb +23 -9
- data/lib/gherkin/i18n.rb +1 -1
- data/lib/gherkin/json_lexer.rb +103 -0
- data/lib/gherkin/tools/reformat.rb +6 -3
- data/lib/gherkin/tools/stats_listener.rb +3 -0
- data/ragel/lexer.java.rl.erb +2 -2
- data/ragel/lexer_common.rl.erb +1 -1
- data/spec/gherkin/fixtures/complex.json +124 -0
- data/spec/gherkin/formatter/pretty_formatter_spec.rb +3 -0
- data/spec/gherkin/json_lexer_spec.rb +97 -0
- data/spec/gherkin/shared/lexer_group.rb +12 -0
- data/spec/spec_helper.rb +2 -8
- data/tasks/compile.rake +16 -2
- metadata +10 -8
- data/lib/gherkin/parser/json_parser.rb +0 -102
- data/spec/gherkin/fixtures/complex.js +0 -105
- data/spec/gherkin/parser/json_parser_spec.rb +0 -129
@@ -1,102 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'gherkin/i18n'
|
3
|
-
|
4
|
-
module Gherkin
|
5
|
-
module Parser
|
6
|
-
class JSONParser
|
7
|
-
attr_reader :i18n_language
|
8
|
-
|
9
|
-
def initialize(listener)
|
10
|
-
@listener = listener
|
11
|
-
end
|
12
|
-
|
13
|
-
def parse(src)
|
14
|
-
feature = JSON.parse(src)
|
15
|
-
|
16
|
-
@i18n_language = Gherkin::I18n.get(feature["language"] || "en" )
|
17
|
-
|
18
|
-
tags_for(feature)
|
19
|
-
@listener.feature(keyword_for("feature", feature), feature["name"], line_for(feature)) if feature["name"]
|
20
|
-
|
21
|
-
if feature["background"]
|
22
|
-
@listener.background(keyword_for("background", feature["background"]), feature["background"]["name"], line_for(feature["background"]))
|
23
|
-
steps_for(feature["background"])
|
24
|
-
end
|
25
|
-
|
26
|
-
feature["elements"].each do |feature_element|
|
27
|
-
parse_element(feature_element)
|
28
|
-
end if feature["elements"]
|
29
|
-
|
30
|
-
@listener.eof
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def parse_element(feature_element)
|
36
|
-
case feature_element["type"]
|
37
|
-
when "Scenario" then parse_scenario(feature_element)
|
38
|
-
when "Scenario Outline" then parse_outline(feature_element)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def parse_outline(scenario_outline)
|
43
|
-
tags_for(scenario_outline)
|
44
|
-
@listener.scenario_outline(keyword_for("scenario_outline", scenario_outline), scenario_outline["name"], line_for(scenario_outline) )
|
45
|
-
steps_for(scenario_outline)
|
46
|
-
scenario_outline["examples"].each do |examples|
|
47
|
-
tags_for(examples)
|
48
|
-
@listener.examples(keyword_for("examples", examples), examples["name"], line_for(examples))
|
49
|
-
rows_for(examples)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def parse_scenario(scenario)
|
54
|
-
tags_for(scenario)
|
55
|
-
@listener.scenario(keyword_for("scenario", scenario), scenario["name"], line_for(scenario))
|
56
|
-
steps_for(scenario)
|
57
|
-
end
|
58
|
-
|
59
|
-
def tags_for(element)
|
60
|
-
element["tags"].each do |tag|
|
61
|
-
@listener.tag(tag, 0)
|
62
|
-
end if element["tags"]
|
63
|
-
end
|
64
|
-
|
65
|
-
def steps_for(element)
|
66
|
-
element["steps"].each do |step|
|
67
|
-
@listener.step(keyword_for("given",step), step["name"], line_for(step))
|
68
|
-
py_string_for(step)
|
69
|
-
rows_for(step)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def py_string_for(element)
|
74
|
-
@listener.py_string(element["py_string"], 0) if element["py_string"]
|
75
|
-
end
|
76
|
-
|
77
|
-
def rows_for(element)
|
78
|
-
element["table"].each do |row|
|
79
|
-
@listener.row(cells_for(row), 0)
|
80
|
-
end if element["table"]
|
81
|
-
end
|
82
|
-
|
83
|
-
def cells_for(row)
|
84
|
-
row["cells"].inject([]) { |col, ele| col << ele["text"] }
|
85
|
-
end
|
86
|
-
|
87
|
-
def line_for(element)
|
88
|
-
if element["line"]
|
89
|
-
element["line"]
|
90
|
-
elsif element["file_colon_line"]
|
91
|
-
element["file_colon_line"].split(':')[1].to_i
|
92
|
-
else
|
93
|
-
0
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def keyword_for(gherkin_keyword, element)
|
98
|
-
element["keyword"] || i18n_language.keywords(gherkin_keyword).reject { |kw| kw == "* " }.first
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
@@ -1,105 +0,0 @@
|
|
1
|
-
{ "name" : "Feature Text\nIn order to test multiline forms",
|
2
|
-
"tags" : [
|
3
|
-
"@tag1",
|
4
|
-
"@tag2"
|
5
|
-
],
|
6
|
-
"background" : {
|
7
|
-
"name" : "",
|
8
|
-
"steps" : [
|
9
|
-
{ "name" : "this is a background step" },
|
10
|
-
{ "name" : "this is another one",
|
11
|
-
"keyword" : "When ",
|
12
|
-
"line" : 412 }
|
13
|
-
]
|
14
|
-
},
|
15
|
-
"elements" : [
|
16
|
-
{ "type" : "Scenario Outline",
|
17
|
-
"name" : "An Scenario Outline",
|
18
|
-
"tags" : [ "@foo" ],
|
19
|
-
"steps" : [
|
20
|
-
{ "name" : "A step with a table",
|
21
|
-
"table" : [
|
22
|
-
{"cells":
|
23
|
-
[ { "text":"a" },
|
24
|
-
{ "text":"row" },
|
25
|
-
{ "text":"for" },
|
26
|
-
{ "text":"a" },
|
27
|
-
{ "text":"step"}
|
28
|
-
]
|
29
|
-
}
|
30
|
-
]
|
31
|
-
}
|
32
|
-
],
|
33
|
-
"examples" : [
|
34
|
-
{ "name" : "Sweet Example",
|
35
|
-
"table" : [
|
36
|
-
{"cells" :
|
37
|
-
[ { "text":"Fill" },
|
38
|
-
{ "text":"In" }]},
|
39
|
-
{"cells" :
|
40
|
-
[ { "text":"The" },
|
41
|
-
{ "text": "Blanks" }]}
|
42
|
-
],
|
43
|
-
"tags" : [ "@exampletag" ]
|
44
|
-
}
|
45
|
-
]
|
46
|
-
},
|
47
|
-
{ "type" : "Scenario",
|
48
|
-
"name" : "Reading a Scenario",
|
49
|
-
"tags" : [
|
50
|
-
"@tag3",
|
51
|
-
"@tag4"
|
52
|
-
],
|
53
|
-
"steps" : [
|
54
|
-
{ "name" : "there is a step" },
|
55
|
-
{ "name" : "not another step" }
|
56
|
-
]
|
57
|
-
},
|
58
|
-
{ "type" : "Scenario",
|
59
|
-
"name" : "Reading a second scenario\nWith two lines of text",
|
60
|
-
"tags" : [ "@tag3" ],
|
61
|
-
"steps" : [
|
62
|
-
{ "name" : "a third step with a table",
|
63
|
-
"table" : [
|
64
|
-
{ "cells" :
|
65
|
-
[ { "text":"a" },
|
66
|
-
{ "text":"b" }]},
|
67
|
-
{ "cells" :
|
68
|
-
[ { "text":"c" },
|
69
|
-
{ "text":"d" }]},
|
70
|
-
{ "cells" :
|
71
|
-
[ { "text":"e" },
|
72
|
-
{ "text":"f" }]}
|
73
|
-
]
|
74
|
-
},
|
75
|
-
{ "name" : "I am still testing things",
|
76
|
-
"table" : [
|
77
|
-
{ "cells" :
|
78
|
-
[ { "text":"g" },
|
79
|
-
{ "text":"h" }]},
|
80
|
-
{ "cells" :
|
81
|
-
[ { "text":"e" },
|
82
|
-
{ "text":"r" }]},
|
83
|
-
{ "cells" :
|
84
|
-
[ { "text":"k" },
|
85
|
-
{ "text":"i" }]},
|
86
|
-
{ "cells" :
|
87
|
-
[ { "text":"n" },
|
88
|
-
{ "text":"" }]}
|
89
|
-
]
|
90
|
-
},
|
91
|
-
{ "name" : "I am done testing these tables" },
|
92
|
-
{ "name" : "I am happy" }
|
93
|
-
]
|
94
|
-
},
|
95
|
-
{ "type" : "Scenario",
|
96
|
-
"name" : "Hammerzeit",
|
97
|
-
"steps" : [
|
98
|
-
{ "name" : "All work and no play",
|
99
|
-
"py_string" : "Makes Homer something something\nAnd something else" },
|
100
|
-
{ "name" : "crazy" }
|
101
|
-
]
|
102
|
-
}
|
103
|
-
]
|
104
|
-
}
|
105
|
-
|
@@ -1,129 +0,0 @@
|
|
1
|
-
#encoding: utf-8
|
2
|
-
require 'spec_helper'
|
3
|
-
require 'gherkin/parser/json_parser'
|
4
|
-
|
5
|
-
module Gherkin
|
6
|
-
module Parser
|
7
|
-
describe JSONParser do
|
8
|
-
|
9
|
-
before do
|
10
|
-
@listener = Gherkin::SexpRecorder.new
|
11
|
-
@parser = Gherkin::Parser::JSONParser.new(@listener)
|
12
|
-
end
|
13
|
-
|
14
|
-
describe "An empty feature" do
|
15
|
-
it "should parse empty features" do
|
16
|
-
@parser.parse('{}')
|
17
|
-
@listener.to_sexp.should == [
|
18
|
-
[:eof]
|
19
|
-
]
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe "A barely empty feature" do
|
24
|
-
it "should parse a feature with no elements" do
|
25
|
-
@parser.parse('{ "name" : "One", "line" : 3 }')
|
26
|
-
@listener.to_sexp.should == [
|
27
|
-
[:feature, "Feature", "One", 3],
|
28
|
-
[:eof]
|
29
|
-
]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe "Determining language" do
|
34
|
-
it "should pick up the i18n language from attributes" do
|
35
|
-
@parser.parse('{ "language" : "fr" }')
|
36
|
-
@parser.i18n_language.iso_code.should == "fr"
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should default to English if no language is found" do
|
40
|
-
@parser.parse('{ "name": "A Featuer" }')
|
41
|
-
@parser.i18n_language.iso_code.should == "en"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
describe "Missing line numbers" do
|
46
|
-
it "should indicate a line number of 0 if a line attribute doesn't exist" do
|
47
|
-
@parser.parse('{ "name" : "My Sweet Featur" }')
|
48
|
-
@listener.to_sexp.should == [
|
49
|
-
[:feature, "Feature", "My Sweet Featur", 0],
|
50
|
-
[:eof]
|
51
|
-
]
|
52
|
-
end
|
53
|
-
|
54
|
-
it "should use line number from file_colon_line if exists" do
|
55
|
-
@parser.parse('{ "name" : "My Sweet Featur",
|
56
|
-
"file_colon_line": "my_nice_feature.js:12" }')
|
57
|
-
@listener.to_sexp.should == [
|
58
|
-
[:feature, "Feature", "My Sweet Featur", 12],
|
59
|
-
[:eof]
|
60
|
-
]
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
describe "Keywords" do
|
65
|
-
it "should use the keyword from the source when provided" do
|
66
|
-
@parser.parse('{ "name" : "My Sweet Featur", "language": "fr", "keyword": "Feature" }')
|
67
|
-
@listener.to_sexp.should == [
|
68
|
-
[:feature, "Feature", "My Sweet Featur", 0],
|
69
|
-
[:eof]
|
70
|
-
]
|
71
|
-
end
|
72
|
-
|
73
|
-
it "should use a default keyword from the i18n_language if no keyword is provided" do
|
74
|
-
@parser.parse('{ "name" : "My Sweet Featur", "language": "fr" }')
|
75
|
-
@listener.to_sexp.should == [
|
76
|
-
[:feature, "Fonctionnalité", "My Sweet Featur", 0],
|
77
|
-
[:eof]
|
78
|
-
]
|
79
|
-
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
describe "A complex feature with tags, comments, multiple scenarios, and multiple steps and tables" do
|
84
|
-
it "should find things in the right order" do
|
85
|
-
parse_file("complex.js")
|
86
|
-
@listener.to_sexp.should == [
|
87
|
-
[:tag, "@tag1", 0],
|
88
|
-
[:tag, "@tag2", 0],
|
89
|
-
[:feature, "Feature", "Feature Text\nIn order to test multiline forms", 0],
|
90
|
-
[:background, "Background", "", 0],
|
91
|
-
[:step, "Given ", "this is a background step", 0],
|
92
|
-
[:step, "When ", "this is another one", 412],
|
93
|
-
[:tag, "@foo", 0],
|
94
|
-
[:scenario_outline, "Scenario Outline", "An Scenario Outline", 0],
|
95
|
-
[:step, "Given ", "A step with a table", 0],
|
96
|
-
[:row, %w{a row for a step}, 0],
|
97
|
-
[:tag, "@exampletag", 0],
|
98
|
-
[:examples, "Examples", "Sweet Example", 0],
|
99
|
-
[:row, %w{Fill In}, 0],
|
100
|
-
[:row, %w{The Blanks}, 0],
|
101
|
-
[:tag, "@tag3", 0],
|
102
|
-
[:tag, "@tag4", 0],
|
103
|
-
[:scenario, "Scenario", "Reading a Scenario", 0],
|
104
|
-
[:step, "Given ", "there is a step", 0],
|
105
|
-
[:step, "Given ", "not another step", 0],
|
106
|
-
[:tag, "@tag3", 0],
|
107
|
-
[:scenario, "Scenario", "Reading a second scenario\nWith two lines of text", 0],
|
108
|
-
[:step, "Given ", "a third step with a table", 0],
|
109
|
-
[:row, %w{a b}, 0],
|
110
|
-
[:row, %w{c d}, 0],
|
111
|
-
[:row, %w{e f}, 0],
|
112
|
-
[:step, "Given ", "I am still testing things", 0],
|
113
|
-
[:row, %w{g h}, 0],
|
114
|
-
[:row, %w{e r}, 0],
|
115
|
-
[:row, %w{k i}, 0],
|
116
|
-
[:row, ['n', ''], 0],
|
117
|
-
[:step, "Given ", "I am done testing these tables", 0],
|
118
|
-
[:step, "Given ", "I am happy", 0],
|
119
|
-
[:scenario, "Scenario", "Hammerzeit", 0],
|
120
|
-
[:step, "Given ", "All work and no play", 0],
|
121
|
-
[:py_string, "Makes Homer something something\nAnd something else", 0 ],
|
122
|
-
[:step, "Given ", "crazy", 0],
|
123
|
-
[:eof]
|
124
|
-
]
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|