class Spork::TestFramework LOAD_PREFERENCE = ['RSpec', 'Cucumber'] BOOTSTRAP_FILE = File.dirname(__FILE__) + "/../../assets/bootstrap.rb" @@supported_test_frameworks = [] attr_reader :stdout, :stderr class FactoryException < Exception; end class NoFrameworksAvailable < FactoryException def message "I can't find any testing frameworks to use. Are you running me from a project directory?" end end class FrameworkNotAvailable < FactoryException def initialize(framework) @framework = framework end def message "I can't find the file #{@framework.helper_file} for the #{@framework.short_name} testing framework.\nAre you running me from the project directory?" end end class NoFrameworkMatched < FactoryException def initialize(beginning_with) @beginning_with = beginning_with end def message "Couldn't find a supported test framework that begins with '#{@beginning_with}'" end end def initialize(stdout = STDOUT, stderr = STDERR) @stdout, @stderr = stdout, stderr end def self.factory(output = STDOUT, error = STDERR, beginning_with = nil) if beginning_with @klass = supported_test_frameworks(beginning_with).first raise(NoFrameworkMatched.new(beginning_with)) if @klass.nil? raise(FrameworkNotAvailable.new(@klass)) unless @klass.available? else @klass = available_test_frameworks.first raise(NoFrameworksAvailable.new) unless @klass end @klass.new(output, error) end def self.helper_file self::HELPER_FILE end def self.default_port (ENV["#{short_name.upcase}_DRB"] || self::DEFAULT_PORT).to_i end def self.short_name self.name.gsub('Spork::TestFramework::', '') end # Returns a list of all testing servers that have detected their testing framework being used in the project. def self.available_test_frameworks supported_test_frameworks.select { |s| s.available? } end # Returns a list of all servers that have been implemented (it keeps track of them automatically via Class.inherited) def self.supported_test_frameworks(starting_with = nil) @@supported_test_frameworks.sort! { |a,b| a.load_preference_index <=> b.load_preference_index } return @@supported_test_frameworks if starting_with.nil? @@supported_test_frameworks.select do |s| s.short_name.match(/^#{Regexp.escape(starting_with)}/i) end end def short_name self.class.short_name end def helper_file self.class.helper_file end # Detects if the test helper has been bootstrapped. def bootstrapped? File.read(helper_file).include?("Spork.prefork") end # Bootstraps the current test helper file by prepending a Spork.prefork and Spork.each_run block at the beginning. def bootstrap if bootstrapped? stderr.puts "Already bootstrapped!" return end stderr.puts "Bootstrapping #{helper_file}." contents = File.read(helper_file) bootstrap_code = File.read(BOOTSTRAP_FILE) File.open(helper_file, "wb") do |f| f.puts bootstrap_code f.puts contents end stderr.puts "Done. Edit #{helper_file} now with your favorite text editor and follow the instructions." true end # Returns true if the testing frameworks helper file exists. Override if this is not sufficient to detect your testing framework. def self.available? File.exist?(helper_file) end # Used to specify def self.load_preference_index LOAD_PREFERENCE.index(short_name) || LOAD_PREFERENCE.length end def preload Spork.exec_prefork do unless bootstrapped? stderr.puts "#{helper_file} has not been bootstrapped. Run spork --bootstrap to do so." stderr.flush if framework.bootstrap_required? 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." stderr.flush return false else load(framework.entry_point) end end framework.preload do if bootstrapped? stderr.puts "Loading Spork.prefork block..." stderr.flush load(helper_file) end end end true end def run_tests(argv, stderr, stdout) raise NotImplementedError end def entry_point bootstrapped? ? helper_file : framework.entry_point end def default_port self.class.default_port end protected def self.inherited(subclass) @@supported_test_frameworks << subclass end def framework @framework ||= Spork::AppFramework.detect_framework end end Spork.detect_and_require('spork/test_framework/*.rb')