spinach 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.
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ capybara-*.html
data/Gemfile CHANGED
@@ -3,6 +3,16 @@ source 'http://rubygems.org'
3
3
  # Specify your gem's dependencies in spinach.gemspec
4
4
  gemspec
5
5
 
6
+ group :test do
7
+ gem 'guard'
8
+ gem 'guard-minitest'
9
+ end
10
+
11
+ group :darwin do
12
+ gem 'rb-fsevent'
13
+ gem 'growl'
14
+ end
15
+
6
16
  group :docs do
7
17
  gem 'yard'
8
18
  end
data/Guardfile ADDED
@@ -0,0 +1,5 @@
1
+ guard 'minitest' do
2
+ watch(%r|^test/(.*)_test\.rb|)
3
+ watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "test/#{m[1]}#{m[2]}_test.rb" }
4
+ watch(%r|^test/test_helper\.rb|) { "test" }
5
+ end
data/Readme.md CHANGED
@@ -3,7 +3,10 @@ Spinach is a BDD framework on top of gherkin
3
3
 
4
4
  ![](http://farm1.static.flickr.com/58/200481513_a1a0aa265a.jpg)
5
5
 
6
+ # Documentation
7
+ [Spinach documentation at rubydoc.info](http://rubydoc.info/github/codegram/spinach/master/frames)
8
+
6
9
  # Testimonials
7
- ![](http://www.80stees.com/images/products/Popeye_the_Sailor_Man_I_Popeye_Spinach-T-link.jpg)
10
+ ![](http://www.80stees.com/images/products/Popeye_the_Sailor_Man_I_Popeye_Spinach-T-link.jpg)
8
11
 
9
12
  *Popeye the Sailor*
data/bin/spinach CHANGED
@@ -4,11 +4,18 @@ begin
4
4
  require 'spinach'
5
5
  rescue LoadError
6
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
7
+ end
8
+
9
+ Dir.glob(
10
+ File.expand_path File.join(Spinach.config[:step_definitions_path], '**', '*.rb')
11
+ ).each do |file|
12
+ require file
13
+ end
14
+
15
+ Dir.glob(
16
+ File.expand_path File.join(Spinach.config[:support_path], '**', '*.rb')
17
+ ).each do |file|
18
+ require file
12
19
  end
13
20
 
14
21
  ARGV.each do |file|
data/lib/spinach.rb CHANGED
@@ -4,18 +4,36 @@ require_relative 'spinach/runner'
4
4
  require_relative 'spinach/parser'
5
5
  require_relative 'spinach/dsl'
6
6
  require_relative 'spinach/feature'
7
+ require_relative 'spinach/reporter'
7
8
 
9
+ # Spinach is a BDD framework in top of gherkin. Its main goals are:
10
+ # * No magic: All features are implemented using actual classes.
11
+ # * Reusability: Steps are methods, so they can be put inside modules.
12
+ # * Proper encapsulation: No conflicts between steps from different
13
+ # scenarios.
14
+ #
8
15
  module Spinach
9
16
  @@features = []
10
17
 
18
+ # @return [Array<Spinach::Feature>]
19
+ # all the registered features
20
+ #
11
21
  def self.features
12
22
  @@features
13
23
  end
14
24
 
25
+ # Resets Spinach to a pristine state, as if any feature was registered.
26
+ # Mostly useful in Spinach's own testing.
27
+ #
15
28
  def self.reset_features
16
29
  @@features = []
17
30
  end
18
31
 
32
+ # Finds a feature given a feature name
33
+ #
34
+ # @param [String] name
35
+ # the feature name
36
+ #
19
37
  def self.find_feature(name)
20
38
  @@features.detect do |feature|
21
39
  feature.feature_name.to_s == name.to_s
@@ -0,0 +1,37 @@
1
+ require 'capybara'
2
+ require 'capybara/dsl'
3
+ require_relative 'feature'
4
+
5
+ module Spinach
6
+ class Feature
7
+
8
+ # Spinach's capybara module integrates capybara into all features
9
+ #
10
+ # @example
11
+ # require 'spinach/capybara'
12
+ # class CapybaraFeature < Spinach::Feature
13
+ # Given "I go to the home page" do
14
+ # visit '/'
15
+ # end
16
+ # end
17
+ #
18
+ module Capybara
19
+ def self.included(base)
20
+ base.class_eval do
21
+ include ::Capybara::DSL
22
+ include InstanceMethods
23
+
24
+ def before
25
+ end
26
+ def after
27
+ ::Capybara.current_session.reset! if ::Capybara.app
28
+ end
29
+ end
30
+ end
31
+ module InstanceMethods
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ Spinach::Feature.send(:include, Spinach::Feature::Capybara)
@@ -1,15 +1,65 @@
1
1
  module Spinach
2
+
3
+ # Accesses spinach config. Allows you to configure several runtime options,
4
+ # like the step definitions path.
5
+ #
6
+ # @return [Spinach::Config]
7
+ # the config object
8
+ #
9
+ # @example
10
+ # Spinach.config[:step_definitions_path]
11
+ # # => 'features/steps'
12
+ # Spinach.config[:step_definitions_path] = 'integration/steps'
13
+ # # => 'integration/steps'
14
+ #
2
15
  def self.config
3
16
  @config ||= Config.new
4
17
  end
18
+
19
+ # The config object holds all the runtime configurations needed for spinach
20
+ # to run.
21
+ #
5
22
  class Config
6
- attr_writer :step_definitions_path
23
+ attr_writer :step_definitions_path, :default_reporter, :support_path
24
+
25
+ # The "step definitions path" helds the place where your feature classes
26
+ # will be searched for. Defaults to 'features/steps'
27
+ #
7
28
  def step_definitions_path
8
29
  @step_definitions_path || 'features/steps'
9
30
  end
31
+
32
+ # The "support path" helds the place where your can put your configuration
33
+ # files
34
+ #
35
+ def support_path
36
+ @support_path || 'features/support'
37
+ end
38
+
39
+ # The default reporter is the reporter spinach will use if there's no other
40
+ # specified. Defaults to Spinach::Reporter::Stdout, which will print all
41
+ # output to the standard output
42
+ #
43
+ def default_reporter
44
+ @default_reporter || Spinach::Reporter::Stdout
45
+ end
46
+
47
+ # Allows you to read the config object using a hash-like syntax.
48
+ #
49
+ # @example
50
+ # Spinach.config[:step_definitions_path]
51
+ # # => 'features/steps'
52
+ #
10
53
  def [](attribute)
11
54
  self.send(attribute)
12
55
  end
56
+
57
+ # Allows you to set config properties using a hash-like syntax
58
+ #
59
+ # @example
60
+ # Spinach.config[:step_definitions_path] = 'integration/steps'
61
+ # # => 'integration/steps'
62
+ #
13
63
  def []=(attribute, params)
14
64
  self.send("#{attribute}=", params)
15
65
  end
data/lib/spinach/dsl.rb CHANGED
@@ -1,19 +1,42 @@
1
1
  module Spinach
2
+ # Spinach DSL aims to provide an easy way to define steps and other domain
3
+ # specific actions into your feature classes
4
+ #
2
5
  module DSL
3
- def When(string, &block)
4
- define_method(string, &block)
6
+
7
+ # Defines an action to perform given a particular step literal.
8
+ #
9
+ # @param [String] step name
10
+ # The step literal
11
+ # @param [Proc] block
12
+ # action to perform in that step
13
+ #
14
+ # @example
15
+ # class MyFeature << Spinach::Feature
16
+ # When "I go to the toilet" do
17
+ # @sittin_on_the_toilet.must_equal true
18
+ # end
19
+ # end
20
+ #
21
+ %w{When Given Then And But}.each do |connector|
22
+ define_method connector do |string, &block|
23
+ define_method("#{connector} #{string}", &block)
24
+ end
5
25
  end
6
- alias_method :Given, :When
7
- alias_method :Then, :When
8
- alias_method :And, :When
9
- alias_method :But, :When
10
26
 
27
+ # Defines this feature's name
28
+ #
29
+ # @example
30
+ # class MyFeature < Spinach::Feature
31
+ # feature "Satisfy needs"
32
+ # end
33
+ #
11
34
  def feature(name)
12
35
  @feature_name = name
13
36
  end
14
37
 
15
- def feature_name
16
- @feature_name
17
- end
38
+ # @return [String] this feature's name
39
+ #
40
+ attr_reader :feature_name
18
41
  end
19
42
  end
@@ -2,10 +2,15 @@ require 'minitest/spec'
2
2
  MiniTest::Spec.new nil
3
3
 
4
4
  module Spinach
5
+ # The feature class is the class where all the features must inherit from.
6
+ #
5
7
  class Feature
6
8
  extend DSL
7
9
  include MiniTest::Assertions
8
10
 
11
+ def before; end;
12
+ def after; end;
13
+
9
14
  def self.inherited(base)
10
15
  Spinach.features << base
11
16
  end
@@ -2,6 +2,9 @@ require 'gherkin'
2
2
  require 'gherkin/formatter/json_formatter'
3
3
 
4
4
  module Spinach
5
+ # Spinach's parser uses Gherkin in the guts to extract all the information
6
+ # needed from the plain feature definition.
7
+ #
5
8
  class Parser
6
9
  def initialize(filename)
7
10
  @filename = filename
@@ -9,10 +12,15 @@ module Spinach
9
12
  @parser = Gherkin::Parser::Parser.new(@formatter)
10
13
  end
11
14
 
15
+ # Gets the plain text content of the feature file.
16
+ # @return [String]
17
+ # the plain feature content
18
+ #
12
19
  def content
13
20
  File.read(@filename)
14
21
  end
15
22
 
23
+ # @return [Hash] the parsed gerkin output
16
24
  def parse
17
25
  @parser.parse(content, @filename, __LINE__-1)
18
26
  @formatter.gherkin_object
@@ -0,0 +1,81 @@
1
+ # encoding: utf-8
2
+ require 'colorize'
3
+
4
+ module Spinach
5
+ # Spinach reporter collects information from Runner hooks and outputs the
6
+ # results
7
+ #
8
+ class Reporter
9
+
10
+ # Receives this hook when a feature is invoked
11
+ # @param [String] name
12
+ # the feature name
13
+ #
14
+ def feature(name)
15
+ raise "Abstract method!"
16
+ end
17
+
18
+ # Receives this hook when a scenario is invoked
19
+ # @param [String] name
20
+ # the scenario name
21
+ #
22
+ def scenario(name)
23
+ raise "Abstract method!"
24
+ end
25
+
26
+ # Receives this hook when a step is invoked
27
+ # @param [String] name
28
+ # the scenario name
29
+ # @param [Symbol] result
30
+ # the step name and its finishing state. May be :success or :failure
31
+ #
32
+ def step(name, result)
33
+ raise "Abstract method!"
34
+ end
35
+
36
+ # Receives this hook when a feature reaches its end
37
+ #
38
+ def end
39
+ raise "Abstract method!"
40
+ end
41
+
42
+ # The Stdout reporter outputs the runner results to the standard output
43
+ #
44
+ class Stdout < Reporter
45
+
46
+ # Prints the feature name to the standard output
47
+ #
48
+ def feature(name)
49
+ puts "\nFeature: #{name}".white.underline
50
+ end
51
+
52
+ # Prints the scenario name to the standard ouput
53
+ #
54
+ def scenario(name)
55
+ puts " Scenario: #{name}".white
56
+ end
57
+
58
+ # Prints the step name to the standard output. If failed, it puts an
59
+ # F! before
60
+ #
61
+ def step(name, result)
62
+ words = name.split(" ")
63
+ connector = words.shift
64
+ phrase = words.join(" ")
65
+ if result == :success
66
+ puts " ✔ #{connector} #{phrase}".green
67
+ elsif result == :failure
68
+ puts " ✘ #{connector} #{phrase}".red
69
+ elsif result == :skip
70
+ puts " ~ #{connector} #{phrase}".yellow
71
+ end
72
+ end
73
+
74
+ # Prints a blank line at the end
75
+ #
76
+ def end
77
+ puts ""
78
+ end
79
+ end
80
+ end
81
+ end
@@ -1,41 +1,86 @@
1
1
  module Spinach
2
+ # Spinach's runner gets the parsed data from the feature and performs the
3
+ # actual calls to the feature classes.
4
+ #
2
5
  class Runner
6
+ # Initializes the runner with a parsed feature
7
+ # @param [Hash] data
8
+ # the parsed feature data
9
+ #
3
10
  def initialize(data)
4
11
  @feature_name = data['name']
5
12
  @scenarios = data['elements']
13
+ @reporter = Spinach::config.default_reporter.new
6
14
  end
7
15
 
16
+ # The default reporter associated to this run
17
+ attr_reader :reporter
18
+
19
+ # Returns the feature class for the provided feature data
20
+ # @return [Spinach::Feature] feature
21
+ # this runner's feature
22
+ #
8
23
  def feature
9
24
  @feature ||= Spinach.find_feature(@feature_name)
10
25
  end
11
26
 
27
+ # @return [Hash]
28
+ # the parsed scenarios for this runner's feature
29
+ #
12
30
  def scenarios
13
31
  @scenarios
14
32
  end
15
33
 
34
+ # Runs this runner and outputs the results in a colorful manner.
35
+ #
16
36
  def run
17
37
  step_count = 0
18
38
  reports = []
19
39
 
40
+ reporter.feature(@feature_name)
41
+
20
42
  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
43
+ Scenario.new(self, scenario).run
31
44
  end
45
+ reporter.end
32
46
 
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")
47
+ end
48
+
49
+ class Scenario
50
+ attr_reader :name, :steps
51
+
52
+ def initialize(runner, data)
53
+ @name = data['name']
54
+ @steps = data['steps']
55
+ @runner = runner
56
+ end
57
+
58
+ def reporter; @runner.reporter; end;
59
+
60
+ def feature
61
+ @feature ||= @runner.feature.new
62
+ end
63
+
64
+ def run
65
+ reporter.scenario(name)
66
+ feature.send(:before)
67
+ steps.each do |step|
68
+ step_name = "#{step['keyword'].strip} #{step['name']}"
69
+ unless @failed
70
+ begin
71
+ feature.send(step_name)
72
+ reporter.step(step_name, :success)
73
+ rescue MiniTest::Assertion=>e
74
+ reporter.step(step_name, :failure)
75
+ @failed = true
76
+ end
77
+ else
78
+ reporter.step(step_name, :skip)
79
+ end
80
+ end
81
+ feature.send(:after)
38
82
  end
39
83
  end
84
+
40
85
  end
41
86
  end
@@ -1,3 +1,3 @@
1
1
  module Spinach
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/spinach.gemspec CHANGED
@@ -10,9 +10,12 @@ Gem::Specification.new do |gem|
10
10
 
11
11
  gem.add_runtime_dependency 'gherkin'
12
12
  gem.add_runtime_dependency 'minitest'
13
+ gem.add_runtime_dependency 'colorize'
13
14
  gem.add_development_dependency 'purdytest'
14
15
  gem.add_development_dependency 'rake'
15
16
  gem.add_development_dependency 'mocha'
17
+ gem.add_development_dependency 'sinatra'
18
+ gem.add_development_dependency 'capybara'
16
19
 
17
20
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
21
  gem.files = `git ls-files`.split("\n")
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+ require 'spinach/capybara'
3
+ require 'sinatra'
4
+
5
+ describe Spinach::Feature::Capybara do
6
+ before do
7
+ @sinatra_app = Sinatra::Application.new do
8
+ get '/' do
9
+ 'Hello world!'
10
+ end
11
+ end
12
+ Capybara.app = @sinatra_app
13
+ @feature = Class.new(Spinach::Feature) do
14
+ def go_home
15
+ visit "/"
16
+ page
17
+ end
18
+ end.new
19
+ end
20
+ it "includes capybara into all features" do
21
+ @feature.kind_of? Capybara
22
+ end
23
+ it "goes to a capybara page and returns its result" do
24
+ page = @feature.go_home
25
+ page.has_content?('Hello world').must_equal true
26
+ end
27
+ end
@@ -10,4 +10,13 @@ describe Spinach::Config do
10
10
  Spinach.config[:step_definitions_path].must_equal 'steps'
11
11
  end
12
12
  end
13
+ describe "#support_path" do
14
+ it "returns a default" do
15
+ (Spinach.config[:support_path].kind_of? String).must_equal true
16
+ end
17
+ it "can be overwritten" do
18
+ Spinach.config[:support_path] = 'support'
19
+ Spinach.config[:support_path].must_equal 'support'
20
+ end
21
+ end
13
22
  end
@@ -6,12 +6,14 @@ describe Spinach::DSL do
6
6
  extend Spinach::DSL
7
7
  end
8
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"
9
+ %w{When Given Then And But}.each do |connector|
10
+ describe "##{connector}" do
11
+ it "should define a method with the step name" do
12
+ @feature.send(connector, "I say goodbye") do
13
+ "You say hello"
14
+ end
15
+ @feature.new.send("#{connector} I say goodbye").must_equal "You say hello"
13
16
  end
14
- @feature.new.send("I say goodbye").must_equal "You say hello"
15
17
  end
16
18
  end
17
19
  describe "#Given, #Then, #And, #But" do
@@ -0,0 +1,91 @@
1
+ # encoding: utf-8
2
+ require_relative '../test_helper'
3
+
4
+ describe Spinach::Reporter do
5
+ describe "abstract methods" do
6
+ before do
7
+ @reporter = Spinach::Reporter.new
8
+ end
9
+ %w{feature scenario}.each do |abstract_method|
10
+ describe "#{abstract_method}" do
11
+ it "raises an error" do
12
+ Proc.new{
13
+ @reporter.send(abstract_method, "arbitrary name")
14
+ }.must_raise RuntimeError
15
+ end
16
+ end
17
+ end
18
+ describe "#step" do
19
+ it "raises an error" do
20
+ Proc.new{
21
+ @reporter.step("arbitrary name", :success)
22
+ }.must_raise RuntimeError
23
+ end
24
+ end
25
+ describe "#end" do
26
+ it "raises an error" do
27
+ Proc.new{
28
+ @reporter.end
29
+ }.must_raise RuntimeError
30
+ end
31
+ end
32
+ end
33
+ describe Spinach::Reporter::Stdout do
34
+ before do
35
+ @reporter = Spinach::Reporter::Stdout.new
36
+ end
37
+ describe "#feature" do
38
+ it "outputs a feature name" do
39
+ out = capture_stdout do
40
+ @reporter.feature "User authentication"
41
+ end
42
+ out.string.must_include "\nFeature: User authentication"
43
+ end
44
+ end
45
+ describe "#scenario" do
46
+ it "outputs a scenario name" do
47
+ out = capture_stdout do
48
+ @reporter.scenario "User logs in"
49
+ end
50
+ out.string.must_include " Scenario: User logs in"
51
+ end
52
+ end
53
+ describe "#step" do
54
+ describe "when succeeding" do
55
+ it "outputs the step name" do
56
+ out = capture_stdout do
57
+ @reporter.step "Given I say goodbye", :success
58
+ end
59
+ out.string.must_include "✔"
60
+ out.string.must_include "Given I say goodbye"
61
+ end
62
+ end
63
+ describe "when failing" do
64
+ it "outputs the step name with a failure mark" do
65
+ out = capture_stdout do
66
+ @reporter.step "Given I say goodbye", :failure
67
+ end
68
+ out.string.must_include "✘"
69
+ out.string.must_include "Given I say goodbye"
70
+ end
71
+ end
72
+ describe "when skipping" do
73
+ it "outputs the step name with a failure mark" do
74
+ out = capture_stdout do
75
+ @reporter.step "Given I say nothing", :skip
76
+ end
77
+ out.string.must_include "~"
78
+ out.string.must_include "Given I say nothing"
79
+ end
80
+ end
81
+ end
82
+ describe "#end" do
83
+ it "outputs a blank line" do
84
+ out = capture_stdout do
85
+ @reporter.end
86
+ end
87
+ out.string.must_include "\n"
88
+ end
89
+ end
90
+ end
91
+ end
@@ -6,33 +6,87 @@ describe Spinach::Runner do
6
6
  @feature = Class.new(Spinach::Feature) do
7
7
  feature "A new feature"
8
8
  When "I say hello" do
9
+ @when_called = true
9
10
  end
10
- Then "You say goodbye" do
11
+ Then "you say goodbye" do
12
+ @then_called = true
13
+ true.must_equal false
11
14
  end
15
+ attr_accessor :when_called, :then_called
12
16
  end
13
17
  data = {
14
18
  'name' => "A new feature",
15
- 'elements' => [{'steps' => [
16
- {'name' => "I say hello"}, {'name' => "You say goodbye"}
17
- ]}]
19
+ 'elements' => [
20
+ {'name' => 'First scenario', 'steps' => [
21
+ {'keyword' => 'When ', 'name' => "I say hello"},
22
+ {'keyword' => 'Then ', 'name' => "you say goodbye"}]
23
+ }
24
+ ]
18
25
  }
19
26
  @runner = Spinach::Runner.new(data)
20
27
  end
21
28
  describe "#feature" do
22
29
  it "returns a Spinach feature" do
23
- @runner.feature.name == @feature.name
30
+ @runner.feature.ancestors.must_include @feature
24
31
  end
25
32
  end
26
33
  describe "#scenarios" do
27
34
  it "should return the scenarios" do
28
- @runner.scenarios.must_equal [{'steps' => [
29
- {'name' => "I say hello"}, {'name' => "You say goodbye"}
30
- ]}]
35
+ @runner.scenarios.must_equal [
36
+ {'name' => 'First scenario', 'steps' => [
37
+ {'keyword' => 'When ', 'name' => "I say hello"},
38
+ {'keyword' => 'Then ', 'name' => "you say goodbye"} ]
39
+ }
40
+ ]
31
41
  end
32
42
  end
33
43
  describe "#run" do
34
- it "should call every step on the feature" do
44
+ it "should hook into the reporter" do
45
+ reporter = stub_everything
46
+ @runner.stubs(reporter: reporter)
47
+ reporter.expects(:feature).with("A new feature")
48
+ reporter.expects(:end).once
35
49
  @runner.run
36
50
  end
37
51
  end
52
+ describe Spinach::Runner::Scenario do
53
+ before do
54
+ @data = {'name' => 'First scenario', 'steps' => [
55
+ {'keyword' => 'When ', 'name' => "I say hello"},
56
+ {'keyword' => 'Then ', 'name' => "you say goodbye"}]
57
+ }
58
+ @reporter = stub_everything
59
+ @runner = stub(reporter: @reporter, feature: @feature)
60
+ @scenario = Spinach::Runner::Scenario.new(@runner, @data)
61
+ end
62
+ it "should call every step on the feature" do
63
+ @scenario.run
64
+ @scenario.feature.when_called.must_equal true
65
+ @scenario.feature.then_called.must_equal true
66
+ end
67
+ it "calls the appropiate methods of the reporter" do
68
+ @reporter.expects(:scenario).with("First scenario")
69
+ @reporter.expects(:step).once.with("When I say hello", :success)
70
+ @reporter.expects(:step).once.with("Then you say goodbye", :failure)
71
+ @scenario.run
72
+ end
73
+ it "stops the run when finds an error" do
74
+ @feature = Class.new(Spinach::Feature) do
75
+ feature "A new feature"
76
+ When "I say hello" do
77
+ @when_called = true
78
+ true.must_equal false
79
+ end
80
+ Then "you say goodbye" do
81
+ @then_called = true
82
+ end
83
+ attr_accessor :when_called, :then_called
84
+ end
85
+ @runner.stubs(feature: @feature)
86
+ @scenario = Spinach::Runner::Scenario.new(@runner, @data)
87
+ @scenario.run
88
+ @scenario.feature.when_called.must_equal true
89
+ @scenario.feature.then_called.wont_equal true
90
+ end
91
+ end
38
92
  end
data/test/test_helper.rb CHANGED
@@ -6,3 +6,19 @@ require 'ostruct'
6
6
  require 'purdytest'
7
7
 
8
8
  require 'spinach'
9
+ require 'spinach/capybara'
10
+
11
+ require 'stringio'
12
+
13
+ module Kernel
14
+
15
+ def capture_stdout
16
+ out = StringIO.new
17
+ $stdout = out
18
+ yield
19
+ return out
20
+ ensure
21
+ $stdout = STDOUT
22
+ end
23
+
24
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spinach
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:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2011-09-24 00:00:00.000000000Z
14
+ date: 2011-09-26 00:00:00.000000000Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: gherkin
18
- requirement: &70306015799560 !ruby/object:Gem::Requirement
18
+ requirement: &70223546997620 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
@@ -23,10 +23,10 @@ dependencies:
23
23
  version: '0'
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *70306015799560
26
+ version_requirements: *70223546997620
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
- requirement: &70306015799140 !ruby/object:Gem::Requirement
29
+ requirement: &70223546997200 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ! '>='
@@ -34,10 +34,21 @@ dependencies:
34
34
  version: '0'
35
35
  type: :runtime
36
36
  prerelease: false
37
- version_requirements: *70306015799140
37
+ version_requirements: *70223546997200
38
+ - !ruby/object:Gem::Dependency
39
+ name: colorize
40
+ requirement: &70223546996780 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ type: :runtime
47
+ prerelease: false
48
+ version_requirements: *70223546996780
38
49
  - !ruby/object:Gem::Dependency
39
50
  name: purdytest
40
- requirement: &70306015798720 !ruby/object:Gem::Requirement
51
+ requirement: &70223546996360 !ruby/object:Gem::Requirement
41
52
  none: false
42
53
  requirements:
43
54
  - - ! '>='
@@ -45,10 +56,10 @@ dependencies:
45
56
  version: '0'
46
57
  type: :development
47
58
  prerelease: false
48
- version_requirements: *70306015798720
59
+ version_requirements: *70223546996360
49
60
  - !ruby/object:Gem::Dependency
50
61
  name: rake
51
- requirement: &70306015798300 !ruby/object:Gem::Requirement
62
+ requirement: &70223546995940 !ruby/object:Gem::Requirement
52
63
  none: false
53
64
  requirements:
54
65
  - - ! '>='
@@ -56,10 +67,32 @@ dependencies:
56
67
  version: '0'
57
68
  type: :development
58
69
  prerelease: false
59
- version_requirements: *70306015798300
70
+ version_requirements: *70223546995940
60
71
  - !ruby/object:Gem::Dependency
61
72
  name: mocha
62
- requirement: &70306015828840 !ruby/object:Gem::Requirement
73
+ requirement: &70223546995520 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: *70223546995520
82
+ - !ruby/object:Gem::Dependency
83
+ name: sinatra
84
+ requirement: &70223546995100 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: *70223546995100
93
+ - !ruby/object:Gem::Dependency
94
+ name: capybara
95
+ requirement: &70223546994680 !ruby/object:Gem::Requirement
63
96
  none: false
64
97
  requirements:
65
98
  - - ! '>='
@@ -67,7 +100,7 @@ dependencies:
67
100
  version: '0'
68
101
  type: :development
69
102
  prerelease: false
70
- version_requirements: *70306015828840
103
+ version_requirements: *70223546994680
71
104
  description: Spinach is a BDD framework on top of gherkin
72
105
  email:
73
106
  - info@codegram.com
@@ -79,6 +112,7 @@ files:
79
112
  - .gitignore
80
113
  - .rvmrc
81
114
  - Gemfile
115
+ - Guardfile
82
116
  - Rakefile
83
117
  - Readme.md
84
118
  - bin/spinach
@@ -86,17 +120,21 @@ files:
86
120
  - examples/user_logs_in.feature
87
121
  - examples/user_logs_in.rb
88
122
  - lib/spinach.rb
123
+ - lib/spinach/capybara.rb
89
124
  - lib/spinach/config.rb
90
125
  - lib/spinach/dsl.rb
91
126
  - lib/spinach/feature.rb
92
127
  - lib/spinach/parser.rb
128
+ - lib/spinach/reporter.rb
93
129
  - lib/spinach/runner.rb
94
130
  - lib/spinach/version.rb
95
131
  - spinach.gemspec
132
+ - test/spinach/capybara_test.rb
96
133
  - test/spinach/config_test.rb
97
134
  - test/spinach/dsl_test.rb
98
135
  - test/spinach/feature_test.rb
99
136
  - test/spinach/parser_test.rb
137
+ - test/spinach/reporter_test.rb
100
138
  - test/spinach/runner_test.rb
101
139
  - test/spinach_test.rb
102
140
  - test/test_helper.rb
@@ -125,10 +163,12 @@ signing_key:
125
163
  specification_version: 3
126
164
  summary: Spinach is a BDD framework on top of gherkin
127
165
  test_files:
166
+ - test/spinach/capybara_test.rb
128
167
  - test/spinach/config_test.rb
129
168
  - test/spinach/dsl_test.rb
130
169
  - test/spinach/feature_test.rb
131
170
  - test/spinach/parser_test.rb
171
+ - test/spinach/reporter_test.rb
132
172
  - test/spinach/runner_test.rb
133
173
  - test/spinach_test.rb
134
174
  - test/test_helper.rb