gherkin 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,17 +1,20 @@
1
1
  require 'gherkin/lexer'
2
+ require 'gherkin/i18n'
2
3
 
3
4
  module Gherkin
4
5
  # The main entry point to lexing Gherkin source.
5
6
  class I18nLexer
6
7
  LANGUAGE_PATTERN = /language\s*:\s*(.*)/ #:nodoc:
7
8
 
9
+ attr_reader :language
10
+
8
11
  def initialize(parser)
9
12
  @parser = parser
10
13
  end
11
14
 
12
15
  def scan(source)
13
- lang = lang(source) || 'en'
14
- delegate = Lexer[lang].new(@parser)
16
+ @language = lang(source)
17
+ delegate = Lexer[@language.key].new(@parser)
15
18
  delegate.scan(source)
16
19
  end
17
20
 
@@ -19,11 +22,8 @@ module Gherkin
19
22
 
20
23
  def lang(source)
21
24
  line_one = source.split(/\n/)[0]
22
- if line_one =~ LANGUAGE_PATTERN
23
- $1.strip
24
- else
25
- nil
26
- end
25
+ match = LANGUAGE_PATTERN.match(line_one)
26
+ I18n.get(match ? match[1] : 'en')
27
27
  end
28
28
  end
29
- end
29
+ end
@@ -15,7 +15,8 @@ module Gherkin
15
15
  begin
16
16
  c[i18n_lang]
17
17
  rescue NameError, LoadError => e
18
- warn("WARNING: #{e.message}. Reverting to Ruby lexer")
18
+ warn("WARNING: #{e.message}. Reverting to Ruby lexer.") unless defined?(@warned)
19
+ @warned = true
19
20
  rb[i18n_lang]
20
21
  end
21
22
  end
@@ -0,0 +1,8 @@
1
+ module Gherkin
2
+ module Tools
3
+ SUB_COMMANDS = %w(stats reformat)
4
+ SUB_COMMANDS.each do |cmd|
5
+ autoload cmd.capitalize.to_sym, "gherkin/tools/#{cmd}"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,30 @@
1
+ require 'gherkin'
2
+
3
+ module Gherkin
4
+ module Tools
5
+ # Base class for file based operations
6
+ class Files
7
+ include Enumerable
8
+
9
+ def initialize(paths)
10
+ raise "Please specify one or more paths" if paths.empty?
11
+ @paths = paths
12
+ end
13
+
14
+ def each(&proc)
15
+ globs = @paths.map do |path|
16
+ raise "#{path} does not exist" unless File.exist?(path)
17
+ File.directory?(path) ? File.join(path, '**', '*.feature') : path
18
+ end
19
+
20
+ Dir[*globs].uniq.sort.each(&proc)
21
+ end
22
+
23
+ def scan(file, listener)
24
+ parser = Parser.new(listener, true)
25
+ lexer = I18nLexer.new(parser)
26
+ lexer.scan(IO.read(file))
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,9 +1,10 @@
1
1
  # encoding: utf-8
2
2
  module Gherkin
3
3
  module Tools
4
- class PrettyPrinter
4
+ class PrettyListener
5
5
  def initialize(io)
6
6
  @io = io
7
+ @tags = nil
7
8
  end
8
9
 
9
10
  def tag(name, line)
@@ -38,7 +39,7 @@ module Gherkin
38
39
  end
39
40
 
40
41
  def examples(keyword, name, line)
41
- @io.puts "\n #{keyword}: #{indent(name, ' ')}"
42
+ @io.puts "\n #{keyword}: #{indent(name, ' ')}"
42
43
  end
43
44
 
44
45
  def step(keyword, name, line)
@@ -48,8 +49,8 @@ module Gherkin
48
49
  def table(rows, line)
49
50
  rows = rows.to_a.map {|row| row.to_a} if defined?(JRUBY_VERSION) # Convert ArrayList
50
51
  max_lengths = rows.transpose.map { |col| col.map { |cell| cell.unpack("U*").length }.max }.flatten
