gherkin 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitattributes +1 -0
- data/History.txt +18 -0
- data/README.rdoc +4 -1
- data/Rakefile +4 -2
- data/VERSION.yml +1 -1
- data/bin/gherkin +1 -1
- data/dotnet/.gitignore +13 -0
- data/features/feature_parser.feature +22 -2
- data/features/native_lexer.feature +1 -1
- data/features/parser_with_native_lexer.feature +1 -1
- data/features/step_definitions/gherkin_steps.rb +2 -6
- data/features/step_definitions/pretty_printer_steps.rb +2 -3
- data/features/steps_parser.feature +1 -1
- data/gherkin.gemspec +53 -24
- data/java/Gherkin.iml +2 -4
- data/java/build.xml +3 -0
- data/java/src/gherkin/FixJava.java +6 -3
- data/java/src/gherkin/I18nLexer.java +48 -0
- data/java/src/gherkin/Listener.java +3 -1
- data/java/src/gherkin/Main.java +17 -0
- data/java/src/gherkin/Parser.java +9 -3
- data/java/src/gherkin/formatter/Argument.java +39 -0
- data/java/src/gherkin/formatter/ArgumentFormat.java +17 -0
- data/java/src/gherkin/formatter/Colors.java +7 -0
- data/java/src/gherkin/formatter/Formatter.java +15 -0
- data/java/src/gherkin/formatter/PrettyFormatter.java +219 -0
- data/java/src/gherkin/parser/StateMachineReader.java +8 -3
- data/java/test/gherkin/formatter/ArgumentTest.java +17 -0
- data/lib/gherkin/csharp_lexer.rb +15 -0
- data/lib/gherkin/format/argument.rb +35 -0
- data/lib/gherkin/format/monochrome_format.rb +9 -0
- data/lib/gherkin/i18n.rb +22 -0
- data/lib/gherkin/i18n.yml +34 -20
- data/lib/gherkin/i18n_lexer.rb +57 -13
- data/lib/gherkin/lexer.rb +9 -18
- data/lib/gherkin/parser.rb +3 -3
- data/lib/gherkin/parser/meta.txt +5 -4
- data/lib/gherkin/parser/root.txt +11 -9
- data/lib/gherkin/parser/steps.txt +4 -3
- data/lib/gherkin/rb_parser.rb +13 -5
- data/lib/gherkin/tools/colors.rb +119 -0
- data/lib/gherkin/tools/files.rb +6 -1
- data/lib/gherkin/tools/pretty_listener.rb +115 -23
- data/ragel/lexer.c.rl.erb +67 -51
- data/ragel/lexer.csharp.rl.erb +240 -0
- data/ragel/lexer.java.rl.erb +27 -18
- data/ragel/lexer.rb.rl.erb +17 -17
- data/ragel/lexer_common.rl.erb +8 -8
- data/spec/gherkin/c_lexer_spec.rb +4 -4
- data/spec/gherkin/csharp_lexer_spec.rb +20 -0
- data/spec/gherkin/fixtures/comments_in_table.feature +9 -0
- data/spec/gherkin/fixtures/complex.feature +2 -0
- data/spec/gherkin/fixtures/dos_line_endings.feature +45 -0
- data/spec/gherkin/fixtures/i18n_fr.feature +1 -0
- data/spec/gherkin/fixtures/i18n_no.feature +1 -0
- data/spec/gherkin/fixtures/i18n_zh-CN.feature +1 -0
- data/spec/gherkin/format/argument_spec.rb +28 -0
- data/spec/gherkin/i18n_lexer_spec.rb +4 -4
- data/spec/gherkin/i18n_spec.rb +31 -23
- data/spec/gherkin/java_lexer_spec.rb +4 -3
- data/spec/gherkin/parser_spec.rb +5 -0
- data/spec/gherkin/rb_lexer_spec.rb +4 -2
- data/spec/gherkin/sexp_recorder.rb +1 -1
- data/spec/gherkin/shared/lexer_spec.rb +169 -60
- data/spec/gherkin/shared/py_string_spec.rb +6 -0
- data/spec/gherkin/shared/row_spec.rb +107 -0
- data/spec/gherkin/shared/tags_spec.rb +1 -1
- data/spec/gherkin/tools/colors_spec.rb +19 -0
- data/spec/gherkin/tools/pretty_listener_spec.rb +147 -0
- data/spec/spec_helper.rb +31 -7
- data/tasks/compile.rake +81 -7
- data/tasks/ragel_task.rb +6 -4
- data/tasks/rspec.rake +2 -2
- metadata +104 -41
- data/lib/gherkin/java_lexer.rb +0 -10
- data/spec/gherkin/shared/table_spec.rb +0 -97
@@ -0,0 +1,20 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
if defined?(RUBY_ENGINE) && RUBY_ENGINE == "ironruby"
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
4
|
+
|
5
|
+
module Gherkin
|
6
|
+
module Lexer
|
7
|
+
describe "C# Lexer" do
|
8
|
+
before do
|
9
|
+
@listener = Gherkin::SexpRecorder.new
|
10
|
+
@lexer = Gherkin::Lexer.csharp['en'].new(@listener)
|
11
|
+
end
|
12
|
+
|
13
|
+
it_should_behave_like "a Gherkin lexer"
|
14
|
+
it_should_behave_like "a Gherkin lexer lexing tags"
|
15
|
+
it_should_behave_like "a Gherkin lexer lexing py_strings"
|
16
|
+
it_should_behave_like "a Gherkin lexer lexing rows"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -21,6 +21,7 @@ Feature: Feature Text
|
|
21
21
|
|
22
22
|
@tag3
|
23
23
|
Scenario: Reading a second scenario
|
24
|
+
With two lines of text
|
24
25
|
#Comment on line 24
|
25
26
|
Given a third step with a table
|
26
27
|
|a|b|
|
@@ -39,5 +40,6 @@ Feature: Feature Text
|
|
39
40
|
Given All work and no play
|
40
41
|
"""
|
41
42
|
Makes Homer something something
|
43
|
+
And something else
|
42
44
|
"""
|
43
45
|
Then crazy
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#Comment on line 1
|
2
|
+
#Comment on line 2
|
3
|
+
@tag1 @tag2
|
4
|
+
Feature: Feature Text
|
5
|
+
In order to test multiline forms
|
6
|
+
As a ragel writer
|
7
|
+
I need to check for complex combinations
|
8
|
+
|
9
|
+
#Comment on line 9
|
10
|
+
|
11
|
+
#Comment on line 11
|
12
|
+
|
13
|
+
Background:
|
14
|
+
Given this is a background step
|
15
|
+
And this is another one
|
16
|
+
|
17
|
+
@tag3 @tag4
|
18
|
+
Scenario: Reading a Scenario
|
19
|
+
Given there is a step
|
20
|
+
But not another step
|
21
|
+
|
22
|
+
@tag3
|
23
|
+
Scenario: Reading a second scenario
|
24
|
+
With two lines of text
|
25
|
+
#Comment on line 24
|
26
|
+
Given a third step with a table
|
27
|
+
|a|b|
|
28
|
+
|c|d|
|
29
|
+
|e|f|
|
30
|
+
And I am still testing things
|
31
|
+
|g|h|
|
32
|
+
|e|r|
|
33
|
+
|k|i|
|
34
|
+
|n||
|
35
|
+
And I am done testing these tables
|
36
|
+
#Comment on line 29
|
37
|
+
Then I am happy
|
38
|
+
|
39
|
+
Scenario: Hammerzeit
|
40
|
+
Given All work and no play
|
41
|
+
"""
|
42
|
+
Makes Homer something something
|
43
|
+
And something else
|
44
|
+
"""
|
45
|
+
Then crazy
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
3
|
+
require 'gherkin/format/argument'
|
4
|
+
|
5
|
+
module Gherkin
|
6
|
+
module Format
|
7
|
+
class BracketFormat
|
8
|
+
class << self
|
9
|
+
def new
|
10
|
+
defined?(JRUBY_VERSION) ? ::Java::GherkinFormatter::ArgumentFormat.new("[", "]") : super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def format_argument(s)
|
15
|
+
"[#{s}]"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe Argument do
|
20
|
+
it "should replace one arg" do
|
21
|
+
argument_class = defined?(JRUBY_VERSION) ? ::Java::GherkinFormatter::Argument : Argument
|
22
|
+
argument_class.format("I have 10 cukes", BracketFormat.new, [Argument.new(7, '10')]).should == "I have [10] cukes"
|
23
|
+
end
|
24
|
+
|
25
|
+
# TODO: Add this spec: http://github.com/alg/cucumber/commit/33188e9db51f59ced74c4861524d7b2e69454630
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -4,19 +4,19 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
4
4
|
module Gherkin
|
5
5
|
describe I18nLexer do
|
6
6
|
before do
|
7
|
-
@lexer = I18nLexer.new(SexpRecorder.new)
|
7
|
+
@lexer = I18nLexer.new(SexpRecorder.new, false)
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should store the i18n language of the last scanned feature" do
|
11
11
|
@lexer.scan("# language: fr\n")
|
12
|
-
@lexer.
|
12
|
+
@lexer.i18n_language.should == "fr"
|
13
13
|
@lexer.scan("# language: no\n")
|
14
|
-
@lexer.
|
14
|
+
@lexer.i18n_language.should == "no"
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should use English i18n by default" do
|
18
18
|
@lexer.scan("Feature: foo\n")
|
19
|
-
@lexer.
|
19
|
+
@lexer.i18n_language.should == "en"
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
data/spec/gherkin/i18n_spec.rb
CHANGED
@@ -13,43 +13,51 @@ module Gherkin
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should recognize keywords in the language of the lexer" do
|
16
|
-
lexer = Gherkin::
|
16
|
+
lexer = Gherkin::I18nLexer.new(@listener, false)
|
17
17
|
scan_file(lexer, "i18n_no.feature")
|
18
18
|
@listener.to_sexp.should == [
|
19
|
-
[:
|
20
|
-
[:
|
21
|
-
[:
|
22
|
-
[:step, "
|
23
|
-
[:step, "
|
19
|
+
[:comment, "#language:no", 1],
|
20
|
+
[:feature, "Egenskap", "i18n support", 2],
|
21
|
+
[:scenario, "Scenario", "Parsing many languages", 4],
|
22
|
+
[:step, "Gitt ", "Gherkin supports many languages", 5],
|
23
|
+
[:step, "Når ", "Norwegian keywords are parsed", 6],
|
24
|
+
[:step, "Så ", "they should be recognized", 7],
|
25
|
+
[:eof]
|
24
26
|
]
|
25
27
|
end
|
26
28
|
|
27
29
|
it "should parse languages without a space after keywords" do
|
28
|
-
lexer = Gherkin::
|
30
|
+
lexer = Gherkin::I18nLexer.new(@listener, false)
|
29
31
|
scan_file(lexer, "i18n_zh-CN.feature")
|
30
32
|
@listener.to_sexp.should == [
|
31
|
-
[:
|
32
|
-
[:
|
33
|
-
[:
|
34
|
-
[:step, "
|
35
|
-
[:step, "
|
36
|
-
[:step, "
|
33
|
+
[:comment, "#language:zh-CN", 1],
|
34
|
+
[:feature, "功能", "加法", 2],
|
35
|
+
[:scenario, "场景", "两个数相加", 4],
|
36
|
+
[:step, "假如", "我已经在计算器里输入6", 5],
|
37
|
+
[:step, "而且", "我已经在计算器里输入7", 6],
|
38
|
+
[:step, "当", "我按相加按钮", 7],
|
39
|
+
[:step, "那么", "我应该在屏幕上看到的结果是13", 8],
|
40
|
+
[:eof]
|
37
41
|
]
|
38
42
|
end
|
39
43
|
|
40
44
|
it "should parse languages with spaces after some keywords but not others" do
|
41
|
-
lexer = Gherkin::
|
45
|
+
lexer = Gherkin::I18nLexer.new(@listener, false)
|
42
46
|
scan_file(lexer, "i18n_fr.feature")
|
43
47
|
@listener.to_sexp.should == [
|
44
|
-
[:
|
45
|
-
[:
|
46
|
-
[:
|
47
|
-
[:step, "
|
48
|
-
[:step, "
|
49
|
-
[:step, "
|
50
|
-
[:step, "
|
51
|
-
[:
|
52
|
-
[:
|
48
|
+
[:comment, "#language:fr", 1],
|
49
|
+
[:feature, "Fonctionnalité", "Addition", 2],
|
50
|
+
[:scenario_outline, "Plan du scénario", "Addition de produits dérivés", 3],
|
51
|
+
[:step, "Soit ", "une calculatrice", 4],
|
52
|
+
[:step, "Etant donné ", "qu'on tape <a>", 5],
|
53
|
+
[:step, "Et ", "qu'on tape <b>", 6],
|
54
|
+
[:step, "Lorsqu'", "on tape additionner", 7],
|
55
|
+
[:step, "Alors ", "le résultat doit être <somme>", 8],
|
56
|
+
[:examples, "Exemples", "", 10],
|
57
|
+
[:row, %w{a b somme}, 11],
|
58
|
+
[:row, %w{2 2 4}, 12],
|
59
|
+
[:row, %w{2 3 5}, 13],
|
60
|
+
[:eof]
|
53
61
|
]
|
54
62
|
end
|
55
63
|
end
|
@@ -1,20 +1,21 @@
|
|
1
1
|
#encoding: utf-8
|
2
2
|
if defined?(JRUBY_VERSION)
|
3
3
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
4
|
+
require 'gherkin.jar'
|
4
5
|
|
5
6
|
module Gherkin
|
6
7
|
module JavaLexer
|
7
8
|
describe "Java Lexer" do
|
8
9
|
before do
|
9
10
|
@listener = Gherkin::SexpRecorder.new
|
10
|
-
@lexer = Gherkin::
|
11
|
+
@lexer = Java::Gherkin::I18nLexer.new(@listener)
|
11
12
|
end
|
12
13
|
|
13
14
|
it_should_behave_like "a Gherkin lexer"
|
14
15
|
it_should_behave_like "a Gherkin lexer lexing tags"
|
15
16
|
it_should_behave_like "a Gherkin lexer lexing py_strings"
|
16
|
-
it_should_behave_like "a Gherkin lexer lexing
|
17
|
+
it_should_behave_like "a Gherkin lexer lexing rows"
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
20
|
-
end
|
21
|
+
end
|
data/spec/gherkin/parser_spec.rb
CHANGED
@@ -19,6 +19,11 @@ module Gherkin
|
|
19
19
|
}.should raise_error(/Parse error on line 12\. Found scenario when expecting one of: comment, feature, tag\. \(Current state: root\)\.$/)
|
20
20
|
end
|
21
21
|
|
22
|
+
it "should allow empty files" do
|
23
|
+
@listener.should_receive(:eof)
|
24
|
+
@parser.eof
|
25
|
+
end
|
26
|
+
|
22
27
|
it "should delegate an error message when raise on error is false" do
|
23
28
|
@listener.should_receive(:syntax_error).with(sym(:root), sym(:background), a([:comment, :feature, :tag]), 1)
|
24
29
|
@parser = Parser.new(@listener, false)
|
@@ -1,18 +1,20 @@
|
|
1
1
|
#encoding: utf-8
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
3
|
+
require 'gherkin/rb_lexer'
|
4
|
+
require 'gherkin/rb_lexer/en'
|
3
5
|
|
4
6
|
module Gherkin
|
5
7
|
module Lexer
|
6
8
|
describe "Ruby Lexer" do
|
7
9
|
before do
|
8
10
|
@listener = Gherkin::SexpRecorder.new
|
9
|
-
@lexer = Gherkin::
|
11
|
+
@lexer = Gherkin::RbLexer::En.new(@listener)
|
10
12
|
end
|
11
13
|
|
12
14
|
it_should_behave_like "a Gherkin lexer"
|
13
15
|
it_should_behave_like "a Gherkin lexer lexing tags"
|
14
16
|
it_should_behave_like "a Gherkin lexer lexing py_strings"
|
15
|
-
it_should_behave_like "a Gherkin lexer lexing
|
17
|
+
it_should_behave_like "a Gherkin lexer lexing rows"
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
@@ -8,14 +8,18 @@ module Gherkin
|
|
8
8
|
describe "Comments" do
|
9
9
|
it "should parse a one line comment" do
|
10
10
|
@lexer.scan("# My comment\n")
|
11
|
-
@listener.to_sexp.should == [
|
11
|
+
@listener.to_sexp.should == [
|
12
|
+
[:comment, "# My comment", 1],
|
13
|
+
[:eof]
|
14
|
+
]
|
12
15
|
end
|
13
16
|
|
14
17
|
it "should parse a multiline comment" do
|
15
18
|
@lexer.scan("# Hello\n\n# World\n")
|
16
19
|
@listener.to_sexp.should == [
|
17
20
|
[:comment, "# Hello", 1],
|
18
|
-
[:comment, "# World", 3]
|
21
|
+
[:comment, "# World", 3],
|
22
|
+
[:eof]
|
19
23
|
]
|
20
24
|
end
|
21
25
|
|
@@ -24,7 +28,8 @@ module Gherkin
|
|
24
28
|
@listener.to_sexp.should == [
|
25
29
|
[:scenario, "Scenario", "test", 1],
|
26
30
|
[:comment, "#hello", 2],
|
27
|
-
[:scenario, "Scenario", "another", 3]
|
31
|
+
[:scenario, "Scenario", "another", 3],
|
32
|
+
[:eof]
|
28
33
|
]
|
29
34
|
end
|
30
35
|
|
@@ -33,7 +38,8 @@ module Gherkin
|
|
33
38
|
@listener.to_sexp.should == [
|
34
39
|
[:comment, "#", 1],
|
35
40
|
[:comment, "# A comment", 2],
|
36
|
-
[:comment, "#", 3]
|
41
|
+
[:comment, "#", 3],
|
42
|
+
[:eof]
|
37
43
|
]
|
38
44
|
end
|
39
45
|
|
@@ -51,7 +57,8 @@ module Gherkin
|
|
51
57
|
[:feature, "Feature", "hi", 1],
|
52
58
|
[:scenario, "Scenario", "test", 2],
|
53
59
|
[:tag, "hello", 4],
|
54
|
-
[:scenario, "Scenario", "another", 5]
|
60
|
+
[:scenario, "Scenario", "another", 5],
|
61
|
+
[:eof]
|
55
62
|
]
|
56
63
|
end
|
57
64
|
end
|
@@ -61,14 +68,16 @@ module Gherkin
|
|
61
68
|
@lexer.scan("Background:\nGiven I am a step\n")
|
62
69
|
@listener.to_sexp.should == [
|
63
70
|
[:background, "Background", "", 1],
|
64
|
-
[:step, "Given", "I am a step", 2]
|
71
|
+
[:step, "Given ", "I am a step", 2],
|
72
|
+
[:eof]
|
65
73
|
]
|
66
74
|
end
|
67
75
|
|
68
76
|
it "should allow multiline names ending at eof" do
|
69
77
|
@lexer.scan("Background: I have several\n Lines to look at\n None starting with Given")
|
70
78
|
@listener.to_sexp.should == [
|
71
|
-
[:background, "Background", "I have several\nLines to look at\nNone starting with Given", 1]
|
79
|
+
[:background, "Background", "I have several\nLines to look at\nNone starting with Given", 1],
|
80
|
+
[:eof]
|
72
81
|
]
|
73
82
|
end
|
74
83
|
|
@@ -82,7 +91,8 @@ Given I am a step})
|
|
82
91
|
@listener.to_sexp.should == [
|
83
92
|
[:feature, "Feature", "Hi", 1],
|
84
93
|
[:background, "Background", "It is my ambition to say\nin ten sentences\nwhat others say\nin a whole book.",2],
|
85
|
-
[:step, "Given", "I am a step", 6]
|
94
|
+
[:step, "Given ", "I am a step", 6],
|
95
|
+
[:eof]
|
86
96
|
]
|
87
97
|
end
|
88
98
|
end
|
@@ -91,7 +101,8 @@ Given I am a step})
|
|
91
101
|
it "should be parsed" do
|
92
102
|
@lexer.scan("Scenario: Hello\n")
|
93
103
|
@listener.to_sexp.should == [
|
94
|
-
[:scenario, "Scenario", "Hello", 1]
|
104
|
+
[:scenario, "Scenario", "Hello", 1],
|
105
|
+
[:eof]
|
95
106
|
]
|
96
107
|
end
|
97
108
|
|
@@ -102,7 +113,8 @@ Given I am a step})
|
|
102
113
|
})
|
103
114
|
@listener.to_sexp.should == [
|
104
115
|
[:scenario, "Scenario", "bar", 1],
|
105
|
-
[:step, "Given", "baz", 3]
|
116
|
+
[:step, "Given ", "baz", 3],
|
117
|
+
[:eof]
|
106
118
|
]
|
107
119
|
end
|
108
120
|
|
@@ -115,14 +127,16 @@ Given I am a step})
|
|
115
127
|
})
|
116
128
|
@listener.to_sexp.should == [
|
117
129
|
[:scenario, "Scenario", "It is my ambition to say\nin ten sentences\nwhat others say\nin a whole book.", 1],
|
118
|
-
[:step, "Given", "I am a step", 5]
|
130
|
+
[:step, "Given ", "I am a step", 5],
|
131
|
+
[:eof]
|
119
132
|
]
|
120
133
|
end
|
121
134
|
|
122
135
|
it "should allow multiline names ending at eof" do
|
123
136
|
@lexer.scan("Scenario: I have several\n Lines to look at\n None starting with Given")
|
124
137
|
@listener.to_sexp.should == [
|
125
|
-
[:scenario, "Scenario", "I have several\nLines to look at\nNone starting with Given", 1]
|
138
|
+
[:scenario, "Scenario", "I have several\nLines to look at\nNone starting with Given", 1],
|
139
|
+
[:eof]
|
126
140
|
]
|
127
141
|
end
|
128
142
|
|
@@ -134,8 +148,9 @@ Given I am a step})
|
|
134
148
|
})
|
135
149
|
@listener.to_sexp.should == [
|
136
150
|
[:scenario, "Scenario", "I have a Button\nButtons are great", 1],
|
137
|
-
[:step, "Given", "I have some", 3],
|
138
|
-
[:step, "But", "I might not because I am a Charles Dickens character", 4]
|
151
|
+
[:step, "Given ", "I have some", 3],
|
152
|
+
[:step, "But ", "I might not because I am a Charles Dickens character", 4],
|
153
|
+
[:eof]
|
139
154
|
]
|
140
155
|
end
|
141
156
|
|
@@ -146,7 +161,8 @@ Given I am a step
|
|
146
161
|
})
|
147
162
|
@listener.to_sexp.should == [
|
148
163
|
[:scenario, "Scenario", "When I have when in scenario\nI should be fine", 1],
|
149
|
-
[:step, "Given", "I am a step", 3]
|
164
|
+
[:step, "Given ", "I am a step", 3],
|
165
|
+
[:eof]
|
150
166
|
]
|
151
167
|
end
|
152
168
|
end
|
@@ -161,9 +177,11 @@ Given I am a step
|
|
161
177
|
})
|
162
178
|
@listener.to_sexp.should == [
|
163
179
|
[:scenario_outline, "Scenario Outline", "Hello", 1],
|
164
|
-
[:step, "Given", "a <what> cucumber", 2],
|
180
|
+
[:step, "Given ", "a <what> cucumber", 2],
|
165
181
|
[:examples, "Examples", "", 3],
|
166
|
-
[:
|
182
|
+
[:row, ["what"], 4],
|
183
|
+
[:row, ["green"], 5],
|
184
|
+
[:eof]
|
167
185
|
]
|
168
186
|
end
|
169
187
|
|
@@ -174,7 +192,8 @@ Given I am a step
|
|
174
192
|
})
|
175
193
|
@listener.to_sexp.should == [
|
176
194
|
[:scenario_outline, "Scenario Outline", "Hello", 1],
|
177
|
-
[:scenario, "Scenario", "My Scenario", 3]
|
195
|
+
[:scenario, "Scenario", "My Scenario", 3],
|
196
|
+
[:eof]
|
178
197
|
]
|
179
198
|
end
|
180
199
|
|
@@ -188,7 +207,8 @@ Given I am a step
|
|
188
207
|
})
|
189
208
|
@listener.to_sexp.should == [
|
190
209
|
[:scenario_outline, "Scenario Outline", "It is my ambition to say\nin ten sentences\nwhat others say\nin a whole book.", 1],
|
191
|
-
[:step, "Given", "I am a step", 5]
|
210
|
+
[:step, "Given ", "I am a step", 5],
|
211
|
+
[:eof]
|
192
212
|
]
|
193
213
|
end
|
194
214
|
end
|
@@ -201,7 +221,9 @@ Given I am a step
|
|
201
221
|
})
|
202
222
|
@listener.to_sexp.should == [
|
203
223
|
[:examples, "Examples", "", 1],
|
204
|
-
[:
|
224
|
+
[:row, ["x","y"], 2],
|
225
|
+
[:row, ["5","6"], 3],
|
226
|
+
[:eof]
|
205
227
|
]
|
206
228
|
end
|
207
229
|
|
@@ -214,7 +236,9 @@ Given I am a step
|
|
214
236
|
})
|
215
237
|
@listener.to_sexp.should == [
|
216
238
|
[:examples, "Examples", "I'm a multiline name\nand I'm ok\nf'real", 1],
|
217
|
-
[:
|
239
|
+
[:row, ["x"], 4],
|
240
|
+
[:row, ["5"], 5],
|
241
|
+
[:eof]
|
218
242
|
]
|
219
243
|
end
|
220
244
|
end
|
@@ -225,16 +249,18 @@ Given I am a step
|
|
225
249
|
|a|b|
|
226
250
|
})
|
227
251
|
@listener.to_sexp.should == [
|
228
|
-
[:step, "Given", "I have a table", 1],
|
229
|
-
[:
|
252
|
+
[:step, "Given ", "I have a table", 1],
|
253
|
+
[:row, ['a','b'], 2],
|
254
|
+
[:eof]
|
230
255
|
]
|
231
256
|
end
|
232
257
|
|
233
258
|
it "should parse steps with inline py_string" do
|
234
259
|
@lexer.scan("Given I have a string\n\"\"\"\nhello\nworld\n\"\"\"")
|
235
260
|
@listener.to_sexp.should == [
|
236
|
-
[:step, "Given", "I have a string", 1],
|
237
|
-
[:py_string, "hello\nworld", 2]
|
261
|
+
[:step, "Given ", "I have a string", 1],
|
262
|
+
[:py_string, "hello\nworld", 2],
|
263
|
+
[:eof]
|
238
264
|
]
|
239
265
|
end
|
240
266
|
end
|
@@ -245,7 +271,8 @@ Given I am a step
|
|
245
271
|
@listener.to_sexp.should == [
|
246
272
|
[:feature, "Feature", "Feature Text", 1],
|
247
273
|
[:scenario, "Scenario", "Reading a Scenario", 2],
|
248
|
-
[:step, "Given", "there is a step", 3]
|
274
|
+
[:step, "Given ", "there is a step", 3],
|
275
|
+
[:eof]
|
249
276
|
]
|
250
277
|
end
|
251
278
|
end
|
@@ -256,7 +283,8 @@ Given I am a step
|
|
256
283
|
@listener.to_sexp.should == [
|
257
284
|
[:feature, "Feature", "Feature Text", 1],
|
258
285
|
[:scenario, "Scenario", "Reading a Scenario", 2],
|
259
|
-
[:step, "Given", "there is a step", 3]
|
286
|
+
[:step, "Given ", "there is a step", 3],
|
287
|
+
[:eof]
|
260
288
|
]
|
261
289
|
end
|
262
290
|
end
|
@@ -268,9 +296,10 @@ Given I am a step
|
|
268
296
|
@listener.to_sexp.should == [
|
269
297
|
[:feature, "Feature", "Feature Text", 1],
|
270
298
|
[:scenario, "Scenario", "Reading a Scenario", 2],
|
271
|
-
[:step, "Given", "there is a step", 3],
|
272
|
-
[:step, "And", "another step", 4],
|
273
|
-
[:step, "And", "a third step", 5]
|
299
|
+
[:step, "Given ", "there is a step", 3],
|
300
|
+
[:step, "And ", "another step", 4],
|
301
|
+
[:step, "And ", "a third step", 5],
|
302
|
+
[:eof]
|
274
303
|
]
|
275
304
|
end
|
276
305
|
end
|
@@ -278,19 +307,28 @@ Given I am a step
|
|
278
307
|
describe "A single feature with no scenario" do
|
279
308
|
it "should find the feature" do
|
280
309
|
@lexer.scan("Feature: Feature Text\n")
|
281
|
-
@listener.to_sexp.should == [
|
310
|
+
@listener.to_sexp.should == [
|
311
|
+
[:feature, "Feature", "Feature Text", 1],
|
312
|
+
[:eof]
|
313
|
+
]
|
282
314
|
end
|
283
315
|
|
284
316
|
it "should parse a one line feature with no newline" do
|
285
317
|
@lexer.scan("Feature: hi")
|
286
|
-
@listener.to_sexp.should == [
|
318
|
+
@listener.to_sexp.should == [
|
319
|
+
[:feature, "Feature", "hi", 1],
|
320
|
+
[:eof]
|
321
|
+
]
|
287
322
|
end
|
288
323
|
end
|
289
324
|
|
290
325
|
describe "A multi-line feature with no scenario" do
|
291
326
|
it "should find the feature" do
|
292
327
|
@lexer.scan("Feature: Feature Text\n And some more text")
|
293
|
-
@listener.to_sexp.should == [
|
328
|
+
@listener.to_sexp.should == [
|
329
|
+
[:feature, "Feature", "Feature Text\nAnd some more text", 1],
|
330
|
+
[:eof]
|
331
|
+
]
|
294
332
|
end
|
295
333
|
end
|
296
334
|
|
@@ -299,7 +337,8 @@ Given I am a step
|
|
299
337
|
@lexer.scan("Feature: Feature Text\nScenario: Reading a Scenario\n")
|
300
338
|
@listener.to_sexp.should == [
|
301
339
|
[:feature, "Feature", "Feature Text", 1],
|
302
|
-
[:scenario, "Scenario", "Reading a Scenario", 2]
|
340
|
+
[:scenario, "Scenario", "Reading a Scenario", 2],
|
341
|
+
[:eof]
|
303
342
|
]
|
304
343
|
end
|
305
344
|
end
|
@@ -310,9 +349,10 @@ Given I am a step
|
|
310
349
|
@listener.to_sexp.should == [
|
311
350
|
[:feature, "Feature", "Feature Text", 1],
|
312
351
|
[:scenario, "Scenario", "Reading a Scenario", 2],
|
313
|
-
[:step, "Given", "a step", 3],
|
352
|
+
[:step, "Given ", "a step", 3],
|
314
353
|
[:scenario, "Scenario", "A second scenario", 5],
|
315
|
-
[:step, "Given", "another step", 6]
|
354
|
+
[:step, "Given ", "another step", 6],
|
355
|
+
[:eof]
|
316
356
|
]
|
317
357
|
end
|
318
358
|
|
@@ -321,9 +361,10 @@ Given I am a step
|
|
321
361
|
@listener.to_sexp.should == [
|
322
362
|
[:feature, "Feature", "Feature Text", 1],
|
323
363
|
[:scenario, "Scenario", "Reading a Scenario", 2],
|
324
|
-
[:step, "Given", "a step", 3],
|
364
|
+
[:step, "Given ", "a step", 3],
|
325
365
|
[:scenario, "Scenario", "A second scenario", 4],
|
326
|
-
[:step, "Given", "another step", 5]
|
366
|
+
[:step, "Given ", "another step", 5],
|
367
|
+
[:eof]
|
327
368
|
]
|
328
369
|
end
|
329
370
|
end
|
@@ -337,8 +378,23 @@ Given I am a step
|
|
337
378
|
[:comment, "# Here is another # comment", 3],
|
338
379
|
[:scenario, "Scenario", "Reading a Scenario", 4],
|
339
380
|
[:comment, "# Here is a third comment", 5],
|
340
|
-
[:step, "Given", "there is a step", 6],
|
341
|
-
[:comment, "# Here is a fourth comment", 7]
|
381
|
+
[:step, "Given ", "there is a step", 6],
|
382
|
+
[:comment, "# Here is a fourth comment", 7],
|
383
|
+
[:eof]
|
384
|
+
]
|
385
|
+
end
|
386
|
+
|
387
|
+
it "should support comments in tables" do
|
388
|
+
scan_file("comments_in_table.feature")
|
389
|
+
@listener.to_sexp.should == [
|
390
|
+
[:feature, "Feature", "x", 1],
|
391
|
+
[:scenario_outline, "Scenario Outline", "x", 3],
|
392
|
+
[:step, "Then ", "x is <state>", 4],
|
393
|
+
[:examples, "Examples", "", 6],
|
394
|
+
[:row, ["state"], 7],
|
395
|
+
[:comment, "# comment", 8],
|
396
|
+
[:row, ["1"], 9],
|
397
|
+
[:eof]
|
342
398
|
]
|
343
399
|
end
|
344
400
|
end
|
@@ -353,12 +409,13 @@ Given I am a step
|
|
353
409
|
[:tag, "st1", 5],
|
354
410
|
[:tag, "st2", 5],
|
355
411
|
[:scenario, "Scenario", "First", 6],
|
356
|
-
[:step, "Given", "Pepper", 7],
|
412
|
+
[:step, "Given ", "Pepper", 7],
|
357
413
|
[:tag, "st3", 9],
|
358
414
|
[:tag, "st4", 10],
|
359
415
|
[:tag, "ST5", 10],
|
360
416
|
[:tag, "#^%&ST6**!", 10],
|
361
|
-
[:scenario, "Scenario", "Second", 11]
|
417
|
+
[:scenario, "Scenario", "Second", 11],
|
418
|
+
[:eof]
|
362
419
|
]
|
363
420
|
end
|
364
421
|
end
|
@@ -371,7 +428,8 @@ Given I am a step
|
|
371
428
|
[:comment, "# Comment", 3],
|
372
429
|
[:scenario, "Scenario", "Anonymous user can get a login form.\nScenery here", 4],
|
373
430
|
[:tag, "tag", 7],
|
374
|
-
[:scenario, "Scenario", "Another one", 8]
|
431
|
+
[:scenario, "Scenario", "Another one", 8],
|
432
|
+
[:eof]
|
375
433
|
]
|
376
434
|
end
|
377
435
|
end
|
@@ -388,30 +446,81 @@ Given I am a step
|
|
388
446
|
[:comment, "#Comment on line 9", 9],
|
389
447
|
[:comment, "#Comment on line 11", 11],
|
390
448
|
[:background, "Background", "", 13],
|
391
|
-
[:step, "Given", "this is a background step", 14],
|
392
|
-
[:step, "And", "this is another one", 15],
|
449
|
+
[:step, "Given ", "this is a background step", 14],
|
450
|
+
[:step, "And ", "this is another one", 15],
|
393
451
|
[:tag, "tag3", 17],
|
394
452
|
[:tag, "tag4", 17],
|
395
453
|
[:scenario, "Scenario", "Reading a Scenario", 18],
|
396
|
-
[:step, "Given", "there is a step", 19],
|
397
|
-
[:step, "But", "not another step", 20],
|
454
|
+
[:step, "Given ", "there is a step", 19],
|
455
|
+
[:step, "But ", "not another step", 20],
|
398
456
|
[:tag, "tag3", 22],
|
399
|
-
[:scenario, "Scenario", "Reading a second scenario", 23],
|
400
|
-
[:comment, "#Comment on line 24",
|
401
|
-
[:step, "Given", "a third step with a table",
|
402
|
-
[:
|
403
|
-
[:
|
404
|
-
[:
|
405
|
-
[:step, "And", "I am
|
406
|
-
[:
|
407
|
-
[:
|
408
|
-
[:
|
409
|
-
[:
|
410
|
-
[:
|
411
|
-
[:
|
457
|
+
[:scenario, "Scenario", "Reading a second scenario\nWith two lines of text", 23],
|
458
|
+
[:comment, "#Comment on line 24", 25],
|
459
|
+
[:step, "Given ", "a third step with a table", 26],
|
460
|
+
[:row, %w{a b}, 27],
|
461
|
+
[:row, %w{c d}, 28],
|
462
|
+
[:row, %w{e f}, 29],
|
463
|
+
[:step, "And ", "I am still testing things", 30],
|
464
|
+
[:row, %w{g h}, 31],
|
465
|
+
[:row, %w{e r}, 32],
|
466
|
+
[:row, %w{k i}, 33],
|
467
|
+
[:row, ['n', ''], 34],
|
468
|
+
[:step, "And ", "I am done testing these tables", 35],
|
469
|
+
[:comment, "#Comment on line 29", 36],
|
470
|
+
[:step, "Then ", "I am happy", 37],
|
471
|
+
[:scenario, "Scenario", "Hammerzeit", 39],
|
472
|
+
[:step, "Given ", "All work and no play", 40],
|
473
|
+
[:py_string, "Makes Homer something something\nAnd something else", 41 ],
|
474
|
+
[:step, "Then ", "crazy", 45],
|
475
|
+
[:eof]
|
412
476
|
]
|
413
477
|
end
|
414
478
|
end
|
479
|
+
|
480
|
+
context "DOS line endings" do
|
481
|
+
describe "A complex feature with tags, comments, multiple scenarios, and multiple steps and tables" do
|
482
|
+
it "should find things in the right order" do
|
483
|
+
scan_file("dos_line_endings.feature")
|
484
|
+
@listener.to_sexp.should == [
|
485
|
+
[:comment, "#Comment on line 1", 1],
|
486
|
+
[:comment, "#Comment on line 2", 2],
|
487
|
+
[:tag, "tag1", 3],
|
488
|
+
[:tag, "tag2", 3],
|
489
|
+
[:feature, "Feature", "Feature Text\r\nIn order to test multiline forms\r\nAs a ragel writer\r\nI need to check for complex combinations", 4],
|
490
|
+
[:comment, "#Comment on line 9", 9],
|
491
|
+
[:comment, "#Comment on line 11", 11],
|
492
|
+
[:background, "Background", "", 13],
|
493
|
+
[:step, "Given ", "this is a background step", 14],
|
494
|
+
[:step, "And ", "this is another one", 15],
|
495
|
+
[:tag, "tag3", 17],
|
496
|
+
[:tag, "tag4", 17],
|
497
|
+
[:scenario, "Scenario", "Reading a Scenario", 18],
|
498
|
+
[:step, "Given ", "there is a step", 19],
|
499
|
+
[:step, "But ", "not another step", 20],
|
500
|
+
[:tag, "tag3", 22],
|
501
|
+
[:scenario, "Scenario", "Reading a second scenario\r\nWith two lines of text", 23],
|
502
|
+
[:comment, "#Comment on line 24", 25],
|
503
|
+
[:step, "Given ", "a third step with a table", 26],
|
504
|
+
[:row, %w{a b}, 27],
|
505
|
+
[:row, %w{c d}, 28],
|
506
|
+
[:row, %w{e f}, 29],
|
507
|
+
[:step, "And ", "I am still testing things", 30],
|
508
|
+
[:row, %w{g h}, 31],
|
509
|
+
[:row, %w{e r}, 32],
|
510
|
+
[:row, %w{k i}, 33],
|
511
|
+
[:row, ['n', ''], 34],
|
512
|
+
[:step, "And ", "I am done testing these tables", 35],
|
513
|
+
[:comment, "#Comment on line 29", 36],
|
514
|
+
[:step, "Then ", "I am happy", 37],
|
515
|
+
[:scenario, "Scenario", "Hammerzeit", 39],
|
516
|
+
[:step, "Given ", "All work and no play", 40],
|
517
|
+
[:py_string, "Makes Homer something something\r\nAnd something else", 41],
|
518
|
+
[:step, "Then ", "crazy", 45],
|
519
|
+
[:eof]
|
520
|
+
]
|
521
|
+
end
|
522
|
+
end
|
523
|
+
end
|
415
524
|
|
416
525
|
describe "errors" do
|
417
526
|
it "should raise a Lexing error if an unparseable token is found" do
|