milhouse-spork 0.7.5.2 → 0.7.5.4
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +19 -19
- data/README.rdoc +99 -99
- data/assets/bootstrap.rb +29 -29
- data/bin/spork +20 -20
- data/features/cucumber_rails_integration.feature +118 -118
- data/features/diagnostic_mode.feature +40 -40
- data/features/rails_delayed_loading_workarounds.feature +115 -115
- data/features/rspec_rails_integration.feature +93 -93
- data/features/spork_debugger.feature +108 -108
- data/features/steps/general_steps.rb +3 -3
- data/features/steps/rails_steps.rb +52 -52
- data/features/steps/sandbox_steps.rb +115 -115
- data/features/support/background_job.rb +63 -63
- data/features/support/env.rb +111 -111
- data/features/unknown_app_framework.feature +41 -41
- data/geminstaller.yml +9 -9
- data/lib/spork.rb +126 -126
- data/lib/spork/app_framework.rb +73 -73
- data/lib/spork/app_framework/rails.rb +157 -157
- data/lib/spork/app_framework/rails_stub_files/application.rb +1 -1
- data/lib/spork/app_framework/rails_stub_files/application_controller.rb +22 -22
- data/lib/spork/app_framework/rails_stub_files/application_helper.rb +2 -2
- data/lib/spork/app_framework/unknown.rb +5 -5
- data/lib/spork/custom_io_streams.rb +24 -24
- data/lib/spork/diagnoser.rb +103 -103
- data/lib/spork/ext/ruby-debug.rb +150 -150
- data/lib/spork/forker.rb +70 -70
- data/lib/spork/run_strategy.rb +44 -44
- data/lib/spork/run_strategy/forking.rb +29 -29
- data/lib/spork/run_strategy/magazine.rb +8 -7
- data/lib/spork/run_strategy/magazine/magazine_slave.rb +0 -0
- data/lib/spork/run_strategy/magazine/magazine_slave_provider.rb +2 -2
- data/lib/spork/run_strategy/magazine/ring_server.rb +1 -1
- data/lib/spork/runner.rb +90 -90
- data/lib/spork/server.rb +74 -74
- data/lib/spork/test_framework.rb +167 -167
- data/lib/spork/test_framework/cucumber.rb +24 -24
- data/lib/spork/test_framework/rspec.rb +14 -14
- data/spec/spec_helper.rb +108 -108
- data/spec/spork/app_framework/rails_spec.rb +22 -22
- data/spec/spork/app_framework/unknown_spec.rb +12 -12
- data/spec/spork/app_framework_spec.rb +16 -16
- data/spec/spork/diagnoser_spec.rb +105 -105
- data/spec/spork/forker_spec.rb +44 -44
- data/spec/spork/run_strategy/forking_spec.rb +38 -38
- data/spec/spork/runner_spec.rb +50 -50
- data/spec/spork/server_spec.rb +15 -15
- data/spec/spork/test_framework/cucumber_spec.rb +11 -11
- data/spec/spork/test_framework/rspec_spec.rb +10 -10
- data/spec/spork/test_framework_spec.rb +114 -114
- data/spec/spork_spec.rb +151 -151
- data/spec/support/fake_framework.rb +15 -15
- data/spec/support/fake_run_strategy.rb +21 -21
- metadata +14 -6
data/lib/spork.rb
CHANGED
@@ -1,126 +1,126 @@
|
|
1
|
-
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
|
2
|
-
require 'pathname'
|
3
|
-
module Spork
|
4
|
-
BINARY = File.expand_path(File.dirname(__FILE__) + '/../bin/spork')
|
5
|
-
LIBDIR = Pathname.new(File.expand_path(File.dirname(__FILE__)))
|
6
|
-
|
7
|
-
autoload :Server, (LIBDIR + 'spork/server').to_s
|
8
|
-
autoload :TestFramework, (LIBDIR + 'spork/test_framework').to_s
|
9
|
-
autoload :AppFramework, (LIBDIR + 'spork/app_framework').to_s
|
10
|
-
autoload :RunStrategy, (LIBDIR + 'spork/run_strategy').to_s
|
11
|
-
autoload :Runner, (LIBDIR + 'spork/runner').to_s
|
12
|
-
autoload :Forker, (LIBDIR + 'spork/forker').to_s
|
13
|
-
autoload :Diagnoser, (LIBDIR + 'spork/diagnoser').to_s
|
14
|
-
|
15
|
-
class << self
|
16
|
-
# Run a block, during prefork mode. By default, if prefork is called twice in the same file and line number, the supplied block will only be ran once.
|
17
|
-
#
|
18
|
-
# == Parameters
|
19
|
-
#
|
20
|
-
# * +prevent_double_run+ - Pass false to disable double run prevention
|
21
|
-
def prefork(prevent_double_run = true, &block)
|
22
|
-
return if prevent_double_run && already_ran?(caller.first)
|
23
|
-
yield
|
24
|
-
end
|
25
|
-
|
26
|
-
# Run a block AFTER the fork occurs. By default, if prefork is called twice in the same file and line number, the supplied block will only be ran once.
|
27
|
-
#
|
28
|
-
# == Parameters
|
29
|
-
#
|
30
|
-
# * +prevent_double_run+ - Pass false to disable double run prevention
|
31
|
-
def each_run(prevent_double_run = true, &block)
|
32
|
-
return if prevent_double_run && already_ran?(caller.first)
|
33
|
-
if @state == :using_spork
|
34
|
-
each_run_procs << block
|
35
|
-
else
|
36
|
-
yield
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# Used by the server. Sets the state to activate spork. Otherwise, prefork and each_run are run in passive mode, allowing specs without a Spork server.
|
41
|
-
def using_spork!
|
42
|
-
@state = :using_spork
|
43
|
-
end
|
44
|
-
|
45
|
-
def using_spork?
|
46
|
-
@state == :using_spork
|
47
|
-
end
|
48
|
-
|
49
|
-
# Used by the server. Returns the current state of Spork.
|
50
|
-
def state
|
51
|
-
@state ||= :not_using_spork
|
52
|
-
end
|
53
|
-
|
54
|
-
# Used by the server. Called when loading the prefork blocks of the code.
|
55
|
-
def exec_prefork(&block)
|
56
|
-
using_spork!
|
57
|
-
yield
|
58
|
-
end
|
59
|
-
|
60
|
-
# Used by the server. Called to run all of the prefork blocks.
|
61
|
-
def exec_each_run(&block)
|
62
|
-
each_run_procs.each { |p| p.call }
|
63
|
-
each_run_procs.clear
|
64
|
-
yield if block_given?
|
65
|
-
end
|
66
|
-
|
67
|
-
# Traps an instance method of a class (or module) so any calls to it don't actually run until Spork.exec_each_run
|
68
|
-
def trap_method(klass, method_name)
|
69
|
-
method_name_without_spork, method_name_with_spork = alias_method_names(method_name, :spork)
|
70
|
-
|
71
|
-
klass.class_eval <<-EOF, __FILE__, __LINE__ + 1
|
72
|
-
alias :#{method_name_without_spork} :#{method_name} unless method_defined?(:#{method_name_without_spork})
|
73
|
-
def #{method_name}(*args)
|
74
|
-
Spork.each_run(false) do
|
75
|
-
#{method_name_without_spork}(*args)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
EOF
|
79
|
-
end
|
80
|
-
|
81
|
-
# Same as trap_method, but for class methods instead
|
82
|
-
def trap_class_method(klass, method_name)
|
83
|
-
trap_method((class << klass; self; end), method_name)
|
84
|
-
end
|
85
|
-
|
86
|
-
def detect_and_require(subfolder)
|
87
|
-
([LIBDIR.to_s] + other_spork_gem_load_paths).uniq.each do |gem_path|
|
88
|
-
Dir.glob(File.join(gem_path, subfolder)).each { |file| require file }
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def other_spork_gem_load_paths
|
93
|
-
@other_spork_gem_load_paths ||= (
|
94
|
-
Gem.latest_load_paths.grep(/spork/).select do |g|
|
95
|
-
not g.match(%r{/spork-[0-9\-.]+/lib}) # don't include other versions of spork
|
96
|
-
end
|
97
|
-
)
|
98
|
-
end
|
99
|
-
|
100
|
-
private
|
101
|
-
def alias_method_names(method_name, feature)
|
102
|
-
/^(.+?)([\?\!]{0,1})$/.match(method_name.to_s)
|
103
|
-
["#{$1}_without_spork#{$2}", "#{$1}_with_spork#{$2}"]
|
104
|
-
end
|
105
|
-
|
106
|
-
def already_ran
|
107
|
-
@already_ran ||= []
|
108
|
-
end
|
109
|
-
|
110
|
-
def expanded_caller(caller_line)
|
111
|
-
file, line = caller_line.split(":")
|
112
|
-
line.gsub(/:.+/, '')
|
113
|
-
File.expand_path(file, Dir.pwd) + ":" + line
|
114
|
-
end
|
115
|
-
|
116
|
-
def already_ran?(caller_script_and_line)
|
117
|
-
return true if already_ran.include?(expanded_caller(caller_script_and_line))
|
118
|
-
already_ran << expanded_caller(caller_script_and_line)
|
119
|
-
false
|
120
|
-
end
|
121
|
-
|
122
|
-
def each_run_procs
|
123
|
-
@each_run_procs ||= []
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
|
2
|
+
require 'pathname'
|
3
|
+
module Spork
|
4
|
+
BINARY = File.expand_path(File.dirname(__FILE__) + '/../bin/spork')
|
5
|
+
LIBDIR = Pathname.new(File.expand_path(File.dirname(__FILE__)))
|
6
|
+
|
7
|
+
autoload :Server, (LIBDIR + 'spork/server').to_s
|
8
|
+
autoload :TestFramework, (LIBDIR + 'spork/test_framework').to_s
|
9
|
+
autoload :AppFramework, (LIBDIR + 'spork/app_framework').to_s
|
10
|
+
autoload :RunStrategy, (LIBDIR + 'spork/run_strategy').to_s
|
11
|
+
autoload :Runner, (LIBDIR + 'spork/runner').to_s
|
12
|
+
autoload :Forker, (LIBDIR + 'spork/forker').to_s
|
13
|
+
autoload :Diagnoser, (LIBDIR + 'spork/diagnoser').to_s
|
14
|
+
|
15
|
+
class << self
|
16
|
+
# Run a block, during prefork mode. By default, if prefork is called twice in the same file and line number, the supplied block will only be ran once.
|
17
|
+
#
|
18
|
+
# == Parameters
|
19
|
+
#
|
20
|
+
# * +prevent_double_run+ - Pass false to disable double run prevention
|
21
|
+
def prefork(prevent_double_run = true, &block)
|
22
|
+
return if prevent_double_run && already_ran?(caller.first)
|
23
|
+
yield
|
24
|
+
end
|
25
|
+
|
26
|
+
# Run a block AFTER the fork occurs. By default, if prefork is called twice in the same file and line number, the supplied block will only be ran once.
|
27
|
+
#
|
28
|
+
# == Parameters
|
29
|
+
#
|
30
|
+
# * +prevent_double_run+ - Pass false to disable double run prevention
|
31
|
+
def each_run(prevent_double_run = true, &block)
|
32
|
+
return if prevent_double_run && already_ran?(caller.first)
|
33
|
+
if @state == :using_spork
|
34
|
+
each_run_procs << block
|
35
|
+
else
|
36
|
+
yield
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Used by the server. Sets the state to activate spork. Otherwise, prefork and each_run are run in passive mode, allowing specs without a Spork server.
|
41
|
+
def using_spork!
|
42
|
+
@state = :using_spork
|
43
|
+
end
|
44
|
+
|
45
|
+
def using_spork?
|
46
|
+
@state == :using_spork
|
47
|
+
end
|
48
|
+
|
49
|
+
# Used by the server. Returns the current state of Spork.
|
50
|
+
def state
|
51
|
+
@state ||= :not_using_spork
|
52
|
+
end
|
53
|
+
|
54
|
+
# Used by the server. Called when loading the prefork blocks of the code.
|
55
|
+
def exec_prefork(&block)
|
56
|
+
using_spork!
|
57
|
+
yield
|
58
|
+
end
|
59
|
+
|
60
|
+
# Used by the server. Called to run all of the prefork blocks.
|
61
|
+
def exec_each_run(&block)
|
62
|
+
each_run_procs.each { |p| p.call }
|
63
|
+
each_run_procs.clear
|
64
|
+
yield if block_given?
|
65
|
+
end
|
66
|
+
|
67
|
+
# Traps an instance method of a class (or module) so any calls to it don't actually run until Spork.exec_each_run
|
68
|
+
def trap_method(klass, method_name)
|
69
|
+
method_name_without_spork, method_name_with_spork = alias_method_names(method_name, :spork)
|
70
|
+
|
71
|
+
klass.class_eval <<-EOF, __FILE__, __LINE__ + 1
|
72
|
+
alias :#{method_name_without_spork} :#{method_name} unless method_defined?(:#{method_name_without_spork})
|
73
|
+
def #{method_name}(*args)
|
74
|
+
Spork.each_run(false) do
|
75
|
+
#{method_name_without_spork}(*args)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
EOF
|
79
|
+
end
|
80
|
+
|
81
|
+
# Same as trap_method, but for class methods instead
|
82
|
+
def trap_class_method(klass, method_name)
|
83
|
+
trap_method((class << klass; self; end), method_name)
|
84
|
+
end
|
85
|
+
|
86
|
+
def detect_and_require(subfolder)
|
87
|
+
([LIBDIR.to_s] + other_spork_gem_load_paths).uniq.each do |gem_path|
|
88
|
+
Dir.glob(File.join(gem_path, subfolder)).each { |file| require file }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def other_spork_gem_load_paths
|
93
|
+
@other_spork_gem_load_paths ||= (
|
94
|
+
Gem.latest_load_paths.grep(/spork/).select do |g|
|
95
|
+
not g.match(%r{/spork-[0-9\-.]+/lib}) # don't include other versions of spork
|
96
|
+
end
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
def alias_method_names(method_name, feature)
|
102
|
+
/^(.+?)([\?\!]{0,1})$/.match(method_name.to_s)
|
103
|
+
["#{$1}_without_spork#{$2}", "#{$1}_with_spork#{$2}"]
|
104
|
+
end
|
105
|
+
|
106
|
+
def already_ran
|
107
|
+
@already_ran ||= []
|
108
|
+
end
|
109
|
+
|
110
|
+
def expanded_caller(caller_line)
|
111
|
+
file, line = caller_line.split(":")
|
112
|
+
line.gsub(/:.+/, '')
|
113
|
+
File.expand_path(file, Dir.pwd) + ":" + line
|
114
|
+
end
|
115
|
+
|
116
|
+
def already_ran?(caller_script_and_line)
|
117
|
+
return true if already_ran.include?(expanded_caller(caller_script_and_line))
|
118
|
+
already_ran << expanded_caller(caller_script_and_line)
|
119
|
+
false
|
120
|
+
end
|
121
|
+
|
122
|
+
def each_run_procs
|
123
|
+
@each_run_procs ||= []
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/lib/spork/app_framework.rb
CHANGED
@@ -1,74 +1,74 @@
|
|
1
|
-
class Spork::AppFramework
|
2
|
-
# A hash of procs where the key is the class name, and the proc takes no arguments and returns true if it detects that said application framework is being used in the project.
|
3
|
-
#
|
4
|
-
# The key :Rails maps to Spork::AppFramework::Rails
|
5
|
-
#
|
6
|
-
# This is used to reduce the amount of code needed to be loaded - only the detected application framework's support code is loaded.
|
7
|
-
SUPPORTED_FRAMEWORKS = {
|
8
|
-
:Rails => lambda {
|
9
|
-
File.exist?("config/environment.rb") && File.read("config/environment.rb").include?('RAILS_GEM_VERSION')
|
10
|
-
}
|
11
|
-
} unless defined? SUPPORTED_FRAMEWORKS
|
12
|
-
|
13
|
-
def self.setup_autoload
|
14
|
-
([:Unknown] + SUPPORTED_FRAMEWORKS.keys).each do |name|
|
15
|
-
autoload name, File.join(File.dirname(__FILE__), "app_framework", name.to_s.downcase)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# Iterates through all SUPPORTED_FRAMEWORKS and returns the symbolic name of the project application framework detected. Otherwise, returns :Unknown
|
20
|
-
def self.detect_framework_name
|
21
|
-
SUPPORTED_FRAMEWORKS.each do |key, value|
|
22
|
-
return key if value.call
|
23
|
-
end
|
24
|
-
:Unknown
|
25
|
-
end
|
26
|
-
|
27
|
-
# Same as detect_framework_name, but returns an instance of the specific AppFramework class.
|
28
|
-
def self.detect_framework
|
29
|
-
name = detect_framework_name
|
30
|
-
self[name]
|
31
|
-
end
|
32
|
-
|
33
|
-
# Initializes, stores, and returns a singleton instance of the named AppFramework.
|
34
|
-
#
|
35
|
-
# == Parameters
|
36
|
-
#
|
37
|
-
# # +name+ - A symbolic name of a AppFramework subclass
|
38
|
-
#
|
39
|
-
# == Example
|
40
|
-
#
|
41
|
-
# Spork::AppFramework[:Rails]
|
42
|
-
def self.[](name)
|
43
|
-
instances[name] ||= const_get(name).new
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.short_name
|
47
|
-
name.gsub('Spork::AppFramework::', '')
|
48
|
-
end
|
49
|
-
|
50
|
-
# If there is some stuff out of the box that the Spork can do to speed up tests without the test helper file being bootstrapped, this should return false.
|
51
|
-
def bootstrap_required?
|
52
|
-
entry_point.nil?
|
53
|
-
end
|
54
|
-
|
55
|
-
# Abstract: The path to the file that loads the project environment, ie config/environment.rb. Returns nil if there is none.
|
56
|
-
def entry_point
|
57
|
-
raise NotImplementedError
|
58
|
-
end
|
59
|
-
|
60
|
-
def preload(&block)
|
61
|
-
yield
|
62
|
-
end
|
63
|
-
|
64
|
-
def short_name
|
65
|
-
self.class.short_name
|
66
|
-
end
|
67
|
-
|
68
|
-
protected
|
69
|
-
def self.instances
|
70
|
-
@instances ||= {}
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
1
|
+
class Spork::AppFramework
|
2
|
+
# A hash of procs where the key is the class name, and the proc takes no arguments and returns true if it detects that said application framework is being used in the project.
|
3
|
+
#
|
4
|
+
# The key :Rails maps to Spork::AppFramework::Rails
|
5
|
+
#
|
6
|
+
# This is used to reduce the amount of code needed to be loaded - only the detected application framework's support code is loaded.
|
7
|
+
SUPPORTED_FRAMEWORKS = {
|
8
|
+
:Rails => lambda {
|
9
|
+
File.exist?("config/environment.rb") && File.read("config/environment.rb").include?('RAILS_GEM_VERSION')
|
10
|
+
}
|
11
|
+
} unless defined? SUPPORTED_FRAMEWORKS
|
12
|
+
|
13
|
+
def self.setup_autoload
|
14
|
+
([:Unknown] + SUPPORTED_FRAMEWORKS.keys).each do |name|
|
15
|
+
autoload name, File.join(File.dirname(__FILE__), "app_framework", name.to_s.downcase)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Iterates through all SUPPORTED_FRAMEWORKS and returns the symbolic name of the project application framework detected. Otherwise, returns :Unknown
|
20
|
+
def self.detect_framework_name
|
21
|
+
SUPPORTED_FRAMEWORKS.each do |key, value|
|
22
|
+
return key if value.call
|
23
|
+
end
|
24
|
+
:Unknown
|
25
|
+
end
|
26
|
+
|
27
|
+
# Same as detect_framework_name, but returns an instance of the specific AppFramework class.
|
28
|
+
def self.detect_framework
|
29
|
+
name = detect_framework_name
|
30
|
+
self[name]
|
31
|
+
end
|
32
|
+
|
33
|
+
# Initializes, stores, and returns a singleton instance of the named AppFramework.
|
34
|
+
#
|
35
|
+
# == Parameters
|
36
|
+
#
|
37
|
+
# # +name+ - A symbolic name of a AppFramework subclass
|
38
|
+
#
|
39
|
+
# == Example
|
40
|
+
#
|
41
|
+
# Spork::AppFramework[:Rails]
|
42
|
+
def self.[](name)
|
43
|
+
instances[name] ||= const_get(name).new
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.short_name
|
47
|
+
name.gsub('Spork::AppFramework::', '')
|
48
|
+
end
|
49
|
+
|
50
|
+
# If there is some stuff out of the box that the Spork can do to speed up tests without the test helper file being bootstrapped, this should return false.
|
51
|
+
def bootstrap_required?
|
52
|
+
entry_point.nil?
|
53
|
+
end
|
54
|
+
|
55
|
+
# Abstract: The path to the file that loads the project environment, ie config/environment.rb. Returns nil if there is none.
|
56
|
+
def entry_point
|
57
|
+
raise NotImplementedError
|
58
|
+
end
|
59
|
+
|
60
|
+
def preload(&block)
|
61
|
+
yield
|
62
|
+
end
|
63
|
+
|
64
|
+
def short_name
|
65
|
+
self.class.short_name
|
66
|
+
end
|
67
|
+
|
68
|
+
protected
|
69
|
+
def self.instances
|
70
|
+
@instances ||= {}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
74
|
Spork::AppFramework.setup_autoload
|
@@ -1,158 +1,158 @@
|
|
1
|
-
class Spork::AppFramework::Rails < Spork::AppFramework
|
2
|
-
|
3
|
-
# TODO - subclass this out to handle different versions of rails
|
4
|
-
# Also... this is the nastiest duck punch ever. Clean this up.
|
5
|
-
module NinjaPatcher
|
6
|
-
def self.included(klass)
|
7
|
-
klass.class_eval do
|
8
|
-
unless method_defined?(:load_environment_without_spork)
|
9
|
-
alias :load_environment_without_spork :load_environment
|
10
|
-
alias :load_environment :load_environment_with_spork
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.run_with_spork(*args, &block) # it's all fun and games until someone gets an eye poked out
|
14
|
-
if ENV['RAILS_ENV']
|
15
|
-
Object.send(:remove_const, :RAILS_ENV)
|
16
|
-
Object.const_set(:RAILS_ENV, ENV['RAILS_ENV'].dup)
|
17
|
-
end
|
18
|
-
run_without_spork(*args, &block)
|
19
|
-
end
|
20
|
-
|
21
|
-
class << self
|
22
|
-
unless method_defined?(:run_without_spork)
|
23
|
-
alias :run_without_spork :run
|
24
|
-
alias :run :run_with_spork
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def load_environment_with_spork
|
31
|
-
result = load_environment_without_spork
|
32
|
-
install_hooks
|
33
|
-
result
|
34
|
-
end
|
35
|
-
|
36
|
-
def install_hooks
|
37
|
-
auto_reestablish_db_connection
|
38
|
-
delay_observer_loading
|
39
|
-
delay_app_preload
|
40
|
-
delay_application_controller_loading
|
41
|
-
delay_route_loading
|
42
|
-
delay_eager_view_loading
|
43
|
-
end
|
44
|
-
|
45
|
-
def reset_rails_env
|
46
|
-
return unless ENV['RAILS_ENV']
|
47
|
-
Object.send(:remove_const, :RAILS_ENV)
|
48
|
-
Object.const_set(:RAILS_ENV, ENV['RAILS_ENV'].dup)
|
49
|
-
end
|
50
|
-
|
51
|
-
def delay_observer_loading
|
52
|
-
if ::Rails::Initializer.instance_methods.include?('load_observers')
|
53
|
-
Spork.trap_method(::Rails::Initializer, :load_observers)
|
54
|
-
end
|
55
|
-
if Object.const_defined?(:ActionController)
|
56
|
-
require "action_controller/dispatcher.rb"
|
57
|
-
Spork.trap_class_method(::ActionController::Dispatcher, :define_dispatcher_callbacks) if ActionController::Dispatcher.respond_to?(:define_dispatcher_callbacks)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def delay_app_preload
|
62
|
-
if ::Rails::Initializer.instance_methods.include?('load_application_classes')
|
63
|
-
Spork.trap_method(::Rails::Initializer, :load_application_classes)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def delay_application_controller_loading
|
68
|
-
if application_controller_source = ["#{Dir.pwd}/app/controllers/application.rb", "#{Dir.pwd}/app/controllers/application_controller.rb"].find { |f| File.exist?(f) }
|
69
|
-
application_helper_source = "#{Dir.pwd}/app/helpers/application_helper.rb"
|
70
|
-
load_paths = (::ActiveSupport.const_defined?(:Dependencies) ? ::ActiveSupport::Dependencies : ::Dependencies).load_paths
|
71
|
-
load_paths.unshift(File.expand_path('rails_stub_files', File.dirname(__FILE__)))
|
72
|
-
Spork.each_run do
|
73
|
-
require application_controller_source
|
74
|
-
require application_helper_source if File.exist?(application_helper_source)
|
75
|
-
# update the rails magic to refresh the module
|
76
|
-
ApplicationController.send(:helper, ApplicationHelper)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def auto_reestablish_db_connection
|
82
|
-
if Object.const_defined?(:ActiveRecord)
|
83
|
-
Spork.each_run do
|
84
|
-
# rails lib/test_help.rb is very aggressive about overriding RAILS_ENV and will switch it back to test after the cucumber env was loaded
|
85
|
-
reset_rails_env
|
86
|
-
ActiveRecord::Base.establish_connection
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def delay_route_loading
|
92
|
-
if ::Rails::Initializer.instance_methods.include?('initialize_routing')
|
93
|
-
Spork.trap_method(::Rails::Initializer, :initialize_routing)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def delay_eager_view_loading
|
98
|
-
# So, in testing mode it seems it would be optimal to not eager load
|
99
|
-
# views (as your may only run a test that uses one or two views).
|
100
|
-
# However, I decided to delay eager loading rather than force it to
|
101
|
-
# disable because you may wish to eager load your views (I.E. you're
|
102
|
-
# testing concurrency)
|
103
|
-
|
104
|
-
# Rails 2.3.x +
|
105
|
-
if defined?(::ActionView::Template::EagerPath)
|
106
|
-
Spork.trap_method(::ActionView::Template::EagerPath, :load!)
|
107
|
-
end
|
108
|
-
# Rails 2.2.x
|
109
|
-
if defined?(::ActionView::PathSet::Path)
|
110
|
-
Spork.trap_method(::ActionView::PathSet::Path, :load)
|
111
|
-
end
|
112
|
-
# Rails 2.0.5 - 2.1.x don't appear to eager cache views.
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def preload(&block)
|
117
|
-
STDERR.puts "Preloading Rails environment"
|
118
|
-
STDERR.flush
|
119
|
-
ENV["RAILS_ENV"] ||= 'test'
|
120
|
-
preload_rails
|
121
|
-
yield
|
122
|
-
end
|
123
|
-
|
124
|
-
def entry_point
|
125
|
-
@entry_point ||= File.expand_path("config/environment.rb", Dir.pwd)
|
126
|
-
end
|
127
|
-
|
128
|
-
alias :environment_file :entry_point
|
129
|
-
|
130
|
-
def boot_file
|
131
|
-
@boot_file ||= File.join(File.dirname(environment_file), 'boot')
|
132
|
-
end
|
133
|
-
|
134
|
-
def environment_contents
|
135
|
-
@environment_contents ||= File.read(environment_file)
|
136
|
-
end
|
137
|
-
|
138
|
-
def vendor
|
139
|
-
@vendor ||= File.expand_path("vendor/rails", Dir.pwd)
|
140
|
-
end
|
141
|
-
|
142
|
-
def version
|
143
|
-
@version ||= (
|
144
|
-
if /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/.match(environment_contents)
|
145
|
-
$1
|
146
|
-
else
|
147
|
-
nil
|
148
|
-
end
|
149
|
-
)
|
150
|
-
end
|
151
|
-
|
152
|
-
def preload_rails
|
153
|
-
Object.const_set(:RAILS_GEM_VERSION, version) if version
|
154
|
-
require boot_file
|
155
|
-
::Rails::Initializer.send(:include, Spork::AppFramework::Rails::NinjaPatcher)
|
156
|
-
end
|
157
|
-
|
1
|
+
class Spork::AppFramework::Rails < Spork::AppFramework
|
2
|
+
|
3
|
+
# TODO - subclass this out to handle different versions of rails
|
4
|
+
# Also... this is the nastiest duck punch ever. Clean this up.
|
5
|
+
module NinjaPatcher
|
6
|
+
def self.included(klass)
|
7
|
+
klass.class_eval do
|
8
|
+
unless method_defined?(:load_environment_without_spork)
|
9
|
+
alias :load_environment_without_spork :load_environment
|
10
|
+
alias :load_environment :load_environment_with_spork
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.run_with_spork(*args, &block) # it's all fun and games until someone gets an eye poked out
|
14
|
+
if ENV['RAILS_ENV']
|
15
|
+
Object.send(:remove_const, :RAILS_ENV)
|
16
|
+
Object.const_set(:RAILS_ENV, ENV['RAILS_ENV'].dup)
|
17
|
+
end
|
18
|
+
run_without_spork(*args, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
unless method_defined?(:run_without_spork)
|
23
|
+
alias :run_without_spork :run
|
24
|
+
alias :run :run_with_spork
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def load_environment_with_spork
|
31
|
+
result = load_environment_without_spork
|
32
|
+
install_hooks
|
33
|
+
result
|
34
|
+
end
|
35
|
+
|
36
|
+
def install_hooks
|
37
|
+
auto_reestablish_db_connection
|
38
|
+
delay_observer_loading
|
39
|
+
delay_app_preload
|
40
|
+
delay_application_controller_loading
|
41
|
+
delay_route_loading
|
42
|
+
delay_eager_view_loading
|
43
|
+
end
|
44
|
+
|
45
|
+
def reset_rails_env
|
46
|
+
return unless ENV['RAILS_ENV']
|
47
|
+
Object.send(:remove_const, :RAILS_ENV)
|
48
|
+
Object.const_set(:RAILS_ENV, ENV['RAILS_ENV'].dup)
|
49
|
+
end
|
50
|
+
|
51
|
+
def delay_observer_loading
|
52
|
+
if ::Rails::Initializer.instance_methods.include?('load_observers')
|
53
|
+
Spork.trap_method(::Rails::Initializer, :load_observers)
|
54
|
+
end
|
55
|
+
if Object.const_defined?(:ActionController)
|
56
|
+
require "action_controller/dispatcher.rb"
|
57
|
+
Spork.trap_class_method(::ActionController::Dispatcher, :define_dispatcher_callbacks) if ActionController::Dispatcher.respond_to?(:define_dispatcher_callbacks)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def delay_app_preload
|
62
|
+
if ::Rails::Initializer.instance_methods.include?('load_application_classes')
|
63
|
+
Spork.trap_method(::Rails::Initializer, :load_application_classes)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def delay_application_controller_loading
|
68
|
+
if application_controller_source = ["#{Dir.pwd}/app/controllers/application.rb", "#{Dir.pwd}/app/controllers/application_controller.rb"].find { |f| File.exist?(f) }
|
69
|
+
application_helper_source = "#{Dir.pwd}/app/helpers/application_helper.rb"
|
70
|
+
load_paths = (::ActiveSupport.const_defined?(:Dependencies) ? ::ActiveSupport::Dependencies : ::Dependencies).load_paths
|
71
|
+
load_paths.unshift(File.expand_path('rails_stub_files', File.dirname(__FILE__)))
|
72
|
+
Spork.each_run do
|
73
|
+
require application_controller_source
|
74
|
+
require application_helper_source if File.exist?(application_helper_source)
|
75
|
+
# update the rails magic to refresh the module
|
76
|
+
ApplicationController.send(:helper, ApplicationHelper)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def auto_reestablish_db_connection
|
82
|
+
if Object.const_defined?(:ActiveRecord)
|
83
|
+
Spork.each_run do
|
84
|
+
# rails lib/test_help.rb is very aggressive about overriding RAILS_ENV and will switch it back to test after the cucumber env was loaded
|
85
|
+
reset_rails_env
|
86
|
+
ActiveRecord::Base.establish_connection
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def delay_route_loading
|
92
|
+
if ::Rails::Initializer.instance_methods.include?('initialize_routing')
|
93
|
+
Spork.trap_method(::Rails::Initializer, :initialize_routing)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def delay_eager_view_loading
|
98
|
+
# So, in testing mode it seems it would be optimal to not eager load
|
99
|
+
# views (as your may only run a test that uses one or two views).
|
100
|
+
# However, I decided to delay eager loading rather than force it to
|
101
|
+
# disable because you may wish to eager load your views (I.E. you're
|
102
|
+
# testing concurrency)
|
103
|
+
|
104
|
+
# Rails 2.3.x +
|
105
|
+
if defined?(::ActionView::Template::EagerPath)
|
106
|
+
Spork.trap_method(::ActionView::Template::EagerPath, :load!)
|
107
|
+
end
|
108
|
+
# Rails 2.2.x
|
109
|
+
if defined?(::ActionView::PathSet::Path)
|
110
|
+
Spork.trap_method(::ActionView::PathSet::Path, :load)
|
111
|
+
end
|
112
|
+
# Rails 2.0.5 - 2.1.x don't appear to eager cache views.
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def preload(&block)
|
117
|
+
STDERR.puts "Preloading Rails environment"
|
118
|
+
STDERR.flush
|
119
|
+
ENV["RAILS_ENV"] ||= 'test'
|
120
|
+
preload_rails
|
121
|
+
yield
|
122
|
+
end
|
123
|
+
|
124
|
+
def entry_point
|
125
|
+
@entry_point ||= File.expand_path("config/environment.rb", Dir.pwd)
|
126
|
+
end
|
127
|
+
|
128
|
+
alias :environment_file :entry_point
|
129
|
+
|
130
|
+
def boot_file
|
131
|
+
@boot_file ||= File.join(File.dirname(environment_file), 'boot')
|
132
|
+
end
|
133
|
+
|
134
|
+
def environment_contents
|
135
|
+
@environment_contents ||= File.read(environment_file)
|
136
|
+
end
|
137
|
+
|
138
|
+
def vendor
|
139
|
+
@vendor ||= File.expand_path("vendor/rails", Dir.pwd)
|
140
|
+
end
|
141
|
+
|
142
|
+
def version
|
143
|
+
@version ||= (
|
144
|
+
if /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/.match(environment_contents)
|
145
|
+
$1
|
146
|
+
else
|
147
|
+
nil
|
148
|
+
end
|
149
|
+
)
|
150
|
+
end
|
151
|
+
|
152
|
+
def preload_rails
|
153
|
+
Object.const_set(:RAILS_GEM_VERSION, version) if version
|
154
|
+
require boot_file
|
155
|
+
::Rails::Initializer.send(:include, Spork::AppFramework::Rails::NinjaPatcher)
|
156
|
+
end
|
157
|
+
|
158
158
|
end
|