gherkin 1.0.30-universal-dotnet

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/.gitattributes +2 -0
  2. data/.gitignore +9 -0
  3. data/.mailmap +2 -0
  4. data/History.txt +187 -0
  5. data/LICENSE +20 -0
  6. data/README.rdoc +59 -0
  7. data/Rakefile +58 -0
  8. data/VERSION.yml +5 -0
  9. data/bin/gherkin +5 -0
  10. data/cucumber.yml +3 -0
  11. data/features/escaped_pipes.feature +8 -0
  12. data/features/feature_parser.feature +226 -0
  13. data/features/native_lexer.feature +19 -0
  14. data/features/parser_with_native_lexer.feature +205 -0
  15. data/features/pretty_printer.feature +14 -0
  16. data/features/step_definitions/eyeball_steps.rb +3 -0
  17. data/features/step_definitions/gherkin_steps.rb +30 -0
  18. data/features/step_definitions/pretty_formatter_steps.rb +55 -0
  19. data/features/steps_parser.feature +46 -0
  20. data/features/support/env.rb +33 -0
  21. data/ikvm/.gitignore +3 -0
  22. data/java/.gitignore +2 -0
  23. data/java/src/main/java/gherkin/lexer/.gitignore +1 -0
  24. data/java/src/main/resources/gherkin/.gitignore +1 -0
  25. data/lib/.gitignore +4 -0
  26. data/lib/gherkin.rb +2 -0
  27. data/lib/gherkin/c_lexer.rb +17 -0
  28. data/lib/gherkin/cli/main.rb +33 -0
  29. data/lib/gherkin/formatter/argument.rb +27 -0
  30. data/lib/gherkin/formatter/colors.rb +119 -0
  31. data/lib/gherkin/formatter/escaping.rb +15 -0
  32. data/lib/gherkin/formatter/monochrome_format.rb +9 -0
  33. data/lib/gherkin/formatter/pretty_formatter.rb +168 -0
  34. data/lib/gherkin/i18n.rb +176 -0
  35. data/lib/gherkin/i18n.yml +588 -0
  36. data/lib/gherkin/i18n_lexer.rb +38 -0
  37. data/lib/gherkin/native.rb +7 -0
  38. data/lib/gherkin/native/ikvm.rb +55 -0
  39. data/lib/gherkin/native/java.rb +47 -0
  40. data/lib/gherkin/native/null.rb +9 -0
  41. data/lib/gherkin/parser/event.rb +45 -0
  42. data/lib/gherkin/parser/filter_listener.rb +199 -0
  43. data/lib/gherkin/parser/meta.txt +5 -0
  44. data/lib/gherkin/parser/parser.rb +142 -0
  45. data/lib/gherkin/parser/root.txt +11 -0
  46. data/lib/gherkin/parser/steps.txt +4 -0
  47. data/lib/gherkin/parser/tag_expression.rb +50 -0
  48. data/lib/gherkin/rb_lexer.rb +8 -0
  49. data/lib/gherkin/rb_lexer/.gitignore +1 -0
  50. data/lib/gherkin/rb_lexer/README.rdoc +8 -0
  51. data/lib/gherkin/rubify.rb +18 -0
  52. data/lib/gherkin/tools.rb +8 -0
  53. data/lib/gherkin/tools/files.rb +35 -0
  54. data/lib/gherkin/tools/reformat.rb +19 -0
  55. data/lib/gherkin/tools/stats.rb +21 -0
  56. data/lib/gherkin/tools/stats_listener.rb +57 -0
  57. data/ragel/i18n/.gitignore +1 -0
  58. data/ragel/lexer.c.rl.erb +425 -0
  59. data/ragel/lexer.java.rl.erb +216 -0
  60. data/ragel/lexer.rb.rl.erb +173 -0
  61. data/ragel/lexer_common.rl.erb +50 -0
  62. data/spec/gherkin/c_lexer_spec.rb +21 -0
  63. data/spec/gherkin/csharp_lexer_spec.rb +20 -0
  64. data/spec/gherkin/fixtures/1.feature +8 -0
  65. data/spec/gherkin/fixtures/comments_in_table.feature +9 -0
  66. data/spec/gherkin/fixtures/complex.feature +45 -0
  67. data/spec/gherkin/fixtures/dos_line_endings.feature +45 -0
  68. data/spec/gherkin/fixtures/i18n_fr.feature +14 -0
  69. data/spec/gherkin/fixtures/i18n_no.feature +7 -0
  70. data/spec/gherkin/fixtures/i18n_zh-CN.feature +9 -0
  71. data/spec/gherkin/fixtures/simple_with_comments.feature +7 -0
  72. data/spec/gherkin/fixtures/simple_with_tags.feature +11 -0
  73. data/spec/gherkin/fixtures/with_bom.feature +3 -0
  74. data/spec/gherkin/formatter/argument_spec.rb +28 -0
  75. data/spec/gherkin/formatter/colors_spec.rb +19 -0
  76. data/spec/gherkin/formatter/pretty_formatter_spec.rb +162 -0
  77. data/spec/gherkin/formatter/spaces.feature +9 -0
  78. data/spec/gherkin/formatter/tabs.feature +9 -0
  79. data/spec/gherkin/i18n_lexer_spec.rb +26 -0
  80. data/spec/gherkin/i18n_spec.rb +144 -0
  81. data/spec/gherkin/java_lexer_spec.rb +21 -0
  82. data/spec/gherkin/parser/filter_listener_spec.rb +390 -0
  83. data/spec/gherkin/parser/parser_spec.rb +50 -0
  84. data/spec/gherkin/parser/tag_expression_spec.rb +116 -0
  85. data/spec/gherkin/rb_lexer_spec.rb +19 -0
  86. data/spec/gherkin/sexp_recorder.rb +32 -0
  87. data/spec/gherkin/shared/lexer_spec.rb +550 -0
  88. data/spec/gherkin/shared/py_string_spec.rb +150 -0
  89. data/spec/gherkin/shared/row_spec.rb +104 -0
  90. data/spec/gherkin/shared/tags_spec.rb +50 -0
  91. data/spec/spec_helper.rb +87 -0
  92. data/tasks/bench.rake +188 -0
  93. data/tasks/bench/feature_builder.rb +49 -0
  94. data/tasks/bench/generated/.gitignore +1 -0
  95. data/tasks/bench/null_listener.rb +4 -0
  96. data/tasks/compile.rake +89 -0
  97. data/tasks/cucumber.rake +26 -0
  98. data/tasks/gems.rake +45 -0
  99. data/tasks/ikvm.rake +47 -0
  100. data/tasks/ragel_task.rb +70 -0
  101. data/tasks/rdoc.rake +12 -0
  102. data/tasks/release.rake +26 -0
  103. data/tasks/rspec.rake +15 -0
  104. metadata +257 -0
