gherkin 2.3.5-universal-dotnet → 2.3.6-universal-dotnet

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 (74) hide show
  1. data/.gitmodules +3 -0
  2. data/Gemfile +1 -1
  3. data/History.txt +9 -0
  4. data/README.rdoc +34 -2
  5. data/VERSION +1 -1
  6. data/features/step_definitions/pretty_formatter_steps.rb +1 -0
  7. data/gherkin.gemspec +4 -1
  8. data/js/.gitignore +1 -0
  9. data/js/.npmignore +1 -0
  10. data/js/lib/gherkin/lexer/.gitignore +1 -0
  11. data/lib/gherkin/i18n.rb +5 -0
  12. data/lib/gherkin/i18n.yml +3 -3
  13. data/lib/gherkin/js_lexer.rb +20 -0
  14. data/lib/gherkin/lexer/i18n_lexer.rb +1 -1
  15. data/lib/gherkin/rubify.rb +7 -0
  16. data/ragel/lexer.c.rl.erb +30 -32
  17. data/ragel/lexer.js.rl.erb +208 -0
  18. data/ragel/lexer.rb.rl.erb +1 -1
  19. data/spec/gherkin/c_lexer_spec.rb +1 -0
  20. data/spec/gherkin/js_lexer_spec.rb +23 -0
  21. data/spec/gherkin/rb_lexer_spec.rb +1 -0
  22. data/spec/gherkin/sexp_recorder.rb +14 -8
  23. data/spec/gherkin/shared/bom_group.rb +20 -0
  24. data/spec/gherkin/shared/lexer_group.rb +0 -10
  25. data/spec/spec_helper.rb +2 -0
  26. data/tasks/compile.rake +9 -0
  27. data/tasks/ikvm.rake +1 -0
  28. data/tasks/ragel_task.rb +8 -2
  29. data/tasks/release.rake +8 -1
  30. metadata +29 -52
  31. data/js/lib/gherkin/lexer/i18n/ar.js +0 -1094
  32. data/js/lib/gherkin/lexer/i18n/bg.js +0 -1308
  33. data/js/lib/gherkin/lexer/i18n/ca.js +0 -1236
  34. data/js/lib/gherkin/lexer/i18n/cs.js +0 -1090
  35. data/js/lib/gherkin/lexer/i18n/cy_gb.js +0 -958
  36. data/js/lib/gherkin/lexer/i18n/da.js +0 -974
  37. data/js/lib/gherkin/lexer/i18n/de.js +0 -1082
  38. data/js/lib/gherkin/lexer/i18n/en.js +0 -965
  39. data/js/lib/gherkin/lexer/i18n/en_au.js +0 -902
  40. data/js/lib/gherkin/lexer/i18n/en_lol.js +0 -859
  41. data/js/lib/gherkin/lexer/i18n/en_pirate.js +0 -1136
  42. data/js/lib/gherkin/lexer/i18n/en_scouse.js +0 -1289
  43. data/js/lib/gherkin/lexer/i18n/en_tx.js +0 -942
  44. data/js/lib/gherkin/lexer/i18n/eo.js +0 -916
  45. data/js/lib/gherkin/lexer/i18n/es.js +0 -1049
  46. data/js/lib/gherkin/lexer/i18n/et.js +0 -915
  47. data/js/lib/gherkin/lexer/i18n/fi.js +0 -894
  48. data/js/lib/gherkin/lexer/i18n/fr.js +0 -1116
  49. data/js/lib/gherkin/lexer/i18n/he.js +0 -1044
  50. data/js/lib/gherkin/lexer/i18n/hr.js +0 -994
  51. data/js/lib/gherkin/lexer/i18n/hu.js +0 -1043
  52. data/js/lib/gherkin/lexer/i18n/id.js +0 -884
  53. data/js/lib/gherkin/lexer/i18n/it.js +0 -1007
  54. data/js/lib/gherkin/lexer/i18n/ja.js +0 -1344
  55. data/js/lib/gherkin/lexer/i18n/ko.js +0 -1028
  56. data/js/lib/gherkin/lexer/i18n/lt.js +0 -972
  57. data/js/lib/gherkin/lexer/i18n/lu.js +0 -1057
  58. data/js/lib/gherkin/lexer/i18n/lv.js +0 -1092
  59. data/js/lib/gherkin/lexer/i18n/nl.js +0 -1036
  60. data/js/lib/gherkin/lexer/i18n/no.js +0 -986
  61. data/js/lib/gherkin/lexer/i18n/pl.js +0 -1140
  62. data/js/lib/gherkin/lexer/i18n/pt.js +0 -1000
  63. data/js/lib/gherkin/lexer/i18n/ro.js +0 -1089
  64. data/js/lib/gherkin/lexer/i18n/ru.js +0 -1560
  65. data/js/lib/gherkin/lexer/i18n/sk.js +0 -972
  66. data/js/lib/gherkin/lexer/i18n/sr_cyrl.js +0 -1728
  67. data/js/lib/gherkin/lexer/i18n/sr_latn.js +0 -1220
  68. data/js/lib/gherkin/lexer/i18n/sv.js +0 -997
  69. data/js/lib/gherkin/lexer/i18n/tr.js +0 -1014
  70. data/js/lib/gherkin/lexer/i18n/uk.js +0 -1572
  71. data/js/lib/gherkin/lexer/i18n/uz.js +0 -1302
  72. data/js/lib/gherkin/lexer/i18n/vi.js +0 -1124
  73. data/js/lib/gherkin/lexer/i18n/zh_cn.js +0 -902
  74. data/js/lib/gherkin/lexer/i18n/zh_tw.js +0 -940
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "js/example/ace"]
2
+ path = js/example/ace
3
+ url = git://github.com/cucumber/ace.git
data/Gemfile CHANGED
@@ -1,7 +1,7 @@
1
1
  source "http://rubygems.org"
