gherkin 2.0.1-i386-mingw32 → 2.0.2-i386-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- 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
|