nimboids-spork 0.8.99

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/Gemfile +6 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +129 -0
  4. data/assets/bootstrap.rb +29 -0
  5. data/bin/spork +20 -0
  6. data/ext/mkrf_conf.rb +26 -0
  7. data/features/at_exit_during_each_run.feature +36 -0
  8. data/features/cucumber_rails_integration.feature +107 -0
  9. data/features/diagnostic_mode.feature +41 -0
  10. data/features/gemfiles/rails3.0/Gemfile +10 -0
  11. data/features/gemfiles/rails3.0/Gemfile.lock +116 -0
  12. data/features/rails_delayed_loading_workarounds.feature +150 -0
  13. data/features/rspec_rails_integration.feature +92 -0
  14. data/features/spork_debugger.feature +108 -0
  15. data/features/steps/general_steps.rb +3 -0
  16. data/features/steps/rails_steps.rb +67 -0
  17. data/features/steps/sandbox_steps.rb +115 -0
  18. data/features/support/background_job.rb +63 -0
  19. data/features/support/bundler_helpers.rb +41 -0
  20. data/features/support/env.rb +105 -0
  21. data/features/unknown_app_framework.feature +42 -0
  22. data/lib/spork.rb +155 -0
  23. data/lib/spork/app_framework.rb +80 -0
  24. data/lib/spork/app_framework/padrino.rb +22 -0
  25. data/lib/spork/app_framework/rails.rb +82 -0
  26. data/lib/spork/app_framework/unknown.rb +6 -0
  27. data/lib/spork/custom_io_streams.rb +25 -0
  28. data/lib/spork/diagnoser.rb +105 -0
  29. data/lib/spork/ext/rails-reloader.rb +14 -0
  30. data/lib/spork/ext/ruby-debug.rb +150 -0
  31. data/lib/spork/forker.rb +71 -0
  32. data/lib/spork/run_strategy.rb +44 -0
  33. data/lib/spork/run_strategy/forking.rb +32 -0
  34. data/lib/spork/run_strategy/magazine.rb +141 -0
  35. data/lib/spork/run_strategy/magazine/magazine_slave.rb +30 -0
  36. data/lib/spork/run_strategy/magazine/magazine_slave_provider.rb +27 -0
  37. data/lib/spork/run_strategy/magazine/ring_server.rb +10 -0
  38. data/lib/spork/runner.rb +90 -0
  39. data/lib/spork/server.rb +76 -0
  40. data/lib/spork/test_framework.rb +167 -0
  41. data/lib/spork/test_framework/cucumber.rb +24 -0
  42. data/lib/spork/test_framework/rspec.rb +14 -0
  43. data/spec/spec_helper.rb +113 -0
  44. data/spec/spork/app_framework/rails_spec.rb +22 -0
  45. data/spec/spork/app_framework/unknown_spec.rb +12 -0
  46. data/spec/spork/app_framework_spec.rb +16 -0
  47. data/spec/spork/diagnoser_spec.rb +105 -0
  48. data/spec/spork/forker_spec.rb +44 -0
  49. data/spec/spork/run_strategy/forking_spec.rb +38 -0
  50. data/spec/spork/runner_spec.rb +50 -0
  51. data/spec/spork/server_spec.rb +15 -0
  52. data/spec/spork/test_framework/cucumber_spec.rb +11 -0
  53. data/spec/spork/test_framework/rspec_spec.rb +10 -0
  54. data/spec/spork/test_framework_shared_examples.rb +23 -0
  55. data/spec/spork/test_framework_spec.rb +90 -0
  56. data/spec/spork_spec.rb +153 -0
  57. data/spec/support/fake_framework.rb +15 -0
  58. data/spec/support/fake_run_strategy.rb +21 -0
  59. metadata +158 -0
