gherkin-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in gherkin.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+ require 'bundler'
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ require 'rake/testtask'
6
+ Rake::TestTask.new do |t|
7
+ t.libs << "test"
8
+ t.test_files = FileList['./test/**/*_test.rb']
9
+ end
10
+
11
+ task :default => [:test]
data/Readme.md ADDED
@@ -0,0 +1,57 @@
1
+ # gherkin-ruby
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
+
4
+ ## Usage
5
+ 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
+
7
+ ```ruby
8
+ class MyVisitor
9
+ def visit(ast)
10
+ ast.accept(self)
11
+ end
12
+
13
+ def visit_Feature(feature)
14
+ # Do something nasty with the feature
15
+ # Set whatever state you want:
16
+ # @current_feature = feature
17
+ # etc etc
18
+ # And keep visiting its children:
19
+
20
+ feature.each { |scenario| scenario.accept(self) }
21
+ end
22
+
23
+ def visit_Scenario(scenario)
24
+ # Do something nasty with the scenario
25
+ # Set whatever state you want:
26
+ # @current_scenario = scenario
27
+ # etc etc
28
+ # And keep visiting its children:
29
+
30
+ scenario.each { |step| step.accept(self) }
31
+ end
32
+
33
+ def visit_Background(background)
34
+ # Do something nasty with the background
35
+ # And keep visiting its children:
36
+
37
+ background.each { |step| step.accept(self) }
38
+ end
39
+
40
+ def visit_Tag(tag)
41
+ # Do something nasty with the tag
42
+ end
43
+
44
+ def visit_Step(step)
45
+ # Finally, print the step name.
46
+ puts "STEP: #{step.name}"
47
+ end
48
+ end
49
+
50
+ ast = Gherkin.parse(File.read('some.feature'))
51
+ visitor = MyVisitor.new
52
+ visitor.visit(ast)
53
+ ```
54
+
55
+ ## Todo
56
+
57
+ * Some optimization
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "gherkin/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "gherkin-ruby"
7
+ s.version = Gherkin::VERSION
8
+ s.authors = ["Marc Divins", "Josep M. Bach"]
9
+ s.email = ["marcdivc@gmail.com", "josep.m.bach@gmail.com"]
10
+ s.homepage = "http://github.com/codegram/gherkin"
11
+ s.summary = %q{Gherkin-ruby is a Gherkin parser in pure Ruby using Parslet}
12
+ s.description = %q{Gherkin-ruby is a Gherkin parser in pure Ruby using Parslet}
13
+
14
+ s.rubyforge_project = "gherkin-ruby"
15
+
16
+ s.add_runtime_dependency 'parslet'
17
+ s.add_development_dependency 'minitest'
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+ end
@@ -0,0 +1,83 @@
1
+ module Gherkin
2
+ module AST
3
+ class Node
4
+ attr_reader :line, :column
5
+
6
+ def accept(visitor)
7
+ name = self.class.name.split('::').last
8
+ visitor.send("visit_#{name}".to_sym, self)
9
+ end
10
+ end
11
+
12
+ class Feature < Node
13
+ attr_reader :name, :background, :scenarios
14
+
15
+ include Enumerable
16
+
17
+ def initialize(name, scenarios=[], background=nil)
18
+ @line, @column = name.line_and_column
19
+
20
+ @name = name.to_s
21
+ @background = background
22
+ @scenarios = scenarios
23
+ end
24
+
25
+ def each
26
+ @scenarios.each
27
+ end
28
+ end
29
+
30
+ class Background < Node
31
+ attr_reader :steps
32
+
33
+ include Enumerable
34
+
35
+ def initialize(steps=[])
36
+ @line = steps.first.line - 1
37
+ @column = 3
38
+
39
+ @steps = steps
40
+ end
41
+
42
+ def each
43
+ @steps.each
44
+ end
45
+ end
46
+
47
+ class Scenario < Node
48
+ attr_reader :name, :steps, :tags
49
+
50
+ include Enumerable
51
+
52
+ def initialize(name, steps=[], tags=[])
53
+ @line, @column = name.line_and_column
54
+
55
+ @name = name.to_s
56
+ @steps = steps
57
+ @tags = tags
58
+ end
59
+
60
+ def each
61
+ @steps.each
62
+ end
63
+ end
64
+
65
+ class Step < Node
66
+ attr_reader :name
67
+ def initialize(name)
68
+ @line, @column = name.line_and_column
69
+
70
+ @name = name.to_s
71
+ end
72
+ end
73
+
74
+ class Tag < Node
75
+ attr_reader :name
76
+ def initialize(name)
77
+ @line, @column = name.line_and_column
78
+
79
+ @name = name.to_s
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,40 @@
1
+ require 'parslet'
2
+
3
+ module Gherkin
4
+ class Parser < Parslet::Parser
5
+ def indent(num=2)
6
+ str(' ' * num)
7
+ end
8
+
9
+ rule(:space) { match('\s').repeat }
10
+ rule(:space?) { space.maybe }
11
+ rule(:newline) { match('\n').repeat }
12
+ rule(:text) { match('[^\n]').repeat }
13
+ rule(:identifier) { match('\w').repeat }
14
+
15
+ rule(:feature_line) { str('Feature:') >> space? >> text.as(:name) }
16
+ rule(:scenario_line) { indent(2) >> str('Scenario:') >> space? >> text.as(:name) }
17
+ rule(:background_line) { indent(2) >> str('Background:') }
18
+
19
+ rule(:step_keyword) { str('Given') | str('When') | str('Then') | str('And') | str('But') }
20
+
21
+ rule(:comment) { str('#') >> text.as(:comment) }
22
+ rule(:description) { indent(2) >> text.as(:description) }
23
+
24
+ rule(:step) { indent(4) >> step_keyword >> space? >> text.as(:name) }
25
+ rule(:steps) { (step.as(:step) >> newline.maybe).repeat }
26
+
27
+ rule(:tags) { indent(2) >> (str('@') >> identifier.as(:tag) >> str(' ').maybe).repeat(1) }
28
+
29
+ rule(:scenario) { (tags.as(:tags) >> newline).maybe >> scenario_line >> newline >> steps.as(:steps) }
30
+ rule(:scenarios) { (scenario.as(:scenario) >> newline.maybe).repeat }
31
+
32
+ rule(:background) { background_line >> newline >> steps.as(:steps) }
33
+
34
+ rule(:feature) { feature_line >> newline >> background.as(:background).maybe >> scenarios.as(:scenarios) }
35
+
36
+ rule(:main) { feature.as(:feature) }
37
+
38
+ root :main
39
+ end
40
+ end
@@ -0,0 +1,49 @@
1
+ module Gherkin
2
+ class Transform < Parslet::Transform
3
+ # Match feature with background
4
+ rule(
5
+ feature: {
6
+ name: simple(:name),
7
+ background: {
8
+ steps: subtree(:background_steps)
9
+ },
10
+ scenarios: subtree(:scenarios)
11
+ }
12
+ ) { AST::Feature.new(name, scenarios, AST::Background.new(background_steps)) }
13
+
14
+ # Match feature without background
15
+ rule(
16
+ feature: {
17
+ name: simple(:name),
18
+ scenarios: subtree(:scenarios)
19
+ }
20
+ ) { AST::Feature.new(name, scenarios, AST::Background.new([])) }
21
+
22
+ # Match scenarios without tags
23
+ rule(
24
+ scenario: {
25
+ name: simple(:name),
26
+ steps: subtree(:steps)
27
+ }
28
+ ) { AST::Scenario.new(name, steps, []) }
29
+
30
+ # Match scenarios with tags
31
+ rule(
32
+ scenario: {
33
+ name: simple(:name),
34
+ steps: subtree(:steps),
35
+ tags: subtree(:tags)
36
+ }
37
+ ) { AST::Scenario.new(name, steps, tags) }
38
+
39
+ rule(
40
+ step: {
41
+ name: simple(:name),
42
+ }
43
+ ) { AST::Step.new(name) }
44
+
45
+ rule(
46
+ tag: simple(:name)
47
+ ) { AST::Tag.new(name) }
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ module Gherkin
2
+ VERSION = "0.0.1"
3
+ end
data/lib/gherkin.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'parslet'
2
+ require_relative "gherkin/version"
3
+ require_relative 'gherkin/ast'
4
+ require_relative 'gherkin/parser'
5
+ require_relative 'gherkin/transform'
6
+
7
+ module Gherkin
8
+ def self.parse(input)
9
+ parser = Parser.new
10
+ transform = Transform.new
11
+
12
+ parsed = parser.parse input
13
+ transform.apply(parsed)
14
+ end
15
+ end
@@ -0,0 +1,102 @@
1
+ require_relative '../test_helper'
2
+ require 'ostruct'
3
+
4
+ class MyVisitor
5
+ def visit_MyNode(my_node)
6
+ my_node.elements
7
+ end
8
+ end
9
+
10
+ class MyNode < Gherkin::AST::Node
11
+ attr_reader :elements
12
+ def initialize(name, elements)
13
+ @name = name
14
+ @elements = elements
15
+ end
16
+ end
17
+
18
+ module Gherkin
19
+ module AST
20
+ describe Node do
21
+ it 'is visitable' do
22
+ my_node = MyNode.new('My Node', ['foo', 'bar', 'baz'])
23
+ visitor = MyVisitor.new
24
+
25
+ my_node.accept(visitor).must_equal ['foo', 'bar', 'baz']
26
+ end
27
+ end
28
+
29
+ [Feature, Scenario, Step, Tag].each do |node|
30
+ describe node do
31
+ it 'is a Node' do
32
+ node.ancestors.must_include Node
33
+ end
34
+
35
+ it 'has a line and column' do
36
+ name = OpenStruct.new(line_and_column: [2, 13])
37
+ def name.to_s; 'Name'; end
38
+
39
+ instance = node.new(name)
40
+ instance.name.must_equal 'Name'
41
+ instance.line.must_equal 2
42
+ instance.column.must_equal 13
43
+ end
44
+ end
45
+ end
46
+
47
+ describe Feature do
48
+ it 'is Enumerable' do
49
+ name = OpenStruct.new(line_and_column: [2, 13])
50
+ def name.to_s; 'Name'; end
51
+
52
+ background = ['foo', 'bar']
53
+ elements = ['+foo', '+bar']
54
+
55
+ instance = Feature.new(name, elements, background )
56
+ instance.background.each.to_a.must_equal ['foo', 'bar']
57
+ instance.each.to_a.must_equal ['+foo', '+bar']
58
+ end
59
+ end
60
+
61
+ describe Scenario do
62
+ it 'is Enumerable' do
63
+ name = OpenStruct.new(line_and_column: [2, 13])
64
+ def name.to_s; 'Name'; end
65
+
66
+ elements = ['foo', 'bar']
67
+
68
+ instance = Scenario.new(name, elements)
69
+ instance.each.to_a.must_equal ['foo', 'bar']
70
+ end
71
+
72
+ it 'has tags' do
73
+ name = OpenStruct.new(line_and_column: [2, 13])
74
+ def name.to_s; 'Name'; end
75
+
76
+ steps = ['foo', 'bar']
77
+ tags = ['javascript', 'wip']
78
+
79
+ instance = Scenario.new(name, steps, tags)
80
+ instance.tags.must_equal tags
81
+ end
82
+ end
83
+
84
+ describe Background do
85
+ it 'is a Node' do
86
+ Background.ancestors.must_include Node
87
+ end
88
+
89
+ it 'is Enumerable' do
90
+ steps = [
91
+ OpenStruct.new(line: 4),
92
+ OpenStruct.new(line: 5),
93
+ ]
94
+
95
+ instance = Background.new(steps)
96
+ instance.line.must_equal 3
97
+ instance.column.must_equal 3
98
+ instance.each.to_a.must_equal steps
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,156 @@
1
+ require_relative '../test_helper'
2
+ require 'parslet'
3
+
4
+ def p(rule, input, tag=nil)
5
+ tag ||= rule
6
+ parser = Gherkin::Parser.new
7
+ parser.send(rule).parse(input)[tag]
8
+ end
9
+
10
+ module Gherkin
11
+ describe 'Feature parsing' do
12
+ it 'parses the Feature name' do
13
+ p(:feature_line, "Feature: Test how Gherkin works", :name).must_equal "Test how Gherkin works"
14
+ end
15
+
16
+ it 'parses the Scenario name' do
17
+ p(:scenario_line, " Scenario: Formal greeting", :name).must_equal "Formal greeting"
18
+ end
19
+
20
+ describe 'Steps' do
21
+ it 'parses a Given step' do
22
+ p(:step, " Given I have an empty array", :name).must_equal "I have an empty array"
23
+ end
24
+
25
+ it 'parses a When step' do
26
+ p(:step, " When I have an empty array", :name).must_equal "I have an empty array"
27
+ end
28
+
29
+ it 'parses a Then step' do
30
+ p(:step, " Then I have an empty array", :name).must_equal "I have an empty array"
31
+ end
32
+
33
+ it 'parses an And step' do
34
+ p(:step, " And I have an empty array", :name).must_equal "I have an empty array"
35
+ end
36
+
37
+ it 'parses a But step' do
38
+ p(:step, " But I have an empty array", :name).must_equal "I have an empty array"
39
+ end
40
+ end
41
+ end
42
+
43
+ describe 'Comment parsing' do
44
+ it 'parses a comment ignoring its content' do
45
+ p(:comment, "# My comment").size.must_be :>, 0
46
+ end
47
+ end
48
+
49
+ 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
54
+ end
55
+ end
56
+
57
+ describe 'Tags parsing' do
58
+ it 'parses many tags' do
59
+ javascript = p(:tags, " @javascript @wip", 0)
60
+ wip = p(:tags, " @javascript @wip", 1)
61
+ javascript[:tag].must_equal 'javascript'
62
+ wip[:tag].must_equal 'wip'
63
+ end
64
+
65
+ it 'parses one tag' do
66
+ p(:tags, " @javascript", 0)[:tag].must_equal 'javascript'
67
+ end
68
+ end
69
+
70
+ describe 'Background parsing' do
71
+ it 'parses a background' do
72
+ background = " Background:\n When I do something\n Then blah"
73
+ steps = p(:background, background, :steps)
74
+ steps.first[:step][:name].must_equal 'I do something'
75
+ steps.last[:step][:name].must_equal 'blah'
76
+ end
77
+ end
78
+
79
+ describe 'Parses scenario objects' do
80
+ it 'parses a Scenario' do
81
+ parser = Gherkin::Parser.new
82
+ scenario = " Scenario: Parse a scenario\n Given something happens\n Then something cooler happens"
83
+ result = parser.scenario.parse(scenario)
84
+
85
+ result[:name].must_equal 'Parse a scenario'
86
+ result[:steps][0][:step][:name].must_equal 'something happens'
87
+ result[:steps][1][:step][:name].must_equal 'something cooler happens'
88
+ end
89
+
90
+ it 'parses a Scenario with a tag' do
91
+ parser = Gherkin::Parser.new
92
+ scenario = " @javascript\n Scenario: Parse a scenario\n Given something happens\n Then something cooler happens"
93
+ result = parser.scenario.parse(scenario)
94
+
95
+ result[:tags].first[:tag].must_equal 'javascript'
96
+ result[:name].must_equal 'Parse a scenario'
97
+ result[:steps][0][:step][:name].must_equal 'something happens'
98
+ result[:steps][1][:step][:name].must_equal 'something cooler happens'
99
+ end
100
+ end
101
+
102
+ describe 'Parses feature objects without background' do
103
+ it 'parses a Feature' do
104
+ parser = Gherkin::Parser.new
105
+ scenario = """Feature: My Feature
106
+ @javascript @wip
107
+ Scenario: something happens
108
+ Given something happens
109
+ Then something cooler happens
110
+
111
+ Scenario: something else happens
112
+ Given foo
113
+ Then bar
114
+ """
115
+ result = parser.parse(scenario)
116
+
117
+ result[:feature][:name].must_equal 'My Feature'
118
+
119
+ result[:feature][:scenarios][0][:scenario][:tags].first[:tag].must_equal 'javascript'
120
+ result[:feature][:scenarios][0][:scenario][:tags].last[:tag].must_equal 'wip'
121
+ result[:feature][:scenarios][0][:scenario][:name].must_equal 'something happens'
122
+ result[:feature][:scenarios][0][:scenario][:steps][0][:step][:name].must_equal 'something happens'
123
+ result[:feature][:scenarios][0][:scenario][:steps][1][:step][:name].must_equal 'something cooler happens'
124
+
125
+ result[:feature][:scenarios][1][:scenario][:name].must_equal 'something else happens'
126
+ result[:feature][:scenarios][1][:scenario][:steps][0][:step][:name].must_equal 'foo'
127
+ result[:feature][:scenarios][1][:scenario][:steps][1][:step][:name].must_equal 'bar'
128
+ end
129
+ end
130
+
131
+ describe 'Parses feature objects with background' do
132
+ it 'parses a Feature' do
133
+ parser = Gherkin::Parser.new
134
+ scenario = """Feature: My Feature
135
+
136
+ Background:
137
+ Given something happens
138
+ And something cooler happens
139
+
140
+ Scenario: something else happens
141
+ Given foo
142
+ Then bar
143
+ """
144
+ result = parser.parse(scenario)
145
+
146
+ result[:feature][:name].must_equal 'My Feature'
147
+
148
+ result[:feature][:background][:steps][0][:step][:name].must_equal 'something happens'
149
+ result[:feature][:background][:steps][1][:step][:name].must_equal 'something cooler happens'
150
+
151
+ result[:feature][:scenarios][0][:scenario][:name].must_equal 'something else happens'
152
+ result[:feature][:scenarios][0][:scenario][:steps][0][:step][:name].must_equal 'foo'
153
+ result[:feature][:scenarios][0][:scenario][:steps][1][:step][:name].must_equal 'bar'
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,65 @@
1
+ require_relative '../test_helper'
2
+ require 'parslet'
3
+
4
+ module Gherkin
5
+ describe 'Feature parsing' do
6
+ before do
7
+ @scenario = """Feature: My Feature
8
+
9
+ Background:
10
+ Given something happens before anything else happens
11
+ And more things happens before anything else happens
12
+
13
+ Scenario: something happens
14
+ Given something happens
15
+ Then something cooler happens
16
+
17
+ @javascript @wip
18
+ Scenario: something else happens
19
+ Given foo
20
+ Then bar
21
+ """
22
+
23
+ parser = Gherkin::Parser.new
24
+ result = parser.parse(@scenario)
25
+ transform = Gherkin::Transform.new
26
+ @result = transform.apply(result)
27
+ end
28
+
29
+ it 'generates a nice tree' do
30
+ @result.must_be_kind_of AST::Feature
31
+ @result.line.must_equal 1
32
+
33
+ background = @result.background
34
+ background.must_be_kind_of AST::Background
35
+ background.line.must_equal 3
36
+ background.column.must_equal 3
37
+ background.steps.first.name.must_equal 'something happens before anything else happens'
38
+ background.steps.first.line.must_equal 4
39
+ background.steps.last.name.must_equal 'more things happens before anything else happens'
40
+ background.steps.last.line.must_equal 5
41
+
42
+ first_scenario = @result.scenarios.first
43
+ first_scenario.must_be_kind_of AST::Scenario
44
+ first_scenario.line.must_equal 7
45
+ first_scenario.name.must_equal 'something happens'
46
+ first_scenario.steps.first.name.must_equal 'something happens'
47
+ first_scenario.steps.first.line.must_equal 8
48
+ first_scenario.steps.last.name.must_equal 'something cooler happens'
49
+ first_scenario.steps.last.line.must_equal 9
50
+
51
+ last_scenario = @result.scenarios.last
52
+ last_scenario.must_be_kind_of AST::Scenario
53
+ last_scenario.line.must_equal 12
54
+ last_scenario.name.must_equal 'something else happens'
55
+
56
+ last_scenario.tags.first.name.must_equal 'javascript'
57
+ last_scenario.tags.last.name.must_equal 'wip'
58
+
59
+ last_scenario.steps.first.name.must_equal 'foo'
60
+ last_scenario.steps.first.line.must_equal 13
61
+ last_scenario.steps.last.name.must_equal 'bar'
62
+ last_scenario.steps.last.line.must_equal 14
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,4 @@
1
+ gem 'minitest'
2
+ require 'minitest/spec'
3
+ require 'minitest/autorun'
4
+ require_relative '../lib/gherkin'
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gherkin-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Marc Divins
9
+ - Josep M. Bach
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2011-11-09 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: parslet
17
+ requirement: &2160498080 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2160498080
26
+ - !ruby/object:Gem::Dependency
27
+ name: minitest
28
+ requirement: &2160497620 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *2160497620
37
+ description: Gherkin-ruby is a Gherkin parser in pure Ruby using Parslet
38
+ email:
39
+ - marcdivc@gmail.com
40
+ - josep.m.bach@gmail.com
41
+ executables: []
42
+ extensions: []
43
+ extra_rdoc_files: []
44
+ files:
45
+ - .gitignore
46
+ - Gemfile
47
+ - Rakefile
48
+ - Readme.md
49
+ - gherkin-ruby.gemspec
50
+ - lib/gherkin.rb
51
+ - lib/gherkin/ast.rb
52
+ - lib/gherkin/parser.rb
53
+ - lib/gherkin/transform.rb
54
+ - lib/gherkin/version.rb
55
+ - test/gherkin/ast_test.rb
56
+ - test/gherkin/parser_test.rb
57
+ - test/gherkin/transform_test.rb
58
+ - test/test_helper.rb
59
+ homepage: http://github.com/codegram/gherkin
60
+ licenses: []
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project: gherkin-ruby
79
+ rubygems_version: 1.8.10
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: Gherkin-ruby is a Gherkin parser in pure Ruby using Parslet
83
+ test_files:
84
+ - test/gherkin/ast_test.rb
85
+ - test/gherkin/parser_test.rb
86
+ - test/gherkin/transform_test.rb
87
+ - test/test_helper.rb