gherkin 2.12.1 → 2.12.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.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/History.md +11 -0
  4. data/README.md +1 -1
  5. data/ext/gherkin_lexer_el/gherkin_lexer_el.c +642 -700
  6. data/ext/gherkin_lexer_kn/extconf.rb +6 -0
  7. data/ext/gherkin_lexer_kn/gherkin_lexer_kn.c +1965 -0
  8. data/gherkin.gemspec +5 -5
  9. data/lib/gherkin/formatter/filter_formatter.rb +5 -1
  10. data/lib/gherkin/formatter/pretty_formatter.rb +3 -2
  11. data/lib/gherkin/i18n.json +15 -1
  12. data/lib/gherkin/lexer/ar.rb +1074 -1071
  13. data/lib/gherkin/lexer/bg.rb +1286 -1283
  14. data/lib/gherkin/lexer/bm.rb +1154 -1151
  15. data/lib/gherkin/lexer/ca.rb +1214 -1211
  16. data/lib/gherkin/lexer/cs.rb +1150 -1147
  17. data/lib/gherkin/lexer/cy_gb.rb +936 -933
  18. data/lib/gherkin/lexer/da.rb +952 -949
  19. data/lib/gherkin/lexer/de.rb +1070 -1067
  20. data/lib/gherkin/lexer/el.rb +1532 -1581
  21. data/lib/gherkin/lexer/en.rb +1060 -1057
  22. data/lib/gherkin/lexer/en_au.rb +1390 -1387
  23. data/lib/gherkin/lexer/en_lol.rb +876 -873
  24. data/lib/gherkin/lexer/en_old.rb +941 -938
  25. data/lib/gherkin/lexer/en_pirate.rb +1114 -1111
  26. data/lib/gherkin/lexer/en_scouse.rb +1266 -1263
  27. data/lib/gherkin/lexer/en_tx.rb +958 -955
  28. data/lib/gherkin/lexer/eo.rb +937 -934
  29. data/lib/gherkin/lexer/es.rb +1044 -1041
  30. data/lib/gherkin/lexer/et.rb +932 -929
  31. data/lib/gherkin/lexer/fa.rb +1118 -1115
  32. data/lib/gherkin/lexer/fi.rb +911 -908
  33. data/lib/gherkin/lexer/fr.rb +1132 -1129
  34. data/lib/gherkin/lexer/gl.rb +1021 -1018
  35. data/lib/gherkin/lexer/he.rb +1022 -1019
  36. data/lib/gherkin/lexer/hi.rb +1463 -1460
  37. data/lib/gherkin/lexer/hr.rb +970 -967
  38. data/lib/gherkin/lexer/hu.rb +1022 -1019
  39. data/lib/gherkin/lexer/id.rb +905 -902
  40. data/lib/gherkin/lexer/is.rb +1024 -1021
  41. data/lib/gherkin/lexer/it.rb +990 -987
  42. data/lib/gherkin/lexer/ja.rb +1322 -1319
  43. data/lib/gherkin/lexer/kn.rb +1672 -0
  44. data/lib/gherkin/lexer/ko.rb +1006 -1003
  45. data/lib/gherkin/lexer/lt.rb +949 -946
  46. data/lib/gherkin/lexer/lu.rb +1036 -1033
  47. data/lib/gherkin/lexer/lv.rb +1070 -1067
  48. data/lib/gherkin/lexer/nl.rb +1019 -1016
  49. data/lib/gherkin/lexer/no.rb +964 -961
  50. data/lib/gherkin/lexer/pa.rb +1756 -1753
  51. data/lib/gherkin/lexer/pl.rb +1361 -1358
  52. data/lib/gherkin/lexer/pt.rb +1334 -1331
  53. data/lib/gherkin/lexer/ro.rb +1068 -1065
  54. data/lib/gherkin/lexer/ru.rb +1670 -1667
  55. data/lib/gherkin/lexer/sk.rb +1356 -1353
  56. data/lib/gherkin/lexer/sr_cyrl.rb +1707 -1704
  57. data/lib/gherkin/lexer/sr_latn.rb +1198 -1195
  58. data/lib/gherkin/lexer/sv.rb +974 -971
  59. data/lib/gherkin/lexer/th.rb +2396 -2393
  60. data/lib/gherkin/lexer/tl.rb +1630 -1627
  61. data/lib/gherkin/lexer/tr.rb +996 -993
  62. data/lib/gherkin/lexer/tt.rb +1547 -1544
  63. data/lib/gherkin/lexer/uk.rb +1550 -1547
  64. data/lib/gherkin/lexer/uz.rb +1280 -1277
  65. data/lib/gherkin/lexer/vi.rb +1102 -1099
  66. data/lib/gherkin/lexer/zh_cn.rb +962 -959
  67. data/lib/gherkin/lexer/zh_tw.rb +956 -953
  68. data/lib/gherkin/listener/formatter_listener.rb +13 -6
  69. data/lib/gherkin/platform.rb +2 -2
  70. data/lib/gherkin/tag_expression.rb +1 -0
  71. data/ragel/lexer.js.rl.erb +109 -14
  72. data/ragel/lexer.rb.rl.erb +3 -0
  73. data/spec/gherkin/i18n_spec.rb +1 -0
  74. data/spec/gherkin/json_parser_spec.rb +10 -22
  75. data/spec/gherkin/lexer/i18n_lexer_spec.rb +7 -3
  76. data/spec/gherkin/parser/parser_spec.rb +1 -1
  77. data/spec/gherkin/rubify_spec.rb +1 -1
  78. data/spec/gherkin/shared/doc_string_group.rb +0 -2
  79. data/spec/gherkin/shared/encoding_group.rb +0 -2
  80. data/spec/gherkin/shared/lexer_group.rb +0 -2
  81. data/spec/gherkin/shared/row_group.rb +0 -2
  82. data/spec/gherkin/shared/tags_group.rb +0 -2
  83. data/spec/spec_helper.rb +21 -7
  84. data/tasks/ikvm.rake +2 -2
  85. data/tasks/ragel_task.rb +8 -0
  86. data/tasks/rspec.rake +1 -1
  87. metadata +25 -21
