zeus-edge 0.12.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/MIT-LICENSE +22 -0
- data/Rakefile +57 -0
- data/bin/zeus +16 -0
- data/build/fsevents-wrapper +0 -0
- data/build/zeus-darwin-amd64 +0 -0
- data/build/zeus-linux-386 +0 -0
- data/build/zeus-linux-amd64 +0 -0
- data/ext/inotify-wrapper/extconf.rb +24 -0
- data/ext/inotify-wrapper/inotify-wrapper.cpp +116 -0
- data/lib/zeus/load_tracking.rb +53 -0
- data/lib/zeus/m/test_collection.rb +52 -0
- data/lib/zeus/m/test_method.rb +35 -0
- data/lib/zeus/m.rb +346 -0
- data/lib/zeus/plan.rb +0 -0
- data/lib/zeus/rails.rb +220 -0
- data/lib/zeus.rb +161 -0
- data/man/build/zeus +61 -0
- data/man/build/zeus-init +13 -0
- data/man/build/zeus-init.txt +17 -0
- data/man/build/zeus-start +16 -0
- data/man/build/zeus-start.txt +18 -0
- data/man/build/zeus.txt +65 -0
- data/spec/fake_mini_test.rb +31 -0
- data/spec/m_spec.rb +83 -0
- data/spec/spec_helper.rb +38 -0
- data/zeus.gemspec +33 -0
- metadata +109 -0
data/lib/zeus/m.rb
ADDED
@@ -0,0 +1,346 @@
|
|
1
|
+
# This is very largely based on @qrush's M, but there are many modifications.
|
2
|
+
|
3
|
+
# we need to load all dependencies up front, because bundler will
|
4
|
+
# remove us from the load path soon.
|
5
|
+
require "rubygems"
|
6
|
+
require "zeus/m/test_collection"
|
7
|
+
require "zeus/m/test_method"
|
8
|
+
|
9
|
+
# the Gemfile may specify a version of method_source, but we also want to require it here.
|
10
|
+
# To avoid possible "you've activated X; gemfile specifies Y" errors, we actually scan
|
11
|
+
# Gemfile.lock for a specific version, and require exactly that version if present.
|
12
|
+
gemfile_lock = ROOT_PATH + "/Gemfile.lock"
|
13
|
+
if File.exists?(gemfile_lock)
|
14
|
+
version = File.read(ROOT_PATH + "/Gemfile.lock").
|
15
|
+
scan(/\bmethod_source\s*\(([\d\.]+)\)/).flatten[0]
|
16
|
+
|
17
|
+
gem "method_source", version if version
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'method_source'
|
21
|
+
|
22
|
+
module Zeus
|
23
|
+
#`m` stands for metal, which is a better test/unit test runner that can run
|
24
|
+
#tests by line number.
|
25
|
+
#
|
26
|
+
#[![m ci](https://secure.travis-ci.org/qrush/m.png)](http://travis-ci.org/qrush/m)
|
27
|
+
#
|
28
|
+
#![Rush is a heavy metal band. Look it up on Wikipedia.](https://raw.github.com/qrush/m/master/rush.jpg)
|
29
|
+
#
|
30
|
+
#<sub>[Rush at the Bristol Colston Hall May 1979](http://www.flickr.com/photos/8507625@N02/3468299995/)</sub>
|
31
|
+
### Install
|
32
|
+
#
|
33
|
+
### Usage
|
34
|
+
#
|
35
|
+
#Basically, I was sick of using the `-n` flag to grab one test to run. Instead, I
|
36
|
+
#prefer how RSpec's test runner allows tests to be run by line number.
|
37
|
+
#
|
38
|
+
#Given this file:
|
39
|
+
#
|
40
|
+
# $ cat -n test/example_test.rb
|
41
|
+
# 1 require 'test/unit'
|
42
|
+
# 2
|
43
|
+
# 3 class ExampleTest < Test::Unit::TestCase
|
44
|
+
# 4 def test_apple
|
45
|
+
# 5 assert_equal 1, 1
|
46
|
+
# 6 end
|
47
|
+
# 7
|
48
|
+
# 8 def test_banana
|
49
|
+
# 9 assert_equal 1, 1
|
50
|
+
# 10 end
|
51
|
+
# 11 end
|
52
|
+
#
|
53
|
+
#You can run a test by line number, using format `m TEST_FILE:LINE_NUMBER_OF_TEST`:
|
54
|
+
#
|
55
|
+
# $ m test/example_test.rb:4
|
56
|
+
# Run options: -n /test_apple/
|
57
|
+
#
|
58
|
+
# # Running tests:
|
59
|
+
#
|
60
|
+
# .
|
61
|
+
#
|
62
|
+
# Finished tests in 0.000525s, 1904.7619 tests/s, 1904.7619 assertions/s.
|
63
|
+
#
|
64
|
+
# 1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
|
65
|
+
#
|
66
|
+
#Hit the wrong line number? No problem, `m` helps you out:
|
67
|
+
#
|
68
|
+
# $ m test/example_test.rb:2
|
69
|
+
# No tests found on line 2. Valid tests to run:
|
70
|
+
#
|
71
|
+
# test_apple: m test/examples/test_unit_example_test.rb:4
|
72
|
+
# test_banana: m test/examples/test_unit_example_test.rb:8
|
73
|
+
#
|
74
|
+
#Want to run the whole test? Just leave off the line number.
|
75
|
+
#
|
76
|
+
# $ m test/example_test.rb
|
77
|
+
# Run options:
|
78
|
+
#
|
79
|
+
# # Running tests:
|
80
|
+
#
|
81
|
+
# ..
|
82
|
+
#
|
83
|
+
# Finished tests in 0.001293s, 1546.7904 tests/s, 3093.5808 assertions/s.
|
84
|
+
#
|
85
|
+
# 1 tests, 2 assertions, 0 failures, 0 errors, 0 skips
|
86
|
+
#
|
87
|
+
#### Supports
|
88
|
+
#
|
89
|
+
#`m` works with a few Ruby test frameworks:
|
90
|
+
#
|
91
|
+
#* `Test::Unit`
|
92
|
+
#* `ActiveSupport::TestCase`
|
93
|
+
#* `MiniTest::Unit::TestCase`
|
94
|
+
#
|
95
|
+
### License
|
96
|
+
#
|
97
|
+
#This gem is MIT licensed, please see `LICENSE` for more information.
|
98
|
+
|
99
|
+
### M, your metal test runner
|
100
|
+
# Maybe this gem should have a longer name? Metal?
|
101
|
+
module M
|
102
|
+
VERSION = "1.2.1" unless defined?(VERSION)
|
103
|
+
|
104
|
+
# Accept arguments coming from bin/m and run tests.
|
105
|
+
def self.run(argv)
|
106
|
+
Runner.new(argv).run
|
107
|
+
end
|
108
|
+
|
109
|
+
### Runner is in charge of running your tests.
|
110
|
+
# Instead of slamming all of this junk in an `M` class, it's here instead.
|
111
|
+
class Runner
|
112
|
+
def initialize(argv)
|
113
|
+
@argv = argv
|
114
|
+
end
|
115
|
+
|
116
|
+
# There's two steps to running our tests:
|
117
|
+
# 1. Parsing the given input for the tests we need to find (or groups of tests)
|
118
|
+
# 2. Run those tests we found that match what you wanted
|
119
|
+
def run
|
120
|
+
parse
|
121
|
+
execute
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def parse
|
127
|
+
# With no arguments,
|
128
|
+
if @argv.empty?
|
129
|
+
# Just shell out to `rake test`.
|
130
|
+
require 'rake'
|
131
|
+
Rake::Task['test'].invoke
|
132
|
+
exit
|
133
|
+
else
|
134
|
+
parse_options! @argv
|
135
|
+
|
136
|
+
# Parse out ARGV, it should be coming in in a format like `test/test_file.rb:9`
|
137
|
+
_, line = @argv.first.split(':')
|
138
|
+
@line ||= line.nil? ? nil : line.to_i
|
139
|
+
|
140
|
+
@files = []
|
141
|
+
@argv.each do |arg|
|
142
|
+
add_file(arg)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def add_file(arg)
|
148
|
+
file = arg.split(':').first
|
149
|
+
if Dir.exist?(file)
|
150
|
+
files = Dir.glob("#{file}/**/*test*.rb")
|
151
|
+
@files.concat(files)
|
152
|
+
else
|
153
|
+
files = Dir.glob(file)
|
154
|
+
files == [] and abort "Couldn't find test file '#{file}'!"
|
155
|
+
@files.concat(files)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def parse_options!(argv)
|
160
|
+
require 'optparse'
|
161
|
+
|
162
|
+
OptionParser.new do |opts|
|
163
|
+
opts.banner = 'Options:'
|
164
|
+
opts.version = M::VERSION
|
165
|
+
|
166
|
+
opts.on '-h', '--help', 'Display this help.' do
|
167
|
+
puts "Usage: m [OPTIONS] [FILES]\n\n", opts
|
168
|
+
exit
|
169
|
+
end
|
170
|
+
|
171
|
+
opts.on '--version', 'Display the version.' do
|
172
|
+
puts "m #{M::VERSION}"
|
173
|
+
exit
|
174
|
+
end
|
175
|
+
|
176
|
+
opts.on '-l', '--line LINE', Integer, 'Line number for file.' do |line|
|
177
|
+
@line = line
|
178
|
+
end
|
179
|
+
|
180
|
+
opts.on '-n', '--name NAME', String, 'Name or pattern for test methods to run.' do |name|
|
181
|
+
if name[0] == "/" && name[-1] == "/"
|
182
|
+
@test_name = Regexp.new(name[1..-2])
|
183
|
+
else
|
184
|
+
@test_name = name
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
opts.parse! argv
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def execute
|
193
|
+
generate_tests_to_run
|
194
|
+
|
195
|
+
test_arguments = build_test_arguments
|
196
|
+
|
197
|
+
# directly run the tests from here and exit with the status of the tests passing or failing
|
198
|
+
case framework
|
199
|
+
when :minitest
|
200
|
+
exit MiniTest::Unit.runner.run test_arguments
|
201
|
+
when :testunit1, :testunit2
|
202
|
+
exit Test::Unit::AutoRunner.run(false, nil, test_arguments)
|
203
|
+
else
|
204
|
+
not_supported
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def generate_tests_to_run
|
209
|
+
# Locate tests to run that may be inside of this line. There could be more than one!
|
210
|
+
all_tests = tests
|
211
|
+
if @line
|
212
|
+
@tests_to_run = all_tests.within(@line)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def build_test_arguments
|
217
|
+
if @line
|
218
|
+
abort_with_no_test_found_by_line_number if @tests_to_run.empty?
|
219
|
+
|
220
|
+
# assemble the regexp to run these tests,
|
221
|
+
test_names = @tests_to_run.map(&:name).join('|')
|
222
|
+
|
223
|
+
# set up the args needed for the runner
|
224
|
+
["-n", "/(#{test_names})/"]
|
225
|
+
elsif user_specified_name?
|
226
|
+
abort_with_no_test_found_by_name unless tests.contains?(@test_name)
|
227
|
+
|
228
|
+
test_names = test_name_to_s
|
229
|
+
["-n", test_names]
|
230
|
+
else
|
231
|
+
[]
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def abort_with_no_test_found_by_line_number
|
236
|
+
abort_with_valid_tests_msg "No tests found on line #{@line}. "
|
237
|
+
end
|
238
|
+
|
239
|
+
def abort_with_no_test_found_by_name
|
240
|
+
abort_with_valid_tests_msg "No test name matches '#{test_name_to_s}'. "
|
241
|
+
end
|
242
|
+
|
243
|
+
def abort_with_valid_tests_msg message=""
|
244
|
+
message << "Valid tests to run:\n\n"
|
245
|
+
# For every test ordered by line number,
|
246
|
+
# spit out the test name and line number where it starts,
|
247
|
+
tests.by_line_number do |test|
|
248
|
+
message << "#{sprintf("%0#{tests.column_size}s", test.name)}: zeus test #{@files[0]}:#{test.start_line}\n"
|
249
|
+
end
|
250
|
+
|
251
|
+
# fail like a good unix process should.
|
252
|
+
abort message
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_name_to_s
|
256
|
+
@test_name.is_a?(Regexp)? "/#{@test_name.source}/" : @test_name
|
257
|
+
end
|
258
|
+
|
259
|
+
def user_specified_name?
|
260
|
+
!@test_name.nil?
|
261
|
+
end
|
262
|
+
|
263
|
+
def framework
|
264
|
+
@framework ||= begin
|
265
|
+
if defined?(MiniTest)
|
266
|
+
:minitest
|
267
|
+
elsif defined?(Test)
|
268
|
+
if Test::Unit::TestCase.respond_to?(:test_suites)
|
269
|
+
:testunit2
|
270
|
+
else
|
271
|
+
:testunit1
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
# Finds all test suites in this test file, with test methods included.
|
278
|
+
def suites
|
279
|
+
# Since we're not using `ruby -Itest -Ilib` to run the tests, we need to add this directory to the `LOAD_PATH`
|
280
|
+
$:.unshift "./test", "./lib"
|
281
|
+
|
282
|
+
if framework == :testunit1
|
283
|
+
Test::Unit::TestCase.class_eval {
|
284
|
+
@@test_suites = {}
|
285
|
+
def self.inherited(klass)
|
286
|
+
@@test_suites[klass] = true
|
287
|
+
end
|
288
|
+
def self.test_suites
|
289
|
+
@@test_suites.keys
|
290
|
+
end
|
291
|
+
def self.test_methods
|
292
|
+
public_instance_methods(true).grep(/^test/).map(&:to_s)
|
293
|
+
end
|
294
|
+
}
|
295
|
+
end
|
296
|
+
|
297
|
+
begin
|
298
|
+
# Fire up the Ruby files. Let's hope they actually have tests.
|
299
|
+
@files.each { |f| load f }
|
300
|
+
rescue LoadError => e
|
301
|
+
# Fail with a happier error message instead of spitting out a backtrace from this gem
|
302
|
+
abort "Failed loading test file:\n#{e.message}"
|
303
|
+
end
|
304
|
+
|
305
|
+
# Figure out what test framework we're using
|
306
|
+
case framework
|
307
|
+
when :minitest
|
308
|
+
suites = MiniTest::Unit::TestCase.test_suites
|
309
|
+
when :testunit1, :testunit2
|
310
|
+
suites = Test::Unit::TestCase.test_suites
|
311
|
+
else
|
312
|
+
not_supported
|
313
|
+
end
|
314
|
+
|
315
|
+
# Use some janky internal APIs to group test methods by test suite.
|
316
|
+
suites.inject({}) do |suites, suite_class|
|
317
|
+
# End up with a hash of suite class name to an array of test methods, so we can later find them and ignore empty test suites
|
318
|
+
suites[suite_class] = suite_class.test_methods if suite_class.test_methods.size > 0
|
319
|
+
suites
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
# Shoves tests together in our custom container and collection classes.
|
324
|
+
# Memoize it since it's unnecessary to do this more than one for a given file.
|
325
|
+
def tests
|
326
|
+
@tests ||= begin
|
327
|
+
# With each suite and array of tests,
|
328
|
+
# and with each test method present in this test file,
|
329
|
+
# shove a new test method into this collection.
|
330
|
+
suites.inject(TestCollection.new) do |collection, (suite_class, test_methods)|
|
331
|
+
test_methods.each do |test_method|
|
332
|
+
find_locations = (@files.size == 1 && @line)
|
333
|
+
collection << TestMethod.create(suite_class, test_method, find_locations)
|
334
|
+
end
|
335
|
+
collection
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
# Fail loudly if this isn't supported
|
341
|
+
def not_supported
|
342
|
+
abort "This test framework is not supported! Please open up an issue at https://github.com/qrush/m !"
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
data/lib/zeus/plan.rb
ADDED
File without changes
|
data/lib/zeus/rails.rb
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
ROOT_PATH = File.expand_path(Dir.pwd)
|
2
|
+
ENV_PATH = File.expand_path('config/environment', ROOT_PATH)
|
3
|
+
BOOT_PATH = File.expand_path('config/boot', ROOT_PATH)
|
4
|
+
APP_PATH = File.expand_path('config/application', ROOT_PATH)
|
5
|
+
|
6
|
+
require 'zeus'
|
7
|
+
require 'zeus/m'
|
8
|
+
|
9
|
+
module Zeus
|
10
|
+
class Rails < Plan
|
11
|
+
def deprecated
|
12
|
+
puts "Zeus 0.11.0 changed zeus.json. You'll have to rm zeus.json && zeus init."
|
13
|
+
end
|
14
|
+
alias_method :spec_helper, :deprecated
|
15
|
+
alias_method :testrb, :deprecated
|
16
|
+
alias_method :rspec, :deprecated
|
17
|
+
|
18
|
+
|
19
|
+
def after_fork
|
20
|
+
reconnect_activerecord
|
21
|
+
restart_girl_friday
|
22
|
+
reconnect_redis
|
23
|
+
end
|
24
|
+
|
25
|
+
def _monkeypatch_rake
|
26
|
+
require 'rake/testtask'
|
27
|
+
Rake::TestTask.class_eval {
|
28
|
+
|
29
|
+
# Create the tasks defined by this task lib.
|
30
|
+
def define
|
31
|
+
desc "Run tests" + (@name==:test ? "" : " for #{@name}")
|
32
|
+
task @name do
|
33
|
+
# ruby "#{ruby_opts_string} #{run_code} #{file_list_string} #{option_list}"
|
34
|
+
rails_env = ENV['RAILS_ENV']
|
35
|
+
rubyopt = ENV['RUBYOPT']
|
36
|
+
ENV['RAILS_ENV'] = nil
|
37
|
+
ENV['RUBYOPT'] = nil # bundler sets this to require bundler :|
|
38
|
+
puts "zeus test #{file_list_string}"
|
39
|
+
system "zeus test #{file_list_string}"
|
40
|
+
ENV['RAILS_ENV'] = rails_env
|
41
|
+
ENV['RUBYOPT'] = rubyopt
|
42
|
+
end
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
alias_method :_original_define, :define
|
47
|
+
|
48
|
+
def self.inherited(klass)
|
49
|
+
return unless klass.name == "TestTaskWithoutDescription"
|
50
|
+
klass.class_eval {
|
51
|
+
def self.method_added(sym)
|
52
|
+
class_eval do
|
53
|
+
if !@rails_hack_reversed
|
54
|
+
@rails_hack_reversed = true
|
55
|
+
alias_method :define, :_original_define
|
56
|
+
def desc(*)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
}
|
62
|
+
end
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
def boot
|
67
|
+
_monkeypatch_rake
|
68
|
+
|
69
|
+
require BOOT_PATH
|
70
|
+
# config/application.rb normally requires 'rails/all'.
|
71
|
+
# Some 'alternative' ORMs such as Mongoid give instructions to switch this require
|
72
|
+
# out for a list of railties, not including ActiveRecord.
|
73
|
+
# We grep config/application.rb for all requires of rails/all or railties, and require them.
|
74
|
+
rails_components = File.read(APP_PATH + ".rb").
|
75
|
+
scan(/^\s*require\s*['"](.*railtie.*|rails\/all)['"]/).flatten
|
76
|
+
|
77
|
+
rails_components = ["rails/all"] if rails_components == []
|
78
|
+
rails_components.each do |component|
|
79
|
+
require component
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def default_bundle
|
84
|
+
Bundler.require(:default)
|
85
|
+
end
|
86
|
+
|
87
|
+
def development_environment
|
88
|
+
Bundler.require(:development)
|
89
|
+
::Rails.env = ENV['RAILS_ENV'] = "development"
|
90
|
+
require APP_PATH
|
91
|
+
::Rails.application.require_environment!
|
92
|
+
end
|
93
|
+
|
94
|
+
def prerake
|
95
|
+
require 'rake'
|
96
|
+
end
|
97
|
+
|
98
|
+
def rake
|
99
|
+
Rake.application.run
|
100
|
+
end
|
101
|
+
|
102
|
+
def generate
|
103
|
+
load_rails_generators
|
104
|
+
require 'rails/commands/generate'
|
105
|
+
end
|
106
|
+
|
107
|
+
def destroy
|
108
|
+
load_rails_generators
|
109
|
+
require 'rails/commands/destroy'
|
110
|
+
end
|
111
|
+
|
112
|
+
def runner
|
113
|
+
require 'rails/commands/runner'
|
114
|
+
end
|
115
|
+
|
116
|
+
def console
|
117
|
+
require 'rails/commands/console'
|
118
|
+
::Rails::Console.start(::Rails.application)
|
119
|
+
end
|
120
|
+
|
121
|
+
def dbconsole
|
122
|
+
require 'rails/commands/dbconsole'
|
123
|
+
|
124
|
+
meth = ::Rails::DBConsole.method(:start)
|
125
|
+
|
126
|
+
# `Rails::DBConsole.start` has been changed to load faster in
|
127
|
+
# https://github.com/rails/rails/commit/346bb018499cde6699fcce6c68dd7e9be45c75e1
|
128
|
+
#
|
129
|
+
# This will work with both versions.
|
130
|
+
if meth.arity.zero?
|
131
|
+
::Rails::DBConsole.start
|
132
|
+
else
|
133
|
+
::Rails::DBConsole.start(::Rails.application)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def server
|
138
|
+
require 'rails/commands/server'
|
139
|
+
server = ::Rails::Server.new
|
140
|
+
Dir.chdir(::Rails.application.root)
|
141
|
+
server.start
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_environment
|
145
|
+
Bundler.require(:test)
|
146
|
+
|
147
|
+
::Rails.env = ENV['RAILS_ENV'] = 'test'
|
148
|
+
require APP_PATH
|
149
|
+
|
150
|
+
$rails_rake_task = 'yup' # lie to skip eager loading
|
151
|
+
::Rails.application.require_environment!
|
152
|
+
$rails_rake_task = nil
|
153
|
+
|
154
|
+
$LOAD_PATH.unshift ".", "./lib", "./test", "./spec"
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_helper
|
158
|
+
if File.exists?(ROOT_PATH + "/spec/spec_helper.rb")
|
159
|
+
require 'spec_helper'
|
160
|
+
elsif File.exist?(ROOT_PATH + "/test/minitest_helper.rb")
|
161
|
+
require 'minitest_helper'
|
162
|
+
else
|
163
|
+
require 'test_helper'
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def test
|
168
|
+
if defined?(RSpec)
|
169
|
+
exit RSpec::Core::Runner.run(ARGV)
|
170
|
+
else
|
171
|
+
Zeus::M.run(ARGV)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def cucumber_environment
|
176
|
+
require 'cucumber/rspec/disable_option_parser'
|
177
|
+
require 'cucumber/cli/main'
|
178
|
+
@cucumber_runtime = Cucumber::Runtime.new
|
179
|
+
end
|
180
|
+
|
181
|
+
def cucumber
|
182
|
+
cucumber_main = Cucumber::Cli::Main.new(ARGV.dup)
|
183
|
+
exit cucumber_main.execute!(@cucumber_runtime)
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
private
|
188
|
+
|
189
|
+
def restart_girl_friday
|
190
|
+
return unless defined?(GirlFriday::WorkQueue)
|
191
|
+
# The Actor is run in a thread, and threads don't persist post-fork.
|
192
|
+
# We just need to restart each one in the newly-forked process.
|
193
|
+
ObjectSpace.each_object(GirlFriday::WorkQueue) do |obj|
|
194
|
+
obj.send(:start)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def reconnect_activerecord
|
199
|
+
ActiveRecord::Base.clear_all_connections! rescue nil
|
200
|
+
ActiveRecord::Base.establish_connection rescue nil
|
201
|
+
end
|
202
|
+
|
203
|
+
def reconnect_redis
|
204
|
+
return unless defined?(Redis::Client)
|
205
|
+
ObjectSpace.each_object(Redis::Client) do |client|
|
206
|
+
client.connect
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def load_rails_generators
|
211
|
+
require 'rails/generators'
|
212
|
+
::Rails.application.load_generators
|
213
|
+
rescue LoadError # Rails 3.0 doesn't require this block to be run, but 3.2+ does
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
Zeus.plan ||= Zeus::Rails.new
|
220
|
+
|