spork 0.9.0.rc8-x86-mingw32
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/Gemfile +10 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +134 -0
- data/assets/bootstrap.rb +47 -0
- data/bin/spork +20 -0
- data/features/at_exit_during_each_run.feature +36 -0
- data/features/cucumber_rails_integration.feature +107 -0
- data/features/diagnostic_mode.feature +41 -0
- data/features/gemfiles/rails3.0/Gemfile +14 -0
- data/features/gemfiles/rails3.0/Gemfile.lock +120 -0
- data/features/rails_delayed_loading_workarounds.feature +177 -0
- data/features/rspec_rails_integration.feature +92 -0
- data/features/spork_debugger.feature +108 -0
- data/features/steps/general_steps.rb +3 -0
- data/features/steps/rails_steps.rb +67 -0
- data/features/steps/sandbox_steps.rb +115 -0
- data/features/support/background_job.rb +63 -0
- data/features/support/bundler_helpers.rb +41 -0
- data/features/support/env.rb +105 -0
- data/features/unknown_app_framework.feature +42 -0
- data/lib/spork.rb +155 -0
- data/lib/spork/app_framework.rb +80 -0
- data/lib/spork/app_framework/padrino.rb +22 -0
- data/lib/spork/app_framework/rails.rb +82 -0
- data/lib/spork/app_framework/unknown.rb +6 -0
- data/lib/spork/custom_io_streams.rb +25 -0
- data/lib/spork/diagnoser.rb +105 -0
- data/lib/spork/ext/rails-reloader.rb +14 -0
- data/lib/spork/ext/ruby-debug.rb +150 -0
- data/lib/spork/forker.rb +71 -0
- data/lib/spork/gem_helpers.rb +38 -0
- data/lib/spork/run_strategy.rb +48 -0
- data/lib/spork/run_strategy/forking.rb +35 -0
- data/lib/spork/run_strategy/magazine.rb +151 -0
- data/lib/spork/run_strategy/magazine/magazine_slave.rb +30 -0
- data/lib/spork/run_strategy/magazine/magazine_slave_provider.rb +30 -0
- data/lib/spork/run_strategy/magazine/ring_server.rb +10 -0
- data/lib/spork/runner.rb +90 -0
- data/lib/spork/server.rb +77 -0
- data/lib/spork/test_framework.rb +167 -0
- data/lib/spork/test_framework/cucumber.rb +38 -0
- data/lib/spork/test_framework/rspec.rb +14 -0
- data/spec/spec_helper.rb +113 -0
- 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/run_strategy/forking_spec.rb +38 -0
- data/spec/spork/runner_spec.rb +50 -0
- data/spec/spork/server_spec.rb +15 -0
- data/spec/spork/test_framework/cucumber_spec.rb +11 -0
- data/spec/spork/test_framework/rspec_spec.rb +10 -0
- data/spec/spork/test_framework_shared_examples.rb +23 -0
- data/spec/spork/test_framework_spec.rb +90 -0
- data/spec/spork_spec.rb +153 -0
- data/spec/support/fake_framework.rb +15 -0
- data/spec/support/fake_run_strategy.rb +21 -0
- metadata +173 -0
data/lib/spork/forker.rb
ADDED
@@ -0,0 +1,71 @@
|
|
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
|
+
begin
|
20
|
+
@server_io.close
|
21
|
+
Marshal.dump(yield, @child_io)
|
22
|
+
# wait for the parent to acknowledge receipt of the result.
|
23
|
+
master_response = Marshal.load(@child_io)
|
24
|
+
rescue EOFError
|
25
|
+
nil
|
26
|
+
rescue Exception => e
|
27
|
+
puts "Exception encountered: #{e.inspect}\nbacktrace:\n#{e.backtrace * %(\n)}"
|
28
|
+
end
|
29
|
+
|
30
|
+
# terminate, skipping any at_exit blocks.
|
31
|
+
exit!(0)
|
32
|
+
end
|
33
|
+
@child_io.close
|
34
|
+
end
|
35
|
+
|
36
|
+
# Wait for the fork to finish running, and then return its return value.
|
37
|
+
#
|
38
|
+
# If the fork was aborted, then result returns nil.
|
39
|
+
def result
|
40
|
+
return unless running?
|
41
|
+
result_thread = Thread.new do
|
42
|
+
begin
|
43
|
+
@result = Marshal.load(@server_io)
|
44
|
+
Marshal.dump('ACK', @server_io)
|
45
|
+
rescue ForkDiedException, EOFError
|
46
|
+
@result = nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
Process.wait(@child_pid)
|
50
|
+
result_thread.raise(ForkDiedException) if @result.nil?
|
51
|
+
@child_pid = nil
|
52
|
+
@result
|
53
|
+
end
|
54
|
+
|
55
|
+
# abort the current running fork
|
56
|
+
def abort
|
57
|
+
if running?
|
58
|
+
Process.kill(Signal.list['TERM'], @child_pid)
|
59
|
+
@child_pid = nil
|
60
|
+
true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def running?
|
65
|
+
return false unless @child_pid
|
66
|
+
Process.getpgid(@child_pid)
|
67
|
+
true
|
68
|
+
rescue Errno::ESRCH
|
69
|
+
false
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Spork::GemHelpers
|
2
|
+
extend self
|
3
|
+
|
4
|
+
class GemPath
|
5
|
+
attr_reader :name, :version, :path, :version_numbers
|
6
|
+
include Comparable
|
7
|
+
def initialize(p)
|
8
|
+
@path = p
|
9
|
+
@name, @version = File.basename(p).scan(/^(.+?)-([^-]+)$/).flatten
|
10
|
+
@version_numbers = @version.split(/[^0-9]+/).map(&:to_i)
|
11
|
+
end
|
12
|
+
|
13
|
+
def <=>(other)
|
14
|
+
raise "Not comparable gem paths ('#{name}' is not '#{other.name}')" unless name == other.name
|
15
|
+
@version_numbers <=> other.version_numbers
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def latest_load_paths
|
20
|
+
case
|
21
|
+
when defined?(Bundler)
|
22
|
+
$LOAD_PATH.uniq
|
23
|
+
when Gem.respond_to?(:path)
|
24
|
+
Dir["{#{Gem.path.join(',')}}" + "/gems/*"].inject({}) do |h,f|
|
25
|
+
gem_path = GemPath.new(f)
|
26
|
+
if h[gem_path.name]
|
27
|
+
h[gem_path.name] = gem_path if gem_path > h[gem_path.name]
|
28
|
+
else
|
29
|
+
h[gem_path.name] = gem_path
|
30
|
+
end
|
31
|
+
h
|
32
|
+
end.values.map(&:path)
|
33
|
+
else
|
34
|
+
STDERR.puts "No mechanism available to scan for other gems implementing spork hooks. "
|
35
|
+
[]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class Spork::RunStrategy
|
2
|
+
attr_reader :test_framework
|
3
|
+
@@run_strategies = []
|
4
|
+
|
5
|
+
def initialize(test_framework)
|
6
|
+
@test_framework = test_framework
|
7
|
+
end
|
8
|
+
|
9
|
+
def preload
|
10
|
+
raise NotImplementedError
|
11
|
+
end
|
12
|
+
|
13
|
+
def run(argv, input, output)
|
14
|
+
raise NotImplementedError
|
15
|
+
end
|
16
|
+
|
17
|
+
def cleanup
|
18
|
+
raise NotImplementedError
|
19
|
+
end
|
20
|
+
|
21
|
+
def running?
|
22
|
+
raise NotImplementedError
|
23
|
+
end
|
24
|
+
|
25
|
+
def assert_ready!
|
26
|
+
raise NotImplementedError
|
27
|
+
end
|
28
|
+
|
29
|
+
def abort
|
30
|
+
raise NotImplementedError
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
def self.factory(test_framework)
|
35
|
+
if RUBY_PLATFORM =~ /mswin|mingw|java/
|
36
|
+
Spork::RunStrategy::Magazine.new(test_framework)
|
37
|
+
else
|
38
|
+
Spork::RunStrategy::Forking.new(test_framework)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.inherited(subclass)
|
43
|
+
@@run_strategies << subclass
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
Dir[File.dirname(__FILE__) + "/run_strategy/*.rb"].each { |file| require file }
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Spork::RunStrategy::Forking < Spork::RunStrategy
|
2
|
+
def self.available?
|
3
|
+
Kernel.respond_to?(:fork)
|
4
|
+
end
|
5
|
+
|
6
|
+
def run(argv, stderr, stdout)
|
7
|
+
abort if running?
|
8
|
+
|
9
|
+
@child = ::Spork::Forker.new do
|
10
|
+
$stdout, $stderr = stdout, stderr
|
11
|
+
load test_framework.helper_file
|
12
|
+
Spork.exec_each_run
|
13
|
+
result = test_framework.run_tests(argv, stderr, stdout)
|
14
|
+
Spork.exec_after_each_run
|
15
|
+
result
|
16
|
+
end
|
17
|
+
@child.result
|
18
|
+
end
|
19
|
+
|
20
|
+
def abort
|
21
|
+
@child && @child.abort
|
22
|
+
end
|
23
|
+
|
24
|
+
def preload
|
25
|
+
test_framework.preload
|
26
|
+
end
|
27
|
+
|
28
|
+
def running?
|
29
|
+
@child && @child.running?
|
30
|
+
end
|
31
|
+
|
32
|
+
def assert_ready!
|
33
|
+
raise RuntimeError, "This process hasn't loaded the environment yet by loading the prefork block" unless Spork.using_spork?
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
# this class' goal:
|
2
|
+
# to boldly just run test after test
|
3
|
+
# as they come in
|
4
|
+
require 'drb'
|
5
|
+
require 'rinda/ring'
|
6
|
+
if RUBY_PLATFORM =~ /mswin|mingw/ and RUBY_VERSION < '1.9.1'
|
7
|
+
begin
|
8
|
+
require 'win32/process'
|
9
|
+
rescue LoadError
|
10
|
+
puts "The 'win32-process' gem is required for windows Spork support with ruby 1.9.1 and lower. Install it, or if using bundler, add it to your Gemfile."
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'rubygems' # used for Gem.ruby
|
16
|
+
|
17
|
+
$:.unshift(File.dirname(__FILE__))
|
18
|
+
require 'magazine/magazine_slave'
|
19
|
+
|
20
|
+
class Spork::RunStrategy::Magazine < Spork::RunStrategy
|
21
|
+
|
22
|
+
Slave_Id_Range = 1..2 # Ringserver uses id: 0. Slave use: 1..MAX_SLAVES
|
23
|
+
|
24
|
+
def slave_max
|
25
|
+
Slave_Id_Range.to_a.size
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(test_framework)
|
29
|
+
@test_framework = test_framework
|
30
|
+
this_path = File.expand_path(File.dirname(__FILE__))
|
31
|
+
@path = File.join(this_path, 'magazine')
|
32
|
+
@pids = []
|
33
|
+
|
34
|
+
@pids << start_Rinda_ringserver
|
35
|
+
sleep 1
|
36
|
+
|
37
|
+
fill_slave_pool
|
38
|
+
rescue RuntimeError => e
|
39
|
+
kill_all_processes
|
40
|
+
raise e
|
41
|
+
end
|
42
|
+
|
43
|
+
def start_Rinda_ringserver
|
44
|
+
app_name = "#{Gem.ruby} ring_server.rb"
|
45
|
+
spawn_process(app_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
def fill_slave_pool
|
49
|
+
Slave_Id_Range.each do |id|
|
50
|
+
start_slave(id)
|
51
|
+
end
|
52
|
+
puts " -- Starting to fill pool..."
|
53
|
+
puts " Wait until at least one slave is provided before running tests..."
|
54
|
+
puts " ** CTRL+BREAK to stop Spork and kill all ruby slave processes **"
|
55
|
+
$stdout.flush
|
56
|
+
end
|
57
|
+
|
58
|
+
def start_slave(id)
|
59
|
+
app_pwd = Dir.pwd # path running app in
|
60
|
+
app = "#{Gem.ruby} magazine_slave_provider.rb #{id} '#{app_pwd}' #{@test_framework.short_name}"
|
61
|
+
@pids[id] = spawn_process(app)
|
62
|
+
end
|
63
|
+
|
64
|
+
def spawn_process(app)
|
65
|
+
|
66
|
+
if RUBY_PLATFORM =~ /java/
|
67
|
+
# jruby 1.8 has no easy way to just spawn, so use a thread
|
68
|
+
Dir.chdir(@path) do
|
69
|
+
io = IO.popen app
|
70
|
+
Thread.new { puts io.read }
|
71
|
+
return io.pid
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
if RUBY_VERSION < '1.9.1'
|
76
|
+
Process.create( :app_name => app, :cwd => @path ).process_id
|
77
|
+
else
|
78
|
+
Process.spawn( app, :chdir => @path )
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.available?
|
83
|
+
true
|
84
|
+
end
|
85
|
+
|
86
|
+
def run(argv, stderr, stdout)
|
87
|
+
DRb.start_service
|
88
|
+
ts = Rinda::RingFinger.primary
|
89
|
+
if ts.read_all([:name, :MagazineSlave, nil, nil]).size > 0
|
90
|
+
print ' <-- take tuple'; stdout.flush
|
91
|
+
tuple = ts.take([:name, :MagazineSlave, nil, nil])
|
92
|
+
slave = tuple[2]
|
93
|
+
id = tuple[3]
|
94
|
+
|
95
|
+
puts "(#{slave.id_num}); slave.run..."; $stdout.flush
|
96
|
+
begin
|
97
|
+
slave.run(argv,stderr,stdout)
|
98
|
+
puts " -- (#{slave.id_num});run done"; $stdout.flush
|
99
|
+
ensure
|
100
|
+
restart_slave(id)
|
101
|
+
end
|
102
|
+
else
|
103
|
+
puts '- NO tuple'; $stdout.flush
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def restart_slave(id)
|
108
|
+
pid = @pids[id]
|
109
|
+
Process.kill(9, pid)
|
110
|
+
start_slave(id)
|
111
|
+
end
|
112
|
+
|
113
|
+
def windows?
|
114
|
+
ENV['OS'] == 'Windows_NT'
|
115
|
+
end
|
116
|
+
|
117
|
+
def kill_all_processes
|
118
|
+
|
119
|
+
@pids.each {|pid|
|
120
|
+
if windows?
|
121
|
+
system("taskkill /f /pid #{pid}")
|
122
|
+
else
|
123
|
+
Process.kill(9, pid)
|
124
|
+
end
|
125
|
+
}
|
126
|
+
puts "\nKilling processes."; $stdout.flush
|
127
|
+
end
|
128
|
+
|
129
|
+
def slave_count
|
130
|
+
DRb.start_service
|
131
|
+
ts = Rinda::RingFinger.primary
|
132
|
+
ts.read_all([:name, :MagazineSlave, nil, nil]).size
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
def abort
|
137
|
+
kill_all_processes
|
138
|
+
end
|
139
|
+
|
140
|
+
def preload
|
141
|
+
true
|
142
|
+
# @test_framework.preload
|
143
|
+
end
|
144
|
+
|
145
|
+
def running?
|
146
|
+
@running
|
147
|
+
end
|
148
|
+
|
149
|
+
def assert_ready!
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'drb'
|
3
|
+
$:.unshift(File.dirname(__FILE__) + "/../../..") # directory of spork.rb
|
4
|
+
require 'spork'
|
5
|
+
|
6
|
+
class MagazineSlave
|
7
|
+
include DRb::DRbUndumped
|
8
|
+
attr_reader :id_num
|
9
|
+
def initialize(id_num, test_framework_short_name)
|
10
|
+
@id_num = id_num
|
11
|
+
@test_framework = Spork::TestFramework.factory(STDOUT, STDERR,
|
12
|
+
test_framework_short_name)
|
13
|
+
# ENV["DRB"] = 'true'
|
14
|
+
# Spork.using_spork!
|
15
|
+
return(nil) unless preload
|
16
|
+
end
|
17
|
+
|
18
|
+
def run(argv, stderr, stdout)
|
19
|
+
$stdout, $stderr = stdout, stderr
|
20
|
+
Spork.exec_each_run
|
21
|
+
load @test_framework.helper_file
|
22
|
+
@test_framework.run_tests(argv, stderr, stdout)
|
23
|
+
puts " <-- Slave(#{@id_num}) run done!"; stdout.flush
|
24
|
+
end
|
25
|
+
|
26
|
+
def preload
|
27
|
+
@test_framework.preload
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# magazine_slave_provider.rb
|
2
|
+
require 'drb'
|
3
|
+
require 'rinda/ring'
|
4
|
+
require 'rinda/tuplespace'
|
5
|
+
require './magazine_slave'
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
# pass on
|
10
|
+
|
11
|
+
id = ARGV[0].to_i || "?"
|
12
|
+
app_pwd = ARGV[1]
|
13
|
+
test_framework_short_name = ARGV[2]
|
14
|
+
|
15
|
+
# start up the Rinda service
|
16
|
+
|
17
|
+
DRb.start_service
|
18
|
+
|
19
|
+
Dir.chdir app_pwd
|
20
|
+
puts " -- build slave #{id}..."; $stdout.flush
|
21
|
+
magazine_slave = MagazineSlave.new(id, test_framework_short_name )
|
22
|
+
|
23
|
+
# never expire, the renewer returns nil, which means expiration of *nix clock
|
24
|
+
renewer = Rinda::SimpleRenewer.new(nil)
|
25
|
+
Rinda::RingProvider.new(:MagazineSlave, magazine_slave, id, renewer).provide
|
26
|
+
|
27
|
+
puts " --> DRb magazine_slave_service: #{id} provided..."; $stdout.flush
|
28
|
+
|
29
|
+
# wait for the DRb service to finish before exiting
|
30
|
+
DRb.thread.join
|
data/lib/spork/runner.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module Spork
|
5
|
+
# This is used by bin/spork. It's wrapped in a class because it's easier to test that way.
|
6
|
+
class Runner
|
7
|
+
attr_reader :test_framework
|
8
|
+
|
9
|
+
def self.run(args, output, error)
|
10
|
+
self.new(args, output, error).run
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(args, output, error)
|
14
|
+
raise ArgumentError, "expected array of args" unless args.is_a?(Array)
|
15
|
+
@output = output
|
16
|
+
@error = error
|
17
|
+
@options = {}
|
18
|
+
opt = OptionParser.new
|
19
|
+
opt.banner = "Usage: spork [test framework name] [options]\n\n"
|
20
|
+
|
21
|
+
opt.separator "Options:"
|
22
|
+
opt.on("-b", "--bootstrap") {|ignore| @options[:bootstrap] = true }
|
23
|
+
opt.on("-d", "--diagnose") {|ignore| @options[:diagnose] = true }
|
24
|
+
opt.on("-h", "--help") {|ignore| @options[:help] = true }
|
25
|
+
opt.on("-p", "--port [PORT]") {|port| @options[:port] = port }
|
26
|
+
non_option_args = args.select { |arg| ! args[0].match(/^-/) }
|
27
|
+
@options[:server_matcher] = non_option_args[0]
|
28
|
+
opt.parse!(args)
|
29
|
+
|
30
|
+
if @options[:help]
|
31
|
+
@output.puts opt
|
32
|
+
@output.puts
|
33
|
+
@output.puts supported_test_frameworks_text
|
34
|
+
exit(0)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def supported_test_frameworks_text
|
39
|
+
text = StringIO.new
|
40
|
+
|
41
|
+
text.puts "Supported test frameworks:"
|
42
|
+
text.puts Spork::TestFramework.supported_test_frameworks.sort { |a,b| a.short_name <=> b.short_name }.map { |s| (s.available? ? '(*) ' : '( ) ') + s.short_name }
|
43
|
+
text.puts "\nLegend: ( ) - not detected in project (*) - detected\n"
|
44
|
+
text.string
|
45
|
+
end
|
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.
|
48
|
+
def find_test_framework
|
49
|
+
Spork::TestFramework.factory(@output, @error, options[:server_matcher])
|
50
|
+
rescue Spork::TestFramework::NoFrameworksAvailable => e
|
51
|
+
@error.puts e.message
|
52
|
+
rescue Spork::TestFramework::FactoryException => e
|
53
|
+
@error.puts "#{e.message}\n\n#{supported_test_frameworks_text}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def run
|
57
|
+
return false unless test_framework = find_test_framework
|
58
|
+
ENV["DRB"] = 'true'
|
59
|
+
@error.puts "Using #{test_framework.short_name}"
|
60
|
+
@error.flush
|
61
|
+
|
62
|
+
case
|
63
|
+
when options[:bootstrap]
|
64
|
+
test_framework.bootstrap
|
65
|
+
when options[:diagnose]
|
66
|
+
require 'spork/diagnoser'
|
67
|
+
|
68
|
+
Spork::Diagnoser.install_hook!(test_framework.entry_point)
|
69
|
+
test_framework.preload
|
70
|
+
Spork::Diagnoser.output_results(@output)
|
71
|
+
return true
|
72
|
+
else
|
73
|
+
run_strategy = Spork::RunStrategy.factory(test_framework)
|
74
|
+
return(false) unless run_strategy.preload
|
75
|
+
Spork::Server.run(:port => @options[:port] || test_framework.default_port, :run_strategy => run_strategy)
|
76
|
+
return true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
attr_reader :options
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
|