gherkin 1.0.30-i386-mswin32 → 2.0.0-i386-mswin32
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/.rspec +1 -0
- data/History.txt +19 -0
- data/Rakefile +4 -4
- data/VERSION.yml +2 -2
- data/features/feature_parser.feature +11 -0
- data/features/json_formatter.feature +238 -0
- data/features/pretty_formatter.feature +9 -0
- data/features/step_definitions/gherkin_steps.rb +1 -1
- data/features/step_definitions/json_formatter_steps.rb +32 -0
- data/features/step_definitions/pretty_formatter_steps.rb +24 -23
- data/features/support/env.rb +3 -3
- data/lib/gherkin/formatter/json_formatter.rb +82 -0
- data/lib/gherkin/formatter/pretty_formatter.rb +73 -78
- data/lib/gherkin/i18n.rb +22 -18
- data/lib/gherkin/i18n.yml +9 -9
- data/lib/gherkin/i18n_lexer.rb +2 -2
- data/lib/gherkin/parser/event.rb +6 -6
- data/lib/gherkin/parser/filter_listener.rb +5 -1
- data/lib/gherkin/parser/formatter_listener.rb +113 -0
- data/lib/gherkin/parser/json_parser.rb +102 -0
- data/lib/gherkin/parser/parser.rb +10 -2
- data/lib/gherkin/parser/row.rb +15 -0
- data/lib/gherkin/rubify.rb +2 -0
- data/lib/gherkin/tools/files.rb +1 -1
- data/lib/gherkin/tools/reformat.rb +1 -2
- data/lib/gherkin/tools/stats.rb +1 -1
- data/lib/gherkin/tools/stats_listener.rb +5 -5
- data/ragel/lexer.c.rl.erb +41 -12
- data/ragel/lexer.java.rl.erb +26 -17
- data/ragel/lexer.rb.rl.erb +10 -5
- data/ragel/lexer_common.rl.erb +6 -6
- data/spec/gherkin/c_lexer_spec.rb +2 -2
- data/spec/gherkin/fixtures/complex.js +105 -0
- data/spec/gherkin/formatter/argument_spec.rb +3 -3
- data/spec/gherkin/formatter/colors_spec.rb +3 -4
- data/spec/gherkin/formatter/pretty_formatter_spec.rb +21 -50
- data/spec/gherkin/i18n_lexer_spec.rb +6 -6
- data/spec/gherkin/i18n_spec.rb +16 -9
- data/spec/gherkin/java_lexer_spec.rb +1 -2
- data/spec/gherkin/output_stream_string_io.rb +24 -0
- data/spec/gherkin/parser/filter_listener_spec.rb +16 -9
- data/spec/gherkin/parser/formatter_listener_spec.rb +134 -0
- data/spec/gherkin/parser/json_parser_spec.rb +129 -0
- data/spec/gherkin/parser/parser_spec.rb +9 -9
- data/spec/gherkin/parser/tag_expression_spec.rb +8 -8
- data/spec/gherkin/rb_lexer_spec.rb +1 -1
- data/spec/gherkin/sexp_recorder.rb +21 -1
- data/spec/gherkin/shared/{lexer_spec.rb → lexer_group.rb} +172 -102
- data/spec/gherkin/shared/{py_string_spec.rb → py_string_group.rb} +21 -17
- data/spec/gherkin/shared/{row_spec.rb → row_group.rb} +36 -19
- data/spec/gherkin/shared/{tags_spec.rb → tags_group.rb} +13 -9
- data/spec/spec_helper.rb +18 -38
- data/tasks/bench.rake +3 -3
- data/tasks/compile.rake +13 -14
- data/tasks/rspec.rake +6 -11
- metadata +42 -28
- data/features/pretty_printer.feature +0 -14
- data/spec/gherkin/csharp_lexer_spec.rb +0 -20
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
require 'gherkin/parser/tag_expression'
|
3
3
|
|
4
4
|
module Gherkin
|
@@ -6,7 +6,7 @@ module Gherkin
|
|
6
6
|
describe TagExpression do
|
7
7
|
context "no tags" do
|
8
8
|
before(:each) do
|
9
|
-
@e = TagExpression.new([])
|
9
|
+
@e = Gherkin::Parser::TagExpression.new([])
|
10
10
|
end
|
11
11
|
|
12
12
|
it "should match @foo" do
|
@@ -20,7 +20,7 @@ module Gherkin
|
|
20
20
|
|
21
21
|
context "@foo" do
|
22
22
|
before(:each) do
|
23
|
-
@e = TagExpression.new(['@foo'])
|
23
|
+
@e = Gherkin::Parser::TagExpression.new(['@foo'])
|
24
24
|
end
|
25
25
|
|
26
26
|
it "should match @foo" do
|
@@ -38,7 +38,7 @@ module Gherkin
|
|
38
38
|
|
39
39
|
context "!@foo" do
|
40
40
|
before(:each) do
|
41
|
-
@e = TagExpression.new(['~@foo'])
|
41
|
+
@e = Gherkin::Parser::TagExpression.new(['~@foo'])
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should match @bar" do
|
@@ -52,7 +52,7 @@ module Gherkin
|
|
52
52
|
|
53
53
|
context "@foo || @bar" do
|
54
54
|
before(:each) do
|
55
|
-
@e = TagExpression.new(['@foo,@bar'])
|
55
|
+
@e = Gherkin::Parser::TagExpression.new(['@foo,@bar'])
|
56
56
|
end
|
57
57
|
|
58
58
|
it "should match @foo" do
|
@@ -70,7 +70,7 @@ module Gherkin
|
|
70
70
|
|
71
71
|
context "(@foo || @bar) && !@zap" do
|
72
72
|
before(:each) do
|
73
|
-
@e = TagExpression.new(['@foo,@bar', '~@zap'])
|
73
|
+
@e = Gherkin::Parser::TagExpression.new(['@foo,@bar', '~@zap'])
|
74
74
|
end
|
75
75
|
|
76
76
|
it "should match @foo" do
|
@@ -84,7 +84,7 @@ module Gherkin
|
|
84
84
|
|
85
85
|
context "(@foo:3 || !@bar:4) && @zap:5" do
|
86
86
|
before(:each) do
|
87
|
-
@e = TagExpression.new(['@foo:3,~@bar','@zap:5'])
|
87
|
+
@e = Gherkin::Parser::TagExpression.new(['@foo:3,~@bar','@zap:5'])
|
88
88
|
end
|
89
89
|
|
90
90
|
it "should count tags for positive tags" do
|
@@ -98,7 +98,7 @@ module Gherkin
|
|
98
98
|
|
99
99
|
context "Parsing '@foo:3,~@bar', '@zap:5'" do
|
100
100
|
before(:each) do
|
101
|
-
@e = TagExpression.new([' @foo:3 , ~@bar ', ' @zap:5 '])
|
101
|
+
@e = Gherkin::Parser::TagExpression.new([' @foo:3 , ~@bar ', ' @zap:5 '])
|
102
102
|
end
|
103
103
|
|
104
104
|
unless defined?(JRUBY_VERSION)
|
@@ -1,5 +1,10 @@
|
|
1
|
+
require 'gherkin/rubify'
|
2
|
+
require 'gherkin/parser/row'
|
3
|
+
|
1
4
|
module Gherkin
|
2
5
|
class SexpRecorder
|
6
|
+
include Rubify
|
7
|
+
|
3
8
|
def initialize
|
4
9
|
@sexps = []
|
5
10
|
end
|
@@ -8,7 +13,8 @@ module Gherkin
|
|
8
13
|
event = :scenario_outline if event == :scenarioOutline # Special Java Lexer handling
|
9
14
|
event = :py_string if event == :pyString # Special Java Lexer handling
|
10
15
|
event = :syntax_error if event == :syntaxError # Special Java Lexer handling
|
11
|
-
args
|
16
|
+
args = rubify(args)
|
17
|
+
args = sexpify(args)
|
12
18
|
@sexps << [event] + args
|
13
19
|
end
|
14
20
|
|
@@ -28,5 +34,19 @@ module Gherkin
|
|
28
34
|
def line(number)
|
29
35
|
@sexps.find { |sexp| sexp.last == number }
|
30
36
|
end
|
37
|
+
|
38
|
+
def sexpify(o)
|
39
|
+
if (defined?(JRUBY_VERSION) && Java.java.util.Collection === o) || Array === o
|
40
|
+
o.map{|e| sexpify(e)}
|
41
|
+
elsif(Parser::Row === o)
|
42
|
+
{
|
43
|
+
"cells" => rubify(o.cells),
|
44
|
+
"comments" => rubify(o.comments),
|
45
|
+
"line" => o.line,
|
46
|
+
}
|
47
|
+
else
|
48
|
+
o
|
49
|
+
end
|
50
|
+
end
|
31
51
|
end
|
32
52
|
end
|
@@ -1,22 +1,27 @@
|
|
1
1
|
#encoding: utf-8
|
2
|
-
require
|
2
|
+
require 'spec_helper'
|
3
3
|
|
4
4
|
module Gherkin
|
5
5
|
module Lexer
|
6
6
|
shared_examples_for "a Gherkin lexer" do
|
7
|
+
def scan(gherkin)
|
8
|
+
@lexer.scan(gherkin, "test.feature", 0)
|
9
|
+
end
|
7
10
|
|
8
11
|
describe "Comments" do
|
9
12
|
it "should parse a one line comment" do
|
10
|
-
|
13
|
+
scan("# My comment\n")
|
11
14
|
@listener.to_sexp.should == [
|
15
|
+
[:location, 'test.feature', 0],
|
12
16
|
[:comment, "# My comment", 1],
|
13
17
|
[:eof]
|
14
18
|
]
|
15
19
|
end
|
16
20
|
|
17
21
|
it "should parse a multiline comment" do
|
18
|
-
|
22
|
+
scan("# Hello\n\n# World\n")
|
19
23
|
@listener.to_sexp.should == [
|
24
|
+
[:location, 'test.feature', 0],
|
20
25
|
[:comment, "# Hello", 1],
|
21
26
|
[:comment, "# World", 3],
|
22
27
|
[:eof]
|
@@ -24,18 +29,20 @@ module Gherkin
|
|
24
29
|
end
|
25
30
|
|
26
31
|
it "should not consume comments as part of a multiline name" do
|
27
|
-
|
32
|
+
scan("Scenario: test\n#hello\n Scenario: another")
|
28
33
|
@listener.to_sexp.should == [
|
29
|
-
[:
|
34
|
+
[:location, 'test.feature', 0],
|
35
|
+
[:scenario, "Scenario", "test", "", 1],
|
30
36
|
[:comment, "#hello", 2],
|
31
|
-
[:scenario, "Scenario", "another", 3],
|
37
|
+
[:scenario, "Scenario", "another", "", 3],
|
32
38
|
[:eof]
|
33
39
|
]
|
34
40
|
end
|
35
41
|
|
36
42
|
it "should allow empty comment lines" do
|
37
|
-
|
43
|
+
scan("#\n # A comment\n #\n")
|
38
44
|
@listener.to_sexp.should == [
|
45
|
+
[:location, 'test.feature', 0],
|
39
46
|
[:comment, "#", 1],
|
40
47
|
[:comment, "# A comment", 2],
|
41
48
|
[:comment, "#", 3],
|
@@ -45,52 +52,66 @@ module Gherkin
|
|
45
52
|
|
46
53
|
it "should not allow comments within the Feature description" do
|
47
54
|
lambda {
|
48
|
-
|
55
|
+
scan("Feature: something\nAs a something\n# Comment\nI want something")
|
49
56
|
}.should raise_error(/Lexing error on line 4/)
|
50
57
|
end
|
51
58
|
end
|
52
59
|
|
53
60
|
describe "Tags" do
|
54
61
|
it "should not take the tags as part of a multiline name feature element" do
|
55
|
-
|
62
|
+
scan("Feature: hi\n Scenario: test\n\n@hello\n Scenario: another")
|
56
63
|
@listener.to_sexp.should == [
|
57
|
-
[:
|
58
|
-
[:
|
64
|
+
[:location, 'test.feature', 0],
|
65
|
+
[:feature, "Feature", "hi", "", 1],
|
66
|
+
[:scenario, "Scenario", "test", "", 2],
|
59
67
|
[:tag, "@hello", 4],
|
60
|
-
[:scenario, "Scenario", "another", 5],
|
68
|
+
[:scenario, "Scenario", "another", "", 5],
|
61
69
|
[:eof]
|
62
70
|
]
|
63
71
|
end
|
64
72
|
end
|
65
73
|
|
66
74
|
describe "Background" do
|
75
|
+
it "should allow an empty background name and description" do
|
76
|
+
scan("Background:\nGiven I am a step\n")
|
77
|
+
@listener.to_sexp.should == [
|
78
|
+
[:location, 'test.feature', 0],
|
79
|
+
[:background, "Background", "", "", 1],
|
80
|
+
[:step, "Given ", "I am a step", 2],
|
81
|
+
[:eof]
|
82
|
+
]
|
83
|
+
end
|
84
|
+
|
67
85
|
it "should allow an empty background description" do
|
68
|
-
|
86
|
+
scan("Background: Yeah\nGiven I am a step\n")
|
69
87
|
@listener.to_sexp.should == [
|
70
|
-
[:
|
88
|
+
[:location, 'test.feature', 0],
|
89
|
+
[:background, "Background", "Yeah", "", 1],
|
71
90
|
[:step, "Given ", "I am a step", 2],
|
72
91
|
[:eof]
|
73
92
|
]
|
74
93
|
end
|
75
94
|
|
76
95
|
it "should allow multiline names ending at eof" do
|
77
|
-
|
96
|
+
scan("Background: I have several\n Lines to look at\n None starting with Given")
|
78
97
|
@listener.to_sexp.should == [
|
79
|
-
[:
|
98
|
+
[:location, 'test.feature', 0],
|
99
|
+
[:background, "Background", "I have several", "Lines to look at\nNone starting with Given", 1],
|
80
100
|
[:eof]
|
81
101
|
]
|
82
102
|
end
|
83
103
|
|
84
104
|
it "should allow multiline names" do
|
85
|
-
|
105
|
+
scan(%{Feature: Hi
|
86
106
|
Background: It is my ambition to say
|
87
107
|
in ten sentences
|
88
108
|
what others say
|
89
109
|
in a whole book.
|
90
110
|
Given I am a step})
|
91
111
|
@listener.to_sexp.should == [
|
92
|
-
[:
|
93
|
-
[:
|
112
|
+
[:location, 'test.feature', 0],
|
113
|
+
[:feature, "Feature", "Hi", "", 1],
|
114
|
+
[:background, "Background", "It is my ambition to say", "in ten sentences\nwhat others say\nin a whole book.",2],
|
94
115
|
[:step, "Given ", "I am a step", 6],
|
95
116
|
[:eof]
|
96
117
|
]
|
@@ -99,68 +120,74 @@ Given I am a step})
|
|
99
120
|
|
100
121
|
describe "Scenarios" do
|
101
122
|
it "should be parsed" do
|
102
|
-
|
123
|
+
scan("Scenario: Hello\n")
|
103
124
|
@listener.to_sexp.should == [
|
104
|
-
[:
|
125
|
+
[:location, 'test.feature', 0],
|
126
|
+
[:scenario, "Scenario", "Hello", "", 1],
|
105
127
|
[:eof]
|
106
128
|
]
|
107
129
|
end
|
108
130
|
|
109
131
|
it "should allow whitespace lines after the Scenario line" do
|
110
|
-
|
132
|
+
scan(%{Scenario: bar
|
111
133
|
|
112
134
|
Given baz
|
113
135
|
})
|
114
136
|
@listener.to_sexp.should == [
|
115
|
-
[:
|
137
|
+
[:location, 'test.feature', 0],
|
138
|
+
[:scenario, "Scenario", "bar", "", 1],
|
116
139
|
[:step, "Given ", "baz", 3],
|
117
140
|
[:eof]
|
118
141
|
]
|
119
142
|
end
|
120
143
|
|
121
144
|
it "should allow multiline names" do
|
122
|
-
|
145
|
+
scan(%{Scenario: It is my ambition to say
|
123
146
|
in ten sentences
|
124
147
|
what others say
|
125
148
|
in a whole book.
|
126
149
|
Given I am a step
|
127
150
|
})
|
128
151
|
@listener.to_sexp.should == [
|
129
|
-
[:
|
152
|
+
[:location, 'test.feature', 0],
|
153
|
+
[:scenario, "Scenario", "It is my ambition to say", "in ten sentences\nwhat others say\nin a whole book.", 1],
|
130
154
|
[:step, "Given ", "I am a step", 5],
|
131
155
|
[:eof]
|
132
156
|
]
|
133
157
|
end
|
134
158
|
|
135
159
|
it "should allow multiline names ending at eof" do
|
136
|
-
|
160
|
+
scan("Scenario: I have several\n Lines to look at\n None starting with Given")
|
137
161
|
@listener.to_sexp.should == [
|
138
|
-
[:
|
162
|
+
[:location, 'test.feature', 0],
|
163
|
+
[:scenario, "Scenario", "I have several", "Lines to look at\nNone starting with Given", 1],
|
139
164
|
[:eof]
|
140
165
|
]
|
141
166
|
end
|
142
167
|
|
143
168
|
it "should ignore gherkin keywords embedded in other words" do
|
144
|
-
|
169
|
+
scan(%{Scenario: I have a Button
|
145
170
|
Buttons are great
|
146
171
|
Given I have some
|
147
172
|
But I might not because I am a Charles Dickens character
|
148
173
|
})
|
149
174
|
@listener.to_sexp.should == [
|
150
|
-
[:
|
175
|
+
[:location, 'test.feature', 0],
|
176
|
+
[:scenario, "Scenario", "I have a Button", "Buttons are great", 1],
|
151
177
|
[:step, "Given ", "I have some", 3],
|
152
178
|
[:step, "But ", "I might not because I am a Charles Dickens character", 4],
|
153
179
|
[:eof]
|
154
180
|
]
|
155
181
|
end
|
156
182
|
|
157
|
-
it "should allow step
|
158
|
-
|
183
|
+
it "should allow step keywords in Scenario names" do
|
184
|
+
scan(%{Scenario: When I have when in scenario
|
159
185
|
I should be fine
|
160
186
|
Given I am a step
|
161
187
|
})
|
162
188
|
@listener.to_sexp.should == [
|
163
|
-
[:
|
189
|
+
[:location, 'test.feature', 0],
|
190
|
+
[:scenario, "Scenario", "When I have when in scenario", "I should be fine", 1],
|
164
191
|
[:step, "Given ", "I am a step", 3],
|
165
192
|
[:eof]
|
166
193
|
]
|
@@ -169,36 +196,41 @@ Given I am a step
|
|
169
196
|
|
170
197
|
describe "Scenario Outlines" do
|
171
198
|
it "should be parsed" do
|
172
|
-
|
199
|
+
scan(%{Scenario Outline: Hello
|
200
|
+
With a description
|
173
201
|
Given a <what> cucumber
|
174
|
-
Examples:
|
202
|
+
Examples: With a name
|
203
|
+
and a description
|
175
204
|
|what|
|
176
205
|
|green|
|
177
206
|
})
|
178
207
|
@listener.to_sexp.should == [
|
179
|
-
[:
|
180
|
-
[:
|
181
|
-
[:
|
182
|
-
[:
|
183
|
-
[:row, ["
|
208
|
+
[:location, 'test.feature', 0],
|
209
|
+
[:scenario_outline, "Scenario Outline", "Hello", "With a description", 1],
|
210
|
+
[:step, "Given ", "a <what> cucumber", 3],
|
211
|
+
[:examples, "Examples", "With a name", "and a description", 4],
|
212
|
+
[:row, ["what"], 6],
|
213
|
+
[:row, ["green"], 7],
|
184
214
|
[:eof]
|
185
215
|
]
|
186
216
|
end
|
187
217
|
|
218
|
+
|
188
219
|
it "should parse with no steps or examples" do
|
189
|
-
|
220
|
+
scan(%{Scenario Outline: Hello
|
190
221
|
|
191
222
|
Scenario: My Scenario
|
192
223
|
})
|
193
224
|
@listener.to_sexp.should == [
|
194
|
-
[:
|
195
|
-
[:
|
225
|
+
[:location, 'test.feature', 0],
|
226
|
+
[:scenario_outline, "Scenario Outline", "Hello", "", 1],
|
227
|
+
[:scenario, "Scenario", "My Scenario", "", 3],
|
196
228
|
[:eof]
|
197
229
|
]
|
198
230
|
end
|
199
231
|
|
200
|
-
it "should allow multiline
|
201
|
-
|
232
|
+
it "should allow multiline description" do
|
233
|
+
scan(%{Scenario Outline: It is my ambition to say
|
202
234
|
in ten sentences
|
203
235
|
what others say
|
204
236
|
in a whole book.
|
@@ -206,7 +238,8 @@ Given I am a step
|
|
206
238
|
|
207
239
|
})
|
208
240
|
@listener.to_sexp.should == [
|
209
|
-
[:
|
241
|
+
[:location, 'test.feature', 0],
|
242
|
+
[:scenario_outline, "Scenario Outline", "It is my ambition to say", "in ten sentences\nwhat others say\nin a whole book.", 1],
|
210
243
|
[:step, "Given ", "I am a step", 5],
|
211
244
|
[:eof]
|
212
245
|
]
|
@@ -215,12 +248,13 @@ Given I am a step
|
|
215
248
|
|
216
249
|
describe "Examples" do
|
217
250
|
it "should be parsed" do
|
218
|
-
|
251
|
+
scan(%{Examples:
|
219
252
|
|x|y|
|
220
253
|
|5|6|
|
221
254
|
})
|
222
255
|
@listener.to_sexp.should == [
|
223
|
-
[:
|
256
|
+
[:location, 'test.feature', 0],
|
257
|
+
[:examples, "Examples", "", "", 1],
|
224
258
|
[:row, ["x","y"], 2],
|
225
259
|
[:row, ["5","6"], 3],
|
226
260
|
[:eof]
|
@@ -228,14 +262,15 @@ Given I am a step
|
|
228
262
|
end
|
229
263
|
|
230
264
|
it "should parse multiline example names" do
|
231
|
-
|
265
|
+
scan(%{Examples: I'm a multiline name
|
232
266
|
and I'm ok
|
233
267
|
f'real
|
234
268
|
|x|
|
235
269
|
|5|
|
236
270
|
})
|
237
271
|
@listener.to_sexp.should == [
|
238
|
-
[:
|
272
|
+
[:location, 'test.feature', 0],
|
273
|
+
[:examples, "Examples", "I'm a multiline name", "and I'm ok\nf'real", 1],
|
239
274
|
[:row, ["x"], 4],
|
240
275
|
[:row, ["5"], 5],
|
241
276
|
[:eof]
|
@@ -245,10 +280,11 @@ Given I am a step
|
|
245
280
|
|
246
281
|
describe "Steps" do
|
247
282
|
it "should parse steps with inline table" do
|
248
|
-
|
283
|
+
scan(%{Given I have a table
|
249
284
|
|a|b|
|
250
285
|
})
|
251
286
|
@listener.to_sexp.should == [
|
287
|
+
[:location, 'test.feature', 0],
|
252
288
|
[:step, "Given ", "I have a table", 1],
|
253
289
|
[:row, ['a','b'], 2],
|
254
290
|
[:eof]
|
@@ -256,8 +292,9 @@ Given I am a step
|
|
256
292
|
end
|
257
293
|
|
258
294
|
it "should parse steps with inline py_string" do
|
259
|
-
|
295
|
+
scan("Given I have a string\n\"\"\"\nhello\nworld\n\"\"\"")
|
260
296
|
@listener.to_sexp.should == [
|
297
|
+
[:location, 'test.feature', 0],
|
261
298
|
[:step, "Given ", "I have a string", 1],
|
262
299
|
[:py_string, "hello\nworld", 2],
|
263
300
|
[:eof]
|
@@ -267,10 +304,11 @@ Given I am a step
|
|
267
304
|
|
268
305
|
describe "A single feature, single scenario, single step" do
|
269
306
|
it "should find the feature, scenario, and step" do
|
270
|
-
|
307
|
+
scan("Feature: Feature Text\n Scenario: Reading a Scenario\n Given there is a step\n")
|
271
308
|
@listener.to_sexp.should == [
|
272
|
-
[:
|
273
|
-
[:
|
309
|
+
[:location, 'test.feature', 0],
|
310
|
+
[:feature, "Feature", "Feature Text", "", 1],
|
311
|
+
[:scenario, "Scenario", "Reading a Scenario", "", 2],
|
274
312
|
[:step, "Given ", "there is a step", 3],
|
275
313
|
[:eof]
|
276
314
|
]
|
@@ -279,10 +317,11 @@ Given I am a step
|
|
279
317
|
|
280
318
|
describe "A feature ending in whitespace" do
|
281
319
|
it "should not raise an error when whitespace follows the Feature, Scenario, and Steps" do
|
282
|
-
|
320
|
+
scan("Feature: Feature Text\n Scenario: Reading a Scenario\n Given there is a step\n ")
|
283
321
|
@listener.to_sexp.should == [
|
284
|
-
[:
|
285
|
-
[:
|
322
|
+
[:location, 'test.feature', 0],
|
323
|
+
[:feature, "Feature", "Feature Text", "", 1],
|
324
|
+
[:scenario, "Scenario", "Reading a Scenario", "", 2],
|
286
325
|
[:step, "Given ", "there is a step", 3],
|
287
326
|
[:eof]
|
288
327
|
]
|
@@ -292,10 +331,11 @@ Given I am a step
|
|
292
331
|
describe "A single feature, single scenario, three steps" do
|
293
332
|
|
294
333
|
it "should find the feature, scenario, and three steps" do
|
295
|
-
|
334
|
+
scan("Feature: Feature Text\n Scenario: Reading a Scenario\n Given there is a step\n And another step\n And a third step\n")
|
296
335
|
@listener.to_sexp.should == [
|
297
|
-
[:
|
298
|
-
[:
|
336
|
+
[:location, 'test.feature', 0],
|
337
|
+
[:feature, "Feature", "Feature Text", "", 1],
|
338
|
+
[:scenario, "Scenario", "Reading a Scenario", "", 2],
|
299
339
|
[:step, "Given ", "there is a step", 3],
|
300
340
|
[:step, "And ", "another step", 4],
|
301
341
|
[:step, "And ", "a third step", 5],
|
@@ -306,17 +346,19 @@ Given I am a step
|
|
306
346
|
|
307
347
|
describe "A single feature with no scenario" do
|
308
348
|
it "should find the feature" do
|
309
|
-
|
349
|
+
scan("Feature: Feature Text\n")
|
310
350
|
@listener.to_sexp.should == [
|
311
|
-
[:
|
351
|
+
[:location, 'test.feature', 0],
|
352
|
+
[:feature, "Feature", "Feature Text", "", 1],
|
312
353
|
[:eof]
|
313
354
|
]
|
314
355
|
end
|
315
356
|
|
316
357
|
it "should parse a one line feature with no newline" do
|
317
|
-
|
358
|
+
scan("Feature: hi")
|
318
359
|
@listener.to_sexp.should == [
|
319
|
-
[:
|
360
|
+
[:location, 'test.feature', 0],
|
361
|
+
[:feature, "Feature", "hi", "", 1],
|
320
362
|
[:eof]
|
321
363
|
]
|
322
364
|
end
|
@@ -324,9 +366,10 @@ Given I am a step
|
|
324
366
|
|
325
367
|
describe "A multi-line feature with no scenario" do
|
326
368
|
it "should find the feature" do
|
327
|
-
|
369
|
+
scan("Feature: Feature Text\n And some more text")
|
328
370
|
@listener.to_sexp.should == [
|
329
|
-
[:
|
371
|
+
[:location, 'test.feature', 0],
|
372
|
+
[:feature, "Feature", "Feature Text", "And some more text", 1],
|
330
373
|
[:eof]
|
331
374
|
]
|
332
375
|
end
|
@@ -334,10 +377,11 @@ Given I am a step
|
|
334
377
|
|
335
378
|
describe "A feature with a scenario but no steps" do
|
336
379
|
it "should find the feature and scenario" do
|
337
|
-
|
380
|
+
scan("Feature: Feature Text\nScenario: Reading a Scenario\n")
|
338
381
|
@listener.to_sexp.should == [
|
339
|
-
[:
|
340
|
-
[:
|
382
|
+
[:location, 'test.feature', 0],
|
383
|
+
[:feature, "Feature", "Feature Text", "", 1],
|
384
|
+
[:scenario, "Scenario", "Reading a Scenario", "", 2],
|
341
385
|
[:eof]
|
342
386
|
]
|
343
387
|
end
|
@@ -345,24 +389,26 @@ Given I am a step
|
|
345
389
|
|
346
390
|
describe "A feature with two scenarios" do
|
347
391
|
it "should find the feature and two scenarios" do
|
348
|
-
|
392
|
+
scan("Feature: Feature Text\nScenario: Reading a Scenario\n Given a step\n\nScenario: A second scenario\n Given another step\n")
|
349
393
|
@listener.to_sexp.should == [
|
350
|
-
[:
|
351
|
-
[:
|
394
|
+
[:location, 'test.feature', 0],
|
395
|
+
[:feature, "Feature", "Feature Text", "", 1],
|
396
|
+
[:scenario, "Scenario", "Reading a Scenario", "", 2],
|
352
397
|
[:step, "Given ", "a step", 3],
|
353
|
-
[:scenario, "Scenario", "A second scenario", 5],
|
398
|
+
[:scenario, "Scenario", "A second scenario", "", 5],
|
354
399
|
[:step, "Given ", "another step", 6],
|
355
400
|
[:eof]
|
356
401
|
]
|
357
402
|
end
|
358
403
|
|
359
404
|
it "should find the feature and two scenarios without indentation" do
|
360
|
-
|
405
|
+
scan("Feature: Feature Text\nScenario: Reading a Scenario\nGiven a step\nScenario: A second scenario\nGiven another step\n")
|
361
406
|
@listener.to_sexp.should == [
|
362
|
-
[:
|
363
|
-
[:
|
407
|
+
[:location, 'test.feature', 0],
|
408
|
+
[:feature, "Feature", "Feature Text", "", 1],
|
409
|
+
[:scenario, "Scenario", "Reading a Scenario", "", 2],
|
364
410
|
[:step, "Given ", "a step", 3],
|
365
|
-
[:scenario, "Scenario", "A second scenario", 4],
|
411
|
+
[:scenario, "Scenario", "A second scenario", "", 4],
|
366
412
|
[:step, "Given ", "another step", 5],
|
367
413
|
[:eof]
|
368
414
|
]
|
@@ -373,10 +419,11 @@ Given I am a step
|
|
373
419
|
it "should find the feature, scenarios, steps, and comments in the proper order" do
|
374
420
|
scan_file("simple_with_comments.feature")
|
375
421
|
@listener.to_sexp.should == [
|
422
|
+
[:location, 'simple_with_comments.feature', 0],
|
376
423
|
[:comment, "# Here is a comment", 1],
|
377
|
-
[:feature, "Feature", "Feature Text", 2],
|
424
|
+
[:feature, "Feature", "Feature Text", "", 2],
|
378
425
|
[:comment, "# Here is another # comment", 3],
|
379
|
-
[:scenario, "Scenario", "Reading a Scenario", 4],
|
426
|
+
[:scenario, "Scenario", "Reading a Scenario", "", 4],
|
380
427
|
[:comment, "# Here is a third comment", 5],
|
381
428
|
[:step, "Given ", "there is a step", 6],
|
382
429
|
[:comment, "# Here is a fourth comment", 7],
|
@@ -387,10 +434,11 @@ Given I am a step
|
|
387
434
|
it "should support comments in tables" do
|
388
435
|
scan_file("comments_in_table.feature")
|
389
436
|
@listener.to_sexp.should == [
|
390
|
-
[:
|
391
|
-
[:
|
437
|
+
[:location, 'comments_in_table.feature', 0],
|
438
|
+
[:feature, "Feature", "x", "", 1],
|
439
|
+
[:scenario_outline, "Scenario Outline", "x", "", 3],
|
392
440
|
[:step, "Then ", "x is <state>", 4],
|
393
|
-
[:examples, "Examples", "", 6],
|
441
|
+
[:examples, "Examples", "", "", 6],
|
394
442
|
[:row, ["state"], 7],
|
395
443
|
[:comment, "# comment", 8],
|
396
444
|
[:row, ["1"], 9],
|
@@ -403,18 +451,19 @@ Given I am a step
|
|
403
451
|
it "should find the feature, scenario, step, and tags in the proper order" do
|
404
452
|
scan_file("simple_with_tags.feature")
|
405
453
|
@listener.to_sexp.should == [
|
454
|
+
[:location, 'simple_with_tags.feature', 0],
|
406
455
|
[:comment, "# FC", 1],
|
407
456
|
[:tag, "@ft",2],
|
408
|
-
[:feature, "Feature", "hi", 3],
|
457
|
+
[:feature, "Feature", "hi", "", 3],
|
409
458
|
[:tag, "@st1", 5],
|
410
459
|
[:tag, "@st2", 5],
|
411
|
-
[:scenario, "Scenario", "First", 6],
|
460
|
+
[:scenario, "Scenario", "First", "", 6],
|
412
461
|
[:step, "Given ", "Pepper", 7],
|
413
462
|
[:tag, "@st3", 9],
|
414
463
|
[:tag, "@st4", 10],
|
415
464
|
[:tag, "@ST5", 10],
|
416
465
|
[:tag, "@#^%&ST6**!", 10],
|
417
|
-
[:scenario, "Scenario", "Second", 11],
|
466
|
+
[:scenario, "Scenario", "Second", "", 11],
|
418
467
|
[:eof]
|
419
468
|
]
|
420
469
|
end
|
@@ -424,11 +473,12 @@ Given I am a step
|
|
424
473
|
it "should lex this feature properly" do
|
425
474
|
scan_file("1.feature")
|
426
475
|
@listener.to_sexp.should == [
|
427
|
-
[:
|
476
|
+
[:location, '1.feature', 0],
|
477
|
+
[:feature, "Feature", "Logging in", "So that I can be myself", 1],
|
428
478
|
[:comment, "# Comment", 3],
|
429
|
-
[:scenario, "Scenario", "Anonymous user can get a login form
|
479
|
+
[:scenario, "Scenario", "Anonymous user can get a login form.", "Scenery here", 4],
|
430
480
|
[:tag, "@tag", 7],
|
431
|
-
[:scenario, "Scenario", "Another one", 8],
|
481
|
+
[:scenario, "Scenario", "Another one", "", 8],
|
432
482
|
[:eof]
|
433
483
|
]
|
434
484
|
end
|
@@ -438,23 +488,24 @@ Given I am a step
|
|
438
488
|
it "should find things in the right order" do
|
439
489
|
scan_file("complex.feature")
|
440
490
|
@listener.to_sexp.should == [
|
491
|
+
[:location, 'complex.feature', 0],
|
441
492
|
[:comment, "#Comment on line 1", 1],
|
442
493
|
[:comment, "#Comment on line 2", 2],
|
443
494
|
[:tag, "@tag1", 3],
|
444
495
|
[:tag, "@tag2", 3],
|
445
|
-
[:feature, "Feature", "Feature Text
|
496
|
+
[:feature, "Feature", "Feature Text", "In order to test multiline forms\nAs a ragel writer\nI need to check for complex combinations", 4],
|
446
497
|
[:comment, "#Comment on line 9", 9],
|
447
498
|
[:comment, "#Comment on line 11", 11],
|
448
|
-
[:background, "Background", "", 13],
|
499
|
+
[:background, "Background", "", "", 13],
|
449
500
|
[:step, "Given ", "this is a background step", 14],
|
450
501
|
[:step, "And ", "this is another one", 15],
|
451
502
|
[:tag, "@tag3", 17],
|
452
503
|
[:tag, "@tag4", 17],
|
453
|
-
[:scenario, "Scenario", "Reading a Scenario", 18],
|
504
|
+
[:scenario, "Scenario", "Reading a Scenario", "", 18],
|
454
505
|
[:step, "Given ", "there is a step", 19],
|
455
506
|
[:step, "But ", "not another step", 20],
|
456
507
|
[:tag, "@tag3", 22],
|
457
|
-
[:scenario, "Scenario", "Reading a second scenario
|
508
|
+
[:scenario, "Scenario", "Reading a second scenario", "With two lines of text", 23],
|
458
509
|
[:comment, "#Comment on line 24", 25],
|
459
510
|
[:step, "Given ", "a third step with a table", 26],
|
460
511
|
[:row, %w{a b}, 27],
|
@@ -468,7 +519,7 @@ Given I am a step
|
|
468
519
|
[:step, "And ", "I am done testing these tables", 35],
|
469
520
|
[:comment, "#Comment on line 29", 36],
|
470
521
|
[:step, "Then ", "I am happy", 37],
|
471
|
-
[:scenario, "Scenario", "Hammerzeit", 39],
|
522
|
+
[:scenario, "Scenario", "Hammerzeit", "", 39],
|
472
523
|
[:step, "Given ", "All work and no play", 40],
|
473
524
|
[:py_string, "Makes Homer something something\nAnd something else", 41 ],
|
474
525
|
[:step, "Then ", "crazy", 45],
|
@@ -481,23 +532,24 @@ Given I am a step
|
|
481
532
|
it "should find things in the right order for CRLF features" do
|
482
533
|
scan_file("dos_line_endings.feature")
|
483
534
|
@listener.to_sexp.should == [
|
535
|
+
[:location, 'dos_line_endings.feature', 0],
|
484
536
|
[:comment, "#Comment on line 1", 1],
|
485
537
|
[:comment, "#Comment on line 2", 2],
|
486
538
|
[:tag, "@tag1", 3],
|
487
539
|
[:tag, "@tag2", 3],
|
488
|
-
[:feature, "Feature", "Feature Text
|
540
|
+
[:feature, "Feature", "Feature Text", "In order to test multiline forms\r\nAs a ragel writer\r\nI need to check for complex combinations", 4],
|
489
541
|
[:comment, "#Comment on line 9", 9],
|
490
542
|
[:comment, "#Comment on line 11", 11],
|
491
|
-
[:background, "Background", "", 13],
|
543
|
+
[:background, "Background", "", "", 13],
|
492
544
|
[:step, "Given ", "this is a background step", 14],
|
493
545
|
[:step, "And ", "this is another one", 15],
|
494
546
|
[:tag, "@tag3", 17],
|
495
547
|
[:tag, "@tag4", 17],
|
496
|
-
[:scenario, "Scenario", "Reading a Scenario", 18],
|
548
|
+
[:scenario, "Scenario", "Reading a Scenario", "", 18],
|
497
549
|
[:step, "Given ", "there is a step", 19],
|
498
550
|
[:step, "But ", "not another step", 20],
|
499
551
|
[:tag, "@tag3", 22],
|
500
|
-
[:scenario, "Scenario", "Reading a second scenario
|
552
|
+
[:scenario, "Scenario", "Reading a second scenario", "With two lines of text", 23],
|
501
553
|
[:comment, "#Comment on line 24", 25],
|
502
554
|
[:step, "Given ", "a third step with a table", 26],
|
503
555
|
[:row, %w{a b}, 27],
|
@@ -511,7 +563,7 @@ Given I am a step
|
|
511
563
|
[:step, "And ", "I am done testing these tables", 35],
|
512
564
|
[:comment, "#Comment on line 29", 36],
|
513
565
|
[:step, "Then ", "I am happy", 37],
|
514
|
-
[:scenario, "Scenario", "Hammerzeit", 39],
|
566
|
+
[:scenario, "Scenario", "Hammerzeit", "", 39],
|
515
567
|
[:step, "Given ", "All work and no play", 40],
|
516
568
|
[:py_string, "Makes Homer something something\r\nAnd something else", 41],
|
517
569
|
[:step, "Then ", "crazy", 45],
|
@@ -522,8 +574,9 @@ Given I am a step
|
|
522
574
|
it "should cope with the retarded BOM that many Windows editors insert at the beginning of a file" do
|
523
575
|
scan_file("with_bom.feature")
|
524
576
|
@listener.to_sexp.should == [
|
525
|
-
[:
|
526
|
-
[:
|
577
|
+
[:location, 'with_bom.feature', 0],
|
578
|
+
[:feature, "Feature", "Feature Text", "", 1],
|
579
|
+
[:scenario, "Scenario", "Reading a Scenario", "", 2],
|
527
580
|
[:step, "Given ", "there is a step", 3],
|
528
581
|
[:eof]
|
529
582
|
]
|
@@ -535,15 +588,32 @@ Given I am a step
|
|
535
588
|
["Some text\nFeature: Hi",
|
536
589
|
"Feature: Hi\nBackground:\nGiven something\nScenario A scenario",
|
537
590
|
"Scenario: My scenario\nGiven foo\nAand bar\nScenario: another one\nGiven blah"].each do |text|
|
538
|
-
lambda {
|
591
|
+
lambda { scan(text) }.should raise_error(/Lexing error on line/)
|
539
592
|
end
|
540
593
|
end
|
541
594
|
|
542
595
|
it "should include the line number and context of the error" do
|
543
596
|
lambda {
|
544
|
-
|
597
|
+
scan("Feature: hello\nScenario: My scenario\nGiven foo\nAand blah\nHmmm wrong\nThen something something")
|
545
598
|
}.should raise_error(/Lexing error on line 4/)
|
546
599
|
end
|
600
|
+
|
601
|
+
it "Feature keyword should terminate narratives for multiline capable tokens" do
|
602
|
+
scan("Feature:\nBackground:\nFeature:\nScenario Outline:\nFeature:\nScenario:\nFeature:\nExamples:\nFeature:\n")
|
603
|
+
@listener.to_sexp.should == [
|
604
|
+
[:location, 'test.feature', 0],
|
605
|
+
[:feature, "Feature", "", "", 1],
|
606
|
+
[:background, "Background", "", "", 2],
|
607
|
+
[:feature, "Feature", "", "", 3],
|
608
|
+
[:scenario_outline, "Scenario Outline", "", "", 4],
|
609
|
+
[:feature, "Feature", "", "", 5],
|
610
|
+
[:scenario, "Scenario", "", "", 6],
|
611
|
+
[:feature, "Feature", "", "", 7],
|
612
|
+
[:examples, "Examples", "","", 8],
|
613
|
+
[:feature, "Feature", "", "", 9],
|
614
|
+
[:eof]
|
615
|
+
]
|
616
|
+
end
|
547
617
|
end
|
548
618
|
end
|
549
619
|
end
|