@@ -12,6 +12,7 @@ module Gherkin
12
12
  def initialize(formatter)
13
13
  @formatter = formatter
14
14
  @stash = Stash.new
15
+ @current_builder = nil
15
16
  end
16
17
 
17
18
  def comment(value, line)
@@ -57,13 +58,13 @@ module Gherkin
57
58
 
58
59
  def step(keyword, name, line)
59
60
  replay_step_or_examples
60
- @stash.basic_statement do |comments, id|
61
+ @stash.step do |comments|
61
62
  @current_builder = Formatter::Model::Step::Builder.new(comments, keyword, name, line)
62
63
  end
63
64
  end
64
65
 
65
66
  def row(cells, line)
66
- @stash.basic_statement do |comments, id|
67
+ @stash.row do |comments, id|
67
68
  @current_builder.row(comments, cells, line, id)
68
69
  end
69
70
  end
@@ -117,13 +118,19 @@ module Gherkin
117
118
  yield @comments, @tags, @examples_id
118
119
  @comments, @tags = [], []
119
120
  end
120
-
121
- def basic_statement
121
+
122
+ def step
122
123
  @row_index += 1
123
- yield @comments, "#{@examples_id};#{@row_index}"
124
+ yield @comments
124
125
  @comments = []
125
126
  end
126
-
127
+
128
+ def row
129
+ @row_index += 1
130
+ yield @comments, defined?(@examples_id) ? "#{@examples_id};#{@row_index}" : :undefined_examples_id
131
+ @comments = []
132
+ end
133
+
127
134
  def tag(tag)
128
135
  @tags << tag
129
136
  end
@@ -3,8 +3,8 @@
3
3
  module Gherkin
4
4
  unless defined?(Gherkin::VERSION)
5
5
  # See the comment in gherkin.gemspec if you bump the MINOR version (MAJOR.MINOR.PATCH).
6
- VERSION = '2.12.1'
7
- JRUBY = defined?(JRUBY_VERSION)
6
+ VERSION = '2.12.2'
7
+ JRUBY = defined?(JRUBY_VERSION)
8
8
 
