gherkin 1.0.2-i386-mswin32 → 1.0.3-i386-mswin32

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 (76) hide show
  1. data/.gitattributes +1 -0
  2. data/History.txt +18 -0
  3. data/README.rdoc +12 -1
  4. data/Rakefile +4 -2
  5. data/VERSION.yml +1 -1
  6. data/bin/gherkin +1 -1
  7. data/dotnet/.gitignore +13 -0
  8. data/features/feature_parser.feature +22 -2
  9. data/features/native_lexer.feature +1 -1
  10. data/features/parser_with_native_lexer.feature +1 -1
  11. data/features/step_definitions/gherkin_steps.rb +2 -6
  12. data/features/step_definitions/pretty_printer_steps.rb +2 -3
  13. data/features/steps_parser.feature +1 -1
  14. data/gherkin.gemspec +40 -13
  15. data/java/Gherkin.iml +2 -4
  16. data/java/build.xml +3 -0
  17. data/java/src/gherkin/FixJava.java +6 -3
  18. data/java/src/gherkin/I18nLexer.java +48 -0
  19. data/java/src/gherkin/Listener.java +3 -1
  20. data/java/src/gherkin/Main.java +17 -0
  21. data/java/src/gherkin/Parser.java +9 -3
  22. data/java/src/gherkin/formatter/Argument.java +39 -0
  23. data/java/src/gherkin/formatter/ArgumentFormat.java +17 -0
  24. data/java/src/gherkin/formatter/Colors.java +7 -0
  25. data/java/src/gherkin/formatter/Formatter.java +15 -0
  26. data/java/src/gherkin/formatter/PrettyFormatter.java +219 -0
  27. data/java/src/gherkin/parser/StateMachineReader.java +8 -3
  28. data/java/test/gherkin/formatter/ArgumentTest.java +17 -0
  29. data/lib/gherkin/csharp_lexer.rb +15 -0
  30. data/lib/gherkin/format/argument.rb +35 -0
  31. data/lib/gherkin/format/monochrome_format.rb +9 -0
  32. data/lib/gherkin/i18n.rb +22 -0
  33. data/lib/gherkin/i18n.yml +34 -20
  34. data/lib/gherkin/i18n_lexer.rb +57 -13
  35. data/lib/gherkin/lexer.rb +9 -18
  36. data/lib/gherkin/parser.rb +3 -3
  37. data/lib/gherkin/parser/meta.txt +5 -4
  38. data/lib/gherkin/parser/root.txt +11 -9
  39. data/lib/gherkin/parser/steps.txt +4 -3
  40. data/lib/gherkin/rb_parser.rb +13 -5
  41. data/lib/gherkin/tools/colors.rb +119 -0
  42. data/lib/gherkin/tools/files.rb +6 -1
  43. data/lib/gherkin/tools/pretty_listener.rb +115 -23
  44. data/ragel/lexer.c.rl.erb +67 -51
  45. data/ragel/lexer.csharp.rl.erb +240 -0
  46. data/ragel/lexer.java.rl.erb +27 -18
  47. data/ragel/lexer.rb.rl.erb +17 -17
  48. data/ragel/lexer_common.rl.erb +8 -8
  49. data/spec/gherkin/c_lexer_spec.rb +4 -4
  50. data/spec/gherkin/csharp_lexer_spec.rb +20 -0
  51. data/spec/gherkin/fixtures/comments_in_table.feature +9 -0
  52. data/spec/gherkin/fixtures/complex.feature +2 -0
  53. data/spec/gherkin/fixtures/dos_line_endings.feature +45 -0
  54. data/spec/gherkin/fixtures/i18n_fr.feature +1 -0
  55. data/spec/gherkin/fixtures/i18n_no.feature +1 -0
  56. data/spec/gherkin/fixtures/i18n_zh-CN.feature +1 -0
  57. data/spec/gherkin/format/argument_spec.rb +28 -0
  58. data/spec/gherkin/i18n_lexer_spec.rb +4 -4
  59. data/spec/gherkin/i18n_spec.rb +31 -23
  60. data/spec/gherkin/java_lexer_spec.rb +4 -3
  61. data/spec/gherkin/parser_spec.rb +5 -0
  62. data/spec/gherkin/rb_lexer_spec.rb +4 -2
  63. data/spec/gherkin/sexp_recorder.rb +1 -1
  64. data/spec/gherkin/shared/lexer_spec.rb +169 -60
  65. data/spec/gherkin/shared/py_string_spec.rb +6 -0
  66. data/spec/gherkin/shared/row_spec.rb +107 -0
  67. data/spec/gherkin/shared/tags_spec.rb +1 -1
  68. data/spec/gherkin/tools/colors_spec.rb +19 -0
  69. data/spec/gherkin/tools/pretty_listener_spec.rb +147 -0
  70. data/spec/spec_helper.rb +31 -7
  71. data/tasks/compile.rake +81 -7
  72. data/tasks/ragel_task.rb +6 -4
  73. data/tasks/rspec.rake +2 -2
  74. metadata +86 -26
  75. data/lib/gherkin/java_lexer.rb +0 -10
  76. data/spec/gherkin/shared/table_spec.rb +0 -97
