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

Sign up to get free protection for your applications and to get access to all the features.
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
+ })();