gherkin 1.0.30-universal-dotnet → 2.0.0-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 (58) hide show
  1. data/.rspec +1 -0
  2. data/History.txt +19 -0
  3. data/Rakefile +4 -4
  4. data/VERSION.yml +2 -2
  5. data/features/feature_parser.feature +11 -0
  6. data/features/json_formatter.feature +238 -0
  7. data/features/pretty_formatter.feature +9 -0
  8. data/features/step_definitions/gherkin_steps.rb +1 -1
  9. data/features/step_definitions/json_formatter_steps.rb +32 -0
  10. data/features/step_definitions/pretty_formatter_steps.rb +24 -23
  11. data/features/support/env.rb +3 -3
  12. data/lib/gherkin/formatter/json_formatter.rb +82 -0
  13. data/lib/gherkin/formatter/pretty_formatter.rb +73 -78
  14. data/lib/gherkin/i18n.rb +22 -18
  15. data/lib/gherkin/i18n.yml +9 -9
  16. data/lib/gherkin/i18n_lexer.rb +2 -2
  17. data/lib/gherkin/parser/event.rb +6 -6
  18. data/lib/gherkin/parser/filter_listener.rb +5 -1
  19. data/lib/gherkin/parser/formatter_listener.rb +113 -0
  20. data/lib/gherkin/parser/json_parser.rb +102 -0
  21. data/lib/gherkin/parser/parser.rb +10 -2
  22. data/lib/gherkin/parser/row.rb +15 -0
  23. data/lib/gherkin/rubify.rb +2 -0
  24. data/lib/gherkin/tools/files.rb +1 -1
  25. data/lib/gherkin/tools/reformat.rb +1 -2
  26. data/lib/gherkin/tools/stats.rb +1 -1
  27. data/lib/gherkin/tools/stats_listener.rb +5 -5
  28. data/ragel/lexer.c.rl.erb +41 -12
  29. data/ragel/lexer.java.rl.erb +26 -17
  30. data/ragel/lexer.rb.rl.erb +10 -5
  31. data/ragel/lexer_common.rl.erb +6 -6
  32. data/spec/gherkin/c_lexer_spec.rb +2 -2
  33. data/spec/gherkin/fixtures/complex.js +105 -0
  34. data/spec/gherkin/formatter/argument_spec.rb +3 -3
  35. data/spec/gherkin/formatter/colors_spec.rb +3 -4
  36. data/spec/gherkin/formatter/pretty_formatter_spec.rb +21 -50
  37. data/spec/gherkin/i18n_lexer_spec.rb +6 -6
  38. data/spec/gherkin/i18n_spec.rb +16 -9
  39. data/spec/gherkin/java_lexer_spec.rb +1 -2
  40. data/spec/gherkin/output_stream_string_io.rb +24 -0
  41. data/spec/gherkin/parser/filter_listener_spec.rb +16 -9
  42. data/spec/gherkin/parser/formatter_listener_spec.rb +134 -0
  43. data/spec/gherkin/parser/json_parser_spec.rb +129 -0
  44. data/spec/gherkin/parser/parser_spec.rb +9 -9
  45. data/spec/gherkin/parser/tag_expression_spec.rb +8 -8
  46. data/spec/gherkin/rb_lexer_spec.rb +1 -1
  47. data/spec/gherkin/sexp_recorder.rb +21 -1
  48. data/spec/gherkin/shared/{lexer_spec.rb → lexer_group.rb} +172 -102
  49. data/spec/gherkin/shared/{py_string_spec.rb → py_string_group.rb} +21 -17
  50. data/spec/gherkin/shared/{row_spec.rb → row_group.rb} +36 -19
  51. data/spec/gherkin/shared/{tags_spec.rb → tags_group.rb} +13 -9
  52. data/spec/spec_helper.rb +18 -38
  53. data/tasks/bench.rake +3 -3
  54. data/tasks/compile.rake +13 -14
  55. data/tasks/rspec.rake +6 -11
  56. metadata +42 -28
  57. data/features/pretty_printer.feature +0 -14
  58. data/spec/gherkin/csharp_lexer_spec.rb +0 -20
@@ -1,10 +1,13 @@
1
1
  # encoding: utf-8
2
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+ require 'spec_helper'
3
3
 
4
4
  module Gherkin
5
5
  module Lexer
6
6
  shared_examples_for "a Gherkin lexer lexing py_strings" do
7
-
7
+ def scan(gherkin)
8
+ @lexer.scan(gherkin, "test.feature", 0)
9
+ end
10
+
8
11
  def ps(content)
