lib/spork.rb in bmabey-spork-0.4.4 vs lib/spork.rb in bmabey-spork-0.5.9
- old
+ new
@@ -1,40 +1,99 @@
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
module Spork
- SPEC_HELPER_FILE = File.join(Dir.pwd, "spec/spec_helper.rb")
-
+ BINARY = File.expand_path(File.dirname(__FILE__) + '/../bin/spork')
+ LIBDIR = File.expand_path(File.dirname(__FILE__))
+
class << self
- def prefork(&block)
- return if @already_preforked
- @already_preforked = true
+ # 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.
+ #
+ # == Parameters
+ #
+ # * +prevent_double_run+ - Pass false to disable double run prevention
+ def prefork(prevent_double_run = true, &block)
+ return if prevent_double_run && already_ran?(caller.first)
yield
end
-
- def each_run(&block)
- return if @state == :preforking || (@state != :not_using_spork && @already_run)
- @already_run = true
- yield
+
+ # 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.
+ #
+ # == Parameters
+ #
+ # * +prevent_double_run+ - Pass false to disable double run prevention
+ def each_run(prevent_double_run = true, &block)
+ return if prevent_double_run && already_ran?(caller.first)
+ if @state == :using_spork
+ each_run_procs << block
+ else
+ yield
+ end
end
-
- def preforking!
- @state = :preforking
+
+ # 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.
+ def using_spork!
+ @state = :using_spork
end
-
- def running!
- @state = :running
- end
-
+
+ # Used by the server. Returns the current state of Spork.
def state
@state ||= :not_using_spork
end
-
- def exec_prefork(helper_file)
- preforking!
- load(helper_file)
+
+ # Used by the server. Called when loading the prefork blocks of the code.
+ def exec_prefork(&block)
+ using_spork!
+ yield
end
-
- def exec_each_run(helper_file)
- running!
- load(helper_file)
+
+ # Used by the server. Called to run all of the prefork blocks.
+ def exec_each_run(&block)
+ each_run_procs.each { |p| p.call }
+ each_run_procs.clear
+ yield if block_given?
end
+
+ # Traps an instance method of a class (or module) so any calls to it don't actually run until Spork.exec_each_run
+ def trap_method(klass, method_name)
+ method_name_without_spork, method_name_with_spork = alias_method_names(method_name, :spork)
+
+ klass.class_eval <<-EOF, __FILE__, __LINE__ + 1
+ alias :#{method_name_without_spork} :#{method_name} unless method_defined?(:#{method_name_without_spork})
+ def #{method_name}(*args)
+ Spork.each_run(false) do
+ #{method_name_without_spork}(*args)
+ end
+ end
+ EOF
+ end
+
+ # Same as trap_method, but for class methods instead
+ def trap_class_method(klass, method_name)
+ trap_method((class << klass; self; end), method_name)
+ end
+
+ private
+ def alias_method_names(method_name, feature)
+ /^(.+?)([\?\!]{0,1})$/.match(method_name.to_s)
+ ["#{$1}_without_spork#{$2}", "#{$1}_with_spork#{$2}"]
+ end
+
+ def already_ran
+ @already_ran ||= []
+ end
+
+ def expanded_caller(caller_line)
+ file, line = caller_line.split(":")
+ line.gsub(/:.+/, '')
+ File.expand_path(file, Dir.pwd) + ":" + line
+ end
+
+ def already_ran?(caller_script_and_line)
+ return true if already_ran.include?(expanded_caller(caller_script_and_line))
+ already_ran << expanded_caller(caller_script_and_line)
+ false
+ end
+
+ def each_run_procs
+ @each_run_procs ||= []
+ end
end
end