Class: Spork::Server

Inherits:
Object
  • Object
show all
Includes:
CustomIOStreams
Defined in:
lib/spork/server.rb

Overview

An abstract class that is implemented to create a server

(This was originally based off of spec_server.rb from rspec-rails (David Chelimsky), which was based on Florian Weber’s TDDMate)

Direct Known Subclasses

Cucumber, RSpec

Defined Under Namespace

Classes: Cucumber, RSpec

Constant Summary collapse

LOAD_PREFERENCE =
['RSpec', 'Cucumber']
BOOTSTRAP_FILE =
File.dirname(__FILE__) + "/../../assets/bootstrap.rb"
@@supported_servers =
[]

Class Method Summary collapse

Instance Method Summary collapse

Methods included from CustomIOStreams

included, #stderr, #stdout

Class Method Details

.available?Boolean

Returns true if the testing frameworks helper file exists. Override if this is not sufficient to detect your testing framework.

Returns:

  • (Boolean)


48
49
50
# File 'lib/spork/server.rb', line 48

def self.available?
  File.exist?(helper_file)
end

.available_serversObject

Returns a list of all testing servers that have detected their testing framework being used in the project.



34
35
36
# File 'lib/spork/server.rb', line 34

def self.available_servers
  supported_servers.select { |s| s.available? }
end

.bootstrapObject

Bootstraps the current test helper file by prepending a Spork.prefork and Spork.each_run block at the beginning.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/spork/server.rb', line 63

def self.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

.bootstrapped?Boolean

Detects if the test helper has been bootstrapped.

Returns:

  • (Boolean)


58
59
60
# File 'lib/spork/server.rb', line 58

def self.bootstrapped?
  File.read(helper_file).include?("Spork.prefork")
end

.helper_fileObject

Abstract method: returns the entry file that loads the testing environment, such as spec/spec_helper.rb.

Raises:

  • (NotImplemented)


24
25
26
# File 'lib/spork/server.rb', line 24

def self.helper_file
  raise NotImplemented
end

.load_preference_indexObject

Used to specify



53
54
55
# File 'lib/spork/server.rb', line 53

def self.load_preference_index
  LOAD_PREFERENCE.index(server_name) || LOAD_PREFERENCE.length
end

.portObject

Abstract method: returns the servers port. Override this to return the port that should be used by the test framework.

Raises:

  • (NotImplemented)


19
20
21
# File 'lib/spork/server.rb', line 19

def self.port
  raise NotImplemented
end

.runObject



80
81
82
83
# File 'lib/spork/server.rb', line 80

def self.run
  return unless available?
  new.listen
end

.server_nameObject

Convenience method that turns the class name without the namespace



29
30
31
# File 'lib/spork/server.rb', line 29

def self.server_name
  self.name.gsub('Spork::Server::', '')
end

.supported_servers(starting_with = nil) ⇒ Object

Returns a list of all servers that have been implemented (it keeps track of them automatically via Class.inherited)



39
40
41
42
43
44
45
# File 'lib/spork/server.rb', line 39

def self.supported_servers(starting_with = nil)
  @@supported_servers.sort! { |a,b| a.load_preference_index <=> b.load_preference_index }
  return @@supported_servers if starting_with.nil?
  @@supported_servers.select do |s|
    s.server_name.match(/^#{Regexp.escape(starting_with)}/i)
  end
end

Instance Method Details

#helper_fileObject



100
101
102
# File 'lib/spork/server.rb', line 100

def helper_file
  self.class.helper_file
end

#listenObject

Sets up signals and starts the DRb service. If it’s successful, it doesn’t return. Not ever. You don’t need to override this.



86
87
88
89
90
91
92
93
94
# File 'lib/spork/server.rb', line 86

def listen
  trap("SIGINT") { sig_int_received }
  trap("SIGTERM") { abort; exit!(0) }
  trap("USR2") { abort; restart } if Signal.list.has_key?("USR2")
  DRb.start_service("druby://127.0.0.1:#{port}", self)
  stderr.puts "Spork is ready and listening on #{port}!"
  stderr.flush
  DRb.thread.join
end

#portObject



96
97
98
# File 'lib/spork/server.rb', line 96

def port
  self.class.port
end

#run(argv, stderr, stdout) ⇒ Object

This is the public facing method that is served up by DRb. To use it from the client side (in a testing framework):

DRb.start_service("druby://localhost:0") # this allows Ruby to do some magical stuff so you can pass an output stream over DRb.
                                         # see http://redmine.ruby-lang.org/issues/show/496 to see why localhost:0 is used.
spec_server = DRbObject.new_with_uri("druby://127.0.0.1:8989")
spec_server.run(options.argv, $stderr, $stdout)

When implementing a test server, don’t override this method: override run_tests instead.



112
113
114
115
116
117
118
119
120
121
# File 'lib/spork/server.rb', line 112

def run(argv, stderr, stdout)
  abort if running?
  
  @child = ::Spork::Forker.new do
    $stdout, $stderr = stdout, stderr
    Spork.exec_each_run { load helper_file }
    run_tests(argv, stderr, stdout)
  end
  @child.result
end

#running?Boolean

returns whether or not the child (a test run) is running right now.

Returns:

  • (Boolean)


124
125
126
# File 'lib/spork/server.rb', line 124

def running?
  @child && @child.running?
end