9
9
  if !JRUBY && !(RUBY_VERSION =~ /^(1\.9\.3|2\.0)/)
10
10
  warn("WARNING: Unsupported Ruby version - #{RUBY_VERSION}")
@@ -21,6 +21,7 @@ module Gherkin
21
21
  def evaluate(tags)
22
22
  return true if @ands.flatten.empty?
23
23
  vars = Hash[*tags.map{|tag| [tag.name, true]}.flatten]
24
+ raise "No vars" if vars.nil? # Useless statement to prevent ruby warnings about unused var
24
25
  !!Kernel.eval(ruby_expression)
25
26
  end
26
27
 
@@ -115,7 +115,7 @@
115
115
  action end_feature {
116
116
  if(this.cs < lexer_first_final) {
117
117
  var content = this.current_line_content(data, p);
118
- throw "Lexing error on line " + this.line_number + ": '" + content + "'. See http://wiki.github.com/cucumber/gherkin/lexingerror for more information.";
118
+ throw new Error("Lexing error on line " + this.line_number + ": '" + content + "'. See http://wiki.github.com/cucumber/gherkin/lexingerror for more information.");
119
119
  } else {
120
120
  this.listener.eof();
121
121
  }
@@ -128,6 +128,7 @@
128
128
  %% write data;
129
129
  %% access this.;
130
130
  %% variable data data;
131
+ %% getkey signedCharValue(data[p]);
131
132
 
132
133
  var Lexer = function(listener) {
133
134
  // Check that listener has the required functions
@@ -135,7 +136,7 @@ var Lexer = function(listener) {
135
136
  for(var i=0, len=events.length; i<len; i++) {
136
137
  var event = events[i];
137
138
  if(typeof listener[event] != 'function') {
138
- throw "Error. No " + event + " function exists on " + JSON.stringify(listener);
139
+ throw new Error("Error. No " + event + " function exists on " + JSON.stringify(listener));
139
140
  }
140
141
  }
141
142
  this.listener = listener;
@@ -157,30 +158,124 @@ Lexer.prototype.scan = function(data) {
157
158
 
158
159
  this.line_number = 1;
159
160
  this.last_newline = 0;
161
+ var signedCharValue=function(v){return v > 127 ? v-256 : v; };
160
162
 
161
163
  %% write init;
162
164
  %% write exec;
163
165
  };
164
166
 
167
+
168
+ /*
169
+ * Decode utf-8 byte sequence to string.
170
+ */
171
+ var decodeUtf8 = function(bytes) {
172
+ var result = "";
173
+ var i = 0;
174
+ var wc;
175
+ var c;
176
+
177
+ while (i < bytes.length) {
178
+ /* parse as UTF-8 lead byte */
179
+ wc = bytes[i++];
180
+ if (wc < 0x80) {
181
+ count = 0;
182
+ } else if (wc < 0xC2 || wc >= 0xF8) {
183
+ throw new Error("input is not a valid UTF-8 lead octet");
184
+ } else if (wc < 0xE0) {
185
+ count = 1;
186
+ wc = (wc & 0x1F) << 6;
187
+ } else if (wc < 0xF0) {
188
+ count = 2;
189
+ wc = (wc & 0x0F) << 12;
190
+ } else /* wc < 0xF8 */ {
191
+ count = 3;
192
+ wc = (wc & 0x07) << 18;
193
+ }
194
+
195
+ /* parse trail bytes, if any */
196
+ while (count) {
197
+ if (!(i < bytes.length)) {
198
+ throw new Error("short read");
199
+ }
200
+ if ((c = bytes[i++] ^ 0x80) > 0x3F) {
201
+ throw new Error("input is not a valid UTF-8 trail octet");
202
+ }
203
+ wc |= c << (6 * --count);
204
+ if (wc < (1 << (5 * count + 6))) {
205
+ throw new Error("invalid non-minimal encoded input");
206
+ }
207
+ }
208
+
209
+ /* handle conversion to UTF-16 if needed */
210
+ if (wc > 0xFFFF) {
211
+ wc -= 0x10000;
212
+ result += String.fromCharCode(0xD800 + (wc >> 10));
213
+ wc = 0xDC00 + (wc & 0x3FF);
214
+ }
215
+ result += String.fromCharCode(wc);
216
+ }
217
+
218
+ return result;
219
+ };
220
+
221
+ /*
222
+ * Encode string to an array of bytes using utf8 encoding.
223
+ *
224
+ * Javascript internally stores character data as utf16 (like java).
225
+ * String.charCodeAt() does *not* produce unicode points, but simply
226
+ * reflects this internal representation. Thus, it is necessary
227
+ * to first decode the utf-16 representation before encoding to
228
+ * utf-8.
229
+ */
230
+ var encodeUtf8 = function(string) {
231
+ var bytes = [];
232
+ var i = 0;
233
+ var j = 0;
234
+ var wc;
235
+
236
+ while (i < string.length) {
237
+ wc = string.charCodeAt(i++);
238
+ if (wc >= 0xD800 && wc <= 0xDBFF && i < string.length && string.charCodeAt(i) >= 0xDC00 && string.charCodeAt(i) <= 0xDFFF) {
239
+ /* decode UTF-16 */
240
+ wc = 0x10000 + ((wc & 0x3FF) << 10) + (string.charCodeAt(i++) & 0x3FF);
241
+ }
242
+
243
+ /* emit lead byte */
244
+ if (wc < 0x80) {
245
+ bytes[j++] = wc;
246
+ count = 0;
247
+ } else if (wc < 0x800) {
248
+ bytes[j++] = 0xC0 | (wc >> 6);
249
+ count = 1;
250
+ } else if (wc < 0x10000) {
251
+ bytes[j++] = 0xE0 | (wc >> 12);
252
+ count = 2;
253
+ } else {
254
+ /* SMP: 21-bit Unicode */
255
+ bytes[j++] = 0xF0 | (wc >> 18);
256
+ count = 3;
257
+ }
258
+
259
+ /* emit trail bytes, if any */
260
+ while (count) {
261
+ bytes[j++] = 0x80 | ((wc >> (6 * --count)) & 0x3F);
262
+ }
263
+ }
264
+
265
+ return bytes;
266
+
267
+ };
268
+
165
269
  Lexer.prototype.bytesToString = function(bytes) {
166
270
  if(typeof bytes.write == 'function') {
167
271
  // Node.js
168
272
  return bytes.toString('utf-8');
169
- } else {
170
- var result = "";
171
- for(var b in bytes) {
172
- result += String.fromCharCode(bytes[b]);
173
- }
174
- return result;
175
273
  }
274
+ return decodeUtf8(bytes);
176
275
  };
177
276
 
178
277
  Lexer.prototype.stringToBytes = function(string) {
179
- var bytes = [];
180
- for(var i = 0; i < string.length; i++) {
181
- bytes[i] = string.charCodeAt(i);
182
- }
183
- return bytes;
278
+ return encodeUtf8(string);
184
279
  };
185
280
 
186
281
  Lexer.prototype.unindent = function(startcol, text) {
@@ -202,7 +297,7 @@ Lexer.prototype.store_keyword_content = function(event, data, p, eof) {
202
297
  };
203
298
 
204
299
  Lexer.prototype.current_line_content = function(data, p) {
205
- var rest = data.slice(this.last_newline, -1);
300
+ var rest = Array.prototype.slice.call(data,this.last_newline, -1);
206
301
  var end = rest.indexOf(10) || -1;
207
302
  return this.bytesToString(rest.slice(0, end)).trim();
208
303
  };
@@ -126,6 +126,9 @@ module Gherkin
126
126
 
127
127
  def initialize(listener)
128
128
  @listener = listener
129
+
130
+ # Initialize ivars to avoid warnings
131
+ @keyword = nil
129
132
  %% write data;
130
133
  end
131
134
 
@@ -198,6 +198,7 @@ module Gherkin
198
198
  | is | Icelandic | Íslenska |
199
199
  | it | Italian | italiano |
200
200
  | ja | Japanese | 日本語 |
201
+ | kn | Kannada | ಕನ್ನಡ |
201
202
  | ko | Korean | 한국어 |
202
203
  | lt | Lithuanian | lietuvių kalba |
203
204
  | lu | Luxemburgish | Lëtzebuergesch |
@@ -98,28 +98,6 @@ module Gherkin
98
98
  {
99
99
  "id":"one/a-scenario",
100
100
  "type":"scenario",
101
- "before": [
102
- {
103
- "match":{
104
- "location":"features/step_definitions/hooks.rb:1"
105
- },
106
- "result":{
107
- "status":"passed",
108
- "error_message":"Passed hook",
109
- "duration": 3
110
- }
111
- },
112
- {
113
- "match":{
114
- "location":"features/step_definitions/hooks.rb:2"
115
- },
116
- "result":{
117
- "status":"failed",
118
- "error_message":"Failed hook",
119
- "duration": 22
120
- }
121
- }
122
- ],
123
101
  "steps":[
124
102
  {
125
103
  "keyword":"Given ",
@@ -152,6 +130,16 @@ module Gherkin
152
130
  }
153
131
  ],
154
132
  "after": [
133
+ {
134
+ "match":{
135
+ "location":"features/step_definitions/hooks.rb:1"
136
+ },
137
+ "result":{
138
+ "status":"passed",
139
+ "error_message":"Passed after",
140
+ "duration": 3
141
+ }
142
+ },
155
143
  {
156
144
  "match":{
157
145
  "location":"features/step_definitions/hooks.rb:3"
@@ -11,9 +11,13 @@ module Gherkin
11
11
 
12
12
  it "should store the i18n language of the last scanned feature" do
13
13
  @lexer.scan("# language: fr\n")
14
- @lexer.i18n_language.iso_code.should == "fr"
15
- @lexer.scan("# language: no\n")
16
- @lexer.i18n_language.iso_code.should == "no"
14
+ # This if is kind of dumb - it's just to avoid warnings from ruby
15
+ if(@lexer.i18n_language.iso_code.should == "fr")
16
+ @lexer.scan("# language: no\n")
17
+ @lexer.i18n_language.iso_code.should == "no"
18
+ else
19
+ fail
20
+ end
17
21
  end
18
22
 
19
23
  it "should detect language when there are spaces and CRLF" do
@@ -5,7 +5,7 @@ module Gherkin
5
5
  describe Parser do
6
6
  unless defined?(JRUBY_VERSION)
7
7
  it "should raise when feature doesn't parse" do
8
- p = Parser.new(mock('formatter').as_null_object)
8
+ p = Parser.new(double('formatter').as_null_object)
9
9
  lambda do
10
10
  p.parse("Feature: f\nFeature: f", __FILE__, __LINE__-1)
11
11
  end.should raise_error(Regexp.new("Parse error at #{__FILE__}:\\d+"))
@@ -7,7 +7,7 @@ if defined?(JRUBY_VERSION)
7
7
  module Rubify
8
8
  describe "rubify" do
9
9
  before do
10
- @java_collection = [mock("Java.java.util.ArrayList")]
10
+ @java_collection = [double("Java.java.util.ArrayList")]
11
11
  @java_collection.stub(:===).and_return(Java.java.util.Collection)
12
12
  @java_collection.stub(:line).and_return(15)
13
13
  @rubified_array = rubify(@java_collection)
@@ -1,6 +1,4 @@
1
1
  # encoding: utf-8
2
- require 'spec_helper'
3
-
4
2
  module Gherkin
5
3
  module Lexer
6
4
  shared_examples_for "a Gherkin lexer lexing doc_strings" do
@@ -1,6 +1,4 @@
1
1
  #encoding: utf-8
2
- require 'spec_helper'
3
-
4
2
  module Gherkin
5
3
  module Lexer
6
4
  shared_examples_for "encoding" do
@@ -1,6 +1,4 @@
1
1
  #encoding: utf-8
2
- require 'spec_helper'
3
-
4
2
  module Gherkin
5
3
  module Lexer
6
4
  shared_examples_for "a Gherkin lexer" do
@@ -1,6 +1,4 @@
1
1
  # encoding: utf-8
2
- require 'spec_helper'
3
-
4
2
  module Gherkin
5
3
  module Lexer
6
4
  shared_examples_for "a Gherkin lexer lexing rows" do
@@ -1,6 +1,4 @@
1
1
  # encoding: utf-8
2
- require 'spec_helper'
3
-
4
2
  module Gherkin
5
3
  module Lexer
6
4
  shared_examples_for "a Gherkin lexer lexing tags" do
@@ -1,6 +1,16 @@
1
+ def silence_warnings(&block)
2
+ warn_level = $VERBOSE
3
+ $VERBOSE = nil
4
+ result = block.call
5
+ $VERBOSE = warn_level
6
+ result
7
+ end
8
+
1
9
  if RUBY_VERSION =~ /1\.9|2\.0/
2
- Encoding.default_external = Encoding::UTF_8
3
- Encoding.default_internal = Encoding::UTF_8
10
+ silence_warnings do
11
+ Encoding.default_external = Encoding::UTF_8
12
+ Encoding.default_internal = Encoding::UTF_8
13
+ end
4
14
  end
5
15
  if defined?(JRUBY_VERSION)
6
16
  java_import java.util.ArrayList
@@ -30,7 +40,7 @@ module GherkinSpecHelper
30
40
 
31
41
  def fixture(file)
32
42
  encoding = Gherkin::Lexer::Encoding.new
33
- source = encoding.read_file(File.dirname(__FILE__) + "/gherkin/fixtures/" + file)
43
+ encoding.read_file(File.dirname(__FILE__) + "/gherkin/fixtures/" + file)
34
44
  end
35
45
 
36
46
  def rubify_hash(hash)
@@ -51,8 +61,10 @@ end
51
61
  # Allows comparison of Java List with Ruby Array (rows)
52
62
  RSpec::Matchers.define :r do |expected|
53
63
  match do |row|
54
- def row.inspect
55
- "r " + self.map{|cell| cell}.inspect
64
+ silence_warnings do
65
+ def row.inspect
66
+ "r " + self.map{|cell| cell}.inspect
67
+ end
56
68
  end
57
69
  row.map{|cell| cell}.should == expected
58
70
  end
@@ -60,8 +72,10 @@ end
60
72
 
61
73
  RSpec::Matchers.define :a do |expected|
62
74
  match do |array|
63
- def array.inspect
64
- "a " + self.map{|e| e.to_sym}.inspect
75
+ silence_warnings do
76
+ def array.inspect
77
+ "a " + self.map{|e| e.to_sym}.inspect
78
+ end
65
79
  end
66
80
  array.map{|e| e.to_sym}.should == expected
67
81
  end
@@ -55,8 +55,8 @@ namespace :ikvm do
55
55
  mkdir_p File.dirname(pkg_dir) unless File.directory?(pkg_dir)
56
56
  nuget("Pack #{GHERKIN_NUSPEC} -Version #{GHERKIN_VERSION} -OutputDirectory #{pkg_dir}")
57
57
  # Now, verify that we have a proper dll inside the package
58
- require 'zip/zipfilesystem'
59
- Zip::ZipFile.open(GHERKIN_NUPKG) do |zipfile|
58
+ require 'zip'
59
+ Zip::File.open(GHERKIN_NUPKG) do |zipfile|
60
60
  dll = zipfile.get_entry('lib/gherkin.dll')
61
61
  if(dll.size < 3_000_000)
62
62
  raise "Looks like the dll is too small."
@@ -39,6 +39,14 @@ class RagelTask
39
39
  # Minify
40
40
  sh %{node #{UGLIFYJS} #{target} > #{min_target}}
41
41
  end
42
+
43
+ if(@lang == 'rb')
44
+ # Prettify the code so we don't get indentation warnings
45
+ sh %{rbeautify #{target} > tmp.rb}
46
+ sh %{mv tmp.rb #{target}}
47
+ # rbeautify has a bug with class << self ... end alignment. Fix it.
48
+ sh %{perl -i -0pe 's/ end\n self._/ end\n self._/g' #{target}}
49
+ end
42
50
  end
43
51
 
44
52
  if(@lang != 'java')