@@ -0,0 +1,150 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
3
+
4
+ module Gherkin
5
+ module Lexer
6
+ shared_examples_for "a Gherkin lexer lexing py_strings" do
7
+
8
+ def ps(content)
9
+ '"""%s"""' % ("\n" + content + "\n")
10
+ end
11
+
12
+ it "should provide the amount of indentation of the triple quotes to the listener" do
13
+ str = <<EOS
14
+ Feature: some feature
15
+ Scenario: some scenario
16
+ Given foo
17
+ """
18
+ Hello
19
+ Goodbye
20
+ """
21
+ Then bar
22
+ EOS
23
+ @listener.should_receive(:py_string).with(" Hello\nGoodbye", 4)
24
+ @lexer.scan(str)
25
+ end
26
+
27
+ it "should parse a simple py_string" do
28
+ @listener.should_receive(:py_string).with("I am a py_string", 1)
29
+ @lexer.scan ps("I am a py_string")
30
+ end
31
+
32
+ it "should parse an empty py_string" do
33
+ @listener.should_receive(:py_string).with("", 4)
34
+ @lexer.scan("Feature: Hi\nScenario: Hi\nGiven a step\n\"\"\"\n\"\"\"")
35
+ end
36
+
37
+ it "should treat a string containing only newlines as only newlines" do
38
+ py_string = <<EOS
39
+ """
40
+
41
+
42
+
43
+ """
44
+ EOS
45
+ @listener.should_receive(:py_string).with("\n\n", 1)
46
+ @lexer.scan(py_string)
47
+ end
48
+
49
+ it "should parse content separated by two newlines" do
50
+ @lexer.scan ps("A\n\nB")
51
+ @listener.to_sexp.should == [
52
+ [:py_string, "A\n\nB", 1],
53
+ [:eof]
54
+ ]
55
+ end
56
+
57
+ it "should parse a multiline string" do
58
+ @listener.should_receive(:py_string).with("A\nB\nC\nD", 1)
59
+ @lexer.scan ps("A\nB\nC\nD")
60
+ end
61
+
62
+ it "should ignore unescaped quotes inside the string delimeters" do
63
+ @listener.should_receive(:py_string).with("What does \"this\" mean?", 1)
64
+ @lexer.scan ps('What does "this" mean?')
65
+ end
66
+
67
+ it "should preserve whitespace within the triple quotes" do
68
+ str = <<EOS
69
+ """
70
+ Line one
71
+ Line two
72
+ """
73
+ EOS
74
+ @listener.should_receive(:py_string).with(" Line one\nLine two", 1)
75
+ @lexer.scan(str)
76
+ end
77
+
78
+ it "should preserve tabs within the content" do
79
+ @listener.should_receive(:py_string).with("I have\tsome tabs\nInside\t\tthe content", 1)
80
+ @lexer.scan ps("I have\tsome tabs\nInside\t\tthe content")
81
+ end
82
+
83
+ it "should handle complex py_strings" do
84
+ py_string = <<EOS
85
+ # Feature comment
86
+ @one
87
+ Feature: Sample
88
+
89
+ @two @three
90
+ Scenario: Missing
91
+ Given missing
92
+
93
+ 1 scenario (1 passed)
94
+ 1 step (1 passed)
95
+
96
+ EOS
97
+
98
+ @listener.should_receive(:py_string).with(py_string, 1)
99
+ @lexer.scan ps(py_string)
100
+ end
101
+
102
+ it "should allow whitespace after the closing py_string delimiter" do
103
+ str = <<EOS
104
+ """
105
+ Line one
106
+ """
107
+ EOS
108
+ @listener.should_receive(:py_string).with(" Line one", 1)
109
+ @lexer.scan(str)
110
+ end
111
+
112
+ it "should preserve the last newline(s) at the end of a py_string" do
113
+ str = <<EOS
114
+ """
115
+ PyString text
116
+
117
+
118
+ """
119
+ EOS
120
+ @listener.should_receive(:py_string).with("PyString text\n\n",1)
121
+ @lexer.scan(str)
122
+ end
123
+
124
+ it "should preserve CRLFs within py_strings" do
125
+ @listener.should_receive(:py_string).with("Line one\r\nLine two\r\n", 1)
126
+ @lexer.scan("\"\"\"\r\nLine one\r\nLine two\r\n\r\n\"\"\"")
127
+ end
128
+
129
+ it "should unescape escaped triple quotes" do
130
+ str = <<EOS
131
+ """
132
+ \\"\\"\\"
133
+ """
134
+ EOS
135
+ @listener.should_receive(:py_string).with('"""', 1)
136
+ @lexer.scan(str)
137
+ end
138
+
139
+ it "should not unescape escaped single quotes" do
140
+ str = <<EOS
141
+ """
142
+ \\" \\"\\"
143
+ """
144
+ EOS
145
+ @listener.should_receive(:py_string).with('\" \"\"', 1)
146
+ @lexer.scan(str)
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,104 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
3
+
4
+ module Gherkin
5
+ module Lexer
6
+ shared_examples_for "a Gherkin lexer lexing rows" do
7
+ rows = {
8
+ "|a|b|\n" => %w{a b},
9
+ "|a|b|c|\n" => %w{a b c},
10
+ }
11
+
12
+ rows.each do |text, expected|
13
+ it "should parse #{text}" do
14
+ @listener.should_receive(:row).with(r(expected), 1)
15
+ @lexer.scan(text.dup)
16
+ end
17
+ end
18
+
19
+ it "should parse a row with many cells" do
20
+ @listener.should_receive(:row).with(r(%w{a b c d e f g h i j k l m n o p}), 1)
21
+ @lexer.scan("|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|\n")
22
+ end
23
+
24
+ it "should parse multicharacter cell content" do
25
+ @listener.should_receive(:row).with(r(%w{foo bar}), 1)
26
+ @lexer.scan("| foo | bar |\n")
27
+ end
28
+
29
+ it "should escape backslashed pipes" do
30
+ @listener.should_receive(:row).with(r(['|', 'the', '\a', '\\', '|\\|']), 1)
31
+ @lexer.scan('| \| | the | \a | \\ | \|\\\| |' + "\n")
32
+ end
33
+
34
+ it "should parse cells with spaces within the content" do
35
+ @listener.should_receive(:row).with(r(["Dill pickle", "Valencia orange"]), 1)
36
+ @lexer.scan("| Dill pickle | Valencia orange |\n")
37
+ end
38
+
39
+ it "should allow utf-8" do
40
+ @lexer.scan(" | ůﻚ | 2 | \n")
41
+ @listener.to_sexp.should == [
42
+ [:row, ["ůﻚ", "2"], 1],
43
+ [:eof]
44
+ ]
45
+ end
46
+
47
+ it "should allow utf-8 using should_receive" do
48
+ @listener.should_receive(:row).with(r(['繁體中文 而且','並且','繁體中文 而且','並且']), 1)
49
+ @lexer.scan("| 繁體中文 而且|並且| 繁體中文 而且|並且|\n")
50
+ end
51
+
52
+ it "should parse a 2x2 table" do
53
+ @listener.should_receive(:row).with(r(%w{1 2}), 1)
54
+ @listener.should_receive(:row).with(r(%w{3 4}), 2)
55
+ @lexer.scan("| 1 | 2 |\n| 3 | 4 |\n")
56
+ end
57
+
58
+ it "should parse a 2x2 table with empty cells" do
59
+ @listener.should_receive(:row).with(r(['1', '']), 1)
60
+ @listener.should_receive(:row).with(r(['', '4']), 2)
61
+ @lexer.scan("| 1 | |\n|| 4 |\n")
62
+ end
63
+
64
+ it "should parse a row with empty cells" do
65
+ @listener.should_receive(:row).with(r(['1', '']), 1).twice
66
+ @lexer.scan("| 1 | |\n")
67
+ @lexer.scan("|1||\n")
68
+ end
69
+
70
+ it "should parse a 1x2 table that does not end in a newline" do
71
+ @listener.should_receive(:row).with(r(%w{1 2}), 1)
72
+ @lexer.scan("| 1 | 2 |")
73
+ end
74
+
75
+ it "should parse a row without spaces and with a newline" do
76
+ @listener.should_receive(:row).with(r(%w{1 2}), 1)
77
+ @lexer.scan("|1|2|\n")
78
+ end
79
+
80
+ it "should parse a row with whitespace after the rows" do
81
+ @listener.should_receive(:row).with(r(%w{1 2}), 1)
82
+ @lexer.scan("| 1 | 2 | \n ")
83
+ end
84
+
85
+ it "should parse a row with lots of whitespace" do
86
+ @listener.should_receive(:row).with(r(["abc", "123"]), 1)
87
+ @lexer.scan(" \t| \t abc\t| \t123\t \t\t| \t\t \t \t\n ")
88
+ end
89
+
90
+ it "should parse a table with a commented-out row" do
91
+ @listener.should_receive(:row).with(r(["abc"]), 1)
92
+ @listener.should_receive(:comment).with("#|123|", 2)
93
+ @listener.should_receive(:row).with(r(["def"]), 3)
94
+ @lexer.scan("|abc|\n#|123|\n|def|\n")
95
+ end
96
+
97
+ it "should raise LexingError for rows that aren't closed" do
98
+ lambda {
99
+ @lexer.scan("|| oh hello \n")
100
+ }.should raise_error(/Parsing error on line 1: '|| oh hello/)
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
3
+
4
+ module Gherkin
5
+ module Lexer
6
+ shared_examples_for "a Gherkin lexer lexing tags" do
7
+ it "should lex a single tag" do
8
+ @listener.should_receive(:tag).with("@dog", 1)
9
+ @lexer.scan("@dog\n")
10
+ end
11
+
12
+ it "should lex multiple tags" do
13
+ @listener.should_receive(:tag).twice
14
+ @lexer.scan("@dog @cat\n")
15
+ end
16
+
17
+ it "should lex UTF-8 tags" do
18
+ @listener.should_receive(:tag).with("@シナリオテンプレート", 1)
19
+ @lexer.scan("@シナリオテンプレート\n")
20
+ end
21
+
22
+ it "should lex mixed tags" do
23
+ @listener.should_receive(:tag).with("@wip", 1).ordered
24
+ @listener.should_receive(:tag).with("@Значения", 1).ordered
25
+ @lexer.scan("@wip @Значения\n")
26
+ end
27
+
28
+ it "should lex wacky identifiers" do
29
+ @listener.should_receive(:tag).exactly(4).times
30
+ @lexer.scan("@BJ-x98.77 @BJ-z12.33 @O_o" "@#not_a_comment\n")
31
+ end
32
+
33
+ # TODO: Ask on ML for opinions about this one
34
+ it "should lex tags without spaces between them?" do
35
+ @listener.should_receive(:tag).twice
36
+ @lexer.scan("@one@two\n")
37
+ end
38
+
39
+ it "should not lex tags beginning with two @@ signs" do
40
+ @listener.should_not_receive(:tag)
41
+ lambda { @lexer.scan("@@test\n") }.should raise_error(/Lexing error on line 1/)
42
+ end
43
+
44
+ it "should not lex a lone @ sign" do
45
+ @listener.should_not_receive(:tag)
46
+ lambda { @lexer.scan("@\n") }.should raise_error(/Lexing error on line 1/)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,87 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'spec/gherkin'))
4
+ require 'gherkin'
5
+ require 'stringio'
6
+ require 'gherkin/sexp_recorder'
7
+ require 'rubygems'
8
+ require 'spec'
9
+ require 'spec/autorun'
10
+ require 'shared/lexer_spec'
11
+ require 'shared/tags_spec'
12
+ require 'shared/py_string_spec'
13
+ require 'shared/row_spec'
14
+
15
+ if defined?(JRUBY_VERSION)
16
+ class OutputStreamStringIO < Java.java.io.ByteArrayOutputStream
17
+ def rewind
18
+ end
19
+
20
+ def read
21
+ toString("UTF-8")
22
+ end
23
+ end
24
+ end
25
+
26
+ class StringIO
27
+ class << self
28
+ def new
29
+ if defined?(JRUBY_VERSION)
30
+ OutputStreamStringIO.new
31
+ else
32
+ super
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ module GherkinSpecHelper
39
+ def scan_file(file)
40
+ @lexer.scan(File.new(File.dirname(__FILE__) + "/gherkin/fixtures/" + file).read)
41
+ end
42
+
43
+ def rubify_hash(hash)
44
+ if defined?(JRUBY_VERSION)
45
+ h = {}
46
+ hash.keySet.each{|key| h[key] = hash[key]}
47
+ h
48
+ else
49
+ hash
50
+ end
51
+ end
52
+ end
53
+
54
+ Spec::Runner.configure do |c|
55
+ c.include(GherkinSpecHelper)
56
+ end
57
+
58
+ # Allows comparison of Java List with Ruby Array (rows)
59
+ Spec::Matchers.define :r do |expected|
60
+ match do |row|
61
+ def row.inspect
62
+ "r " + self.map{|cell| cell}.inspect
63
+ end
64
+ row.map{|cell| cell}.should == expected
65
+ end
66
+ end
67
+
68
+ Spec::Matchers.define :a do |expected|
69
+ match do |array|
70
+ def array.inspect
71
+ "a " + self.map{|e| e.to_sym}.inspect
72
+ end
73
+ array.map{|e| e.to_sym}.should == expected
74
+ end
75
+ end
76
+
77
+ Spec::Matchers.define :sym do |expected|
78
+ match do |actual|
79
+ expected.to_s == actual.to_s
80
+ end
81
+ end
82
+
83
+ Spec::Matchers.define :allow do |event|
84
+ match do |parser|
85
+ parser.expected.index(event)
86
+ end
87
+ end
@@ -0,0 +1,188 @@
1
+ %w{/../lib /bench}.each do |l|
2
+ $LOAD_PATH << File.expand_path(File.dirname(__FILE__) + l)
3
+ end
4
+
5
+ require 'benchmark'
6
+
7
+ GENERATED_FEATURES = File.expand_path(File.dirname(__FILE__) + "/bench/generated")
8
+
9
+ class RandomFeatureGenerator
10
+ def initialize(number)
11
+ require 'faker'
12
+ require 'feature_builder'
13
+
14
+ @number = number
15
+ end
16
+
17
+ def generate
18
+ @number.times do
19
+ name = catch_phrase
20
+ feature = FeatureBuilder.new(name) do |f|
21
+ num_scenarios = rand_in(1..10)
22
+ num_scenarios.times do
23
+ f.scenario(bs) do |steps|
24
+ num_steps = rand_in(3..10)
25
+ num_steps.times do
26
+ steps.step(sentence, self)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ write feature.to_s, name
32
+ end
33
+ end
34
+
35
+ def write(content, name)
36
+ File.open(GENERATED_FEATURES + "/#{name.downcase.gsub(/[\s\-\/]/, '_')}.feature", "w+") do |file|
37
+ file << content
38
+ end
39
+ end
40
+
41
+ def rand_in(range)
42
+ ary = range.to_a
43
+ ary[rand(ary.length - 1)]
44
+ end
45
+
46
+ def catch_phrase
47
+ Faker::Company.catch_phrase
48
+ end
49
+
50
+ def bs
51
+ Faker::Company.bs.capitalize
52
+ end
53
+
54
+ def sentence
55
+ Faker::Lorem.sentence
56
+ end
57
+
58
+ def table_cell
59
+ Faker::Lorem.words(rand(2)+1).join(" ")
60
+ end
61
+ end
62
+
63
+ class Benchmarker
64
+ def initialize
65
+ @features = Dir[GENERATED_FEATURES + "/**/*feature"]
66
+ end
67
+
68
+ def report(lexer)
69
+ Benchmark.bm do |x|
70
+ x.report("#{lexer}:") { send :"run_#{lexer}" }
71
+ end
72
+ end
73
+
74
+ def report_all
75
+ Benchmark.bmbm do |x|
76
+ x.report("native_gherkin:") { run_native_gherkin }
77
+ x.report("native_gherkin_no_parser:") { run_native_gherkin_no_parser }
78
+ x.report("rb_gherkin:") { run_rb_gherkin }
79
+ x.report("cucumber:") { run_cucumber }
80
+ x.report("tt:") { run_tt }
81
+ end
82
+ end
83
+
84
+ def run_cucumber
85
+ require 'cucumber'
86
+ require 'logger'
87
+ step_mother = Cucumber::StepMother.new
88
+ logger = Logger.new(STDOUT)
89
+ logger.level = Logger::INFO
90
+ step_mother.log = logger
91
+ step_mother.load_plain_text_features(@features)
92
+ end
93
+
94
+ def run_tt
95
+ require 'cucumber'
96
+ # Using Cucumber's Treetop lexer, but never calling #build to build the AST
97
+ lexer = Cucumber::Parser::NaturalLanguage.new(nil, 'en').parser
98
+ @features.each do |file|
99
+ source = IO.read(file)
100
+ parse_tree = lexer.parse(source)
101
+ if parse_tree.nil?
102
+ raise Cucumber::Parser::SyntaxError.new(lexer, file, 0)
103
+ end
104
+ end
105
+ end
106
+
107
+ def run_rb_gherkin
108
+ require 'gherkin'
109
+ require 'gherkin/i18n_lexer'
110
+ require 'null_listener'
111
+ parser = Gherkin::Parser::Parser.new(NullListener.new, true, "root")
112
+ lexer = Gherkin::I18nLexer.new(parser, true)
113
+ @features.each do |feature|
114
+ lexer.scan(File.read(feature))
115
+ end
116
+ end
117
+
118
+ def run_native_gherkin
119
+ require 'gherkin'
120
+ require 'gherkin/i18n_lexer'
121
+ require 'null_listener'
122
+ parser = Gherkin::Parser::Parser.new(NullListener.new, true, "root")
123
+ lexer = Gherkin::I18nLexer.new(parser, false)
124
+ @features.each do |feature|
125
+ lexer.scan(File.read(feature))
126
+ end
127
+ end
128
+
129
+ def run_native_gherkin_no_parser
130
+ require 'gherkin'
131
+ require 'gherkin/i18n_lexer'
132
+ require 'null_listener'
133
+ lexer = Gherkin::I18nLexer.new(NullListener.new, false)
134
+ @features.each do |feature|
135
+ lexer.scan(File.read(feature))
136
+ end
137
+ end
138
+ end
139
+
140
+ desc "Generate 500 random features and benchmark Cucumber, Treetop and Gherkin with them"
141
+ task :bench => ["bench:clean", "bench:gen"] do
142
+ benchmarker = Benchmarker.new
143
+ benchmarker.report_all
144
+ end
145
+
146
+ namespace :bench do
147
+ desc "Generate [number] features with random content, or 500 features if number is not provided"
148
+ task :gen, :number do |t, args|
149
+ args.with_defaults(:number => 500)
150
+ generator = RandomFeatureGenerator.new(args.number.to_i)
151
+ generator.generate
152
+ end
153
+
154
+ desc "Benchmark Cucumber AST building from the features in tasks/bench/generated"
155
+ task :cucumber do
156
+ benchmarker = Benchmarker.new
157
+ benchmarker.report("cucumber")
158
+ end
159
+
160
+ desc "Benchmark the Treetop parser with the features in tasks/bench/generated"
161
+ task :tt do
162
+ benchmarker = Benchmarker.new
163
+ benchmarker.report("tt")
164
+ end
165
+
166
+ desc "Benchmark the Ruby Gherkin lexer+parser with the features in tasks/bench/generated"
167
+ task :rb_gherkin do
168
+ benchmarker = Benchmarker.new
169
+ benchmarker.report("rb_gherkin")
170
+ end
171
+
172
+ desc "Benchmark the ntive Gherkin lexer+parser with the features in tasks/bench/generated"
173
+ task :native_gherkin do
174
+ benchmarker = Benchmarker.new
175
+ benchmarker.report("native_gherkin")
176
+ end
177
+
178
+ desc "Benchmark the native Gherkin lexer (no parser) with the features in tasks/bench/generated"
179
+ task :native_gherkin_no_parser do
180
+ benchmarker = Benchmarker.new
181
+ benchmarker.report("native_gherkin_no_parser")
182
+ end
183
+
184
+ desc "Remove all generated features in tasks/bench/generated"
185
+ task :clean do
186
+ rm_f FileList[GENERATED_FEATURES + "/**/*feature"]
187
+ end
188
+ end