spinach 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rvmrc +1 -0
- data/Gemfile +8 -0
- data/Rakefile +12 -0
- data/Readme.md +9 -0
- data/bin/spinach +18 -0
- data/examples/steps/user_logs_in.rb +23 -0
- data/examples/user_logs_in.feature +6 -0
- data/examples/user_logs_in.rb +23 -0
- data/lib/spinach/config.rb +17 -0
- data/lib/spinach/dsl.rb +19 -0
- data/lib/spinach/feature.rb +13 -0
- data/lib/spinach/parser.rb +21 -0
- data/lib/spinach/runner.rb +41 -0
- data/lib/spinach/version.rb +3 -0
- data/lib/spinach.rb +24 -0
- data/spinach.gemspec +23 -0
- data/test/spinach/config_test.rb +13 -0
- data/test/spinach/dsl_test.rb +30 -0
- data/test/spinach/feature_test.rb +22 -0
- data/test/spinach/parser_test.rb +37 -0
- data/test/spinach/runner_test.rb +38 -0
- data/test/spinach_test.rb +34 -0
- data/test/test_helper.rb +8 -0
- metadata +134 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create use 1.9.2@spinach
|
data/Gemfile
ADDED
data/Rakefile
ADDED
data/Readme.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# About Spinach
|
2
|
+
Spinach is a BDD framework on top of gherkin
|
3
|
+
|
4
|
+
![](http://farm1.static.flickr.com/58/200481513_a1a0aa265a.jpg)
|
5
|
+
|
6
|
+
# Testimonials
|
7
|
+
![](http://www.80stees.com/images/products/Popeye_the_Sailor_Man_I_Popeye_Spinach-T-link.jpg)
|
8
|
+
|
9
|
+
*Popeye the Sailor*
|
data/bin/spinach
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'spinach'
|
5
|
+
rescue LoadError
|
6
|
+
require_relative '../lib/spinach'
|
7
|
+
Dir.glob(
|
8
|
+
File.expand_path File.join(Spinach.config[:step_definitions_path], '**', '*.rb')
|
9
|
+
).each do |file|
|
10
|
+
require file
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
ARGV.each do |file|
|
15
|
+
Spinach::Runner.new(
|
16
|
+
Spinach::Parser.new(file).parse
|
17
|
+
).run
|
18
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class UserLogsIn < Spinach::Feature
|
2
|
+
feature "User logs in"
|
3
|
+
|
4
|
+
Given 'I am not logged in' do
|
5
|
+
123
|
6
|
+
end
|
7
|
+
|
8
|
+
When 'I log in' do
|
9
|
+
@a = 'hey'
|
10
|
+
end
|
11
|
+
|
12
|
+
Then 'I should be logged in' do
|
13
|
+
user.must_equal 'heyo'
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def user
|
19
|
+
@user ||= User.make
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class UserLogsIn < Spinach::Feature
|
2
|
+
feature "User logs in"
|
3
|
+
|
4
|
+
Given 'I am not logged in' do
|
5
|
+
123
|
6
|
+
end
|
7
|
+
|
8
|
+
When 'I log in' do
|
9
|
+
@a = 'hey'
|
10
|
+
end
|
11
|
+
|
12
|
+
Then 'I should be logged in' do
|
13
|
+
user.must_equal 'heyo'
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def user
|
19
|
+
@user ||= User.make
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Spinach
|
2
|
+
def self.config
|
3
|
+
@config ||= Config.new
|
4
|
+
end
|
5
|
+
class Config
|
6
|
+
attr_writer :step_definitions_path
|
7
|
+
def step_definitions_path
|
8
|
+
@step_definitions_path || 'features/steps'
|
9
|
+
end
|
10
|
+
def [](attribute)
|
11
|
+
self.send(attribute)
|
12
|
+
end
|
13
|
+
def []=(attribute, params)
|
14
|
+
self.send("#{attribute}=", params)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/spinach/dsl.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Spinach
|
2
|
+
module DSL
|
3
|
+
def When(string, &block)
|
4
|
+
define_method(string, &block)
|
5
|
+
end
|
6
|
+
alias_method :Given, :When
|
7
|
+
alias_method :Then, :When
|
8
|
+
alias_method :And, :When
|
9
|
+
alias_method :But, :When
|
10
|
+
|
11
|
+
def feature(name)
|
12
|
+
@feature_name = name
|
13
|
+
end
|
14
|
+
|
15
|
+
def feature_name
|
16
|
+
@feature_name
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'gherkin'
|
2
|
+
require 'gherkin/formatter/json_formatter'
|
3
|
+
|
4
|
+
module Spinach
|
5
|
+
class Parser
|
6
|
+
def initialize(filename)
|
7
|
+
@filename = filename
|
8
|
+
@formatter = Gherkin::Formatter::JSONFormatter.new(nil)
|
9
|
+
@parser = Gherkin::Parser::Parser.new(@formatter)
|
10
|
+
end
|
11
|
+
|
12
|
+
def content
|
13
|
+
File.read(@filename)
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse
|
17
|
+
@parser.parse(content, @filename, __LINE__-1)
|
18
|
+
@formatter.gherkin_object
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Spinach
|
2
|
+
class Runner
|
3
|
+
def initialize(data)
|
4
|
+
@feature_name = data['name']
|
5
|
+
@scenarios = data['elements']
|
6
|
+
end
|
7
|
+
|
8
|
+
def feature
|
9
|
+
@feature ||= Spinach.find_feature(@feature_name)
|
10
|
+
end
|
11
|
+
|
12
|
+
def scenarios
|
13
|
+
@scenarios
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
step_count = 0
|
18
|
+
reports = []
|
19
|
+
|
20
|
+
scenarios.each do |scenario|
|
21
|
+
instance = feature.new
|
22
|
+
scenario['steps'].each do |step|
|
23
|
+
begin
|
24
|
+
instance.send(step['name'])
|
25
|
+
print "\e[32m."
|
26
|
+
rescue MiniTest::Assertion=>e
|
27
|
+
reports << e
|
28
|
+
print "\e[31mF"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
print "\e[0m\n"
|
34
|
+
puts
|
35
|
+
reports.each do |report|
|
36
|
+
puts "* #{report.message}\n\t"
|
37
|
+
puts report.backtrace.reverse.join("\n")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/spinach.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'spinach/version'
|
2
|
+
require_relative 'spinach/config'
|
3
|
+
require_relative 'spinach/runner'
|
4
|
+
require_relative 'spinach/parser'
|
5
|
+
require_relative 'spinach/dsl'
|
6
|
+
require_relative 'spinach/feature'
|
7
|
+
|
8
|
+
module Spinach
|
9
|
+
@@features = []
|
10
|
+
|
11
|
+
def self.features
|
12
|
+
@@features
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.reset_features
|
16
|
+
@@features = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.find_feature(name)
|
20
|
+
@@features.detect do |feature|
|
21
|
+
feature.feature_name.to_s == name.to_s
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/spinach.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/spinach/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Josep Jaume Rey", "Josep M. Bach", "Oriol Gual"]
|
6
|
+
gem.email = ["info@codegram.com"]
|
7
|
+
gem.description = %q{Spinach is a BDD framework on top of gherkin}
|
8
|
+
gem.summary = %q{Spinach is a BDD framework on top of gherkin}
|
9
|
+
gem.homepage = "http://github.com/codegram/spinach"
|
10
|
+
|
11
|
+
gem.add_runtime_dependency 'gherkin'
|
12
|
+
gem.add_runtime_dependency 'minitest'
|
13
|
+
gem.add_development_dependency 'purdytest'
|
14
|
+
gem.add_development_dependency 'rake'
|
15
|
+
gem.add_development_dependency 'mocha'
|
16
|
+
|
17
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
gem.files = `git ls-files`.split("\n")
|
19
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
gem.name = "spinach"
|
21
|
+
gem.require_paths = ["lib"]
|
22
|
+
gem.version = Spinach::VERSION
|
23
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe Spinach::Config do
|
4
|
+
describe "#step_definitions_path" do
|
5
|
+
it "returns a default" do
|
6
|
+
(Spinach.config[:step_definitions_path].kind_of? String).must_equal true
|
7
|
+
end
|
8
|
+
it "can be overwritten" do
|
9
|
+
Spinach.config[:step_definitions_path] = 'steps'
|
10
|
+
Spinach.config[:step_definitions_path].must_equal 'steps'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe Spinach::DSL do
|
4
|
+
before do
|
5
|
+
@feature = Class.new do
|
6
|
+
extend Spinach::DSL
|
7
|
+
end
|
8
|
+
end
|
9
|
+
describe "#When" do
|
10
|
+
it "should define a method with the step name" do
|
11
|
+
@feature.When("I say goodbye") do
|
12
|
+
"You say hello"
|
13
|
+
end
|
14
|
+
@feature.new.send("I say goodbye").must_equal "You say hello"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
describe "#Given, #Then, #And, #But" do
|
18
|
+
it "should be #When aliases" do
|
19
|
+
%w{Given Then And But}.each do |m|
|
20
|
+
@feature.must_respond_to m
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
describe "#feature" do
|
25
|
+
it "should set the name for this feature" do
|
26
|
+
@feature.feature("User salutes")
|
27
|
+
@feature.feature_name.must_equal "User salutes"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe Spinach::Feature do
|
4
|
+
describe "ancestors" do
|
5
|
+
it "should include minitest helpers" do
|
6
|
+
Spinach::Feature.ancestors.must_include MiniTest::Assertions
|
7
|
+
end
|
8
|
+
it "should be extended by the DSL" do
|
9
|
+
(class << Spinach::Feature; self; end).ancestors.must_include Spinach::DSL
|
10
|
+
end
|
11
|
+
end
|
12
|
+
describe "#inherited" do
|
13
|
+
it "should register any feature subclass" do
|
14
|
+
@feature1 = Class.new(Spinach::Feature)
|
15
|
+
@feature2 = Class.new(Spinach::Feature)
|
16
|
+
@feature3 = Class.new
|
17
|
+
Spinach.features.must_include @feature1
|
18
|
+
Spinach.features.must_include @feature2
|
19
|
+
Spinach.features.wont_include @feature3
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe Spinach::Parser do
|
4
|
+
before do
|
5
|
+
@parser = Spinach::Parser.new("feature_definition.feature")
|
6
|
+
@parser.stubs(:content).returns('
|
7
|
+
Feature: User authentication
|
8
|
+
Scenario: User logs in
|
9
|
+
Given I am on the front page
|
10
|
+
When I fill in the login form and press "login"
|
11
|
+
Then I should be on my dashboard
|
12
|
+
')
|
13
|
+
end
|
14
|
+
describe "#parse" do
|
15
|
+
before do
|
16
|
+
@parsed = @parser.parse
|
17
|
+
end
|
18
|
+
it "parses the feature name" do
|
19
|
+
@parsed['name'].must_equal "User authentication"
|
20
|
+
end
|
21
|
+
describe "scenario" do
|
22
|
+
before do
|
23
|
+
@scenario = @parsed['elements'][0]
|
24
|
+
end
|
25
|
+
it "parses the scenario name" do
|
26
|
+
@scenario['name'].must_equal "User logs in"
|
27
|
+
end
|
28
|
+
it "parses the scenario steps" do
|
29
|
+
@scenario['steps'][0]['name'].must_equal "I am on the front page"
|
30
|
+
@scenario['steps'][1]['name'].must_equal(
|
31
|
+
"I fill in the login form and press \"login\""
|
32
|
+
)
|
33
|
+
@scenario['steps'][2]['name'].must_equal "I should be on my dashboard"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe Spinach::Runner do
|
4
|
+
before do
|
5
|
+
Spinach.reset_features
|
6
|
+
@feature = Class.new(Spinach::Feature) do
|
7
|
+
feature "A new feature"
|
8
|
+
When "I say hello" do
|
9
|
+
end
|
10
|
+
Then "You say goodbye" do
|
11
|
+
end
|
12
|
+
end
|
13
|
+
data = {
|
14
|
+
'name' => "A new feature",
|
15
|
+
'elements' => [{'steps' => [
|
16
|
+
{'name' => "I say hello"}, {'name' => "You say goodbye"}
|
17
|
+
]}]
|
18
|
+
}
|
19
|
+
@runner = Spinach::Runner.new(data)
|
20
|
+
end
|
21
|
+
describe "#feature" do
|
22
|
+
it "returns a Spinach feature" do
|
23
|
+
@runner.feature.name == @feature.name
|
24
|
+
end
|
25
|
+
end
|
26
|
+
describe "#scenarios" do
|
27
|
+
it "should return the scenarios" do
|
28
|
+
@runner.scenarios.must_equal [{'steps' => [
|
29
|
+
{'name' => "I say hello"}, {'name' => "You say goodbye"}
|
30
|
+
]}]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
describe "#run" do
|
34
|
+
it "should call every step on the feature" do
|
35
|
+
@runner.run
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
describe Spinach do
|
4
|
+
before do
|
5
|
+
@feature1 = OpenStruct.new(feature_name: "User authentication")
|
6
|
+
@feature2 = OpenStruct.new(feature_name: "Slip management")
|
7
|
+
@feature3 = OpenStruct.new(feature_name: "File attachments")
|
8
|
+
[@feature1, @feature2, @feature3].each do |feature|
|
9
|
+
Spinach.features << feature
|
10
|
+
end
|
11
|
+
end
|
12
|
+
describe "#features" do
|
13
|
+
it "returns all the loaded features" do
|
14
|
+
Spinach.features.must_include @feature1
|
15
|
+
Spinach.features.must_include @feature2
|
16
|
+
Spinach.features.must_include @feature3
|
17
|
+
end
|
18
|
+
end
|
19
|
+
describe "#reset_features" do
|
20
|
+
it "resets the features to a pristine state" do
|
21
|
+
Spinach.reset_features
|
22
|
+
[@feature1, @feature3, @feature3].each do |feature|
|
23
|
+
Spinach.features.wont_include feature
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
describe "#find_feature" do
|
28
|
+
it "finds a feature by name" do
|
29
|
+
Spinach.find_feature("User authentication").must_equal @feature1
|
30
|
+
Spinach.find_feature("Slip management").must_equal @feature2
|
31
|
+
Spinach.find_feature("File attachments").must_equal @feature3
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: spinach
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Josep Jaume Rey
|
9
|
+
- Josep M. Bach
|
10
|
+
- Oriol Gual
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2011-09-24 00:00:00.000000000Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: gherkin
|
18
|
+
requirement: &70306015799560 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ! '>='
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '0'
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: *70306015799560
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: &70306015799140 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ! '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: *70306015799140
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: purdytest
|
40
|
+
requirement: &70306015798720 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
type: :development
|
47
|
+
prerelease: false
|
48
|
+
version_requirements: *70306015798720
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rake
|
51
|
+
requirement: &70306015798300 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: *70306015798300
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: mocha
|
62
|
+
requirement: &70306015828840 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: *70306015828840
|
71
|
+
description: Spinach is a BDD framework on top of gherkin
|
72
|
+
email:
|
73
|
+
- info@codegram.com
|
74
|
+
executables:
|
75
|
+
- spinach
|
76
|
+
extensions: []
|
77
|
+
extra_rdoc_files: []
|
78
|
+
files:
|
79
|
+
- .gitignore
|
80
|
+
- .rvmrc
|
81
|
+
- Gemfile
|
82
|
+
- Rakefile
|
83
|
+
- Readme.md
|
84
|
+
- bin/spinach
|
85
|
+
- examples/steps/user_logs_in.rb
|
86
|
+
- examples/user_logs_in.feature
|
87
|
+
- examples/user_logs_in.rb
|
88
|
+
- lib/spinach.rb
|
89
|
+
- lib/spinach/config.rb
|
90
|
+
- lib/spinach/dsl.rb
|
91
|
+
- lib/spinach/feature.rb
|
92
|
+
- lib/spinach/parser.rb
|
93
|
+
- lib/spinach/runner.rb
|
94
|
+
- lib/spinach/version.rb
|
95
|
+
- spinach.gemspec
|
96
|
+
- test/spinach/config_test.rb
|
97
|
+
- test/spinach/dsl_test.rb
|
98
|
+
- test/spinach/feature_test.rb
|
99
|
+
- test/spinach/parser_test.rb
|
100
|
+
- test/spinach/runner_test.rb
|
101
|
+
- test/spinach_test.rb
|
102
|
+
- test/test_helper.rb
|
103
|
+
homepage: http://github.com/codegram/spinach
|
104
|
+
licenses: []
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options: []
|
107
|
+
require_paths:
|
108
|
+
- lib
|
109
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ! '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
requirements: []
|
122
|
+
rubyforge_project:
|
123
|
+
rubygems_version: 1.8.6
|
124
|
+
signing_key:
|
125
|
+
specification_version: 3
|
126
|
+
summary: Spinach is a BDD framework on top of gherkin
|
127
|
+
test_files:
|
128
|
+
- test/spinach/config_test.rb
|
129
|
+
- test/spinach/dsl_test.rb
|
130
|
+
- test/spinach/feature_test.rb
|
131
|
+
- test/spinach/parser_test.rb
|
132
|
+
- test/spinach/runner_test.rb
|
133
|
+
- test/spinach_test.rb
|
134
|
+
- test/test_helper.rb
|