@@ -50,6 +50,7 @@ EOS
50
50
  @lexer.scan ps("A\n\nB")
51
51
  @listener.to_sexp.should == [
52
52
  [:py_string, "A\n\nB", 1],
53
+ [:eof]
53
54
  ]
54
55
  end
55
56
 
@@ -119,6 +120,11 @@ EOS
119
120
  @listener.should_receive(:py_string).with("PyString text\n\n",1)
120
121
  @lexer.scan(str)
121
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
122
128
  end
123
129
  end
124
130
  end
@@ -0,0 +1,107 @@
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 parse cells with spaces within the content" do
30
+ @listener.should_receive(:row).with(r(["Dill pickle", "Valencia orange"]), 1)
31
+ @lexer.scan("| Dill pickle | Valencia orange |\n")
32
+ end
33
+
34
+ it "should allow utf-8" do
35
+ # Fails in 1.9.1!
36
+ # 'Gherkin::Lexer::Table should allow utf-8 with using == to evaluate' FAILED
37
+ # expected: [[:row, [["ůﻚ", "2"]], 1]],
38
+ # got: [[:row, [["\xC5\xAF\xEF\xBB\x9A", "2"]], 1]] (using ==)
39
+ # BUT, simply running:
40
+ # [[:row, [["ůﻚ", "2"]], 1]].should == [[:row, [["\xC5\xAF\xEF\xBB\x9A", "2"]], 1]]
41
+ # passes
42
+ #
43
+ @lexer.scan(" | ůﻚ | 2 | \n")
44
+ @listener.to_sexp.should == [
45
+ [:row, ["ůﻚ", "2"], 1],
46
+ [:eof]
47
+ ]
48
+ end
49
+
50
+ it "should allow utf-8 using should_receive" do
51
+ @listener.should_receive(:row).with(r(['繁體中文 而且','並且','繁體中文 而且','並且']), 1)
52
+ @lexer.scan("| 繁體中文 而且|並且| 繁體中文 而且|並且|\n")
53
+ end
54
+
55
+ it "should parse a 2x2 table" do
56
+ @listener.should_receive(:row).with(r(%w{1 2}), 1)
57
+ @listener.should_receive(:row).with(r(%w{3 4}), 2)
58
+ @lexer.scan("| 1 | 2 |\n| 3 | 4 |\n")
59
+ end
60
+
61
+ it "should parse a 2x2 table with empty cells" do
62
+ @listener.should_receive(:row).with(r(['1', '']), 1)
63
+ @listener.should_receive(:row).with(r(['', '4']), 2)
64
+ @lexer.scan("| 1 | |\n|| 4 |\n")
65
+ end
66
+
67
+ it "should parse a row with empty cells" do
68
+ @listener.should_receive(:row).with(r(['1', '']), 1).twice
69
+ @lexer.scan("| 1 | |\n")
70
+ @lexer.scan("|1||\n")
71
+ end
72
+
73
+ it "should parse a 1x2 table that does not end in a newline" do
74
+ @listener.should_receive(:row).with(r(%w{1 2}), 1)
75
+ @lexer.scan("| 1 | 2 |")
76
+ end
77
+
78
+ it "should parse a row without spaces and with a newline" do
79
+ @listener.should_receive(:row).with(r(%w{1 2}), 1)
80
+ @lexer.scan("|1|2|\n")
81
+ end
82
+
83
+ it "should parse a row with whitespace after the rows" do
84
+ @listener.should_receive(:row).with(r(%w{1 2}), 1)
85
+ @lexer.scan("| 1 | 2 | \n ")
86
+ end
87
+
88
+ it "should parse a row with lots of whitespace" do
89
+ @listener.should_receive(:row).with(r(["abc", "123"]), 1)
90
+ @lexer.scan(" \t| \t abc\t| \t123\t \t\t| \t\t \t \t\n ")
91
+ end
92
+
93
+ it "should parse a table with a commented-out row" do
94
+ @listener.should_receive(:row).with(r(["abc"]), 1)
95
+ @listener.should_receive(:comment).with("#|123|", 2)
96
+ @listener.should_receive(:row).with(r(["def"]), 3)
97
+ @lexer.scan("|abc|\n#|123|\n|def|\n")
98
+ end
99
+
100
+ it "should raise LexingError for rows that aren't closed" do
101
+ lambda {
102
+ @lexer.scan("|| oh hello \n")
103
+ }.should raise_error(/Parsing error on line 1: '|| oh hello/)
104
+ end
105
+ end
106
+ end
107
+ end
@@ -1,4 +1,4 @@
1
- #encoding: utf-8
1
+ # encoding: utf-8
2
2
  require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
3
3
 
4
4
  module Gherkin
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+ require 'gherkin/tools/pretty_listener'
3
+
4
+
5
+ module Gherkin
6
+ module Tools
7
+ describe Colors do
8
+ include Colors
9
+
10
+ it "should colour stuff red" do
11
+ failed("hello").should == "\e[31mhello\e[0m"
12
+ end
13
+
14
+ it "should be possible to specify no colouring" do
15
+ failed("hello", true).should == "hello"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,147 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
3
+ require 'gherkin/tools/pretty_listener'
4
+ require 'gherkin/format/argument'
5
+ require 'stringio'
6
+
7
+ module Gherkin
8
+ module Tools
9
+ describe PrettyListener do
10
+ def assert_io(s)
11
+ @io.rewind
12
+ actual = @io.read
13
+ actual.should == s
14
+ end
15
+
16
+ def assert_pretty(text)
17
+ io = StringIO.new
18
+ l = PrettyListener.new(io, true)
19
+ parser = Gherkin::Parser.new(l, true, "root")
20
+ lexer = Gherkin::I18nLexer.new(parser, true)
21
+ lexer.scan(text)
22
+ io.rewind
23
+ actual = io.read
24
+ actual.should == text
25
+ end
26
+
27
+ before do
28
+ @io = StringIO.new
29
+ @l = PrettyListener.new(@io, true)
30
+ end
31
+
32
+ it "should print comments when scenario is longer" do
33
+ @l.feature("Feature", "Hello\nWorld", 1)
34
+ @l.steps([
35
+ ['Given ', 'some stuff'],
36
+ ['When ', 'foo']
37
+ ])
38
+ @l.scenario("Scenario", "The scenario", 4, "features/foo.feature:4")
39
+ @l.step("Given ", "some stuff", 5, nil, nil, "features/step_definitions/bar.rb:56")
40
+ @l.step("When ", "foo", 6, nil, nil, "features/step_definitions/bar.rb:96")
41
+
42
+ assert_io(%{Feature: Hello
43
+ World
44
+
45
+ Scenario: The scenario # features/foo.feature:4
46
+ Given some stuff # features/step_definitions/bar.rb:56
47
+ When foo # features/step_definitions/bar.rb:96
48
+ })
49
+ end
50
+
51
+ it "should print comments when step is longer" do
52
+ @l.feature("Feature", "Hello\nWorld", 1)
53
+ @l.steps([
54
+ ['Given ', 'some stuff that is longer']
55
+ ])
56
+ @l.scenario("Scenario", "The scenario", 4, "features/foo.feature:4")
57
+ @l.step("Given ", "some stuff that is longer", 5, nil, nil, "features/step_definitions/bar.rb:56")
58
+
59
+ assert_io(%{Feature: Hello
60
+ World
61
+
62
+ Scenario: The scenario # features/foo.feature:4
63
+ Given some stuff that is longer # features/step_definitions/bar.rb:56
64
+ })
65
+ end
66
+
67
+ it "should print ANSI coloured steps" do
68
+ @l.feature("Feature", "Hello\nWorld", 1)
69
+ @l.steps([
70
+ ['Given ', 'some stuff that is longer']
71
+ ])
72
+ @l.scenario("Scenario", "The scenario", 4, "features/foo.feature:4")
73
+ @l.step("Given ", "some stuff that is longer", 5, nil, nil, "features/step_definitions/bar.rb:56")
74
+
75
+ assert_io(%{Feature: Hello
76
+ World
77
+
78
+ Scenario: The scenario # features/foo.feature:4
79
+ Given some stuff that is longer # features/step_definitions/bar.rb:56
80
+ })
81
+ end
82
+
83
+ it "should prettify a whole table with padding (typically ANSI)" do
84
+ @l.row(%w(a bb), 1)
85
+ @l.row(%w(ccc d), 2)
86
+ @l.row(%w(ee ffff), 3)
87
+ @l.flush_table
88
+
89
+ assert_io(
90
+ " | a | bb |\n" +
91
+ " | ccc | d |\n" +
92
+ " | ee | ffff |\n"
93
+ )
94
+ end
95
+
96
+ it "should highlight arguments for regular steps" do
97
+ passed = defined?(JRUBY_VERSION) ? 'passed' : :passed
98
+ @l.step("Given ", "I have 999 cukes in my belly", 3, passed, [Gherkin::Format::Argument.new(7, '999')], nil)
99
+ assert_io(" Given I have 999 cukes in my belly\n")
100
+ end
101
+
102
+ it "should prettify scenario" do
103
+ assert_pretty(%{Feature: Feature Description
104
+ Some preamble
105
+
106
+ Scenario: Scenario Description
107
+ Given there is a step
108
+ """
109
+ with
110
+ pystrings
111
+ """
112
+ And there is another step
113
+ | æ | o |
114
+ | a | ø |
115
+ Then we will see steps
116
+ })
117
+ end
118
+
119
+
120
+ it "should prettify scenario outline with table" do
121
+ assert_pretty(%{# A feature comment
122
+ @foo
123
+ Feature: Feature Description
124
+ Some preamble
125
+
126
+ # A Scenario Outline comment
127
+ @bar
128
+ Scenario Outline: Scenario Ouline Description
129
+ Given there is a
130
+ """
131
+ string with <foo>
132
+ """
133
+ And a table with
134
+ | <bar> |
135
+ | <baz> |
136
+
137
+ @zap @boing
138
+ Examples: Examples Description
139
+ | foo | bar | baz |
140
+ | Banana | I | am hungry |
141
+ | Beer | You | are thirsty |
142
+ | Bed | They | are tired |
143
+ })
144
+ end
145
+ end
146
+ end
147
+ end
@@ -2,6 +2,7 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
3
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'spec/gherkin'))
4
4
  require 'gherkin'