51
- rows.each do |line|
52
- @io.puts ' | ' + line.zip(max_lengths).map { |cell, max_length| cell + ' ' * (max_length-cell.unpack("U*").length) }.join(' | ') + ' |'
52
+ rows.each do |table_line|
53
+ @io.puts ' | ' + table_line.zip(max_lengths).map { |cell, max_length| cell + ' ' * (max_length-cell.unpack("U*").length) }.join(' | ') + ' |'
53
54
  end
54
55
  end
55
56
 
@@ -0,0 +1,19 @@
1
+ require 'stringio'
2
+ require 'gherkin/tools/files'
3
+ require 'gherkin/tools/pretty_listener'
4
+
5
+ module Gherkin
6
+ module Tools
7
+ class Reformat < Files
8
+ def run
9
+ each do |file|
10
+ purdy = StringIO.new
11
+ listener = PrettyListener.new(purdy)
12
+ scan(file, listener)
13
+ purdy.rewind
14
+ File.open(file, 'w') {|io| io.write(purdy.read)}
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ require 'gherkin'
2
+ require 'gherkin/tools/files'
3
+ require 'gherkin/tools/stats_listener'
4
+
5
+ module Gherkin
6
+ module Tools
7
+ class Stats < Files
8
+ def run
9
+ listener = StatsListener.new
10
+ each do |f|
11
+ parser = Gherkin::Parser.new(listener, true)
12
+ lexer = Gherkin::I18nLexer.new(parser)
13
+ lexer.scan(IO.read(f))
14
+ end
15
+ puts "Features: #{listener.features}"
16
+ puts "Scenarios: #{listener.scenarios}"
17
+ puts "Steps: #{listener.steps}"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+ module Gherkin
3
+ module Tools
4
+ class StatsListener
5
+ attr_reader :features, :scenarios, :steps
6
+
7
+ def initialize
8
+ @features = 0
9
+ @scenarios = 0
10
+ @steps = 0
11
+ end
12
+
13
+ def tag(name, line)
14
+ end
15
+
16
+ def comment(content, line)
17
+ end
18
+
19
+ def feature(keyword, name, line)
20
+ @features += 1
21
+ end
22
+
23
+ def background(keyword, name, line)
24
+ end
25
+
26
+ def scenario(keyword, name, line)
27
+ @scenarios += 1
28
+ end
29
+
30
+ def scenario_outline(keyword, name, line)
31
+ end
32
+
33
+ def examples(keyword, name, line)
34
+ end
35
+
36
+ def step(keyword, name, line)
37
+ @steps += 1
38
+ end
39
+
40
+ def table(rows, line)
41
+ end
42
+
43
+ def py_string(string, line)
44
+ end
45
+
46
+ def syntax_error(state, event, legal_events, line)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1,5 +1,5 @@
1
1
  #!/bin/sh
2
2
  # Builds gems for all supported platforms
3
- rake gemspec build PLATFORM=universal-java-1.5
3
+ rake gemspec build PLATFORM=java
4
4
  rake cross compile gemspec build PLATFORM=i386-mswin32 RUBY_CC_VERSION=1.8.6
5
5
  rake gemspec build PLATFORM=i386-mingw32 RUBY_CC_VERSION=1.8.6
@@ -139,62 +139,62 @@ public class <%= @i18n.sanitized_key.capitalize %> implements Lexer {
139
139
  include lexer_common "lexer_common.<%= @i18n.sanitized_key %>.rl";
140
140
  }%%
141
141
 
