bmabey-spork 0.4.4 → 0.5.9
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +51 -23
- data/assets/bootstrap.rb +1 -1
- data/bin/spork +0 -0
- data/features/cucumber_rails_integration.feature +113 -0
- data/features/diagnostic_mode.feature +41 -0
- data/features/rails_delayed_loading_workarounds.feature +80 -0
- data/features/rspec_rails_integration.feature +90 -0
- data/features/steps/rails_steps.rb +53 -0
- data/features/steps/sandbox_steps.rb +98 -0
- data/features/support/env.rb +98 -0
- data/features/unknown_app_framework.feature +42 -0
- data/lib/spork.rb +85 -26
- data/lib/spork/app_framework.rb +74 -0
- data/lib/spork/app_framework/rails.rb +158 -0
- data/lib/spork/app_framework/rails_stub_files/application.rb +3 -0
- data/lib/spork/app_framework/rails_stub_files/application_controller.rb +3 -0
- data/lib/spork/app_framework/rails_stub_files/application_helper.rb +3 -0
- data/lib/spork/app_framework/unknown.rb +6 -0
- data/lib/spork/custom_io_streams.rb +25 -0
- data/lib/spork/diagnoser.rb +103 -0
- data/lib/spork/forker.rb +70 -0
- data/lib/spork/runner.rb +28 -10
- data/lib/spork/server.rb +88 -46
- data/lib/spork/server/cucumber.rb +21 -9
- data/lib/spork/server/rspec.rb +1 -1
- data/spec/spec_helper.rb +93 -35
- data/spec/spork/app_framework/rails_spec.rb +22 -0
- data/spec/spork/app_framework/unknown_spec.rb +12 -0
- data/spec/spork/app_framework_spec.rb +16 -0
- data/spec/spork/diagnoser_spec.rb +105 -0
- data/spec/spork/forker_spec.rb +44 -0
- data/spec/spork/runner_spec.rb +2 -2
- data/spec/spork/server/cucumber_spec.rb +25 -0
- data/spec/spork/server/rspec_spec.rb +17 -3
- data/spec/spork/server_spec.rb +32 -17
- data/spec/spork_spec.rb +112 -13
- metadata +33 -3
@@ -0,0 +1,25 @@
|
|
1
|
+
# This class is mainly used for testing.
|
2
|
+
# When included (and used), it gives us an opportunity to stub out the output streams used for a given class
|
3
|
+
module Spork::CustomIOStreams
|
4
|
+
def self.included(klass)
|
5
|
+
klass.send(:extend, ::Spork::CustomIOStreams::ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
def stderr
|
9
|
+
self.class.stderr
|
10
|
+
end
|
11
|
+
|
12
|
+
def stdout
|
13
|
+
self.class.stdout
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
def stderr
|
18
|
+
$stderr
|
19
|
+
end
|
20
|
+
|
21
|
+
def stdout
|
22
|
+
$stdout
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# The Diagnoser hooks into load and require and keeps track of when files are required / loaded, and who loaded them.
|
2
|
+
# It's used when you run spork --diagnose
|
3
|
+
#
|
4
|
+
# = Example
|
5
|
+
#
|
6
|
+
# Spork::Diagnoser.install_hook!('/path/env.rb', '/path')
|
7
|
+
# require '/path/to/env.rb'
|
8
|
+
# Spork::Diagnoser.output_results(STDOUT)
|
9
|
+
class Spork::Diagnoser
|
10
|
+
class << self
|
11
|
+
def loaded_files
|
12
|
+
@loaded_files ||= {}
|
13
|
+
end
|
14
|
+
|
15
|
+
# Installs the diagnoser hook into Kernel#require and Kernel#load
|
16
|
+
#
|
17
|
+
# == Parameters
|
18
|
+
#
|
19
|
+
# * +entry_file+ - The file that is used to load the project. Used to filter the backtrace so anything that happens after it is hidden.
|
20
|
+
# * +dir+ - The project directory. Any file loaded outside of this directory will not be logged.
|
21
|
+
def install_hook!(entry_file = nil, dir = Dir.pwd)
|
22
|
+
@dir = File.expand_path(Dir.pwd, dir)
|
23
|
+
@entry_file = entry_file
|
24
|
+
|
25
|
+
Kernel.class_eval do
|
26
|
+
alias :require_without_diagnoser :require
|
27
|
+
alias :load_without_diagnoser :load
|
28
|
+
|
29
|
+
def require(string)
|
30
|
+
::Spork::Diagnoser.add_included_file(string, caller)
|
31
|
+
require_without_diagnoser(string)
|
32
|
+
end
|
33
|
+
|
34
|
+
def load(string)
|
35
|
+
::Spork::Diagnoser.add_included_file(string, caller)
|
36
|
+
load_without_diagnoser(string)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_included_file(filename, callstack)
|
42
|
+
filename = expand_filename(filename)
|
43
|
+
return unless File.exist?(filename)
|
44
|
+
loaded_files[filename] = filter_callstack(caller) if subdirectory?(filename)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Uninstall the hook. Generally useful only for testing the Diagnoser.
|
48
|
+
def remove_hook!
|
49
|
+
return unless Kernel.private_instance_methods.include?('require_without_diagnoser')
|
50
|
+
Kernel.class_eval do
|
51
|
+
alias :require :require_without_diagnoser
|
52
|
+
alias :load :load_without_diagnoser
|
53
|
+
|
54
|
+
undef_method(:require_without_diagnoser)
|
55
|
+
undef_method(:load_without_diagnoser)
|
56
|
+
end
|
57
|
+
true
|
58
|
+
end
|
59
|
+
|
60
|
+
# output the results of a diagnostic run.
|
61
|
+
#
|
62
|
+
# == Parameters
|
63
|
+
#
|
64
|
+
# * +stdout+ - An IO stream to output the results to.
|
65
|
+
def output_results(stdout)
|
66
|
+
project_prefix = Dir.pwd + "/"
|
67
|
+
minimify = lambda { |f| f.gsub(project_prefix, '')}
|
68
|
+
stdout.puts "- Spork Diagnosis -\n"
|
69
|
+
stdout.puts "-- Summary --"
|
70
|
+
stdout.puts loaded_files.keys.sort.map(&minimify)
|
71
|
+
stdout.puts "\n\n\n"
|
72
|
+
stdout.puts "-- Detail --"
|
73
|
+
loaded_files.keys.sort.each do |file|
|
74
|
+
stdout.puts "\n\n\n--- #{minimify.call(file)} ---\n"
|
75
|
+
stdout.puts loaded_files[file].map(&minimify)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
def filter_callstack(callstack, entry_file = @entry_file)
|
81
|
+
callstack.pop until callstack.empty? || callstack.last.include?(@entry_file) if @entry_file
|
82
|
+
callstack.map do |line|
|
83
|
+
next if line.include?('lib/spork/diagnoser.rb')
|
84
|
+
line.gsub!('require_without_diagnoser', 'require')
|
85
|
+
line
|
86
|
+
end.compact
|
87
|
+
end
|
88
|
+
|
89
|
+
def expand_filename(filename)
|
90
|
+
([Dir.pwd] + $:).each do |attempted_path|
|
91
|
+
attempted_filename = File.expand_path(filename, attempted_path)
|
92
|
+
return attempted_filename if File.file?(attempted_filename)
|
93
|
+
attempted_filename = attempted_filename + ".rb"
|
94
|
+
return attempted_filename if File.file?(attempted_filename)
|
95
|
+
end
|
96
|
+
filename
|
97
|
+
end
|
98
|
+
|
99
|
+
def subdirectory?(directory)
|
100
|
+
File.expand_path(directory, Dir.pwd).include?(@dir)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/spork/forker.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# A helper class that allows you to run a block inside of a fork, and then get the result from that block.
|
2
|
+
#
|
3
|
+
# == Example:
|
4
|
+
#
|
5
|
+
# forker = Spork::Forker.new do
|
6
|
+
# sleep 3
|
7
|
+
# "success"
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# forker.result # => "success"
|
11
|
+
class Spork::Forker
|
12
|
+
|
13
|
+
# Raised if the fork died (was killed) before it sent it's response back.
|
14
|
+
class ForkDiedException < Exception; end
|
15
|
+
def initialize(&block)
|
16
|
+
return unless block_given?
|
17
|
+
@child_io, @server_io = UNIXSocket.socketpair
|
18
|
+
@child_pid = Kernel.fork do
|
19
|
+
@server_io.close
|
20
|
+
Marshal.dump(yield, @child_io)
|
21
|
+
# wait for the parent to acknowledge receipt of the result.
|
22
|
+
master_response =
|
23
|
+
begin
|
24
|
+
Marshal.load(@child_io)
|
25
|
+
rescue EOFError
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
# terminate, skipping any at_exit blocks.
|
30
|
+
exit!(0)
|
31
|
+
end
|
32
|
+
@child_io.close
|
33
|
+
end
|
34
|
+
|
35
|
+
# Wait for the fork to finish running, and then return its return value.
|
36
|
+
#
|
37
|
+
# If the fork was aborted, then result returns nil.
|
38
|
+
def result
|
39
|
+
return unless running?
|
40
|
+
result_thread = Thread.new do
|
41
|
+
begin
|
42
|
+
@result = Marshal.load(@server_io)
|
43
|
+
Marshal.dump('ACK', @server_io)
|
44
|
+
rescue ForkDiedException
|
45
|
+
@result = nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
Process.wait(@child_pid)
|
49
|
+
result_thread.raise(ForkDiedException) if @result.nil?
|
50
|
+
@child_pid = nil
|
51
|
+
@result
|
52
|
+
end
|
53
|
+
|
54
|
+
# abort the current running fork
|
55
|
+
def abort
|
56
|
+
if running?
|
57
|
+
Process.kill(Signal.list['TERM'], @child_pid)
|
58
|
+
@child_pid = nil
|
59
|
+
true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def running?
|
64
|
+
return false unless @child_pid
|
65
|
+
Process.getpgid(@child_pid)
|
66
|
+
true
|
67
|
+
rescue Errno::ESRCH
|
68
|
+
false
|
69
|
+
end
|
70
|
+
end
|
data/lib/spork/runner.rb
CHANGED
@@ -2,6 +2,7 @@ require 'optparse'
|
|
2
2
|
require 'spork/server'
|
3
3
|
|
4
4
|
module Spork
|
5
|
+
# This is used by bin/spork. It's wrapped in a class because it's easier to test that way.
|
5
6
|
class Runner
|
6
7
|
attr_reader :server
|
7
8
|
|
@@ -19,7 +20,9 @@ module Spork
|
|
19
20
|
|
20
21
|
opt.separator "Options:"
|
21
22
|
opt.on("-b", "--bootstrap") {|ignore| @options[:bootstrap] = true }
|
23
|
+
opt.on("-d", "--diagnose") {|ignore| @options[:diagnose] = true }
|
22
24
|
opt.on("-h", "--help") {|ignore| @options[:help] = true }
|
25
|
+
opt.on("-p", "--port [PORT]") {|port| @options[:port] = port }
|
23
26
|
non_option_args = args.select { |arg| ! args[0].match(/^-/) }
|
24
27
|
@options[:server_matcher] = non_option_args[0]
|
25
28
|
opt.parse!(args)
|
@@ -41,11 +44,12 @@ module Spork
|
|
41
44
|
text.string
|
42
45
|
end
|
43
46
|
|
47
|
+
# Returns a server for the specified (or the detected default) testing framework. Returns nil if none detected, or if the specified is not supported or available.
|
44
48
|
def find_server
|
45
49
|
if options[:server_matcher]
|
46
50
|
@server = Spork::Server.supported_servers(options[:server_matcher]).first
|
47
51
|
unless @server
|
48
|
-
@
|
52
|
+
@error.puts <<-ERROR
|
49
53
|
#{options[:server_matcher].inspect} didn't match a supported test framework.
|
50
54
|
|
51
55
|
#{supported_servers_text}
|
@@ -54,7 +58,7 @@ module Spork
|
|
54
58
|
end
|
55
59
|
|
56
60
|
unless @server.available?
|
57
|
-
@
|
61
|
+
@error.puts <<-USEFUL_ERROR
|
58
62
|
I can't find the helper file #{@server.helper_file} for the #{@server.server_name} testing framework.
|
59
63
|
Are you running me from the project directory?
|
60
64
|
USEFUL_ERROR
|
@@ -63,7 +67,7 @@ Are you running me from the project directory?
|
|
63
67
|
else
|
64
68
|
@server = Spork::Server.available_servers.first
|
65
69
|
if @server.nil?
|
66
|
-
@
|
70
|
+
@error.puts <<-USEFUL_ERROR
|
67
71
|
I can't find any testing frameworks to use.
|
68
72
|
Are you running me from a project directory?
|
69
73
|
USEFUL_ERROR
|
@@ -76,14 +80,28 @@ Are you running me from a project directory?
|
|
76
80
|
def run
|
77
81
|
return false unless find_server
|
78
82
|
ENV["DRB"] = 'true'
|
79
|
-
|
80
|
-
@
|
81
|
-
|
82
|
-
|
83
|
-
server.run
|
84
|
-
return true
|
85
|
-
end
|
83
|
+
@error.puts "Using #{server.server_name}"
|
84
|
+
@error.flush
|
85
|
+
|
86
|
+
server.port = options[:port]
|
86
87
|
|
88
|
+
case
|
89
|
+
when options[:bootstrap]
|
90
|
+
server.bootstrap
|
91
|
+
when options[:diagnose]
|
92
|
+
require 'spork/diagnoser'
|
93
|
+
|
94
|
+
Spork::Diagnoser.install_hook!(server.entry_point)
|
95
|
+
server.preload
|
96
|
+
Spork::Diagnoser.output_results(@output)
|
97
|
+
return true
|
98
|
+
else
|
99
|
+
return(false) unless server.preload
|
100
|
+
server.run
|
101
|
+
return true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
87
105
|
private
|
88
106
|
attr_reader :options
|
89
107
|
|
data/lib/spork/server.rb
CHANGED
@@ -1,33 +1,41 @@
|
|
1
1
|
require 'drb/drb'
|
2
2
|
require 'rbconfig'
|
3
|
+
require 'spork/forker.rb'
|
4
|
+
require 'spork/custom_io_streams.rb'
|
5
|
+
require 'spork/app_framework.rb'
|
3
6
|
|
4
|
-
#
|
7
|
+
# An abstract class that is implemented to create a server
|
8
|
+
#
|
9
|
+
# (This was originally based off of spec_server.rb from rspec-rails (David Chelimsky), which was based on Florian Weber's TDDMate)
|
5
10
|
class Spork::Server
|
6
11
|
@@supported_servers = []
|
7
12
|
|
8
13
|
LOAD_PREFERENCE = ['RSpec', 'Cucumber']
|
9
14
|
BOOTSTRAP_FILE = File.dirname(__FILE__) + "/../../assets/bootstrap.rb"
|
10
15
|
|
16
|
+
include Spork::CustomIOStreams
|
17
|
+
|
18
|
+
# Abstract method: returns the servers port. Override this to return the port that should be used by the test framework.
|
11
19
|
def self.port
|
12
20
|
raise NotImplemented
|
13
21
|
end
|
14
22
|
|
23
|
+
# Abstract method: returns the entry file that loads the testing environment, such as spec/spec_helper.rb.
|
15
24
|
def self.helper_file
|
16
25
|
raise NotImplemented
|
17
26
|
end
|
18
27
|
|
28
|
+
# Convenience method that turns the class name without the namespace
|
19
29
|
def self.server_name
|
20
30
|
self.name.gsub('Spork::Server::', '')
|
21
31
|
end
|
22
32
|
|
23
|
-
|
24
|
-
@@supported_servers << subclass
|
25
|
-
end
|
26
|
-
|
33
|
+
# Returns a list of all testing servers that have detected their testing framework being used in the project.
|
27
34
|
def self.available_servers
|
28
35
|
supported_servers.select { |s| s.available? }
|
29
36
|
end
|
30
37
|
|
38
|
+
# Returns a list of all servers that have been implemented (it keeps track of them automatically via Class.inherited)
|
31
39
|
def self.supported_servers(starting_with = nil)
|
32
40
|
@@supported_servers.sort! { |a,b| a.load_preference_index <=> b.load_preference_index }
|
33
41
|
return @@supported_servers if starting_with.nil?
|
@@ -36,28 +44,28 @@ class Spork::Server
|
|
36
44
|
end
|
37
45
|
end
|
38
46
|
|
47
|
+
# Returns true if the testing frameworks helper file exists. Override if this is not sufficient to detect your testing framework.
|
39
48
|
def self.available?
|
40
49
|
File.exist?(helper_file)
|
41
50
|
end
|
42
51
|
|
52
|
+
# Used to specify
|
43
53
|
def self.load_preference_index
|
44
54
|
LOAD_PREFERENCE.index(server_name) || LOAD_PREFERENCE.length
|
45
55
|
end
|
46
56
|
|
47
|
-
|
48
|
-
File.exist?("config/environment.rb")
|
49
|
-
end
|
50
|
-
|
57
|
+
# Detects if the test helper has been bootstrapped.
|
51
58
|
def self.bootstrapped?
|
52
59
|
File.read(helper_file).include?("Spork.prefork")
|
53
60
|
end
|
54
61
|
|
62
|
+
# Bootstraps the current test helper file by prepending a Spork.prefork and Spork.each_run block at the beginning.
|
55
63
|
def self.bootstrap
|
56
64
|
if bootstrapped?
|
57
|
-
puts "Already bootstrapped!"
|
65
|
+
stderr.puts "Already bootstrapped!"
|
58
66
|
return
|
59
67
|
end
|
60
|
-
puts "Bootstrapping #{helper_file}."
|
68
|
+
stderr.puts "Bootstrapping #{helper_file}."
|
61
69
|
contents = File.read(helper_file)
|
62
70
|
bootstrap_code = File.read(BOOTSTRAP_FILE)
|
63
71
|
File.open(helper_file, "wb") do |f|
|
@@ -65,7 +73,7 @@ class Spork::Server
|
|
65
73
|
f.puts contents
|
66
74
|
end
|
67
75
|
|
68
|
-
puts "Done. Edit #{helper_file} now with your favorite text editor and follow the instructions."
|
76
|
+
stderr.puts "Done. Edit #{helper_file} now with your favorite text editor and follow the instructions."
|
69
77
|
true
|
70
78
|
end
|
71
79
|
|
@@ -74,65 +82,101 @@ class Spork::Server
|
|
74
82
|
new.listen
|
75
83
|
end
|
76
84
|
|
85
|
+
# Sets up signals and starts the DRb service. If it's successful, it doesn't return. Not ever. You don't need to override this.
|
77
86
|
def listen
|
78
87
|
trap("SIGINT") { sig_int_received }
|
79
88
|
trap("SIGTERM") { abort; exit!(0) }
|
80
89
|
trap("USR2") { abort; restart } if Signal.list.has_key?("USR2")
|
81
90
|
DRb.start_service("druby://127.0.0.1:#{port}", self)
|
82
|
-
puts "Spork is ready and listening on #{port}!"
|
91
|
+
stderr.puts "Spork is ready and listening on #{port}!"
|
92
|
+
stderr.flush
|
83
93
|
DRb.thread.join
|
84
94
|
end
|
85
95
|
|
86
96
|
def port
|
87
|
-
self.class.port
|
97
|
+
self.class.instance_variable_get("@port") || self.class.port
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.port= p
|
101
|
+
@port = p
|
88
102
|
end
|
89
103
|
|
90
104
|
def helper_file
|
91
105
|
self.class.helper_file
|
92
106
|
end
|
93
107
|
|
108
|
+
# This is the public facing method that is served up by DRb. To use it from the client side (in a testing framework):
|
109
|
+
#
|
110
|
+
# DRb.start_service("druby://localhost:0") # this allows Ruby to do some magical stuff so you can pass an output stream over DRb.
|
111
|
+
# # see http://redmine.ruby-lang.org/issues/show/496 to see why localhost:0 is used.
|
112
|
+
# spec_server = DRbObject.new_with_uri("druby://127.0.0.1:8989")
|
113
|
+
# spec_server.run(options.argv, $stderr, $stdout)
|
114
|
+
#
|
115
|
+
# When implementing a test server, don't override this method: override run_tests instead.
|
94
116
|
def run(argv, stderr, stdout)
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
Spork.exec_each_run
|
117
|
+
abort if running?
|
118
|
+
|
119
|
+
@child = ::Spork::Forker.new do
|
120
|
+
$stdout, $stderr = stdout, stderr
|
121
|
+
Spork.exec_each_run { load helper_file }
|
100
122
|
run_tests(argv, stderr, stdout)
|
101
123
|
end
|
102
|
-
|
103
|
-
@child_pid = nil
|
104
|
-
true
|
124
|
+
@child.result
|
105
125
|
end
|
106
126
|
|
127
|
+
# returns whether or not the child (a test run) is running right now.
|
107
128
|
def running?
|
108
|
-
|
129
|
+
@child && @child.running?
|
109
130
|
end
|
110
131
|
|
132
|
+
protected
|
133
|
+
# Abstract method: here is where the server runs the tests.
|
134
|
+
def run_tests(argv, input, output)
|
135
|
+
raise NotImplemented
|
136
|
+
end
|
137
|
+
|
111
138
|
private
|
139
|
+
def self.inherited(subclass)
|
140
|
+
@@supported_servers << subclass
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.framework
|
144
|
+
@framework ||= Spork::AppFramework.detect_framework
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.entry_point
|
148
|
+
bootstrapped? ? helper_file : framework.entry_point
|
149
|
+
end
|
150
|
+
|
112
151
|
def self.preload
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
152
|
+
Spork.exec_prefork do
|
153
|
+
unless bootstrapped?
|
154
|
+
stderr.puts "#{helper_file} has not been bootstrapped. Run spork --bootstrap to do so."
|
155
|
+
stderr.flush
|
156
|
+
|
157
|
+
if framework.bootstrap_required?
|
158
|
+
stderr.puts "I can't do anything for you by default for the framework your using: #{framework.short_name}.\nYou must bootstrap #{helper_file} to continue."
|
159
|
+
stderr.flush
|
160
|
+
return false
|
161
|
+
else
|
162
|
+
load(framework.entry_point)
|
163
|
+
end
|
125
164
|
end
|
165
|
+
|
166
|
+
framework.preload do
|
167
|
+
if bootstrapped?
|
168
|
+
stderr.puts "Loading Spork.prefork block..."
|
169
|
+
stderr.flush
|
170
|
+
load(helper_file)
|
171
|
+
end
|
172
|
+
end
|
126
173
|
end
|
127
174
|
true
|
128
175
|
end
|
129
176
|
|
130
|
-
def run_tests(argv, input, output)
|
131
|
-
raise NotImplemented
|
132
|
-
end
|
133
|
-
|
134
177
|
def restart
|
135
|
-
puts "restarting"
|
178
|
+
stderr.puts "restarting"
|
179
|
+
stderr.flush
|
136
180
|
config = ::Config::CONFIG
|
137
181
|
ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT']
|
138
182
|
command_line = [ruby, $0, ARGV].flatten.join(' ')
|
@@ -140,20 +184,18 @@ class Spork::Server
|
|
140
184
|
end
|
141
185
|
|
142
186
|
def abort
|
143
|
-
|
144
|
-
Process.kill(Signal.list['TERM'], @child_pid)
|
145
|
-
true
|
146
|
-
end
|
187
|
+
@child && @child.abort
|
147
188
|
end
|
148
189
|
|
149
190
|
def sig_int_received
|
150
191
|
if running?
|
151
192
|
abort
|
152
|
-
puts "Running
|
193
|
+
stderr.puts "Running tests stopped. Press CTRL-C again to stop the server."
|
194
|
+
stderr.flush
|
153
195
|
else
|
154
196
|
exit!(0)
|
155
197
|
end
|
156
198
|
end
|
157
199
|
end
|
158
200
|
|
159
|
-
Dir[File.dirname(__FILE__) + "/server/*.rb"].each { |file| require file }
|
201
|
+
Dir[File.dirname(__FILE__) + "/server/*.rb"].each { |file| require file }
|