5
+ require 'stringio'
5
6
  require 'gherkin/sexp_recorder'
6
7
  require 'rubygems'
7
8
  require 'spec'
@@ -9,7 +10,30 @@ require 'spec/autorun'
9
10
  require 'shared/lexer_spec'
10
11
  require 'shared/tags_spec'
11
12
  require 'shared/py_string_spec'
12
- require 'shared/table_spec'
13
+ require 'shared/row_spec'
14
+
15
+ if defined?(JRUBY_VERSION)
16
+ class OutputStreamStringIO < 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
13
37
 
14
38
  module GherkinSpecHelper
15
39
  def scan_file(file)
@@ -21,13 +45,13 @@ Spec::Runner.configure do |c|
21
45
  c.include(GherkinSpecHelper)
22
46
  end
23
47
 
24
- # Allows comparison of Java List with Ruby Array (tables)
25
- Spec::Matchers.define :t do |expected|
26
- match do |table|
27
- def table.inspect
28
- "t " + self.map{|row| row.map{|cell| cell}}.inspect
48
+ # Allows comparison of Java List with Ruby Array (rows)
49
+ Spec::Matchers.define :r do |expected|
50
+ match do |row|
51
+ def row.inspect
52
+ "r " + self.map{|cell| cell}.inspect
29
53
  end