142
- private final Listener listener;
143
-
144
- public <%= @i18n.sanitized_key.capitalize %>(Listener listener) {
145
- this.listener = listener;
146
- }
147
-
148
- %% write data noerror;
149
-
150
- public void scan(CharSequence inputSequence) {
151
- String input = inputSequence.toString() + "\n%_FEATURE_END_%";
152
- byte[] data = input.getBytes();
153
- int cs, p = 0, pe = data.length;
154
- int eof = pe;
155
-
156
- int lineNumber = 1;
157
- int lastNewline = 0;
158
-
159
- int contentStart = -1;
160
- int currentLine = -1;
161
- int startCol = -1;
162
- int nextKeywordStart = -1;
163
- int keywordStart = -1;
164
- String keyword = null;
165
- List<List<String>> rows = null;
166
- List<String> currentRow = null;
167
-
168
- %% write init;
169
- %% write exec;
170
- }
171
-
172
- private String keywordContent(byte[] data, int p, int eof, int nextKeywordStart, int contentStart) {
173
- int endPoint = (nextKeywordStart == -1 || (p == eof)) ? p : nextKeywordStart;
174
- return substring(data, contentStart, endPoint);
175
- }
176
-
177
- private String multilineStrip(String text) {
178
- StringBuffer result = new StringBuffer();
179
- for(String s : text.split("\n")) {
180
- result.append(s.trim()).append("\n");
181
- }
182
- return result.toString().trim();
183
- }
184
-
185
- private String unindent(int startCol, String text) {
186
- return Pattern.compile("^ {0," + startCol + "}", Pattern.MULTILINE).matcher(text).replaceAll("");
187
- }
188
-
189
- private String currentLineContent(byte[] data, int lastNewline) {
190
- return substring(data, lastNewline, data.length).trim();
191
- }
192
-
193
- private String substring(byte[] data, int start, int end) {
194
- try {
195
- return new String(data, start, end-start, "utf-8");
196
- } catch(java.io.UnsupportedEncodingException e) {
197
- throw new RuntimeException("Internal error", e);
198
- }
199
- }
142
+ private final Listener listener;
143
+
144
+ public <%= @i18n.sanitized_key.capitalize %>(Listener listener) {
145
+ this.listener = listener;
146
+ }
147
+
148
+ %% write data noerror;
149
+
150
+ public void scan(CharSequence inputSequence) {
151
+ String input = inputSequence.toString() + "\n%_FEATURE_END_%";
152
+ byte[] data = input.getBytes();
153
+ int cs, p = 0, pe = data.length;
154
+ int eof = pe;
155
+
156
+ int lineNumber = 1;
157
+ int lastNewline = 0;
158
+
159
+ int contentStart = -1;
160
+ int currentLine = -1;
161
+ int startCol = -1;
162
+ int nextKeywordStart = -1;
163
+ int keywordStart = -1;
164
+ String keyword = null;
165
+ List<List<String>> rows = null;
166
+ List<String> currentRow = null;
167
+
168
+ %% write init;
169
+ %% write exec;
170
+ }
171
+
172
+ private String keywordContent(byte[] data, int p, int eof, int nextKeywordStart, int contentStart) {
173
+ int endPoint = (nextKeywordStart == -1 || (p == eof)) ? p : nextKeywordStart;
174
+ return substring(data, contentStart, endPoint);
175
+ }
176
+
177
+ private String multilineStrip(String text) {
178
+ StringBuffer result = new StringBuffer();
179
+ for(String s : text.split("\n")) {
180
+ result.append(s.trim()).append("\n");
181
+ }
182
+ return result.toString().trim();
183
+ }
184
+
185
+ private String unindent(int startCol, String text) {
186
+ return Pattern.compile("^ {0," + startCol + "}", Pattern.MULTILINE).matcher(text).replaceAll("");
187
+ }
188
+
189
+ private String currentLineContent(byte[] data, int lastNewline) {
190
+ return substring(data, lastNewline, data.length).trim();
191
+ }
192
+
193
+ private String substring(byte[] data, int start, int end) {
194
+ try {
195
+ return new String(data, start, end-start, "utf-8");
196
+ } catch(java.io.UnsupportedEncodingException e) {
197
+ throw new RuntimeException("Internal error", e);
198
+ }
199
+ }
200
200
  }