@@ -0,0 +1,150 @@
1
+ Feature: Rails Delayed Work arounds
2
+ To allow a rails developer to update as many parts of his application as possible without needing to restart Spork
3
+ Spork automatically tells rails to delay loading certain parts of the application until after the fork occurs
4
+
5
+ Background: Rails App with RSpec and Spork
6
+
7
+ Given I am in a fresh rails project named "test_rails_project"
8
+ And a file named "spec/spec_helper.rb" with:
9
+ """
10
+ require 'rubygems'
11
+ require 'spork'
12
+ require 'spork/ext/ruby-debug'
13
+
14
+ Spork.prefork do
15
+ require File.dirname(__FILE__) + '/../config/environment.rb'
16
+ require 'rspec'
17
+ require 'rspec/rails'
18
+ end
19
+
20
+ Spork.each_run do
21
+ end
22
+ """
23
+ And the application has a model, observer, route, and application helper
24
+
25
+ Given the following code appears in "config/routes.rb" after /routes\.draw/:
26
+ """
27
+ resources :users
28
+ """
29
+ Given a file named "app/helpers/application_helper.rb" with:
30
+ """
31
+ require 'reverseatron'
32
+ module ApplicationHelper
33
+ include Reverseatron
34
+ end
35
+ """
36
+ Given a file named "lib/reverseatron.rb" with:
37
+ """
38
+ module Reverseatron
39
+ def reverse_text(txt)
40
+ txt.reverse
41
+ end
42
+ end
43
+ """
44
+ Given a file named "app/controllers/users_controller.rb" with:
45
+ """
46
+ class UsersController < ApplicationController
47
+ $loaded_stuff << 'UsersController'
48
+ def index
49
+ @users = []
50
+ end
51
+ end
52
+ """
53
+ Given a file named "app/helpers/misc_helper.rb" with:
54
+ """
55
+ module MiscHelper
56
+ def misc_helper_method
57
+ 'hello miscellaneous'
58
+ end
59
+ end
60
+ """
61
+ Given a file named "app/helpers/users_helper.rb" with:
62
+ """
63
+ module UsersHelper
64
+ end
65
+ """
66
+ Given a file named "app/views/users/index.html.erb" with:
67
+ """
68
+ Original View
69
+ """
70
+ Scenario: within a view rendered by a controller, calling helper methods from an included module in ApplicationHelper
71
+ Given a file named "spec/controllers/users_controller_spec.rb" with:
72
+ """
73
+ require "spec_helper"
74
+ describe UsersController do
75
+ render_views
76
+ it "renders a page, using a method inherited from ApplicationController" do
77
+ get :index
78
+ response.body.should_not include('Original View')
79
+ puts "Views are not being cached when rendering from a controller"
80
+
81
+ response.body.should include('listing users')
82
+ puts "Controller stack is functioning when rendering from a controller"
83
+
84
+ response.body.should include('hello miscellaneous')
85
+ puts "All helper modules were included when rendering from a controller"
86
+ end
87
+ end
88
+ """
89
+ Given a file named "spec/views/index.html.erb_spec.rb" with:
90
+ """
91
+ require "spec_helper"
92
+ describe "/users/index.html.erb" do
93
+
94
+ it "renders the view" do
95
+ render
96
+ rendered.should_not include('Original View')
97
+ puts "Views are not being cached when rendering directly"
98
+
99
+ rendered.should include('listing users')
100
+ puts "Controller stack is functioning when rendering directly"
101
+
102
+ rendered.should include('hello miscellaneous')
103
+ puts "All helper modules were included when rendering directly"
104
+ end
105
+ end
106
+ """
107
+ When I fire up a spork instance with "spork rspec"
108
+ And the contents of "app/views/users/index.html.erb" are changed to:
109
+ """
110
+ <%= reverse_text('listing users'.reverse) %>
111
+ <%= misc_helper_method rescue nil %>
112
+ <p>Here is a list of users</p>
113
+ """
114
+
115
+ And I run rspec --drb spec/controllers/users_controller_spec.rb
116
+ Then the output should contain "Controller stack is functioning when rendering from a controller"
117
+ And the output should contain "Views are not being cached when rendering from a controller"
118
+ And the output should contain "All helper modules were included when rendering from a controller"
119
+
120
+ When I run rspec --drb spec/views/index.html.erb_spec.rb
121
+ Then the output should contain "Controller stack is functioning when rendering directly"
122
+ And the output should contain "Views are not being cached when rendering directly"
123
+ And the output should contain "All helper modules were included when rendering directly"
124
+
125
+ Given the contents of "app/helpers/application_helper.rb" are changed to:
126
+ """
127
+ module ApplicationHelper
128
+ def make_it_loud(message)
129
+ message.upcase
130
+ end
131
+ end
132
+ """
133
+ And the contents of "app/views/users/index.html.erb" are changed to:
134
+ """
135
+ <%= make_it_loud('listing users') %>
136
+ """
137
+ And the contents of "spec/controllers/users_controller_spec.rb" are changed to:
138
+ """
139
+ require "spec_helper"
140
+ describe UsersController do
141
+ render_views
142
+ it "renders a page, using a method inherited from ApplicationController" do
143
+ get :index
144
+ response.body.should include('LISTING USERS')
145
+ puts "Helpers aren't being cached"
146
+ end
147
+ end
148
+ """
149
+ When I run rspec --drb spec/controllers/users_controller_spec.rb
150
+ Then the output should contain "Helpers aren't being cached"
@@ -0,0 +1,92 @@
1
+ Feature: Rails Integration
2
+ To get a developer up and running quickly
3
+ Spork automatically integrates with rails
4
+ Providing default hooks and behaviors
5
+
6
+ Background: Rails App with RSpec and Spork
7
+ Given I am in a fresh rails project named "test_rails_project"
8
+ And a file named "spec/spec_helper.rb" with:
9
+ """
10
+ require 'rubygems'
11
+ require 'spork'
12
+
13
+ Spork.prefork do
14
+ # Loading more in this block will cause your specs to run faster. However,
15
+ # if you change any configuration or code from libraries loaded here, you'll
16
+ # need to restart spork for it take effect.
17
+ require File.dirname(__FILE__) + '/../config/environment.rb'
18
+ require 'rspec'
19
+ require 'rspec/rails'
20
+
21
+ #### this is for this test only #######
22
+ $loaded_stuff << 'prefork block' ######
23
+ #######################################
24
+ end
25
+
26
+ Spork.each_run do
27
+ # This code will be run each time you run your specs.
28
+
29
+ #### this is for this test only #######
30
+ $loaded_stuff << 'each_run block' #####
31
+ #######################################
32
+ end
33
+ """
34
+ And the application has a model, observer, route, and application helper
35
+ Scenario: Analyzing files were preloaded
36
+ When I run spork --diagnose
37
+ Then the output should not contain "user_observer.rb"
38
+ Then the output should not contain "user.rb"
39
+ Then the output should not contain "app/controllers/application.rb"
40
+ Then the output should not contain "app/controllers/application_controller.rb"
41
+ Then the output should not contain "app/controllers/application_helper.rb"
42
+ # Then the output should not contain "config/routes.rb"
43
+
44
+ Scenario: Running spork with a rails app and observers
45
+ Given a file named "spec/did_it_work_spec.rb" with:
46
+ """
47
+ require 'spec_helper'
48
+ describe "Did it work?" do
49
+ it "checks to see if all worked" do
50
+ Spork.using_spork?.should == true
51
+ (Rails.respond_to?(:logger) ? Rails.logger : ActionController::Base.logger).info "hey there"
52
+ $loaded_stuff.should include('ActiveRecord::Base.establish_connection')
53
+ $loaded_stuff.should include('User')
54
+ $loaded_stuff.should include('UserObserver')
55
+ $loaded_stuff.should include('ApplicationHelper')
56
+ $loaded_stuff.should include('config/routes.rb')
57
+ $loaded_stuff.should include('each_run block')
58
+ $loaded_stuff.should include('prefork block')
59
+ puts "Specs successfully run within spork, and all initialization files were loaded"
60
+ end
61
+ end
62
+ """
63
+ When I fire up a spork instance with "spork rspec"
64
+ And I run rspec --drb spec/did_it_work_spec.rb
65
+ Then the error output should be empty
66
+ And the output should contain "Specs successfully run within spork, and all initialization files were loaded"
67
+ And the file "log/test.log" should include "hey there"
68
+
69
+
70
+ Scenario: Running spork with a rails app and a non-standard port
71
+ Given a file named "spec/did_it_work_spec.rb" with:
72
+ """
73
+ describe "Did it work?" do
74
+ it "checks to see if all worked" do
75
+ Spork.using_spork?.should == true
76
+ (Rails.respond_to?(:logger) ? Rails.logger : ActionController::Base.logger).info "hey there"
77
+ $loaded_stuff.should include('ActiveRecord::Base.establish_connection')
78
+ $loaded_stuff.should include('User')
79
+ $loaded_stuff.should include('UserObserver')
80
+ $loaded_stuff.should include('ApplicationHelper')
81
+ $loaded_stuff.should include('config/routes.rb')
82
+ $loaded_stuff.should include('each_run block')
83
+ $loaded_stuff.should include('prefork block')
84
+ puts "Specs successfully run within spork, and all initialization files were loaded"
85
+ end
86
+ end
87
+ """
88
+ When I fire up a spork instance with "spork rspec --port 7000"
89
+ And I run rspec --drb --drb-port 7000 spec/did_it_work_spec.rb
90
+ Then the error output should be empty
91
+ And the output should contain "Specs successfully run within spork, and all initialization files were loaded"
92
+ And the file "log/test.log" should include "hey there"
@@ -0,0 +1,108 @@
1
+ Feature: Spork Debugger integration
2
+ As a developer
3
+ I want to invoke the debugger my specs within Spork
4
+ In order to drill in and figure out what's wrong
5
+
6
+ Scenario: Invoking the debugger via 'debugger'
7
+ Given a file named "spec/spec_helper.rb" with:
8
+ """
9
+ require 'rubygems'
10
+ require 'spork'
11
+ require 'spork/ext/ruby-debug'
12
+
13
+ Spork.prefork { require 'rspec' }
14
+ Spork.each_run { }
15
+ """
16
+ And a file named "spec/debugger_spec.rb" with:
17
+ """
18
+ require 'spec_helper.rb'
19
+
20
+ describe "Debugger" do
21
+ it "should debug" do
22
+ 2.times do |count|
23
+ @message = "count = #{count}"
24
+ debugger
25
+ @message = nil
26
+ end
27
+ puts "it worked!"
28
+ end
29
+ end
30
+ """
31
+
32
+ When I fire up a spork instance with "spork rspec"
33
+ And I run this in the background: rspec --drb spec/debugger_spec.rb
34
+
35
+ Then the spork window should output a line containing "Debug Session Started"
36
+
37
+ When I type this in the spork window: "e @message"
38
+ Then the spork window should output a line containing "count = 0"
39
+
40
+ When I type this in the spork window: "continue"
41
+
42
+ When I type this in the spork window: "e @message"
43
+ Then the spork window should output a line containing "count = 1"
44
+
45
+ When I type this in the spork window: "continue"
46
+
47
+ Then the spork window should output a line containing "Debug Session Terminated"
48
+ And the output should contain "it worked!"
49
+
50
+ Scenario: When ruby-debug is already required and started.
51
+ Given a file named "spec/spec_helper.rb" with:
52
+ """
53
+ require 'rubygems'
54
+ require 'spork'
55
+ require 'ruby-debug'
56
+ Debugger.start
57
+
58
+ require 'spork/ext/ruby-debug'
59
+
60
+ Spork.prefork { require 'rspec' }
61
+ Spork.each_run { }
62
+ """
63
+
64
+ And a file named "spec/debugger_spec.rb" with:
65
+ """
66
+ require File.dirname(__FILE__) + '/spec_helper.rb'
67
+
68
+ describe "Debugger" do
69
+ it "should debug" do
70
+ @message = "yup"
71
+ debugger
72
+ puts "it worked!"
73
+ end
74
+ end
75
+ """
76
+
77
+ When I fire up a spork instance with "spork rspec"
78
+ And I run this in the background: rspec --drb spec/debugger_spec.rb
79
+
80
+ Then the spork window should output a line containing "Debug Session Started"
81
+
82
+ When I type this in the spork window: "e @message"
83
+ Then the spork window should output a line containing "yup"
84
+
85
+ When I type this in the spork window: "continue"
86
+
87
+ Then the spork window should output a line containing "Debug Session Terminated"
88
+ And the output should contain "it worked!"
89
+
90
+ Scenario: When ruby-debug is invoked during preload
91
+ Given a file named "spec/spec_helper.rb" with:
92
+ """
93
+ require 'rubygems'
94
+ require 'spork'
95
+ require 'spork/ext/ruby-debug'
96
+
97
+ STDERR.puts("Spork is ready and listening") # trick out the start spork step to believe spork is ready... naughty, but effective.
98
+ @message = "it worked"
99
+ debugger
100
+ Spork.prefork { require 'rspec' }
101
+ Spork.each_run { }
102
+ """
103
+
104
+ When I fire up a spork instance with "spork rspec"
105
+ Then the spork window should output a line containing "spec_helper.rb"
106
+ When I type this in the spork window: "e @message"
107
+ Then the spork window should output a line containing "it worked"
108
+ When I type this in the spork window: "continue"
@@ -0,0 +1,3 @@
1
+ Given /^this scenario is pending.+/ do
2
+ pending
3
+ end
@@ -0,0 +1,67 @@
1
+ Given /^I am in a fresh rails project named "(.+)"$/ do |folder_name|
2
+ @current_dir = SporkWorld::SANDBOX_DIR
3
+ # version_argument = ENV['RAILS_VERSION'] ? "_#{ENV['RAILS_VERSION']}_" : nil
4
+ # run("#{SporkWorld::RUBY_BINARY} #{%x{which rails}.chomp} #{folder_name}")
5
+ run(["rails", "new", folder_name].compact * " ")
6
+
7
+ if last_exit_status != 0
8
+ puts "Couldn't generate project. Output:\nSTDERR:\n-------\n#{last_stderr}\n------\n\nSTDOUT:\n-------\n#{last_stdout}\n\n"
9
+ last_exit_status.should == 0
10
+ end
11
+ @current_dir = File.join(File.join(SporkWorld::SANDBOX_DIR, folder_name))
12
+ in_current_dir do
13
+ FileUtils.ln_sf(ENV["BUNDLE_GEMFILE"], "Gemfile")
14
+ FileUtils.ln_sf(ENV["BUNDLE_GEMFILE"] + ".lock", "Gemfile.lock")
15
+ FileUtils.ln_sf(File.dirname(ENV["BUNDLE_GEMFILE"]) + "/.bundle", ".bundle")
16
+ end
17
+ end
18
+
19
+
20
+ Given "the application has a model, observer, route, and application helper" do
21
+ Given 'the following code appears in "config/application.rb" after /^end/:',
22
+ """
23
+ ActiveRecord::Base.observers = [:user_observer]
24
+ """
25
+ Given 'a file named "app/models/user.rb" with:',
26
+ """
27
+ class User < ActiveRecord::Base
28
+ $loaded_stuff << 'User'
29
+ end
30
+ """
31
+ Given 'a file named "app/models/user_observer.rb" with:',
32
+ """
33
+ class UserObserver < ActiveRecord::Observer
34
+ $loaded_stuff << 'UserObserver'
35
+ end
36
+ """
37
+ Given 'a file named "app/helpers/application_helper.rb" with:',
38
+ """
39
+ module ApplicationHelper
40
+ $loaded_stuff << 'ApplicationHelper'
41
+ end
42
+ """
43
+ Given 'the following code appears in "config/environment.rb" after /Rails::Initializer.run/:',
44
+ """
45
+ config.active_record.observers = :user_observer
46
+ """
47
+ Given 'the following code appears in "config/routes.rb" after /^end/:',
48
+ """
49
+ $loaded_stuff << 'config/routes.rb'
50
+ """
51
+ Given 'a file named "config/initializers/initialize_loaded_stuff.rb" with:',
52
+ """
53
+ $loaded_stuff ||= []
54
+ """
55
+ Given 'a file named "config/initializers/log_establish_connection_calls.rb" with:',
56
+ """
57
+ class ActiveRecord::Base
58
+ class << self
59
+ def establish_connection_with_load_logging(*args)
60
+ $loaded_stuff << 'ActiveRecord::Base.establish_connection'
61
+ establish_connection_without_load_logging(*args)
62
+ end
63
+ alias_method_chain :establish_connection, :load_logging
64
+ end
65
+ end
66
+ """
67
+ end
@@ -0,0 +1,115 @@
1
+ Given /^I am in the directory "(.*)"$/ do |sandbox_dir_relative_path|
2
+ path = File.join(SporkWorld::SANDBOX_DIR, sandbox_dir_relative_path)
3
+ FileUtils.mkdir_p(path)
4
+ @current_dir = File.join(path)
5
+ end
6
+
7
+ Given /^a file named "([^\"]*)"$/ do |file_name|
8
+ create_file(file_name, '')
9
+ end
10
+
11
+ Given /^a file named "([^\"]*)" with:$/ do |file_name, file_content|
12
+ create_file(file_name, file_content)
13
+ end
14
+
15
+ When /^the contents of "([^\"]*)" are changed to:$/ do |file_name, file_content|
16
+ create_file(file_name, file_content)
17
+ end
18
+
19
+ # the following code appears in "config/environment.rb" after /Rails::Initializer.run/:
20
+ Given /^the following code appears in "([^\"]*)" after \/([^\/]*)\/:$/ do |file_name, regex, content|
21
+ regex = Regexp.new(regex)
22
+ in_current_dir do
23
+ content_lines = File.read(file_name).split("\n")
24
+ 0.upto(content_lines.length - 1) do |line_index|
25
+ if regex.match(content_lines[line_index])
26
+ content_lines.insert(line_index + 1, content)
27
+ break
28
+ end
29
+ end
30
+ File.open(file_name, 'wb') { |f| f << (content_lines * "\n") }
31
+ end
32
+ end
33
+
34
+ When /^I run (spork|rspec|cucumber)(| .*)$/ do |command, args|
35
+ run("#{command} #{args}")
36
+ end
37
+
38
+ When /^I run this in the background: (spork|rspec|cucumber)(| .*)$/ do |command, args|
39
+ @background_script = run_in_background("#{command} #{args}")
40
+ end
41
+
42
+ When /^I fire up a spork instance with "spork(.*)"$/ do |spork_opts|
43
+ @spork_server = run_in_background("#{SporkWorld::RUBY_BINARY} -I #{Cucumber::LIBDIR} #{SporkWorld::BINARY} #{spork_opts}")
44
+
45
+ output = ""
46
+ begin
47
+ status = Timeout::timeout(15) do
48
+ # Something that should be interrupted if it takes too much time...
49
+ while line = @spork_server.stderr.gets
50
+ output << line
51
+ puts line
52
+ break if line.include?("Spork is ready and listening")
53
+ end
54
+ end
55
+ rescue Timeout::Error
56
+ puts "I can't seem to launch Spork properly. Output was:\n#{output}"
57
+ true.should == false
58
+ end
59
+ end
60
+
61
+ Then /^the spork window should output a line containing "(.+)"/ do |expected|
62
+ output = ""
63
+ begin
64
+ status = Timeout::timeout(5) do
65
+ # Something that should be interrupted if it takes too much time...
66
+ while line = @spork_server.stdout.gets
67
+ output << line
68
+ puts line
69
+ break if output.include?(expected)
70
+ end
71
+ end
72
+ rescue Timeout::Error
73
+ output.should include(expected)
74
+ end
75
+ end
76
+
77
+ When /^I type this in the spork window: "(.+)"/ do |line|
78
+ @spork_server.stdin.puts(line)
79
+ @spork_server.stdin.flush
80
+ end
81
+
82
+
83
+ Then /^the file "([^\"]*)" should include "([^\"]*)"$/ do |filename, content|
84
+ in_current_dir do
85
+ File.read(filename).should include(content)
86
+ end
87
+ end
88
+
89
+ Then /^the (error output|output) should contain$/ do |which, text|
90
+ (which == "error output" ? last_stderr : last_stdout).should include(text)
91
+ end
92
+
93
+ Then /^the (error output|output) should contain "(.+)"$/ do |which, text|
94
+ (which == "error output" ? last_stderr : last_stdout).should include(text)
95
+ end
96
+
97
+ Then /^the (error output|output) should match \/(.+)\/$/ do |which, regex|
98
+ (which == "error output" ? last_stderr : last_stdout).should match(Regexp.new(regex))
99
+ end
100
+
101
+ Then /^the (error output|output) should not contain$/ do |which, text|
102
+ (which == "error output" ? last_stderr : last_stdout).should_not include(text)
103
+ end
104
+
105
+ Then /^the (error output|output) should not contain "(.+)"$/ do |which, text|
106
+ (which == "error output" ? last_stderr : last_stdout).should_not include(text)
107
+ end
108
+
109
+ Then /^the (error output|output) should be empty$/ do |which|
110
+ (which == "error output" ? last_stderr : last_stdout).should == ""
111
+ end
112
+
113
+ Then /^the (error output|output) should be$/ do |which, text|
114
+ (which == "error output" ? last_stderr : last_stdout).should == text
115
+ end