30
- table.map{|row| row.map{|cell| cell}}.should == expected
54
+ row.map{|cell| cell}.should == expected
31
55
  end
32
56
  end
33
57
 
@@ -8,7 +8,10 @@ CLEAN.include [
8
8
  'ragel/i18n/*.rl',
9
9
  'lib/gherkin/rb_lexer/*.rb',
10
10
  'ext/**/*.c',
11
- 'java/src/gherkin/lexer/*.java'
11
+ 'java/src/gherkin/lexer/*.java',
12
+ 'dotnet/Gherkin/Lexer',
13
+ 'dotnet/Gherkin/obj',
14
+ 'dotnet/Gherkin/bin'
12
15
  ]
13
16
 
14
17
  desc "Compile the Java extensions"
@@ -16,12 +19,83 @@ task :jar do
16
19
  sh("ant -f java/build.xml")
17
20
  end
18
21
 
19
- Gherkin::I18n.all.each do |i18n|
20
- java = RagelTask.new('java', i18n)
21
- rb = RagelTask.new('rb', i18n)
22
+ namespace :dotnet do
23
+ require 'albacore'
22
24
 
23
- task :jar => java.target
24
- task :jar => rb.target
25
+ FileList['lib/gherkin/parser/*'].each do |src|
26
+ dst = "dotnet/Gherkin/StateMachine/#{File.basename(src)}"
27
+ file dst => src do
28
+ cp src, dst, :verbose => true
29
+ end
30
+ task :compile => dst
31
+ end
32
+
33
+ task :compile => :lexer
34
+
35
+ if (`which mono` rescue "") =~ /mono/
36
+ xbuild :compile do |msb|
37
+ msb.properties :configuration => :Release
38
+ msb.targets :Build
39
+ msb.solution = 'dotnet/Gherkin.sln'
40
+ end
41
+
42
+ require 'rake/xunittask'
43
+ class XUnitTestRunner
44
+ def execute
45
+ system("mono dotnet/lib/xunit/xunit.console.exe dotnet/Gherkin.Tests/bin/Release/Gherkin.Tests.dll")
46
+ exit 1 if $? != 0
47
+ end
48
+ end
49
+ else
50
+ msbuild :compile do |msb|
51
+ msb.properties :configuration => :Release
52
+ msb.targets :Build
53
+ msb.solution = 'dotnet/Gherkin.sln'
54
+ end
55
+ end
56
+
57
+ xunit :test => :compile do |xunit|
58
+ xunit.path_to_command = "dotnet/lib/xunit/xunit.console.exe"
59
+ xunit.assembly = "dotnet/Gherkin.Tests/bin/Release/Gherkin.Tests.dll"
60
+ end
61
+
62
+ task :package => :test do
63
+ cp 'dotnet/Gherkin/bin/Release/Gherkin.dll', 'lib/Gherkin.dll'
64
+ end
65
+ end
66
+
67
+ desc "Compile and package the .NET extensions"
68
+ task :dotnet => ['dotnet:package']
69
+
70
+ class CSharpSByteFixTask
71
+ def initialize(source)
72
+ @source = source
73
+ define_tasks
74
+ end
75
+
76
+ def define_tasks
77
+ directory File.dirname(target)
78
+ file target => [File.dirname(target), @source] do
79
+ sh "cat #{@source} | sed ""s/sbyte/short/g"" > #{target}"
80
+ end
81
+ end
82
+
83
+ def target
84
+ "dotnet/Gherkin/Lexer/#{File.basename(@source)}"
85
+ end
86
+ end
87
+
88
+ rl_langs = ENV['RL_LANGS'] ? ENV['RL_LANGS'].split(',') : []
89
+ langs = Gherkin::I18n.all.select { |lang| rl_langs.empty? || rl_langs.include?(lang.key) }
90
+
91
+ langs.each do |i18n|
92
+ java = RagelTask.new('java', i18n)
93
+ rb = RagelTask.new('rb', i18n)
94
+ csharp_tmp = RagelTask.new('csharp', i18n)
95
+ csharp = CSharpSByteFixTask.new(csharp_tmp.target)
96
+
97
+ task :jar => [java.target, rb.target]
98
+ task 'dotnet:lexer' => csharp.target
25
99
 
26
100
  begin
27
101
  unless defined?(JRUBY_VERSION)
@@ -67,4 +141,4 @@ EOF
67
141
  task :compile # no-op
68
142
  end
69
143
  end
70
- end
144
+ end