@@ -0,0 +1,22 @@
1
+ #encoding: utf-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ module Gherkin
5
+ describe I18nLexer do
6
+ before do
7
+ @lexer = I18nLexer.new(SexpRecorder.new)
8
+ end
9
+
10
+ it "should store the i18n language of the last scanned feature" do
11
+ @lexer.scan("# language: fr\n")
12
+ @lexer.language.key.should == "fr"
13
+ @lexer.scan("# language: no\n")
14
+ @lexer.language.key.should == "no"
15
+ end
16
+
17
+ it "should use English i18n by default" do
18
+ @lexer.scan("Feature: foo\n")
19
+ @lexer.language.key.should == "en"
20
+ end
21
+ end
22
+ end
@@ -179,13 +179,6 @@ namespace :bench do
179
179
  benchmarker.report("native_gherkin_no_parser")
180
180
  end
181
181
 
182
- desc "Show basic statistics about the features in tasks/bench/generated"
183
- task :stats do
184
- ["Feature", "Scenario", "Given"].each do |kw|
185
- sh "grep #{kw} #{GENERATED_FEATURES}/* | wc -l"
186
- end
187
- end
188
-
189
182
  desc "Remove all generated features in tasks/bench/generated"
190
183
  task :clean do
191
184
  rm_f FileList[GENERATED_FEATURES + "/**/*feature"]
@@ -2,6 +2,7 @@ require File.dirname(__FILE__) + '/ragel_task'
2
2
  require 'gherkin/i18n'
3
3
 
