turnip 0.1.0

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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ -r turnip
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in turnip.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # Turnip
2
+
3
+ Turnip is a [Gherkin](https://github.com/cucumber/cucumber/wiki/Gherkin) extension for RSpec. It allows you to write tests in Gherkin and run them through your RSpec environment. Basically you can write cucumber features in RSpec.
4
+
5
+ ## DISCLAIMER, READ THIS!!!
6
+
7
+ Turnip is a proof of concept, there are currently NO TESTS, and there is a lot of cucumber's syntax it does NOT support. There are currently no tables, multiline string or scenario outlines.
8
+
9
+ ## Installation
10
+
11
+ Install the gem
12
+
13
+ ```
14
+ gem install turnip
15
+ ```
16
+
17
+ Or add it to your Gemfile and run `bundle`.
18
+
19
+ ``` ruby
20
+ group :test do
21
+ gem "turnip"
22
+ end
23
+ ```
24
+
25
+ Now edit the `.rspec` file in your project directory (create it if doesn't exist), and add the following line:
26
+
27
+ ```
28
+ -r turnip
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ Add a feature file anywhere in your `spec` directory:
34
+
35
+ ``` cucumber
36
+ # spec/acceptance/attack_monster.feature
37
+ Feature: Attacking a monster
38
+ Background:
39
+ Given there is a monster
40
+
41
+ Scenario: attack the monster
42
+ When I attack it
43
+ Then it should die
44
+ ```
45
+
46
+ Now you can run it just like you would run any other rspec spec:
47
+
48
+ ```
49
+ rspec spec/acceptance/attack_monster.feature
50
+ ```
51
+
52
+ It will automatically be run if you run all your specs with `rake spec` or `rspec spec`.
53
+
54
+ Yes, that's really it.
55
+
56
+ ## Defining steps
57
+
58
+ You might want to define some steps. You can put them anywhere. Turnip automatically requires your `spec_helper`, so you can add them there or put them in separate files (recommended). Define them like this:
59
+
60
+ ``` ruby
61
+ step "there is a monster" do
62
+ @monster = Monster.new
63
+ end
64
+ ```
65
+
66
+ Note that unlike Cucumber, Turnip does not support regexps in step definitions.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/carrot.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "gherkin"
2
+ require "gherkin/formatter/tag_count_formatter"
3
+
4
+ require "carrot/version"
5
+ require "carrot/loader"
6
+ require "carrot/builder"
7
+ require "carrot/run"
8
+ require "carrot/steps"
9
+ require "carrot/dsl"
10
+ require "carrot/rspec"
@@ -0,0 +1,88 @@
1
+ module Turnip
2
+ class Feature
3
+ attr_reader :scenarios, :backgrounds
4
+ def initialize(raw)
5
+ @raw = raw
6
+ @scenarios = []
7
+ @backgrounds = []
8
+ end
9
+
10
+ def name
11
+ @raw.name
12
+ end
13
+ end
14
+
15
+ class Background
16
+ attr_reader :steps
17
+ def initialize(raw)
18
+ @raw = raw
19
+ @steps = []
20
+ end
21
+ end
22
+
23
+ class Scenario
24
+ attr_reader :name, :steps
25
+ def initialize(raw)
26
+ @raw = raw
27
+ @steps = []
28
+ end
29
+
30
+ def name
31
+ @raw.name
32
+ end
33
+
34
+ def tags
35
+ @raw.tags.map { |tag| tag.name.sub(/^@/, '').to_sym }
36
+ end
37
+
38
+ def tags_hash
39
+ Hash[tags.map { |t| [t, true] }]
40
+ end
41
+
42
+ def metadata_hash
43
+ tags_hash
44
+ end
45
+ end
46
+
47
+ class Step
48
+ attr_reader :name
49
+ def initialize(raw)
50
+ @raw = raw
51
+ end
52
+
53
+ def name
54
+ @raw.name
55
+ end
56
+ end
57
+
58
+ class Builder
59
+ attr_reader :features
60
+
61
+ def initialize
62
+ @features = []
63
+ end
64
+
65
+ def background(background)
66
+ @current_step_context = Turnip::Background.new(background)
67
+ @current_feature.backgrounds << @current_step_context
68
+ end
69
+
70
+ def feature(feature)
71
+ @current_feature = Turnip::Feature.new(feature)
72
+ @features << @current_feature
73
+ end
74
+
75
+ def scenario(scenario)
76
+ @current_step_context = Turnip::Scenario.new(scenario)
77
+ @current_feature.scenarios << @current_step_context
78
+ end
79
+
80
+ def step(step)
81
+ @current_step = Turnip::Step.new(step)
82
+ @current_step_context.steps << @current_step
83
+ end
84
+
85
+ def eof
86
+ end
87
+ end
88
+ end
data/lib/turnip/dsl.rb ADDED
@@ -0,0 +1,10 @@
1
+ module Turnip
2
+ module DSL
3
+ def step(description, &block)
4
+ Turnip::Steps.add_step(description, &block)
5
+ end
6
+ end
7
+ end
8
+
9
+ self.extend Turnip::DSL
10
+
@@ -0,0 +1,13 @@
1
+ module Turnip
2
+ module Loader
3
+ def load(*a, &b)
4
+ if a.first.end_with?('.feature')
5
+ require 'spec_helper'
6
+ content = File.read(a.first)
7
+ Turnip.run(content)
8
+ else
9
+ super
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ RSpec::Core::Configuration.send(:include, Turnip::Loader)
2
+
3
+ RSpec.configure do |config|
4
+ config.pattern << ",**/*.feature"
5
+ end
data/lib/turnip/run.rb ADDED
@@ -0,0 +1,27 @@
1
+ module Turnip
2
+ def self.run(content)
3
+ builder = Turnip::Builder.new
4
+ formatter = Gherkin::Formatter::TagCountFormatter.new(builder, {})
5
+ parser = Gherkin::Parser::Parser.new(formatter, true, "root", false)
6
+ parser.parse(content, nil, 0)
7
+
8
+ builder.features.each do |feature|
9
+ describe feature.name do
10
+ feature.backgrounds.each do |background|
11
+ before do
12
+ background.steps.each do |step|
13
+ Turnip::Steps.execute_step(self, step.name)
14
+ end
15
+ end
16
+ end
17
+ feature.scenarios.each do |scenario|
18
+ it scenario.name, scenario.metadata_hash do
19
+ scenario.steps.each do |step|
20
+ Turnip::Steps.execute_step(self, step.name)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,31 @@
1
+ module Turnip
2
+ module Steps
3
+ class Pending < StandardError; end
4
+ class Ambiguous < StandardError; end
5
+
6
+ extend self
7
+
8
+ def execute_step(context, description)
9
+ context.instance_eval(&find_step(description))
10
+ rescue Pending
11
+ context.pending "the step '#{description}' is not implemented"
12
+ end
13
+
14
+ def add_step(description, &block)
15
+ steps << [description, block]
16
+ end
17
+
18
+ def find_step(description)
19
+ found = steps.select do |step|
20
+ step.first == description
21
+ end
22
+ raise Pending, description if found.length == 0
23
+ raise Ambiguous, description if found.length > 1
24
+ found[0][1]
25
+ end
26
+
27
+ def steps
28
+ @steps ||= []
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module Turnip
2
+ VERSION = "0.1.0"
3
+ end
data/lib/turnip.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "gherkin"
2
+ require "gherkin/formatter/tag_count_formatter"
3
+
4
+ require "turnip/version"
5
+ require "turnip/loader"
6
+ require "turnip/builder"
7
+ require "turnip/run"
8
+ require "turnip/steps"
9
+ require "turnip/dsl"
10
+ require "turnip/rspec"
@@ -0,0 +1,3 @@
1
+ Feature: Ambiguous
2
+ Scenario: This is an ambiguous feature
3
+ Given this is ambiguous
@@ -0,0 +1,6 @@
1
+ Feature: Feature with background
2
+ Background:
3
+ Given there is a monster
4
+ Scenario: simple scenario
5
+ When I attack it
6
+ Then it should die
@@ -0,0 +1,3 @@
1
+ Feature: Pending
2
+ Scenario: This is a pending feature
3
+ Given there is an unimplemented step
@@ -0,0 +1,5 @@
1
+ Feature: A simple feature
2
+ Scenario: This is a simple feature
3
+ Given there is a monster
4
+ When I attack it
5
+ Then it should die
@@ -0,0 +1,14 @@
1
+ @awesome
2
+ Feature: With tags
3
+ @cool
4
+ Scenario: Attack a monster with cool tag
5
+ Given there is a monster
6
+ When I attack it
7
+ Then it should die
8
+
9
+ @stealthy @wicked
10
+ Scenario: With multiple tags
11
+ Given there is a strong monster
12
+ When I attack it
13
+ And I attack it
14
+ Then it should die
@@ -0,0 +1,21 @@
1
+ step "there is a monster" do
2
+ @monster = 1
3
+ end
4
+
5
+ step "there is a strong monster" do
6
+ @monster = 2
7
+ end
8
+
9
+ step "I attack it" do
10
+ @monster -= 1
11
+ end
12
+
13
+ step "it should die" do
14
+ @monster.should eq(0)
15
+ end
16
+
17
+ step "this is ambiguous" do
18
+ end
19
+
20
+ step "this is ambiguous" do
21
+ end
data/turnip.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "turnip/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "turnip"
7
+ s.version = Turnip::VERSION
8
+ s.authors = ["Jonas Nicklas"]
9
+ s.email = ["jonas.nicklas@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Gherkin extension for RSpec}
12
+ s.description = %q{Provides the ability to define steps and run Gherkin files from with RSpec}
13
+
14
+ s.rubyforge_project = "turnip"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_runtime_dependency "rspec", "~>2.0"
22
+ s.add_runtime_dependency "gherkin"
23
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: turnip
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jonas Nicklas
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-21 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &2153440840 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2153440840
25
+ - !ruby/object:Gem::Dependency
26
+ name: gherkin
27
+ requirement: &2153440340 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2153440340
36
+ description: Provides the ability to define steps and run Gherkin files from with
37
+ RSpec
38
+ email:
39
+ - jonas.nicklas@gmail.com
40
+ executables: []
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - .gitignore
45
+ - .rspec
46
+ - Gemfile
47
+ - README.md
48
+ - Rakefile
49
+ - lib/carrot.rb
50
+ - lib/turnip.rb
51
+ - lib/turnip/builder.rb
52
+ - lib/turnip/dsl.rb
53
+ - lib/turnip/loader.rb
54
+ - lib/turnip/rspec.rb
55
+ - lib/turnip/run.rb
56
+ - lib/turnip/steps.rb
57
+ - lib/turnip/version.rb
58
+ - spec/fixture/ambiguous.feature
59
+ - spec/fixture/backgrounds.feature
60
+ - spec/fixture/pending.feature
61
+ - spec/fixture/simple_feature.feature
62
+ - spec/fixture/tags.feature
63
+ - spec/spec_helper.rb
64
+ - turnip.gemspec
65
+ homepage: ''
66
+ licenses: []
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project: turnip
85
+ rubygems_version: 1.8.6
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Gherkin extension for RSpec
89
+ test_files:
90
+ - spec/fixture/ambiguous.feature
91
+ - spec/fixture/backgrounds.feature
92
+ - spec/fixture/pending.feature
93
+ - spec/fixture/simple_feature.feature
94
+ - spec/fixture/tags.feature
95
+ - spec/spec_helper.rb