aslakhellesoy-cucumber 0.1.99.1 → 0.1.99.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +14 -6
- data/Manifest.txt +2 -1
- data/examples/tickets/features/step_definitons/tickets_steps.rb +21 -3
- data/examples/tickets/features/tickets.feature +4 -0
- data/lib/cucumber.rb +6 -0
- data/lib/cucumber/cli.rb +17 -10
- data/lib/cucumber/languages.yml +4 -3
- data/lib/cucumber/parser.rb +1 -4
- data/lib/cucumber/parser/feature.rb +2 -381
- data/lib/cucumber/parser/feature.tt +1 -47
- data/lib/cucumber/parser/i18n.tt +1 -0
- data/lib/cucumber/parser/table.rb +396 -0
- data/lib/cucumber/parser/table.tt +53 -0
- data/lib/cucumber/parser/treetop_ext.rb +58 -0
- data/lib/cucumber/step_definition.rb +6 -2
- data/lib/cucumber/step_mother.rb +11 -1
- data/lib/cucumber/version.rb +1 -1
- metadata +3 -3
- data/lib/cucumber/parser/file_parser.rb +0 -50
data/History.txt
CHANGED
@@ -10,11 +10,19 @@ on how to use alternatives.
|
|
10
10
|
**** CALL FOR TRANSLATORS ****
|
11
11
|
Since the grammar has changed, there are some new keywords. We have to rely on the community
|
12
12
|
to provide updated translations. This is much easier than before - just update languages.yml.
|
13
|
-
There is no static code generation anymore.
|
13
|
+
There is no static code generation anymore. To list all languages:
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
cucumber --lang help
|
16
|
+
|
17
|
+
And to list the keywords for a particular language:
|
18
|
+
|
19
|
+
cucumber --lang en-lol help
|
20
|
+
|
21
|
+
So just go ahead and list the language of your choice and send us updated translations.
|
22
|
+
|
23
|
+
There are some really awesome new features in this release: Tagging, Autoformatting, automatic
|
24
|
+
aliasing of keywords in all languages, much better Ruby 1.9 support and improved output
|
25
|
+
for multiline arguments are some of the highlights.
|
18
26
|
|
19
27
|
This version also brings Cucumber even closer to Java. Although it has been possible to
|
20
28
|
run Cucumber on JRuby since v0.1.11, it has required that step definitions be defined
|
@@ -65,9 +73,9 @@ pure Ruby users have been enjoying for a while.
|
|
65
73
|
* It's no longer necessary to compile the Treetop grammar when adding a new language. Localised parser is generated at runtime.
|
66
74
|
|
67
75
|
=== Removed features
|
68
|
-
* "GivenScenario" is gone. Instead you can
|
76
|
+
* "GivenScenario" is gone. Instead you can call Steps from Steps, or wait for "Background (#153)"
|
69
77
|
* "More Examples" is gone. "Scenario" + "More Examples" is no longer supported. Use "Scenario Outline" + "Examples" instead.
|
70
|
-
* Pure Ruby features are no longer supported
|
78
|
+
* Pure Ruby features are no longer supported.
|
71
79
|
|
72
80
|
== 0.1.16.x (Master)
|
73
81
|
|
data/Manifest.txt
CHANGED
@@ -193,8 +193,9 @@ lib/cucumber/parser.rb
|
|
193
193
|
lib/cucumber/parser/basic.rb
|
194
194
|
lib/cucumber/parser/feature.rb
|
195
195
|
lib/cucumber/parser/feature.tt
|
196
|
-
lib/cucumber/parser/file_parser.rb
|
197
196
|
lib/cucumber/parser/i18n.tt
|
197
|
+
lib/cucumber/parser/table.rb
|
198
|
+
lib/cucumber/parser/table.tt
|
198
199
|
lib/cucumber/parser/treetop_ext.rb
|
199
200
|
lib/cucumber/platform.rb
|
200
201
|
lib/cucumber/rails/rspec.rb
|
@@ -9,15 +9,33 @@ Given "be_empty" do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
Given "nested step is called" do
|
12
|
-
Given "
|
12
|
+
Given "I like mushroom", Cucumber::Ast::Table.new([
|
13
|
+
%w{sponge bob},
|
14
|
+
%w{is cool}
|
15
|
+
])
|
13
16
|
end
|
14
17
|
|
15
|
-
Given
|
16
|
-
|
18
|
+
Given 'nested step is called using text table' do
|
19
|
+
Given "I like mushroom", table(%{
|
20
|
+
| sponge | bob |
|
21
|
+
| is | cool |
|
22
|
+
})
|
23
|
+
|
24
|
+
# Alternative syntax (file and line will be reported on parse error)
|
25
|
+
# Given "I like mushroom", table(<<-EOT, __FILE__, __LINE__)
|
26
|
+
# | sponge | bob |
|
27
|
+
# | is | cool
|
28
|
+
# EOT
|
29
|
+
end
|
30
|
+
|
31
|
+
Given "I like $what" do |what, table|
|
32
|
+
@magic = what
|
33
|
+
@tool = table.raw[0][0]
|
17
34
|
end
|
18
35
|
|
19
36
|
Then "nested step should be executed" do
|
20
37
|
@magic.should == 'mushroom'
|
38
|
+
@tool.should == 'sponge'
|
21
39
|
end
|
22
40
|
|
23
41
|
Given /^the following table$/ do |table|
|
@@ -9,6 +9,10 @@ Feature: Cucumber
|
|
9
9
|
Scenario: Call step from step
|
10
10
|
Given nested step is called
|
11
11
|
Then nested step should be executed
|
12
|
+
|
13
|
+
Scenario: Call step from step using text table
|
14
|
+
Given nested step is called using text table
|
15
|
+
Then nested step should be executed
|
12
16
|
|
13
17
|
Scenario: Reading a table
|
14
18
|
Given the following table
|
data/lib/cucumber.rb
CHANGED
@@ -12,6 +12,8 @@ require 'cucumber/broadcaster'
|
|
12
12
|
require 'cucumber/core_ext/exception'
|
13
13
|
|
14
14
|
module Cucumber
|
15
|
+
KEYWORD_KEYS = %w{name native encoding feature background scenario scenario_outline examples given when then but}
|
16
|
+
|
15
17
|
class << self
|
16
18
|
attr_reader :lang
|
17
19
|
|
@@ -22,6 +24,10 @@ module Cucumber
|
|
22
24
|
Parser.load_parser(keyword_hash)
|
23
25
|
end
|
24
26
|
|
27
|
+
def language_complete?(lang)
|
28
|
+
KEYWORD_KEYS.detect{|key| keyword_hash(lang)[key].nil?}
|
29
|
+
end
|
30
|
+
|
25
31
|
# File mode that accounts for Ruby platform and current language
|
26
32
|
def file_mode(m)
|
27
33
|
Cucumber::RUBY_1_9 ? "#{m}:#{keyword_hash['encoding']}" : m
|
data/lib/cucumber/cli.rb
CHANGED
@@ -78,7 +78,7 @@ module Cucumber
|
|
78
78
|
if v == 'help'
|
79
79
|
list_languages
|
80
80
|
elsif args==['help']
|
81
|
-
list_keywords(
|
81
|
+
list_keywords(v)
|
82
82
|
else
|
83
83
|
@options[:lang] = v
|
84
84
|
end
|
@@ -364,23 +364,22 @@ Defined profiles in cucumber.yml:
|
|
364
364
|
raw = Cucumber::LANGUAGES.keys.sort.map do |lang|
|
365
365
|
[lang, Cucumber::LANGUAGES[lang]['name'], Cucumber::LANGUAGES[lang]['native']]
|
366
366
|
end
|
367
|
-
|
367
|
+
print_lang_table(raw, {:check_lang=>true})
|
368
368
|
end
|
369
369
|
|
370
|
-
def list_keywords(
|
370
|
+
def list_keywords(lang)
|
371
371
|
unless Cucumber::LANGUAGES[lang]
|
372
372
|
exit_with_error("No language with key #{v}")
|
373
373
|
end
|
374
|
-
Cucumber.
|
375
|
-
|
376
|
-
[Cucumber::LANGUAGES[ref][key], Cucumber::LANGUAGES[lang][key]]
|
374
|
+
raw = Cucumber::KEYWORD_KEYS.map do |key|
|
375
|
+
[key, Cucumber::LANGUAGES[lang][key]]
|
377
376
|
end
|
378
|
-
|
377
|
+
print_lang_table(raw, {})
|
379
378
|
end
|
380
379
|
|
381
|
-
def
|
380
|
+
def print_lang_table(raw, options)
|
382
381
|
table = Ast::Table.new(raw)
|
383
|
-
formatter = Formatter::Pretty.new(nil, @out_stream,
|
382
|
+
formatter = Formatter::Pretty.new(nil, @out_stream, options, '')
|
384
383
|
|
385
384
|
def formatter.visit_table_row(table_row, status)
|
386
385
|
@col = 1
|
@@ -388,7 +387,15 @@ Defined profiles in cucumber.yml:
|
|
388
387
|
end
|
389
388
|
|
390
389
|
def formatter.visit_table_cell_value(value, width, status)
|
391
|
-
|
390
|
+
if @col == 1
|
391
|
+
if(@options[:check_lang])
|
392
|
+
@incomplete = Cucumber.language_complete?(value)
|
393
|
+
end
|
394
|
+
status = :comment
|
395
|
+
elsif @incomplete
|
396
|
+
status = :failed
|
397
|
+
end
|
398
|
+
|
392
399
|
@col += 1
|
393
400
|
super(value, width, status)
|
394
401
|
end
|
data/lib/cucumber/languages.yml
CHANGED
@@ -52,6 +52,7 @@
|
|
52
52
|
feature: Egenskab
|
53
53
|
background: Baggrund
|
54
54
|
scenario: Scenarie
|
55
|
+
scenario_outline: Abstrakt Scenario
|
55
56
|
examples: Eksempler
|
56
57
|
given: Givet
|
57
58
|
when: Når
|
@@ -115,8 +116,6 @@
|
|
115
116
|
encoding: UTF-8
|
116
117
|
feature: Omadus
|
117
118
|
scenario: Stsenaarium
|
118
|
-
scenario_outline: Scenario Outline
|
119
|
-
examples: Examples
|
120
119
|
given: Eeldades
|
121
120
|
when: Kui
|
122
121
|
then: Siis
|
@@ -215,7 +214,7 @@
|
|
215
214
|
feature: Egenskap
|
216
215
|
background: Bakgrunn
|
217
216
|
scenario: Scenario
|
218
|
-
scenario_outline:
|
217
|
+
scenario_outline: Abstrakt Scenario
|
219
218
|
examples: Eksempler
|
220
219
|
given: Gitt
|
221
220
|
when: Når
|
@@ -284,6 +283,8 @@
|
|
284
283
|
feature: Egenskap
|
285
284
|
background: Bakgrund
|
286
285
|
scenario: Scenario
|
286
|
+
scenario_outline: Abstrakt Scenario
|
287
|
+
examples: Exempel
|
287
288
|
given: Givet
|
288
289
|
when: När
|
289
290
|
then: Så
|
data/lib/cucumber/parser.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
require 'erb'
|
2
|
-
require 'treetop'
|
3
|
-
require 'treetop/runtime'
|
4
|
-
require 'treetop/ruby_extensions'
|
5
2
|
require 'cucumber/platform'
|
6
3
|
require 'cucumber/ast'
|
7
|
-
require 'cucumber/parser/file_parser'
|
8
4
|
require 'cucumber/parser/treetop_ext'
|
5
|
+
require 'cucumber/parser/table'
|
9
6
|
|
10
7
|
module Cucumber
|
11
8
|
# Classes in this module parse feature files and translate the parse tree
|
@@ -10,10 +10,10 @@ module Cucumber
|
|
10
10
|
@root || :feature
|
11
11
|
end
|
12
12
|
|
13
|
-
include FileParser
|
14
|
-
|
15
13
|
include I18n
|
16
14
|
|
15
|
+
include Table
|
16
|
+
|
17
17
|
module Feature0
|
18
18
|
end
|
19
19
|
|
@@ -976,271 +976,6 @@ module Cucumber
|
|
976
976
|
return r0
|
977
977
|
end
|
978
978
|
|
979
|
-
module Table0
|
980
|
-
def build
|
981
|
-
Ast::Table.new(raw)
|
982
|
-
end
|
983
|
-
|
984
|
-
def raw
|
985
|
-
elements.map{|e| e.build}
|
986
|
-
end
|
987
|
-
end
|
988
|
-
|
989
|
-
def _nt_table
|
990
|
-
start_index = index
|
991
|
-
if node_cache[:table].has_key?(index)
|
992
|
-
cached = node_cache[:table][index]
|
993
|
-
@index = cached.interval.end if cached
|
994
|
-
return cached
|
995
|
-
end
|
996
|
-
|
997
|
-
s0, i0 = [], index
|
998
|
-
loop do
|
999
|
-
r1 = _nt_table_row
|
1000
|
-
if r1
|
1001
|
-
s0 << r1
|
1002
|
-
else
|
1003
|
-
break
|
1004
|
-
end
|
1005
|
-
end
|
1006
|
-
if s0.empty?
|
1007
|
-
self.index = i0
|
1008
|
-
r0 = nil
|
1009
|
-
else
|
1010
|
-
r0 = SyntaxNode.new(input, i0...index, s0)
|
1011
|
-
r0.extend(Table0)
|
1012
|
-
end
|
1013
|
-
|
1014
|
-
node_cache[:table][start_index] = r0
|
1015
|
-
|
1016
|
-
return r0
|
1017
|
-
end
|
1018
|
-
|
1019
|
-
module TableRow0
|
1020
|
-
def cell
|
1021
|
-
elements[0]
|
1022
|
-
end
|
1023
|
-
|
1024
|
-
end
|
1025
|
-
|
1026
|
-
module TableRow1
|
1027
|
-
def cells
|
1028
|
-
elements[2]
|
1029
|
-
end
|
1030
|
-
|
1031
|
-
end
|
1032
|
-
|
1033
|
-
module TableRow2
|
1034
|
-
def build
|
1035
|
-
row = cells.elements.map do |elt|
|
1036
|
-
value = elt.cell.text_value.strip
|
1037
|
-
value.empty? ? nil : value
|
1038
|
-
end
|
1039
|
-
|
1040
|
-
class << row
|
1041
|
-
attr_accessor :line
|
1042
|
-
end
|
1043
|
-
row.line = cells.line
|
1044
|
-
|
1045
|
-
row
|
1046
|
-
end
|
1047
|
-
end
|
1048
|
-
|
1049
|
-
def _nt_table_row
|
1050
|
-
start_index = index
|
1051
|
-
if node_cache[:table_row].has_key?(index)
|
1052
|
-
cached = node_cache[:table_row][index]
|
1053
|
-
@index = cached.interval.end if cached
|
1054
|
-
return cached
|
1055
|
-
end
|
1056
|
-
|
1057
|
-
i0, s0 = index, []
|
1058
|
-
s1, i1 = [], index
|
1059
|
-
loop do
|
1060
|
-
r2 = _nt_space
|
1061
|
-
if r2
|
1062
|
-
s1 << r2
|
1063
|
-
else
|
1064
|
-
break
|
1065
|
-
end
|
1066
|
-
end
|
1067
|
-
r1 = SyntaxNode.new(input, i1...index, s1)
|
1068
|
-
s0 << r1
|
1069
|
-
if r1
|
1070
|
-
if input.index('|', index) == index
|
1071
|
-
r3 = (SyntaxNode).new(input, index...(index + 1))
|
1072
|
-
@index += 1
|
1073
|
-
else
|
1074
|
-
terminal_parse_failure('|')
|
1075
|
-
r3 = nil
|
1076
|
-
end
|
1077
|
-
s0 << r3
|
1078
|
-
if r3
|
1079
|
-
s4, i4 = [], index
|
1080
|
-
loop do
|
1081
|
-
i5, s5 = index, []
|
1082
|
-
r6 = _nt_cell
|
1083
|
-
s5 << r6
|
1084
|
-
if r6
|
1085
|
-
if input.index('|', index) == index
|
1086
|
-
r7 = (SyntaxNode).new(input, index...(index + 1))
|
1087
|
-
@index += 1
|
1088
|
-
else
|
1089
|
-
terminal_parse_failure('|')
|
1090
|
-
r7 = nil
|
1091
|
-
end
|
1092
|
-
s5 << r7
|
1093
|
-
end
|
1094
|
-
if s5.last
|
1095
|
-
r5 = (SyntaxNode).new(input, i5...index, s5)
|
1096
|
-
r5.extend(TableRow0)
|
1097
|
-
else
|
1098
|
-
self.index = i5
|
1099
|
-
r5 = nil
|
1100
|
-
end
|
1101
|
-
if r5
|
1102
|
-
s4 << r5
|
1103
|
-
else
|
1104
|
-
break
|
1105
|
-
end
|
1106
|
-
end
|
1107
|
-
if s4.empty?
|
1108
|
-
self.index = i4
|
1109
|
-
r4 = nil
|
1110
|
-
else
|
1111
|
-
r4 = SyntaxNode.new(input, i4...index, s4)
|
1112
|
-
end
|
1113
|
-
s0 << r4
|
1114
|
-
if r4
|
1115
|
-
s8, i8 = [], index
|
1116
|
-
loop do
|
1117
|
-
r9 = _nt_space
|
1118
|
-
if r9
|
1119
|
-
s8 << r9
|
1120
|
-
else
|
1121
|
-
break
|
1122
|
-
end
|
1123
|
-
end
|
1124
|
-
r8 = SyntaxNode.new(input, i8...index, s8)
|
1125
|
-
s0 << r8
|
1126
|
-
if r8
|
1127
|
-
i10 = index
|
1128
|
-
s11, i11 = [], index
|
1129
|
-
loop do
|
1130
|
-
r12 = _nt_eol
|
1131
|
-
if r12
|
1132
|
-
s11 << r12
|
1133
|
-
else
|
1134
|
-
break
|
1135
|
-
end
|
1136
|
-
end
|
1137
|
-
if s11.empty?
|
1138
|
-
self.index = i11
|
1139
|
-
r11 = nil
|
1140
|
-
else
|
1141
|
-
r11 = SyntaxNode.new(input, i11...index, s11)
|
1142
|
-
end
|
1143
|
-
if r11
|
1144
|
-
r10 = r11
|
1145
|
-
else
|
1146
|
-
r13 = _nt_eof
|
1147
|
-
if r13
|
1148
|
-
r10 = r13
|
1149
|
-
else
|
1150
|
-
self.index = i10
|
1151
|
-
r10 = nil
|
1152
|
-
end
|
1153
|
-
end
|
1154
|
-
s0 << r10
|
1155
|
-
end
|
1156
|
-
end
|
1157
|
-
end
|
1158
|
-
end
|
1159
|
-
if s0.last
|
1160
|
-
r0 = (SyntaxNode).new(input, i0...index, s0)
|
1161
|
-
r0.extend(TableRow1)
|
1162
|
-
r0.extend(TableRow2)
|
1163
|
-
else
|
1164
|
-
self.index = i0
|
1165
|
-
r0 = nil
|
1166
|
-
end
|
1167
|
-
|
1168
|
-
node_cache[:table_row][start_index] = r0
|
1169
|
-
|
1170
|
-
return r0
|
1171
|
-
end
|
1172
|
-
|
1173
|
-
module Cell0
|
1174
|
-
end
|
1175
|
-
|
1176
|
-
def _nt_cell
|
1177
|
-
start_index = index
|
1178
|
-
if node_cache[:cell].has_key?(index)
|
1179
|
-
cached = node_cache[:cell][index]
|
1180
|
-
@index = cached.interval.end if cached
|
1181
|
-
return cached
|
1182
|
-
end
|
1183
|
-
|
1184
|
-
s0, i0 = [], index
|
1185
|
-
loop do
|
1186
|
-
i1, s1 = index, []
|
1187
|
-
i2 = index
|
1188
|
-
i3 = index
|
1189
|
-
if input.index('|', index) == index
|
1190
|
-
r4 = (SyntaxNode).new(input, index...(index + 1))
|
1191
|
-
@index += 1
|
1192
|
-
else
|
1193
|
-
terminal_parse_failure('|')
|
1194
|
-
r4 = nil
|
1195
|
-
end
|
1196
|
-
if r4
|
1197
|
-
r3 = r4
|
1198
|
-
else
|
1199
|
-
r5 = _nt_eol
|
1200
|
-
if r5
|
1201
|
-
r3 = r5
|
1202
|
-
else
|
1203
|
-
self.index = i3
|
1204
|
-
r3 = nil
|
1205
|
-
end
|
1206
|
-
end
|
1207
|
-
if r3
|
1208
|
-
r2 = nil
|
1209
|
-
else
|
1210
|
-
self.index = i2
|
1211
|
-
r2 = SyntaxNode.new(input, index...index)
|
1212
|
-
end
|
1213
|
-
s1 << r2
|
1214
|
-
if r2
|
1215
|
-
if index < input_length
|
1216
|
-
r6 = (SyntaxNode).new(input, index...(index + 1))
|
1217
|
-
@index += 1
|
1218
|
-
else
|
1219
|
-
terminal_parse_failure("any character")
|
1220
|
-
r6 = nil
|
1221
|
-
end
|
1222
|
-
s1 << r6
|
1223
|
-
end
|
1224
|
-
if s1.last
|
1225
|
-
r1 = (SyntaxNode).new(input, i1...index, s1)
|
1226
|
-
r1.extend(Cell0)
|
1227
|
-
else
|
1228
|
-
self.index = i1
|
1229
|
-
r1 = nil
|
1230
|
-
end
|
1231
|
-
if r1
|
1232
|
-
s0 << r1
|
1233
|
-
else
|
1234
|
-
break
|
1235
|
-
end
|
1236
|
-
end
|
1237
|
-
r0 = SyntaxNode.new(input, i0...index, s0)
|
1238
|
-
|
1239
|
-
node_cache[:cell][start_index] = r0
|
1240
|
-
|
1241
|
-
return r0
|
1242
|
-
end
|
1243
|
-
|
1244
979
|
module LineToEol0
|
1245
980
|
end
|
1246
981
|
|
@@ -1570,120 +1305,6 @@ module Cucumber
|
|
1570
1305
|
return r0
|
1571
1306
|
end
|
1572
1307
|
|
1573
|
-
def _nt_space
|
1574
|
-
start_index = index
|
1575
|
-
if node_cache[:space].has_key?(index)
|
1576
|
-
cached = node_cache[:space][index]
|
1577
|
-
@index = cached.interval.end if cached
|
1578
|
-
return cached
|
1579
|
-
end
|
1580
|
-
|
1581
|
-
if input.index(Regexp.new('[ \\t]'), index) == index
|
1582
|
-
r0 = (SyntaxNode).new(input, index...(index + 1))
|
1583
|
-
@index += 1
|
1584
|
-
else
|
1585
|
-
r0 = nil
|
1586
|
-
end
|
1587
|
-
|
1588
|
-
node_cache[:space][start_index] = r0
|
1589
|
-
|
1590
|
-
return r0
|
1591
|
-
end
|
1592
|
-
|
1593
|
-
module Eol0
|
1594
|
-
end
|
1595
|
-
|
1596
|
-
def _nt_eol
|
1597
|
-
start_index = index
|
1598
|
-
if node_cache[:eol].has_key?(index)
|
1599
|
-
cached = node_cache[:eol][index]
|
1600
|
-
@index = cached.interval.end if cached
|
1601
|
-
return cached
|
1602
|
-
end
|
1603
|
-
|
1604
|
-
i0 = index
|
1605
|
-
if input.index("\n", index) == index
|
1606
|
-
r1 = (SyntaxNode).new(input, index...(index + 1))
|
1607
|
-
@index += 1
|
1608
|
-
else
|
1609
|
-
terminal_parse_failure("\n")
|
1610
|
-
r1 = nil
|
1611
|
-
end
|
1612
|
-
if r1
|
1613
|
-
r0 = r1
|
1614
|
-
else
|
1615
|
-
i2, s2 = index, []
|
1616
|
-
if input.index("\r", index) == index
|
1617
|
-
r3 = (SyntaxNode).new(input, index...(index + 1))
|
1618
|
-
@index += 1
|
1619
|
-
else
|
1620
|
-
terminal_parse_failure("\r")
|
1621
|
-
r3 = nil
|
1622
|
-
end
|
1623
|
-
s2 << r3
|
1624
|
-
if r3
|
1625
|
-
if input.index("\n", index) == index
|
1626
|
-
r5 = (SyntaxNode).new(input, index...(index + 1))
|
1627
|
-
@index += 1
|
1628
|
-
else
|
1629
|
-
terminal_parse_failure("\n")
|
1630
|
-
r5 = nil
|
1631
|
-
end
|
1632
|
-
if r5
|
1633
|
-
r4 = r5
|
1634
|
-
else
|
1635
|
-
r4 = SyntaxNode.new(input, index...index)
|
1636
|
-
end
|
1637
|
-
s2 << r4
|
1638
|
-
end
|
1639
|
-
if s2.last
|
1640
|
-
r2 = (SyntaxNode).new(input, i2...index, s2)
|
1641
|
-
r2.extend(Eol0)
|
1642
|
-
else
|
1643
|
-
self.index = i2
|
1644
|
-
r2 = nil
|
1645
|
-
end
|
1646
|
-
if r2
|
1647
|
-
r0 = r2
|
1648
|
-
else
|
1649
|
-
self.index = i0
|
1650
|
-
r0 = nil
|
1651
|
-
end
|
1652
|
-
end
|
1653
|
-
|
1654
|
-
node_cache[:eol][start_index] = r0
|
1655
|
-
|
1656
|
-
return r0
|
1657
|
-
end
|
1658
|
-
|
1659
|
-
def _nt_eof
|
1660
|
-
start_index = index
|
1661
|
-
if node_cache[:eof].has_key?(index)
|
1662
|
-
cached = node_cache[:eof][index]
|
1663
|
-
@index = cached.interval.end if cached
|
1664
|
-
return cached
|
1665
|
-
end
|
1666
|
-
|
1667
|
-
i0 = index
|
1668
|
-
if index < input_length
|
1669
|
-
r1 = (SyntaxNode).new(input, index...(index + 1))
|
1670
|
-
@index += 1
|
1671
|
-
else
|
1672
|
-
terminal_parse_failure("any character")
|
1673
|
-
r1 = nil
|
1674
|
-
end
|
1675
|
-
if r1
|
1676
|
-
r0 = nil
|
1677
|
-
else
|
1678
|
-
self.index = i0
|
1679
|
-
r0 = SyntaxNode.new(input, index...index)
|
1680
|
-
end
|
1681
|
-
|
1682
|
-
node_cache[:eof][start_index] = r0
|
1683
|
-
|
1684
|
-
return r0
|
1685
|
-
end
|
1686
|
-
|
1687
1308
|
end
|
1688
1309
|
|
1689
1310
|
class FeatureParser < Treetop::Runtime::CompiledParser
|
@@ -4,8 +4,8 @@ module Cucumber
|
|
4
4
|
# Treetop will then generate the parser in-memory. When you're happy, just generate
|
5
5
|
# the rb file with tt feature.tt
|
6
6
|
grammar Feature
|
7
|
-
include FileParser
|
8
7
|
include I18n
|
8
|
+
include Table
|
9
9
|
|
10
10
|
rule feature
|
11
11
|
white comment white tags white header:(!(scenario_outline / scenario) .)* feature_elements {
|
@@ -119,40 +119,6 @@ module Cucumber
|
|
119
119
|
table / py_string
|
120
120
|
end
|
121
121
|
|
122
|
-
rule table
|
123
|
-
table_row+ {
|
124
|
-
def build
|
125
|
-
Ast::Table.new(raw)
|
126
|
-
end
|
127
|
-
|
128
|
-
def raw
|
129
|
-
elements.map{|e| e.build}
|
130
|
-
end
|
131
|
-
}
|
132
|
-
end
|
133
|
-
|
134
|
-
rule table_row
|
135
|
-
space* '|' cells:(cell '|')+ space* (eol+ / eof) {
|
136
|
-
def build
|
137
|
-
row = cells.elements.map do |elt|
|
138
|
-
value = elt.cell.text_value.strip
|
139
|
-
value.empty? ? nil : value
|
140
|
-
end
|
141
|
-
|
142
|
-
class << row
|
143
|
-
attr_accessor :line
|
144
|
-
end
|
145
|
-
row.line = cells.line
|
146
|
-
|
147
|
-
row
|
148
|
-
end
|
149
|
-
}
|
150
|
-
end
|
151
|
-
|
152
|
-
rule cell
|
153
|
-
(!('|' / eol) .)*
|
154
|
-
end
|
155
|
-
|
156
122
|
rule line_to_eol
|
157
123
|
(!eol .)+
|
158
124
|
end
|
@@ -189,18 +155,6 @@ module Cucumber
|
|
189
155
|
(space / eol)*
|
190
156
|
end
|
191
157
|
|
192
|
-
rule space
|
193
|
-
[ \t]
|
194
|
-
end
|
195
|
-
|
196
|
-
rule eol
|
197
|
-
"\n" / ("\r" "\n"?)
|
198
|
-
end
|
199
|
-
|
200
|
-
rule eof
|
201
|
-
!.
|
202
|
-
end
|
203
|
-
|
204
158
|
end
|
205
159
|
end
|
206
160
|
end
|
data/lib/cucumber/parser/i18n.tt
CHANGED
@@ -0,0 +1,396 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Parser
|
3
|
+
module Table
|
4
|
+
include Treetop::Runtime
|
5
|
+
|
6
|
+
def root
|
7
|
+
@root || :table
|
8
|
+
end
|
9
|
+
|
10
|
+
module Table0
|
11
|
+
def build
|
12
|
+
Ast::Table.new(raw)
|
13
|
+
end
|
14
|
+
|
15
|
+
def raw
|
16
|
+
elements.map{|e| e.build}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def _nt_table
|
21
|
+
start_index = index
|
22
|
+
if node_cache[:table].has_key?(index)
|
23
|
+
cached = node_cache[:table][index]
|
24
|
+
@index = cached.interval.end if cached
|
25
|
+
return cached
|
26
|
+
end
|
27
|
+
|
28
|
+
s0, i0 = [], index
|
29
|
+
loop do
|
30
|
+
r1 = _nt_table_row
|
31
|
+
if r1
|
32
|
+
s0 << r1
|
33
|
+
else
|
34
|
+
break
|
35
|
+
end
|
36
|
+
end
|
37
|
+
if s0.empty?
|
38
|
+
self.index = i0
|
39
|
+
r0 = nil
|
40
|
+
else
|
41
|
+
r0 = SyntaxNode.new(input, i0...index, s0)
|
42
|
+
r0.extend(Table0)
|
43
|
+
end
|
44
|
+
|
45
|
+
node_cache[:table][start_index] = r0
|
46
|
+
|
47
|
+
return r0
|
48
|
+
end
|
49
|
+
|
50
|
+
module TableRow0
|
51
|
+
def cell
|
52
|
+
elements[0]
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
module TableRow1
|
58
|
+
def cells
|
59
|
+
elements[2]
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
module TableRow2
|
65
|
+
def build
|
66
|
+
row = cells.elements.map do |elt|
|
67
|
+
value = elt.cell.text_value.strip
|
68
|
+
value.empty? ? nil : value
|
69
|
+
end
|
70
|
+
|
71
|
+
class << row
|
72
|
+
attr_accessor :line
|
73
|
+
end
|
74
|
+
row.line = cells.line
|
75
|
+
|
76
|
+
row
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def _nt_table_row
|
81
|
+
start_index = index
|
82
|
+
if node_cache[:table_row].has_key?(index)
|
83
|
+
cached = node_cache[:table_row][index]
|
84
|
+
@index = cached.interval.end if cached
|
85
|
+
return cached
|
86
|
+
end
|
87
|
+
|
88
|
+
i0, s0 = index, []
|
89
|
+
s1, i1 = [], index
|
90
|
+
loop do
|
91
|
+
r2 = _nt_space
|
92
|
+
if r2
|
93
|
+
s1 << r2
|
94
|
+
else
|
95
|
+
break
|
96
|
+
end
|
97
|
+
end
|
98
|
+
r1 = SyntaxNode.new(input, i1...index, s1)
|
99
|
+
s0 << r1
|
100
|
+
if r1
|
101
|
+
if input.index('|', index) == index
|
102
|
+
r3 = (SyntaxNode).new(input, index...(index + 1))
|
103
|
+
@index += 1
|
104
|
+
else
|
105
|
+
terminal_parse_failure('|')
|
106
|
+
r3 = nil
|
107
|
+
end
|
108
|
+
s0 << r3
|
109
|
+
if r3
|
110
|
+
s4, i4 = [], index
|
111
|
+
loop do
|
112
|
+
i5, s5 = index, []
|
113
|
+
r6 = _nt_cell
|
114
|
+
s5 << r6
|
115
|
+
if r6
|
116
|
+
if input.index('|', index) == index
|
117
|
+
r7 = (SyntaxNode).new(input, index...(index + 1))
|
118
|
+
@index += 1
|
119
|
+
else
|
120
|
+
terminal_parse_failure('|')
|
121
|
+
r7 = nil
|
122
|
+
end
|
123
|
+
s5 << r7
|
124
|
+
end
|
125
|
+
if s5.last
|
126
|
+
r5 = (SyntaxNode).new(input, i5...index, s5)
|
127
|
+
r5.extend(TableRow0)
|
128
|
+
else
|
129
|
+
self.index = i5
|
130
|
+
r5 = nil
|
131
|
+
end
|
132
|
+
if r5
|
133
|
+
s4 << r5
|
134
|
+
else
|
135
|
+
break
|
136
|
+
end
|
137
|
+
end
|
138
|
+
if s4.empty?
|
139
|
+
self.index = i4
|
140
|
+
r4 = nil
|
141
|
+
else
|
142
|
+
r4 = SyntaxNode.new(input, i4...index, s4)
|
143
|
+
end
|
144
|
+
s0 << r4
|
145
|
+
if r4
|
146
|
+
s8, i8 = [], index
|
147
|
+
loop do
|
148
|
+
r9 = _nt_space
|
149
|
+
if r9
|
150
|
+
s8 << r9
|
151
|
+
else
|
152
|
+
break
|
153
|
+
end
|
154
|
+
end
|
155
|
+
r8 = SyntaxNode.new(input, i8...index, s8)
|
156
|
+
s0 << r8
|
157
|
+
if r8
|
158
|
+
i10 = index
|
159
|
+
s11, i11 = [], index
|
160
|
+
loop do
|
161
|
+
r12 = _nt_eol
|
162
|
+
if r12
|
163
|
+
s11 << r12
|
164
|
+
else
|
165
|
+
break
|
166
|
+
end
|
167
|
+
end
|
168
|
+
if s11.empty?
|
169
|
+
self.index = i11
|
170
|
+
r11 = nil
|
171
|
+
else
|
172
|
+
r11 = SyntaxNode.new(input, i11...index, s11)
|
173
|
+
end
|
174
|
+
if r11
|
175
|
+
r10 = r11
|
176
|
+
else
|
177
|
+
r13 = _nt_eof
|
178
|
+
if r13
|
179
|
+
r10 = r13
|
180
|
+
else
|
181
|
+
self.index = i10
|
182
|
+
r10 = nil
|
183
|
+
end
|
184
|
+
end
|
185
|
+
s0 << r10
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
if s0.last
|
191
|
+
r0 = (SyntaxNode).new(input, i0...index, s0)
|
192
|
+
r0.extend(TableRow1)
|
193
|
+
r0.extend(TableRow2)
|
194
|
+
else
|
195
|
+
self.index = i0
|
196
|
+
r0 = nil
|
197
|
+
end
|
198
|
+
|
199
|
+
node_cache[:table_row][start_index] = r0
|
200
|
+
|
201
|
+
return r0
|
202
|
+
end
|
203
|
+
|
204
|
+
module Cell0
|
205
|
+
end
|
206
|
+
|
207
|
+
def _nt_cell
|
208
|
+
start_index = index
|
209
|
+
if node_cache[:cell].has_key?(index)
|
210
|
+
cached = node_cache[:cell][index]
|
211
|
+
@index = cached.interval.end if cached
|
212
|
+
return cached
|
213
|
+
end
|
214
|
+
|
215
|
+
s0, i0 = [], index
|
216
|
+
loop do
|
217
|
+
i1, s1 = index, []
|
218
|
+
i2 = index
|
219
|
+
i3 = index
|
220
|
+
if input.index('|', index) == index
|
221
|
+
r4 = (SyntaxNode).new(input, index...(index + 1))
|
222
|
+
@index += 1
|
223
|
+
else
|
224
|
+
terminal_parse_failure('|')
|
225
|
+
r4 = nil
|
226
|
+
end
|
227
|
+
if r4
|
228
|
+
r3 = r4
|
229
|
+
else
|
230
|
+
r5 = _nt_eol
|
231
|
+
if r5
|
232
|
+
r3 = r5
|
233
|
+
else
|
234
|
+
self.index = i3
|
235
|
+
r3 = nil
|
236
|
+
end
|
237
|
+
end
|
238
|
+
if r3
|
239
|
+
r2 = nil
|
240
|
+
else
|
241
|
+
self.index = i2
|
242
|
+
r2 = SyntaxNode.new(input, index...index)
|
243
|
+
end
|
244
|
+
s1 << r2
|
245
|
+
if r2
|
246
|
+
if index < input_length
|
247
|
+
r6 = (SyntaxNode).new(input, index...(index + 1))
|
248
|
+
@index += 1
|
249
|
+
else
|
250
|
+
terminal_parse_failure("any character")
|
251
|
+
r6 = nil
|
252
|
+
end
|
253
|
+
s1 << r6
|
254
|
+
end
|
255
|
+
if s1.last
|
256
|
+
r1 = (SyntaxNode).new(input, i1...index, s1)
|
257
|
+
r1.extend(Cell0)
|
258
|
+
else
|
259
|
+
self.index = i1
|
260
|
+
r1 = nil
|
261
|
+
end
|
262
|
+
if r1
|
263
|
+
s0 << r1
|
264
|
+
else
|
265
|
+
break
|
266
|
+
end
|
267
|
+
end
|
268
|
+
r0 = SyntaxNode.new(input, i0...index, s0)
|
269
|
+
|
270
|
+
node_cache[:cell][start_index] = r0
|
271
|
+
|
272
|
+
return r0
|
273
|
+
end
|
274
|
+
|
275
|
+
def _nt_space
|
276
|
+
start_index = index
|
277
|
+
if node_cache[:space].has_key?(index)
|
278
|
+
cached = node_cache[:space][index]
|
279
|
+
@index = cached.interval.end if cached
|
280
|
+
return cached
|
281
|
+
end
|
282
|
+
|
283
|
+
if input.index(Regexp.new('[ \\t]'), index) == index
|
284
|
+
r0 = (SyntaxNode).new(input, index...(index + 1))
|
285
|
+
@index += 1
|
286
|
+
else
|
287
|
+
r0 = nil
|
288
|
+
end
|
289
|
+
|
290
|
+
node_cache[:space][start_index] = r0
|
291
|
+
|
292
|
+
return r0
|
293
|
+
end
|
294
|
+
|
295
|
+
module Eol0
|
296
|
+
end
|
297
|
+
|
298
|
+
def _nt_eol
|
299
|
+
start_index = index
|
300
|
+
if node_cache[:eol].has_key?(index)
|
301
|
+
cached = node_cache[:eol][index]
|
302
|
+
@index = cached.interval.end if cached
|
303
|
+
return cached
|
304
|
+
end
|
305
|
+
|
306
|
+
i0 = index
|
307
|
+
if input.index("\n", index) == index
|
308
|
+
r1 = (SyntaxNode).new(input, index...(index + 1))
|
309
|
+
@index += 1
|
310
|
+
else
|
311
|
+
terminal_parse_failure("\n")
|
312
|
+
r1 = nil
|
313
|
+
end
|
314
|
+
if r1
|
315
|
+
r0 = r1
|
316
|
+
else
|
317
|
+
i2, s2 = index, []
|
318
|
+
if input.index("\r", index) == index
|
319
|
+
r3 = (SyntaxNode).new(input, index...(index + 1))
|
320
|
+
@index += 1
|
321
|
+
else
|
322
|
+
terminal_parse_failure("\r")
|
323
|
+
r3 = nil
|
324
|
+
end
|
325
|
+
s2 << r3
|
326
|
+
if r3
|
327
|
+
if input.index("\n", index) == index
|
328
|
+
r5 = (SyntaxNode).new(input, index...(index + 1))
|
329
|
+
@index += 1
|
330
|
+
else
|
331
|
+
terminal_parse_failure("\n")
|
332
|
+
r5 = nil
|
333
|
+
end
|
334
|
+
if r5
|
335
|
+
r4 = r5
|
336
|
+
else
|
337
|
+
r4 = SyntaxNode.new(input, index...index)
|
338
|
+
end
|
339
|
+
s2 << r4
|
340
|
+
end
|
341
|
+
if s2.last
|
342
|
+
r2 = (SyntaxNode).new(input, i2...index, s2)
|
343
|
+
r2.extend(Eol0)
|
344
|
+
else
|
345
|
+
self.index = i2
|
346
|
+
r2 = nil
|
347
|
+
end
|
348
|
+
if r2
|
349
|
+
r0 = r2
|
350
|
+
else
|
351
|
+
self.index = i0
|
352
|
+
r0 = nil
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
node_cache[:eol][start_index] = r0
|
357
|
+
|
358
|
+
return r0
|
359
|
+
end
|
360
|
+
|
361
|
+
def _nt_eof
|
362
|
+
start_index = index
|
363
|
+
if node_cache[:eof].has_key?(index)
|
364
|
+
cached = node_cache[:eof][index]
|
365
|
+
@index = cached.interval.end if cached
|
366
|
+
return cached
|
367
|
+
end
|
368
|
+
|
369
|
+
i0 = index
|
370
|
+
if index < input_length
|
371
|
+
r1 = (SyntaxNode).new(input, index...(index + 1))
|
372
|
+
@index += 1
|
373
|
+
else
|
374
|
+
terminal_parse_failure("any character")
|
375
|
+
r1 = nil
|
376
|
+
end
|
377
|
+
if r1
|
378
|
+
r0 = nil
|
379
|
+
else
|
380
|
+
self.index = i0
|
381
|
+
r0 = SyntaxNode.new(input, index...index)
|
382
|
+
end
|
383
|
+
|
384
|
+
node_cache[:eof][start_index] = r0
|
385
|
+
|
386
|
+
return r0
|
387
|
+
end
|
388
|
+
|
389
|
+
end
|
390
|
+
|
391
|
+
class TableParser < Treetop::Runtime::CompiledParser
|
392
|
+
include Table
|
393
|
+
end
|
394
|
+
|
395
|
+
end
|
396
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Parser
|
3
|
+
grammar Table
|
4
|
+
|
5
|
+
rule table
|
6
|
+
table_row+ {
|
7
|
+
def build
|
8
|
+
Ast::Table.new(raw)
|
9
|
+
end
|
10
|
+
|
11
|
+
def raw
|
12
|
+
elements.map{|e| e.build}
|
13
|
+
end
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
rule table_row
|
18
|
+
space* '|' cells:(cell '|')+ space* (eol+ / eof) {
|
19
|
+
def build
|
20
|
+
row = cells.elements.map do |elt|
|
21
|
+
value = elt.cell.text_value.strip
|
22
|
+
value.empty? ? nil : value
|
23
|
+
end
|
24
|
+
|
25
|
+
class << row
|
26
|
+
attr_accessor :line
|
27
|
+
end
|
28
|
+
row.line = cells.line
|
29
|
+
|
30
|
+
row
|
31
|
+
end
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
rule cell
|
36
|
+
(!('|' / eol) .)*
|
37
|
+
end
|
38
|
+
|
39
|
+
rule space
|
40
|
+
[ \t]
|
41
|
+
end
|
42
|
+
|
43
|
+
rule eol
|
44
|
+
"\n" / ("\r" "\n"?)
|
45
|
+
end
|
46
|
+
|
47
|
+
rule eof
|
48
|
+
!.
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,3 +1,46 @@
|
|
1
|
+
require 'treetop'
|
2
|
+
require 'treetop/runtime'
|
3
|
+
require 'treetop/ruby_extensions'
|
4
|
+
|
5
|
+
module Cucumber
|
6
|
+
module Parser
|
7
|
+
module TreetopExt
|
8
|
+
FILE_LINE_PATTERN = /^([\w\W]*?):([\d:]+)$/
|
9
|
+
|
10
|
+
# Parses a file and returns a Cucumber::Ast
|
11
|
+
def parse_file(file)
|
12
|
+
_, path, lines = *FILE_LINE_PATTERN.match(file)
|
13
|
+
if path
|
14
|
+
lines = lines.split(':').map { |line| line.to_i }
|
15
|
+
else
|
16
|
+
path = file
|
17
|
+
lines = []
|
18
|
+
end
|
19
|
+
|
20
|
+
feature = File.open(path, Cucumber.file_mode('r')) do |io|
|
21
|
+
parse_or_fail(io.read, path)
|
22
|
+
end
|
23
|
+
feature.lines = lines
|
24
|
+
feature
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class SyntaxError < StandardError
|
29
|
+
def initialize(parser, file, line_offset)
|
30
|
+
tf = parser.terminal_failures
|
31
|
+
expected = tf.size == 1 ? tf[0].expected_string.inspect : "one of #{tf.map{|f| f.expected_string.inspect}.uniq*', '}"
|
32
|
+
after = parser.input[parser.index...parser.failure_index]
|
33
|
+
found = parser.input[parser.failure_index..parser.failure_index]
|
34
|
+
|
35
|
+
line = parser.failure_line + line_offset
|
36
|
+
message = "#{file}:#{line}:#{parser.failure_column}: " +
|
37
|
+
"Parse error, expected #{expected}. After #{after.inspect}. Found: #{found.inspect}"
|
38
|
+
super(message)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
1
44
|
module Treetop
|
2
45
|
module Runtime
|
3
46
|
class SyntaxNode
|
@@ -5,5 +48,20 @@ module Treetop
|
|
5
48
|
input.line_of(interval.first)
|
6
49
|
end
|
7
50
|
end
|
51
|
+
|
52
|
+
class CompiledParser
|
53
|
+
include Cucumber::Parser::TreetopExt
|
54
|
+
|
55
|
+
def parse_or_fail(s, file=nil, line=0)
|
56
|
+
parse_tree = parse(s)
|
57
|
+
if parse_tree.nil?
|
58
|
+
raise Cucumber::Parser::SyntaxError.new(self, file, line)
|
59
|
+
else
|
60
|
+
ast = parse_tree.build
|
61
|
+
ast.file = file
|
62
|
+
ast
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
8
66
|
end
|
9
67
|
end
|
@@ -24,9 +24,13 @@ module Cucumber
|
|
24
24
|
|
25
25
|
attr_reader :regexp
|
26
26
|
|
27
|
-
def initialize(
|
27
|
+
def initialize(pattern, &proc)
|
28
28
|
raise MissingProc if proc.nil?
|
29
|
-
|
29
|
+
if String === pattern
|
30
|
+
p = pattern.gsub(/\$\w+/, '(.*)')
|
31
|
+
pattern = Regexp.new("^#{p}$")
|
32
|
+
end
|
33
|
+
@regexp, @proc = pattern, proc
|
30
34
|
end
|
31
35
|
|
32
36
|
#:stopdoc:
|
data/lib/cucumber/step_mother.rb
CHANGED
@@ -130,12 +130,22 @@ module Cucumber
|
|
130
130
|
# Call a step from within a step definition
|
131
131
|
def __cucumber_invoke(name, *multiline_arguments)
|
132
132
|
begin
|
133
|
-
|
133
|
+
# TODO: Very similar to code in Step. Refactor. Get back StepInvocation?
|
134
|
+
# Make more similar to JBehave?
|
135
|
+
step_definition = @__cucumber_step_mother.step_definition(name)
|
136
|
+
matched_args = step_definition.matched_args(name)
|
137
|
+
args = (matched_args + multiline_arguments)
|
138
|
+
step_definition.execute(name, self, *args)
|
134
139
|
rescue Exception => e
|
135
140
|
@__cucumber_current_step.exception = e
|
136
141
|
raise e
|
137
142
|
end
|
138
143
|
end
|
144
|
+
|
145
|
+
def table(text, file=nil, line=0)
|
146
|
+
@table_parser ||= Parser::TableParser.new
|
147
|
+
@table_parser.parse_or_fail(text.strip, file, line)
|
148
|
+
end
|
139
149
|
|
140
150
|
def pending(message = "TODO")
|
141
151
|
if block_given?
|
data/lib/cucumber/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aslakhellesoy-cucumber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.99.
|
4
|
+
version: 0.1.99.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Aslak Helles\xC3\xB8y"
|
@@ -172,7 +172,6 @@ files:
|
|
172
172
|
- examples/jbehave/features/support/env.rb
|
173
173
|
- examples/jbehave/features/trading.feature
|
174
174
|
- examples/jbehave/pom.xml
|
175
|
-
- examples/jbehave/target/maven-archiver/pom.properties
|
176
175
|
- examples/selenium/Rakefile
|
177
176
|
- examples/selenium/features/search.feature
|
178
177
|
- examples/selenium/features/step_definitons/stories_steps.rb
|
@@ -259,8 +258,9 @@ files:
|
|
259
258
|
- lib/cucumber/parser/basic.rb
|
260
259
|
- lib/cucumber/parser/feature.rb
|
261
260
|
- lib/cucumber/parser/feature.tt
|
262
|
-
- lib/cucumber/parser/file_parser.rb
|
263
261
|
- lib/cucumber/parser/i18n.tt
|
262
|
+
- lib/cucumber/parser/table.rb
|
263
|
+
- lib/cucumber/parser/table.tt
|
264
264
|
- lib/cucumber/parser/treetop_ext.rb
|
265
265
|
- lib/cucumber/platform.rb
|
266
266
|
- lib/cucumber/rails/rspec.rb
|
@@ -1,50 +0,0 @@
|
|
1
|
-
module Cucumber
|
2
|
-
module Parser
|
3
|
-
module FileParser
|
4
|
-
FILE_LINE_PATTERN = /^([\w\W]*?):([\d:]+)$/
|
5
|
-
|
6
|
-
# Parses a file and returns a Cucumber::Ast
|
7
|
-
def parse_file(file)
|
8
|
-
_, path, lines = *FILE_LINE_PATTERN.match(file)
|
9
|
-
if path
|
10
|
-
lines = lines.split(':').map { |line| line.to_i }
|
11
|
-
else
|
12
|
-
path = file
|
13
|
-
lines = []
|
14
|
-
end
|
15
|
-
|
16
|
-
feature = File.open(path, Cucumber.file_mode('r')) do |io|
|
17
|
-
parse_or_fail(io.read, path)
|
18
|
-
end
|
19
|
-
feature.lines = lines
|
20
|
-
feature
|
21
|
-
end
|
22
|
-
|
23
|
-
def parse_or_fail(s, file=nil)
|
24
|
-
parse_tree = parse(s)
|
25
|
-
if parse_tree.nil?
|
26
|
-
raise SyntaxError.new(file, self)
|
27
|
-
else
|
28
|
-
ast = parse_tree.build
|
29
|
-
ast.file = file
|
30
|
-
ast
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
class SyntaxError < StandardError
|
36
|
-
def initialize(file, parser)
|
37
|
-
tf = parser.terminal_failures
|
38
|
-
expected = tf.size == 1 ? tf[0].expected_string.inspect : "one of #{tf.map{|f| f.expected_string.inspect}.uniq*', '}"
|
39
|
-
after = parser.input[parser.index...parser.failure_index]
|
40
|
-
found = parser.input[parser.failure_index..parser.failure_index]
|
41
|
-
@message = "#{file}:#{parser.failure_line}:#{parser.failure_column}: " +
|
42
|
-
"Parse error, expected #{expected}. After #{after.inspect}. Found: #{found.inspect}"
|
43
|
-
end
|
44
|
-
|
45
|
-
def message
|
46
|
-
@message
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|