4
4
  CLEAN.include [
5
+ 'pkg', 'tmp',
5
6
  '**/*.{o,bundle,jar,so,obj,pdb,lib,def,exp,log}', 'ext',
6
7
  'java/target',
7
8
  'ragel/i18n/*.rl',
@@ -23,11 +24,12 @@ Gherkin::I18n.all.each do |i18n|
23
24
  task :jar => rb.target
24
25
 
25
26
  begin
27
+ unless defined?(JRUBY_VERSION)
26
28
  require 'rake/extensiontask'
29
+
27
30
  c = RagelTask.new('c', i18n)
28
31
 
29
32
  extconf = "ext/gherkin_lexer_#{i18n.sanitized_key}/extconf.rb"
30
-
31
33
  file extconf do
32
34
  FileUtils.mkdir(File.dirname(extconf)) unless File.directory?(File.dirname(extconf))
33
35
  File.open(extconf, "w") do |io|
@@ -48,9 +50,6 @@ EOF
48
50
  end
49
51
  end
50
52
 
51
- task :compile => c.target
52
- task :compile => rb.target
53
-
54
53
  # The way tasks are defined with compile:xxx (but without namespace) in rake-compiler forces us
55
54
  # to use these hacks for setting up dependencies. Ugly!
56
55
  Rake::Task["compile:gherkin_lexer_#{i18n.sanitized_key}"].prerequisites.unshift(extconf)
@@ -60,6 +59,7 @@ EOF
60
59
  Rake::Task["compile"].prerequisites.unshift(extconf)
61
60
  Rake::Task["compile"].prerequisites.unshift(c.target)
62
61
  Rake::Task["compile"].prerequisites.unshift(rb.target)
62
+ end
63
63
  rescue LoadError
64
64
  unless defined?($c_warned)
65
65
  warn "WARNING: Rake::ExtensionTask not installed. Skipping C compilation."
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gherkin
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Sassak
@@ -11,16 +11,26 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2009-12-02 00:00:00 +01:00
14
+ date: 2009-12-30 00:00:00 +01:00
15
15
  default_executable: gherkin
16
16
  dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: trollop
19
+ type: :runtime
20
+ version_requirement:
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: "1.15"
26
+ version:
17
27
  - !ruby/object:Gem::Dependency
18
28
  name: rspec
19
29
  type: :development
20
30
  version_requirement:
21
31
  version_requirements: !ruby/object:Gem::Requirement
22
32
  requirements:
23
- - - "="
33
+ - - ">="
24
34
  - !ruby/object:Gem::Version
25
35
  version: 1.2.9
26
36
  version:
@@ -30,9 +40,9 @@ dependencies:
30
40
  version_requirement:
31
41
  version_requirements: !ruby/object:Gem::Requirement
32
42
  requirements:
33
- - - "="
43
+ - - ">="
34
44
  - !ruby/object:Gem::Version
35
- version: 0.4.4
45
+ version: 0.5.1
36
46
  version:
37
47
  - !ruby/object:Gem::Dependency
38
48
  name: rake-compiler
@@ -40,15 +50,14 @@ dependencies:
40
50
  version_requirement:
41
51
  version_requirements: !ruby/object:Gem::Requirement
42
52
  requirements:
43
- - - "="
53
+ - - ">="
44
54
  - !ruby/object:Gem::Version
45
- version: 0.6.0
55
+ version: 0.7.0
46
56
  version:
47
- description: A fast Gherkin lexer in Ragel
57
+ description: A fast Gherkin lexer/parser based on the Ragel State Machine Compiler.
48
58
  email: cukes@googlegroups.com
49
59
  executables:
50
60
  - gherkin
51
- - gherkin-purdy
52
61
  extensions:
53
62
  - ext/gherkin_lexer_ar/extconf.rb
54
63
  - ext/gherkin_lexer_bg/extconf.rb
@@ -95,12 +104,13 @@ extra_rdoc_files:
95
104
  - README.rdoc
96
105
  files:
97
106
  - .gitignore
107
+ - .mailmap
108
+ - History.txt
98
109
  - LICENSE
99
110
  - README.rdoc
100
111
  - Rakefile
101
112
  - VERSION.yml
102
113
  - bin/gherkin
103
- - bin/gherkin-purdy
104
114
  - cucumber.yml
105
115
  - ext/gherkin_lexer_ar/gherkin_lexer_ar.c
106
116
  - ext/gherkin_lexer_bg/gherkin_lexer_bg.c
@@ -165,6 +175,7 @@ files:
165
175
  - lib/.gitignore
166
176
  - lib/gherkin.rb
167
177
  - lib/gherkin/c_lexer.rb
178
+ - lib/gherkin/cli/main.rb
168
179
  - lib/gherkin/core_ext/array.rb
169
180
  - lib/gherkin/i18n.rb
170
181
  - lib/gherkin/i18n.yml
@@ -219,7 +230,12 @@ files:
219
230
  - lib/gherkin/rb_lexer/zhCN.rb
220
231
  - lib/gherkin/rb_lexer/zhTW.rb
221
232
  - lib/gherkin/rb_parser.rb
222
- - lib/gherkin/tools/pretty_printer.rb
233
+ - lib/gherkin/tools.rb
234
+ - lib/gherkin/tools/files.rb
235
+ - lib/gherkin/tools/pretty_listener.rb
236
+ - lib/gherkin/tools/reformat.rb
237
+ - lib/gherkin/tools/stats.rb
238
+ - lib/gherkin/tools/stats_listener.rb
223
239
  - nativegems.sh
224
240
  - ragel/i18n/.gitignore
225
241
  - ragel/lexer.c.rl.erb
@@ -235,6 +251,7 @@ files:
235
251
  - spec/gherkin/fixtures/simple.feature
236
252
  - spec/gherkin/fixtures/simple_with_comments.feature
237
253
  - spec/gherkin/fixtures/simple_with_tags.feature
254
+ - spec/gherkin/i18n_lexer_spec.rb
238
255
  - spec/gherkin/i18n_spec.rb
239
256
  - spec/gherkin/java_lexer_spec.rb
240
257
  - spec/gherkin/parser_spec.rb
@@ -281,9 +298,10 @@ rubyforge_project:
281
298
  rubygems_version: 1.3.5
282
299
  signing_key:
283
300
  specification_version: 3
284
- summary: Fast Gherkin lexer
301
+ summary: Fast Gherkin lexer/parser
285
302
  test_files:
286
303
  - spec/gherkin/c_lexer_spec.rb
304
+ - spec/gherkin/i18n_lexer_spec.rb
287
305
  - spec/gherkin/i18n_spec.rb
288
306
  - spec/gherkin/java_lexer_spec.rb
289
307
  - spec/gherkin/parser_spec.rb