gherkin-ruby 0.0.1 → 0.0.2

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.
@@ -0,0 +1,8 @@
1
+ env:
2
+ - RBXOPT=-X19 JRUBY_OPTS="--1.9"
3
+ rvm:
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - ruby-head
7
+ - rbx-head
8
+ - jruby
data/Gemfile CHANGED
@@ -2,3 +2,4 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in gherkin.gemspec
4
4
  gemspec
5
+ gem 'rake'
data/Readme.md CHANGED
@@ -1,6 +1,25 @@
1
1
  # gherkin-ruby
2
2
  Gherkin-ruby is a pure Ruby implementation of a [Gherkin](http://github.com/cucumber/gherkin) parser, using [Parslet](http://github.com/kschiess/parslet).
3
3
 
4
+ ## Why this one over the official, fast, Ragel-based Gherkin parser?
5
+
6
+ * Less than 200 LOC.
7
+ * No C-exts
8
+ * No Java/.NET crap.
9
+ * Fast enough for our purposes (using it for the [Spinach](http://github.com/codegram/spinach) project)
10
+
11
+ ## Install
12
+
13
+ $ gem install gherkin-ruby
14
+
15
+ Or in your Gemfile:
16
+
17
+ ```ruby
18
+ # Gemfile
19
+
20
+ gem 'gherkin-ruby'
21
+ ```
22
+
4
23
  ## Usage
5
24
  You can easily implement your own visitors to traverse the Abstract Syntax Tree. The following example just prints the step names to standard output:
6
25
 
@@ -33,8 +33,10 @@ module Gherkin
33
33
  include Enumerable
34
34
 
35
35
  def initialize(steps=[])
36
- @line = steps.first.line - 1
37
- @column = 3
36
+ if steps.any?
37
+ @line = steps.first.line - 1
38
+ @column = 3
39
+ end
38
40
 
39
41
  @steps = steps
40
42
  end
@@ -63,11 +65,12 @@ module Gherkin
63
65
  end
64
66
 
65
67
  class Step < Node
66
- attr_reader :name
67
- def initialize(name)
68
+ attr_reader :name, :keyword
69
+ def initialize(name, keyword)
68
70
  @line, @column = name.line_and_column
69
71
 
70
- @name = name.to_s
72
+ @name = name.to_s
73
+ @keyword = keyword.to_s
71
74
  end
72
75
  end
73
76
 
@@ -14,14 +14,17 @@ module Gherkin
14
14
 
15
15
  rule(:feature_line) { str('Feature:') >> space? >> text.as(:name) }
16
16
  rule(:scenario_line) { indent(2) >> str('Scenario:') >> space? >> text.as(:name) }
17
- rule(:background_line) { indent(2) >> str('Background:') }
18
17
 
19
18
  rule(:step_keyword) { str('Given') | str('When') | str('Then') | str('And') | str('But') }
20
19
 
21
20
  rule(:comment) { str('#') >> text.as(:comment) }
22
- rule(:description) { indent(2) >> text.as(:description) }
23
21
 
24
- rule(:step) { indent(4) >> step_keyword >> space? >> text.as(:name) }
22
+ rule(:description_text) { (str('Background:') | str('Scenario:') | str('@')).absent? >> text }
23
+ rule(:description) { (indent(2) >> description_text >> newline).repeat }
24
+
25
+ rule(:background_line) { indent(2) >> str('Background:') }
26
+
27
+ rule(:step) { indent(4) >> step_keyword.as(:keyword) >> space? >> text.as(:name) }
25
28
  rule(:steps) { (step.as(:step) >> newline.maybe).repeat }
26
29
 
27
30
  rule(:tags) { indent(2) >> (str('@') >> identifier.as(:tag) >> str(' ').maybe).repeat(1) }
@@ -31,7 +34,7 @@ module Gherkin
31
34
 
32
35
  rule(:background) { background_line >> newline >> steps.as(:steps) }
33
36
 
34
- rule(:feature) { feature_line >> newline >> background.as(:background).maybe >> scenarios.as(:scenarios) }
37
+ rule(:feature) { feature_line >> newline >> description >> background.as(:background).maybe >> scenarios.as(:scenarios) }
35
38
 
36
39
  rule(:main) { feature.as(:feature) }
37
40
 
@@ -39,8 +39,9 @@ module Gherkin
39
39
  rule(
40
40
  step: {
41
41
  name: simple(:name),
42
+ keyword: simple(:keyword),
42
43
  }
43
- ) { AST::Step.new(name) }
44
+ ) { AST::Step.new(name, keyword) }
44
45
 
45
46
  rule(
46
47
  tag: simple(:name)
@@ -1,3 +1,3 @@
1
1
  module Gherkin
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -26,7 +26,7 @@ module Gherkin
26
26
  end
27
27
  end
28
28
 
29
- [Feature, Scenario, Step, Tag].each do |node|
29
+ [Feature, Scenario, Tag].each do |node|
30
30
  describe node do
31
31
  it 'is a Node' do
32
32
  node.ancestors.must_include Node
@@ -82,21 +82,54 @@ module Gherkin
82
82
  end
83
83
 
84
84
  describe Background do
85
- it 'is a Node' do
86
- Background.ancestors.must_include Node
87
- end
88
-
89
- it 'is Enumerable' do
85
+ let(:steps) do
90
86
  steps = [
91
87
  OpenStruct.new(line: 4),
92
88
  OpenStruct.new(line: 5),
93
89
  ]
90
+ end
94
91
 
92
+ it 'is a Node' do
93
+ Background.ancestors.must_include Node
94
+ end
95
+
96
+ it 'is Enumerable' do
95
97
  instance = Background.new(steps)
96
- instance.line.must_equal 3
97
- instance.column.must_equal 3
98
98
  instance.each.to_a.must_equal steps
99
99
  end
100
+
101
+ describe 'when there are background steps' do
102
+ it 'records line and column' do
103
+ instance = Background.new(steps)
104
+ instance.line.must_equal 3
105
+ instance.column.must_equal 3
106
+ end
107
+ end
108
+
109
+ describe 'otherwise' do
110
+ it 'does not' do
111
+ instance = Background.new([])
112
+ instance.line.must_equal nil
113
+ instance.column.must_equal nil
114
+ end
115
+ end
116
+ end
117
+
118
+ describe Step do
119
+ it 'is a Node' do
120
+ Step.ancestors.must_include Node
121
+ end
122
+
123
+ it 'has a line and column' do
124
+ name = OpenStruct.new(line_and_column: [2, 13])
125
+ def name.to_s; 'Name'; end
126
+
127
+ instance = Step.new(name, 'Given')
128
+ instance.name.must_equal 'Name'
129
+ instance.keyword.must_equal 'Given'
130
+ instance.line.must_equal 2
131
+ instance.column.must_equal 13
132
+ end
100
133
  end
101
134
  end
102
135
  end
@@ -19,23 +19,33 @@ module Gherkin
19
19
 
20
20
  describe 'Steps' do
21
21
  it 'parses a Given step' do
22
- p(:step, " Given I have an empty array", :name).must_equal "I have an empty array"
22
+ step = " Given I have an empty array"
23
+ p(:step, step, :name).must_equal "I have an empty array"
24
+ p(:step, step, :keyword).must_equal "Given"
23
25
  end
24
26
 
25
27
  it 'parses a When step' do
26
- p(:step, " When I have an empty array", :name).must_equal "I have an empty array"
28
+ step = " When I have an empty array"
29
+ p(:step, step, :name).must_equal "I have an empty array"
30
+ p(:step, step, :keyword).must_equal "When"
27
31
  end
28
32
 
29
33
  it 'parses a Then step' do
30
- p(:step, " Then I have an empty array", :name).must_equal "I have an empty array"
34
+ step = " Then I have an empty array"
35
+ p(:step, step, :name).must_equal "I have an empty array"
36
+ p(:step, step, :keyword).must_equal "Then"
31
37
  end
32
38
 
33
39
  it 'parses an And step' do
34
- p(:step, " And I have an empty array", :name).must_equal "I have an empty array"
40
+ step = " And I have an empty array"
41
+ p(:step, step, :name).must_equal "I have an empty array"
42
+ p(:step, step, :keyword).must_equal "And"
35
43
  end
36
44
 
37
45
  it 'parses a But step' do
38
- p(:step, " But I have an empty array", :name).must_equal "I have an empty array"
46
+ step = " But I have an empty array"
47
+ p(:step, step, :name).must_equal "I have an empty array"
48
+ p(:step, step, :keyword).must_equal "But"
39
49
  end
40
50
  end
41
51
  end
@@ -47,10 +57,13 @@ module Gherkin
47
57
  end
48
58
 
49
59
  describe 'Description parsing' do
50
- it 'parses descriptions ignoring their content' do
51
- p(:description, " In order to know what the heck is Gherkin").size.must_be :>, 0
52
- p(:description, " As a developer").size.must_be :>, 0
53
- p(:description, " I want it to behave in an expected way").size.must_be :>, 0
60
+ it 'parses multiline descriptions' do
61
+ description = """ In order to know what the heck is Gherkin
62
+ As a developer
63
+ I want it to behave in an expected way
64
+ """
65
+ parser = Gherkin::Parser.new
66
+ parser.description.parse(description)
54
67
  end
55
68
  end
56
69
 
@@ -5,6 +5,9 @@ module Gherkin
5
5
  describe 'Feature parsing' do
6
6
  before do
7
7
  @scenario = """Feature: My Feature
8
+ In order to do something
9
+ As a developer
10
+ I want to be happy
8
11
 
9
12
  Background:
10
13
  Given something happens before anything else happens
@@ -32,34 +35,40 @@ module Gherkin
32
35
 
33
36
  background = @result.background
34
37
  background.must_be_kind_of AST::Background
35
- background.line.must_equal 3
38
+ background.line.must_equal 6
36
39
  background.column.must_equal 3
40
+ background.steps.first.keyword.must_equal 'Given'
37
41
  background.steps.first.name.must_equal 'something happens before anything else happens'
38
- background.steps.first.line.must_equal 4
42
+ background.steps.first.line.must_equal 7
43
+ background.steps.last.keyword.must_equal 'And'
39
44
  background.steps.last.name.must_equal 'more things happens before anything else happens'
40
- background.steps.last.line.must_equal 5
45
+ background.steps.last.line.must_equal 8
41
46
 
42
47
  first_scenario = @result.scenarios.first
43
48
  first_scenario.must_be_kind_of AST::Scenario
44
- first_scenario.line.must_equal 7
49
+ first_scenario.line.must_equal 10
45
50
  first_scenario.name.must_equal 'something happens'
51
+ first_scenario.steps.first.keyword.must_equal 'Given'
46
52
  first_scenario.steps.first.name.must_equal 'something happens'
47
- first_scenario.steps.first.line.must_equal 8
53
+ first_scenario.steps.first.line.must_equal 11
54
+ first_scenario.steps.last.keyword.must_equal 'Then'
48
55
  first_scenario.steps.last.name.must_equal 'something cooler happens'
49
- first_scenario.steps.last.line.must_equal 9
56
+ first_scenario.steps.last.line.must_equal 12
50
57
 
51
58
  last_scenario = @result.scenarios.last
52
59
  last_scenario.must_be_kind_of AST::Scenario
53
- last_scenario.line.must_equal 12
60
+ last_scenario.line.must_equal 15
54
61
  last_scenario.name.must_equal 'something else happens'
55
62
 
56
63
  last_scenario.tags.first.name.must_equal 'javascript'
57
64
  last_scenario.tags.last.name.must_equal 'wip'
58
65
 
66
+ last_scenario.steps.first.keyword.must_equal 'Given'
59
67
  last_scenario.steps.first.name.must_equal 'foo'
60
- last_scenario.steps.first.line.must_equal 13
68
+ last_scenario.steps.first.line.must_equal 16
69
+ last_scenario.steps.last.keyword.must_equal 'Then'
61
70
  last_scenario.steps.last.name.must_equal 'bar'
62
- last_scenario.steps.last.line.must_equal 14
71
+ last_scenario.steps.last.line.must_equal 17
63
72
  end
64
73
  end
65
74
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gherkin-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-11-09 00:00:00.000000000 Z
13
+ date: 2011-11-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: parslet
17
- requirement: &2160498080 !ruby/object:Gem::Requirement
17
+ requirement: &2156944000 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2160498080
25
+ version_requirements: *2156944000
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: minitest
28
- requirement: &2160497620 !ruby/object:Gem::Requirement
28
+ requirement: &2156943540 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,7 +33,7 @@ dependencies:
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *2160497620
36
+ version_requirements: *2156943540
37
37
  description: Gherkin-ruby is a Gherkin parser in pure Ruby using Parslet
38
38
  email:
39
39
  - marcdivc@gmail.com
@@ -43,6 +43,7 @@ extensions: []
43
43
  extra_rdoc_files: []
44
44
  files:
45
45
  - .gitignore
46
+ - .travis.yml
46
47
  - Gemfile
47
48
  - Rakefile
48
49
  - Readme.md