9
12
  '"""%s"""' % ("\n" + content + "\n")
10
13
  end
@@ -21,17 +24,17 @@ Feature: some feature
21
24
  Then bar
22
25
  EOS
23
26
  @listener.should_receive(:py_string).with(" Hello\nGoodbye", 4)
24
- @lexer.scan(str)
27
+ scan(str)
25
28
  end
26
29
 
27
30
  it "should parse a simple py_string" do
28
31
  @listener.should_receive(:py_string).with("I am a py_string", 1)
29
- @lexer.scan ps("I am a py_string")
32
+ scan ps("I am a py_string")
30
33
  end
31
34
 
32
35
  it "should parse an empty py_string" do
33
36
  @listener.should_receive(:py_string).with("", 4)
34
- @lexer.scan("Feature: Hi\nScenario: Hi\nGiven a step\n\"\"\"\n\"\"\"")
37
+ scan("Feature: Hi\nScenario: Hi\nGiven a step\n\"\"\"\n\"\"\"")
35
38
  end
36
39
 
37
40
  it "should treat a string containing only newlines as only newlines" do
@@ -43,12 +46,13 @@ py_string = <<EOS
43
46
  """
44
47
  EOS
45
48
  @listener.should_receive(:py_string).with("\n\n", 1)
46
- @lexer.scan(py_string)
49
+ scan(py_string)
47
50
  end
48
51
 
49
52
  it "should parse content separated by two newlines" do
50
- @lexer.scan ps("A\n\nB")
53
+ scan ps("A\n\nB")
51
54
  @listener.to_sexp.should == [
55
+ [:location, 'test.feature', 0],
52
56
  [:py_string, "A\n\nB", 1],
53
57
  [:eof]
54
58
  ]
@@ -56,12 +60,12 @@ EOS
56
60
 
57
61
  it "should parse a multiline string" do
58
62
  @listener.should_receive(:py_string).with("A\nB\nC\nD", 1)
59
- @lexer.scan ps("A\nB\nC\nD")
63
+ scan ps("A\nB\nC\nD")
60
64
  end
61
65
 
62
66
  it "should ignore unescaped quotes inside the string delimeters" do
63
67
  @listener.should_receive(:py_string).with("What does \"this\" mean?", 1)
64
- @lexer.scan ps('What does "this" mean?')
68
+ scan ps('What does "this" mean?')
65
69
  end
66
70
 
67
71
  it "should preserve whitespace within the triple quotes" do
@@ -72,12 +76,12 @@ str = <<EOS
72
76
  """
73
77
  EOS
74
78
  @listener.should_receive(:py_string).with(" Line one\nLine two", 1)
75
- @lexer.scan(str)
79
+ scan(str)
76
80
  end
77
81
 
78
82
  it "should preserve tabs within the content" do
79
83
  @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")
84
+ scan ps("I have\tsome tabs\nInside\t\tthe content")
81
85
  end
82
86
 
83
87
  it "should handle complex py_strings" do
@@ -96,7 +100,7 @@ Feature: Sample
96
100
  EOS
97
101
 
98
102
  @listener.should_receive(:py_string).with(py_string, 1)
99
- @lexer.scan ps(py_string)
103
+ scan ps(py_string)
100
104
  end
101
105
 
102
106
  it "should allow whitespace after the closing py_string delimiter" do
@@ -106,7 +110,7 @@ str = <<EOS
106
110
  """
107
111
  EOS
108
112
  @listener.should_receive(:py_string).with(" Line one", 1)
109
- @lexer.scan(str)
113
+ scan(str)
110
114
  end
111
115
 
112
116
  it "should preserve the last newline(s) at the end of a py_string" do
@@ -118,12 +122,12 @@ str = <<EOS
118
122
  """
119
123
  EOS
120
124
  @listener.should_receive(:py_string).with("PyString text\n\n",1)
121
- @lexer.scan(str)
125
+ scan(str)
122
126
  end
123
127
 
124
128
  it "should preserve CRLFs within py_strings" do
125
129
  @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\"\"\"")
130
+ scan("\"\"\"\r\nLine one\r\nLine two\r\n\r\n\"\"\"")
127
131
  end
128
132
 
129
133
  it "should unescape escaped triple quotes" do
@@ -133,7 +137,7 @@ str = <<EOS
133
137
  """
134
138
  EOS
135
139
  @listener.should_receive(:py_string).with('"""', 1)
136
- @lexer.scan(str)
140
+ scan(str)
137
141
  end
138
142
 
139
143
  it "should not unescape escaped single quotes" do