2
2
  gemspec
3
3
 
4
- unless ENV['TM_RUBY']
4
+ if !ENV['TM_RUBY'] && File.directory?('../cucumber')
5
5
  @dependencies.reject!{|dep| dep.name == 'cucumber'}
6
6
  gem 'cucumber', :path => '../cucumber'
7
7
  end
data/History.txt CHANGED
@@ -1,3 +1,12 @@
1
+ == 2.3.6 (2011-04-19)
2
+
3
+ === New Features
4
+ * Javascript implementation (#38 Aslak Hellesøy)
5
+
6
+ === Bugfixes
7
+ * Fix compilation error on Arch Linux (#98,#99 Ben Hamill)
8
+ * Corrected Russian translation (#97 Vagif Abilov)
9
+
1
10
  == 2.3.5 (2011-03-20)
2
11
 
3
12
  === Changes
data/README.rdoc CHANGED
@@ -9,9 +9,9 @@ Supported platforms:
9
9
 
10
10
  * Ruby 1.8.6-1.9.2 (MRI, JRuby, REE, Rubinius)
11
11
  * Pure Java
12
+ * Javascript (Tested with V8/node.js/Chrome, but might work on other Javascript engines)
12
13
  * .NET
13
14
  * IronRuby (experimental)
14
- * Javascript (coming soon)
15
15
 
16
16
  == Installing the toolchain
17
17
 
@@ -67,6 +67,36 @@ Now you can build the jar with:
67
67
 
68
68
  rake clean jar
69
69
 
70
+ === Javascript
71
+
72
+ In order to build and test Gherkin for Javascript you must install:
73
+
74
+ * Node.js (0.4.6 or higher)
75
+ * NPM (0.3.18 or higher)
76
+ * Ragel with Javascript support: http://github.com/dominicmarks/ragel-js
77
+ * Define the GHERKIN_JS environment variable in your shell (any value will do)
78
+
79
+ Now you can build the Javascript with:
80
+
81
+ rake js
82
+ cd js
83
+ npm install
84
+
85
+ And you can try it out with node.js:
86
+
87
+ node js/example/print.js spec/gherkin/fixtures/1.feature
88
+
89
+ You can also try out Gherkin running in the browser (likely to move to a separate project):
90
+
91
+ # Pull in the Ace (http://ace.ajax.org/) editor:
92
+ git submodule update --init
93
+ # Open a sample Gherkin-powered editor in Chrome
94
+ open js/example/index.html
95
+
96
+ If you're hacking and just want to rebuild the English parser:
97
+
98
+ rake js/lib/gherkin/lexer/en.js
99
+
70
100
  === .NET and IronRuby
71
101
 
72
102
  You must install Mono and IKVM to build the pure .NET dll and the IronRuby gem:
@@ -125,9 +155,11 @@ Make sure you have openssl installed first.
125
155
 
126
156
  == Release process
127
157
 
158
+ * Make sure GHERKIN_JS is defined (see Javascript section above)
128
159
  * Bump version in the VERSION file and:
129
160
  ** java/pom.xml
130
- ** ikvm/Gherkin/Gherkin.csproj
161
+ ** ikvm/Gherkin/Gherkin.csproj (2 places)
162
+ ** js/package.json
131
163
  * Commit changes.
132
164
  * rake gems:prepare && ./build_native_gems.sh && rake release:ALL
133
165
  * Announce on Cucumber list, IRC and Twitter.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.5
1
+ 2.3.6
@@ -59,6 +59,7 @@ When /^I send each prettified original through the "([^"]*)" machinery$/ do |mac
59
59
  @error = false
60
60
  @feature_paths.each do |feature_path|
61
61
  begin
62
+ next if feature_path =~ /iso-8859-1\.feature/
62
63
  original = pretty_machinery(IO.read(feature_path), feature_path)
63
64
  via_machinery = self.__send__("#{machinery}_machinery", original, feature_path)
64
65
  via_machinery.should == original
data/gherkin.gemspec CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
7
7
  s.name = "gherkin"
8
8
  s.version = Gherkin::VERSION
9
9
  s.authors = ["Mike Sassak", "Gregory Hnatiuk", "Aslak Hellesøy"]
10
- s.description = "A fast Gherkin lexer/parser based on the Ragel State Machine Compiler."
10
+ s.description = "A fast Gherkin lexer/parser for based on the Ragel State Machine Compiler."
11
11
  s.summary = "gherkin-#{Gherkin::VERSION}"
12
12
  s.email = "cukes@googlegroups.com"
13
13
  s.homepage = "http://github.com/aslakhellesoy/gherkin"
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
 
25
25
  s.files -= Dir['ikvm/**/*']
26
26
  s.files -= Dir['java/**/*']
27
+ s.files -= Dir['js/**/*']
27
28
  s.files -= Dir['ext/**/*']
28
29
  s.files -= Dir['lib/gherkin.jar']
29
30
  s.files -= Dir['lib/**/*.dll']
@@ -55,6 +56,8 @@ Gem::Specification.new do |s|
55
56
  s.add_development_dependency('bundler', '>= 1.0.10')
56
57
  s.add_development_dependency('rspec', '>= 2.5.0')
57
58
  s.add_development_dependency('awesome_print', '>= 0.3')
59
+ s.add_development_dependency('therubyracer', '>= 0.8.2.pre2') if ENV['GHERKIN_JS'] && !defined?(JRUBY_VERSION)
60
+
58
61
  # Only needed by Cucumber. Remove when Cucumber no longer needs those.
59
62
  s.add_development_dependency('term-ansicolor', '>= 1.0.5')
60
63
  s.add_development_dependency('builder', '>= 3.0.0')
data/js/.gitignore ADDED
@@ -0,0 +1 @@
1
+ gherkin.*.js
data/js/.npmignore ADDED
@@ -0,0 +1 @@
1
+ example
@@ -0,0 +1 @@
1
+ *.js
data/lib/gherkin/i18n.rb CHANGED
@@ -118,6 +118,11 @@ module Gherkin
118
118
  RbLexer[underscored_iso_code].new(listener)
119
119
  end
120
120
 
121
+ def js(listener)
122
+ require 'gherkin/js_lexer'
123
+ JsLexer[underscored_iso_code].new(listener)
124
+ end
125
+
121
126
  def underscored_iso_code
122
127
  @iso_code.gsub(/[\s-]/, '_').downcase
123
128
  end
data/lib/gherkin/i18n.yml CHANGED
@@ -446,11 +446,11 @@
446
446
  "ru":
447
447
  name: Russian
448
448
  native: русский
449
- feature: Функционал|Фича
450
- background: Предыстория
449
+ feature: Функция|Функционал|Свойство
450
+ background: Предыстория|Контекст
451
451
  scenario: Сценарий
452
452
  scenario_outline: Структура сценария
453
- examples: Значения
453
+ examples: Примеры
454
454
  given: "*|Допустим|Дано|Пусть"
455
455
  when: "*|Если|Когда"
456
456
  then: "*|То|Тогда"
@@ -0,0 +1,20 @@
1
+ require 'v8'
2
+
3
+ module Gherkin
4
+ # Thin adapter for the Javascript lexer, primarily used for testing.
5
+ class JsLexer
6
+ def self.[](i18n_underscored_iso_code)
7
+ cxt = V8::Context.new
8
+ cxt['exports'] = {}
9
+
10
+ # Mimic Node.js / Firebug console.log
11
+ cxt['console'] = STDOUT
12
+ def STDOUT.log(*a)
13
+ p a
14
+ end
15
+
16
+ cxt.load(File.dirname(__FILE__) + "/../../js/lib/gherkin/lexer/#{i18n_underscored_iso_code}.js")
17
+ cxt['exports']['Lexer']
18
+ end
19
+ end
20
+ end
@@ -32,7 +32,7 @@ module Gherkin
32
32
 
33
33
  def lang(source)
34
34
  key = 'en'
35
- source.split(/\n/).each do |line|
35
+ source.each_line do |line|
36
36
  break unless COMMENT_OR_EMPTY_LINE_PATTERN =~ line
37
37
  if LANGUAGE_PATTERN =~ line
38
38
  key = $1
@@ -15,6 +15,13 @@ module Gherkin
15
15
  o
16
16
  end
17
17
  end
18
+ elsif defined?(V8)
19
+ case(o)
20
+ when V8::Array
21
+ o.map{|e| rubify(e)}
22
+ else
23
+ o
24
+ end
18
25
  else
19
26
  def rubify(o)
20
27
  o
data/ragel/lexer.c.rl.erb CHANGED
@@ -195,45 +195,43 @@ static VALUE rb_eGherkinLexingError;
195
195
  action end_feature {
196
196
  int line;
197
197
  if (cs < lexer_first_final) {
198
- if (raise_lexer_error != NULL) {
199
- size_t count = 0;
200
- VALUE newstr_val;
201
- char *newstr;
202
- int newstr_count = 0;
203
- size_t len;
204
- const char *buff;
205
- if (lexer->last_newline != 0) {
206
- len = LEN(last_newline, eof);
207
- buff = PTR_TO(last_newline);
208
- } else {
209
- len = strlen(data);
210
- buff = data;
211
- }
198
+ size_t count = 0;
199
+ VALUE newstr_val;
200
+ char *newstr;
201
+ int newstr_count = 0;
202
+ size_t len;
203
+ const char *buff;
204
+ if (lexer->last_newline != 0) {
205
+ len = LEN(last_newline, eof);
206
+ buff = PTR_TO(last_newline);
207
+ } else {
208
+ len = strlen(data);
209
+ buff = data;
210
+ }
212
211
 
213
- // Allocate as a ruby string so that it gets cleaned up by GC
214
- newstr_val = rb_str_new(buff, len);
215
- newstr = RSTRING_PTR(newstr_val);
212
+ // Allocate as a ruby string so that it gets cleaned up by GC
213
+ newstr_val = rb_str_new(buff, len);
214
+ newstr = RSTRING_PTR(newstr_val);
216
215
 
217
216
 
218
- for (count = 0; count < len; count++) {
219
- if(buff[count] == 10) {
220
- newstr[newstr_count] = '\0'; // terminate new string at first newline found
221
- break;
217
+ for (count = 0; count < len; count++) {
218
+ if(buff[count] == 10) {
219
+ newstr[newstr_count] = '\0'; // terminate new string at first newline found
220
+ break;
221
+ } else {
222
+ if (buff[count] == '%') {
223
+ newstr[newstr_count++] = buff[count];
224
+ newstr[newstr_count] = buff[count];
222
225
  } else {
223
- if (buff[count] == '%') {
224
- newstr[newstr_count++] = buff[count];
225
- newstr[newstr_count] = buff[count];
226
- } else {
227
- newstr[newstr_count] = buff[count];
228
- }
226
+ newstr[newstr_count] = buff[count];
229
227
  }
230
- newstr_count++;
231
228
  }
232
-
233
- line = lexer->line_number;
234
- lexer_init(lexer); // Re-initialize so we can scan again with the same lexer
235
- raise_lexer_error(newstr, line);
229
+ newstr_count++;
236
230
  }
231
+
232
+ line = lexer->line_number;
233
+ lexer_init(lexer); // Re-initialize so we can scan again with the same lexer
234
+ raise_lexer_error(newstr, line);
237
235
  } else {
238
236
  rb_funcall(listener, rb_intern("eof"), 0);
239
237
  }
@@ -0,0 +1,208 @@
1
+ ;(function() {
2
+
3
+ %%{
4
+ machine lexer;
5
+
6
+ action begin_content {
7
+ this.content_start = p;
8
+ this.current_line = this.line_number;
9
+ this.start_col = p - this.last_newline - (this.keyword+':').length;
10
+ }
11
+
12
+ action start_pystring {
13
+ this.current_line = this.line_number;
14
+ this.start_col = p - this.last_newline;
15
+ }
16
+
17
+ action begin_pystring_content {
18
+ this.content_start = p;
19
+ }
20
+
21
+ action store_pystring_content {
22
+ var con = this.unindent(
23
+ this.start_col,
24
+ this.bytesToString(data.slice(this.content_start, this.next_keyword_start-1)).replace(/(\r?\n)?([\t ])*$/, '').replace(/ESCAPED_TRIPLE_QUOTE/mg, '"""')
25
+ );
26
+ this.listener.py_string(con, this.current_line);
27
+ }
28
+
29
+ action store_feature_content {
30
+ p = this.store_keyword_content('feature', data, p, eof);
31
+ }
32
+
33
+ action store_background_content {
34
+ p = this.store_keyword_content('background', data, p, eof);
35
+ }
36
+
37
+ action store_scenario_content {
38
+ p = this.store_keyword_content('scenario', data, p, eof);
39
+ }
40
+
41
+ action store_scenario_outline_content {
42
+ p = this.store_keyword_content('scenario_outline', data, p, eof);
43
+ }
44
+
45
+ action store_examples_content {
46
+ p = this.store_keyword_content('examples', data, p, eof);
47
+ }
48
+
49
+ action store_step_content {
50
+ var con = this.bytesToString(data.slice(this.content_start, p)).trim();
51
+ this.listener.step(this.keyword, con, this.current_line);
52
+ }
53
+
54
+ action store_comment_content {
55
+ var con = this.bytesToString(data.slice(this.content_start, p)).trim();
56
+ this.listener.comment(con, this.line_number);
57
+ this.keyword_start = null;
58
+ }
59
+
60
+ action store_tag_content {
61
+ var con = this.bytesToString(data.slice(this.content_start, p)).trim();
62
+ this.listener.tag(con, this.line_number);
63
+ this.keyword_start = null;
64
+ }
65
+
66
+ action inc_line_number {
67
+ this.line_number++;
68
+ }
69
+
70
+ action last_newline {
71
+ this.last_newline = p + 1;
72
+ }
73
+
74
+ action start_keyword {
75
+ this.keyword_start = this.keyword_start || p;
76
+ }
77
+
78
+ action end_keyword {
79
+ this.keyword = this.bytesToString(data.slice(this.keyword_start, p)).replace(/:$/, '');
80
+ this.keyword_start = null;
81
+ }
82
+
83
+ action next_keyword_start {
84
+ this.next_keyword_start = p;
85
+ }
86
+
87
+ action start_row {
88
+ p = p - 1;
89
+ current_row = [];
90
+ this.current_line = this.line_number;
91
+ }
92
+
93
+ action begin_cell_content {
94
+ this.content_start = p;
95
+ }
96
+
97
+ action store_cell_content {
98
+ var con = this.bytesToString(data.slice(this.content_start, p)).trim();
99
+ current_row.push(con.replace(/\\\|/, "|").replace(/\\n/, "\n").replace(/\\\\/, "\\"));
100
+ }
101
+
102
+ action store_row {
103
+ this.listener.row(current_row, this.current_line);
104
+ }
105
+
106
+ action end_feature {
107
+ if(this.cs < lexer_first_final) {
108
+ var content = this.current_line_content(data, p);
109
+ throw "Lexing error on line " + this.line_number + ": '" + content + "'. See http://wiki.github.com/aslakhellesoy/gherkin/lexingerror for more information.";
110
+ } else {
111
+ this.listener.eof();
112
+ }
113
+
114
+ }
115
+
116
+ include lexer_common "lexer_common.<%= @i18n.underscored_iso_code %>.rl";
117
+ }%%
118
+
119
+ %% write data;
120
+ %% access this.;
121
+ %% variable data data;
122
+
123
+ var Lexer = function(listener) {
124
+ // Check that listener has the required functions
125
+ var events = ['comment', 'tag', 'feature', 'background', 'scenario', 'scenario_outline', 'examples', 'step', 'py_string', 'row', 'eof'];
126
+ for(e in events) {
127
+ var event = events[e];
128
+ if(typeof listener[event] != 'function') {
129
+ "Error. No " + event + " function exists on " + JSON.stringify(listener);
130
+ }
131
+ }
132
+ this.listener = listener;
133
+ };
134
+
135
+ Lexer.prototype.scan = function(data) {
136
+ var ending = "\n%_FEATURE_END_%";
137
+ if(typeof data == 'string') {
138
+ data = this.stringToBytes(data + ending);
139
+ } else if(typeof Buffer != 'undefined' && Buffer.isBuffer(data)) {
140
+ // Node.js
141
+ var buf = new Buffer(data.length + ending.length);
142
+ data.copy(buf, 0, 0);
143
+ new Buffer(ending).copy(buf, data.length, 0);
144
+ data = buf;
145
+ }
146
+ var eof = pe = data.length;
147
+ var p = 0;
148
+
149
+ this.line_number = 1;
150
+ this.last_newline = 0;
151
+
152
+ %% write init;
153
+ %% write exec;
154
+ };
155
+
156
+ Lexer.prototype.bytesToString = function(bytes) {
157
+ if(typeof bytes.write == 'function') {
158
+ // Node.js
159
+ return bytes.toString('utf-8');
160
+ } else {
161
+ var result = "";
162
+ for(var b in bytes) {
163
+ result += String.fromCharCode(bytes[b]);
164
+ }
165
+ return result;
166
+ }
167
+ };
168
+
169
+ Lexer.prototype.stringToBytes = function(string) {
170
+ var bytes = [];
171
+ for(var i = 0; i < string.length; i++) {
172
+ bytes[i] = string.charCodeAt(i);
173
+ }
174
+ return bytes;
175
+ };
176
+
177
+ Lexer.prototype.unindent = function(startcol, text) {
178
+ startcol = startcol || 0;
179
+ return text.replace(new RegExp('^[\t ]{0,' + startcol + '}', 'gm'), '');
180
+ };
181
+
182
+ Lexer.prototype.store_keyword_content = function(event, data, p, eof) {
183
+ var end_point = (!this.next_keyword_start || (p == eof)) ? p : this.next_keyword_start;
184
+ var content = this.unindent(this.start_col + 2, this.bytesToString(data.slice(this.content_start, end_point))).trimRight();
185
+ var content_lines = content.split("\n")
186
+ var name = content_lines.shift() || "";
187
+ name = name.trim();
188
+ var description = content_lines.join("\n");
189
+ this.listener[event](this.keyword, name, description, this.current_line);
190
+ var nks = this.next_keyword_start;
191
+ this.next_keyword_start = null;
192
+ return nks ? nks - 1 : p;
193
+ };
194
+
195
+ Lexer.prototype.current_line_content = function(data, p) {
196
+ var rest = data.slice(this.last_newline, -1);
197
+ var end = rest.indexOf(10) || -1;
198
+ return this.bytesToString(rest.slice(0, end)).trim();
199
+ };
200
+
201
+ if(typeof exports != 'undefined') {
202
+ exports.Lexer = Lexer;
203
+ }
204
+ if(typeof window != 'undefined') {
205
+ window.Lexer = Lexer;
206
+ }
207
+
208
+ })();