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