@@ -143,7 +147,7 @@ str = <<EOS
143
147
  """
144
148
  EOS
145
149
  @listener.should_receive(:py_string).with('\" \"\"', 1)
146
- @lexer.scan(str)
150
+ scan(str)
147
151
  end
148
152
  end
149
153
  end
@@ -1,9 +1,13 @@
1
1
  # encoding: utf-8
2
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+ require 'spec_helper'
3
3
 
4
4
  module Gherkin
5
5
  module Lexer
6
6
  shared_examples_for "a Gherkin lexer lexing rows" do
7
+ def scan(gherkin)
8
+ @lexer.scan(gherkin, "test.feature", 0)
9
+ end
10
+
7
11
  rows = {
8
12
  "|a|b|\n" => %w{a b},
9
13
  "|a|b|c|\n" => %w{a b c},
@@ -12,33 +16,34 @@ module Gherkin
12
16
  rows.each do |text, expected|
13
17
  it "should parse #{text}" do
14
18
  @listener.should_receive(:row).with(r(expected), 1)
15
- @lexer.scan(text.dup)
19
+ scan(text.dup)
16
20
  end
17
21
  end
18
22
 
19
23
  it "should parse a row with many cells" do
20
24
  @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")
25
+ scan("|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|\n")
22
26
  end
23
27
 
24
28
  it "should parse multicharacter cell content" do
25
29
  @listener.should_receive(:row).with(r(%w{foo bar}), 1)
26
- @lexer.scan("| foo | bar |\n")
30
+ scan("| foo | bar |\n")
27
31
  end
28
32
 
29
33
  it "should escape backslashed pipes" do
30
34
  @listener.should_receive(:row).with(r(['|', 'the', '\a', '\\', '|\\|']), 1)
31
- @lexer.scan('| \| | the | \a | \\ | \|\\\| |' + "\n")
35
+ scan('| \| | the | \a | \\ | \|\\\| |' + "\n")
32
36
  end
33
37
 
34
38
  it "should parse cells with spaces within the content" do
35
39
  @listener.should_receive(:row).with(r(["Dill pickle", "Valencia orange"]), 1)
36
- @lexer.scan("| Dill pickle | Valencia orange |\n")
40
+ scan("| Dill pickle | Valencia orange |\n")
37
41
  end
38
42
 
39
43
  it "should allow utf-8" do
40
- @lexer.scan(" | ůﻚ | 2 | \n")
44
+ scan(" | ůﻚ | 2 | \n")
41
45
  @listener.to_sexp.should == [
46
+ [:location, 'test.feature', 0],
42
47
  [:row, ["ůﻚ", "2"], 1],
43
48
  [:eof]
44
49
  ]
@@ -46,58 +51,70 @@ module Gherkin
46
51
 
47
52
  it "should allow utf-8 using should_receive" do
48
53
  @listener.should_receive(:row).with(r(['繁體中文 而且','並且','繁體中文 而且','並且']), 1)
49
- @lexer.scan("| 繁體中文 而且|並且| 繁體中文 而且|並且|\n")
54
+ scan("| 繁體中文 而且|並且| 繁體中文 而且|並且|\n")
50
55
  end
51
56
 
52
57
  it "should parse a 2x2 table" do
53
58
  @listener.should_receive(:row).with(r(%w{1 2}), 1)
54
59
  @listener.should_receive(:row).with(r(%w{3 4}), 2)
55
- @lexer.scan("| 1 | 2 |\n| 3 | 4 |\n")
60
+ scan("| 1 | 2 |\n| 3 | 4 |\n")
56
61
  end
57
62
 
58
63
  it "should parse a 2x2 table with empty cells" do
59
64
  @listener.should_receive(:row).with(r(['1', '']), 1)
60
65
  @listener.should_receive(:row).with(r(['', '4']), 2)
61
- @lexer.scan("| 1 | |\n|| 4 |\n")
66
+ scan("| 1 | |\n|| 4 |\n")
62
67
  end
63
68
 
64
69
  it "should parse a row with empty cells" do
65
70
  @listener.should_receive(:row).with(r(['1', '']), 1).twice
66
- @lexer.scan("| 1 | |\n")
67
- @lexer.scan("|1||\n")
71
+ scan("| 1 | |\n")
72
+ scan("|1||\n")
68
73
  end
69
74
 
70
75
  it "should parse a 1x2 table that does not end in a newline" do
71
76
  @listener.should_receive(:row).with(r(%w{1 2}), 1)
72
- @lexer.scan("| 1 | 2 |")
77
+ scan("| 1 | 2 |")
73
78
  end
74
79
 
75
80
  it "should parse a row without spaces and with a newline" do
76
81
  @listener.should_receive(:row).with(r(%w{1 2}), 1)
77
- @lexer.scan("|1|2|\n")
82
+ scan("|1|2|\n")
78
83
  end
79
84
 
80
85
  it "should parse a row with whitespace after the rows" do
81
86
  @listener.should_receive(:row).with(r(%w{1 2}), 1)
82
- @lexer.scan("| 1 | 2 | \n ")
87
+ scan("| 1 | 2 | \n ")
83
88
  end
84
89
 
85
90
  it "should parse a row with lots of whitespace" do
86
91
  @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 ")
92
+ scan(" \t| \t abc\t| \t123\t \t\t| \t\t \t \t\n ")
88
93
  end
89
94
 
90
95
  it "should parse a table with a commented-out row" do
91
96
  @listener.should_receive(:row).with(r(["abc"]), 1)
92
97
  @listener.should_receive(:comment).with("#|123|", 2)
93
98
  @listener.should_receive(:row).with(r(["def"]), 3)
94
- @lexer.scan("|abc|\n#|123|\n|def|\n")
99
+ scan("|abc|\n#|123|\n|def|\n")
95
100
  end
96
101
 
97
102
  it "should raise LexingError for rows that aren't closed" do
98
103
  lambda {
99
- @lexer.scan("|| oh hello \n")
100
- }.should raise_error(/Parsing error on line 1: '|| oh hello/)
104
+ scan("|| oh hello \n")
105
+ }.should raise_error(/Lexing error on line 1: '\|\| oh hello/)
106
+ end
107
+
108
+ it "should raise LexingError for rows that are followed by a comment" do
109
+ lambda {
110
+ scan("|hi| # oh hello \n")
111
+ }.should raise_error(/Lexing error on line 1: '\|hi\| # oh hello/)
112
+ end
113
+
114
+ it "should raise LexingError for rows that aren't closed" do
115
+ lambda {
116
+ scan("|| oh hello \n |Shoudn't Get|Here|")
117
+ }.should raise_error(/Lexing error on line 1: '\|\| oh hello/)
101
118
  end
102
119
  end
103
120
  end
@@ -1,49 +1,53 @@
1
1
  # encoding: utf-8
2
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+ require 'spec_helper'
3
3
 
4
4
  module Gherkin
5
5
  module Lexer
6
6
  shared_examples_for "a Gherkin lexer lexing tags" do
7
+ def scan(gherkin)
8
+ @lexer.scan(gherkin, "test.feature", 0)
9
+ end
10
+
7
11
  it "should lex a single tag" do
8
12
  @listener.should_receive(:tag).with("@dog", 1)
9
- @lexer.scan("@dog\n")
13
+ scan("@dog\n")
10
14
  end
11
15
 
12
16
  it "should lex multiple tags" do
13
17
  @listener.should_receive(:tag).twice
14
- @lexer.scan("@dog @cat\n")
18
+ scan("@dog @cat\n")
15
19
  end
16
20
 
17
21
  it "should lex UTF-8 tags" do
18
22
  @listener.should_receive(:tag).with("@シナリオテンプレート", 1)
19
- @lexer.scan("@シナリオテンプレート\n")
23
+ scan("@シナリオテンプレート\n")
20
24
  end
21
25
 
22
26
  it "should lex mixed tags" do
23
27
  @listener.should_receive(:tag).with("@wip", 1).ordered
24
28
  @listener.should_receive(:tag).with("@Значения", 1).ordered
25
- @lexer.scan("@wip @Значения\n")
29
+ scan("@wip @Значения\n")
26
30
  end
27
31
 
28
32
  it "should lex wacky identifiers" do
29
33
  @listener.should_receive(:tag).exactly(4).times
30
- @lexer.scan("@BJ-x98.77 @BJ-z12.33 @O_o" "@#not_a_comment\n")
34
+ scan("@BJ-x98.77 @BJ-z12.33 @O_o" "@#not_a_comment\n")
31
35
  end
32
36
 
33
37
  # TODO: Ask on ML for opinions about this one
34
38
  it "should lex tags without spaces between them?" do
35
39
  @listener.should_receive(:tag).twice
36
- @lexer.scan("@one@two\n")
40
+ scan("@one@two\n")
37
41
  end
38
42
 
39
43
  it "should not lex tags beginning with two @@ signs" do
40
44
  @listener.should_not_receive(:tag)
41
- lambda { @lexer.scan("@@test\n") }.should raise_error(/Lexing error on line 1/)
45
+ lambda { scan("@@test\n") }.should raise_error(/Lexing error on line 1/)
42
46
  end
43
47
 
44
48
  it "should not lex a lone @ sign" do
45
49
  @listener.should_not_receive(:tag)
46
- lambda { @lexer.scan("@\n") }.should raise_error(/Lexing error on line 1/)
50
+ lambda { scan("@\n") }.should raise_error(/Lexing error on line 1/)
47
51
  end
48
52
  end
49
53
  end
data/spec/spec_helper.rb CHANGED
@@ -1,43 +1,23 @@
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
1
  require 'gherkin'
5
2
  require 'stringio'
6
3
  require 'gherkin/sexp_recorder'
4
+ require 'gherkin/output_stream_string_io'
7
5
  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
6
+ require 'rspec/autorun'
7
+ require 'gherkin/shared/lexer_group'
8
+ require 'gherkin/shared/tags_group'
9
+ require 'gherkin/shared/py_string_group'
10
+ require 'gherkin/shared/row_group'
37
11
 
38
12
  module GherkinSpecHelper
13
+ # TODO: Rename to gherkin_scan_file
39
14
  def scan_file(file)
40
- @lexer.scan(File.new(File.dirname(__FILE__) + "/gherkin/fixtures/" + file).read)
15
+ @lexer.scan(File.new(File.dirname(__FILE__) + "/gherkin/fixtures/" + file).read, file, 0)
16
+ end
17
+
18
+ # TODO: Remove
19
+ def parse_file(file)
20
+ @parser.parse(File.new(File.dirname(__FILE__) + "/gherkin/fixtures/" + file).read)
41
21
  end
42
22
 
43
23
  def rubify_hash(hash)
@@ -51,12 +31,12 @@ module GherkinSpecHelper
51
31
  end
52
32
  end
53
33
 
54
- Spec::Runner.configure do |c|
34
+ RSpec.configure do |c|
55
35
  c.include(GherkinSpecHelper)
56
36
  end
57
37
 
58
38
  # Allows comparison of Java List with Ruby Array (rows)
59
- Spec::Matchers.define :r do |expected|
39
+ RSpec::Matchers.define :r do |expected|
60
40
  match do |row|
61
41
  def row.inspect
62
42
  "r " + self.map{|cell| cell}.inspect
@@ -65,7 +45,7 @@ Spec::Matchers.define :r do |expected|
65
45
  end
66
46
  end
67
47
 
68
- Spec::Matchers.define :a do |expected|
48
+ RSpec::Matchers.define :a do |expected|
69
49
  match do |array|
70
50
  def array.inspect
71
51
  "a " + self.map{|e| e.to_sym}.inspect
@@ -74,13 +54,13 @@ Spec::Matchers.define :a do |expected|
74
54
  end
75
55
  end
76
56
 
77
- Spec::Matchers.define :sym do |expected|
57
+ RSpec::Matchers.define :sym do |expected|
78
58
  match do |actual|
79
59
  expected.to_s == actual.to_s
80
60
  end
81
61
  end
82
62
 
83
- Spec::Matchers.define :allow do |event|
63
+ RSpec::Matchers.define :allow do |event|
84
64
  match do |parser|
85
65
  parser.expected.index(event)
86
66
  end
data/tasks/bench.rake CHANGED
@@ -111,7 +111,7 @@ class Benchmarker
111
111
  parser = Gherkin::Parser::Parser.new(NullListener.new, true, "root")
112
112
  lexer = Gherkin::I18nLexer.new(parser, true)
113
113
  @features.each do |feature|
114
- lexer.scan(File.read(feature))
114
+ lexer.scan(File.read(feature), feature, 0)
115
115
  end
116
116
  end
117
117
 
@@ -122,7 +122,7 @@ class Benchmarker
122
122
  parser = Gherkin::Parser::Parser.new(NullListener.new, true, "root")
123
123
  lexer = Gherkin::I18nLexer.new(parser, false)
124
124
  @features.each do |feature|
125
- lexer.scan(File.read(feature))
125
+ lexer.scan(File.read(feature), feature, 0)
126
126
  end
127
127
  end
128
128
 
@@ -132,7 +132,7 @@ class Benchmarker
132
132
  require 'null_listener'
133
133
  lexer = Gherkin::I18nLexer.new(NullListener.new, false)
134
134
  @features.each do |feature|
135
- lexer.scan(File.read(feature))
135
+ lexer.scan(File.read(feature), feature, 0)
136
136
  end
137
137
  end
138
138
  end