Module: Spin

Extended by:
Hooks
Defined in:
lib/spin.rb,
lib/spin/cli.rb,
lib/spin/hooks.rb,
lib/spin/logger.rb,
lib/spin/version.rb

Defined Under Namespace

Modules: CLI, Hooks Classes: Logger

Constant Summary collapse

PUSH_FILE_SEPARATOR =
'|'
ARGS_SEPARATOR =
' -- '
SIGQUIT_MESSAGE =

Messages written to/read from the self-pipe queue.

'SIGQUIT'
SIGINT_MESSAGE =
'SIGINT'
VERSION =
"0.7.1"

Constants included from Hooks

Hooks::HOOKS

Class Method Summary collapse

Methods included from Hooks

execute_hook, hook, parse_hook_file

Class Method Details

.loggerObject



98
99
100
# File 'lib/spin.rb', line 98

def logger
  @logger ||= Spin::Logger.new
end

.push(argv, options) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/spin.rb', line 112

def push(argv, options)
  files_to_load = convert_push_arguments_to_files(argv)

  if root_path = rails_root(options[:preload])
    make_files_relative(files_to_load, root_path)
    Dir.chdir root_path
  end

  files_to_load << "tty?" if $stdout.tty?

  abort if files_to_load.empty?

  logger.info "Spinning up #{files_to_load.join(" ")}"
  send_files_to_serve(files_to_load, options[:trailing_pushed_args] || [])
end

.serve(options) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/spin.rb', line 24

def serve(options)
  ENV['RAILS_ENV'] = 'test' unless ENV['RAILS_ENV']

  if root_path = rails_root(options[:preload])
    Dir.chdir(root_path)
    Spin.parse_hook_file(root_path)
  else
    logger.warn "Could not find #{options[:preload]}. Are you running this from the root of a Rails project?"
  end

  set_server_process_pid

  open_socket do |socket|
    preload(options) if root_path
    self_read, self_write = IO.pipe

    if options[:push_results]
      logger.info "Pushing test results back to push processes"
    else
      trap('SIGQUIT') { sigquit_handler(self_write) }
    end
    trap('SIGINT') { sigint_handler(self_write) }

    loop do
      readable_io = ready_while do
        IO.select([socket, self_read])[0][0]
      end

      if readable_io == self_read
        # One of our signal handlers has fired
        case readable_io.gets.strip
        when SIGQUIT_MESSAGE
          rerun_last_tests(options)
        when SIGINT_MESSAGE
          exit_server(socket)
        end
      else
        # The socket must have had a new test written to it
        run_pushed_tests(socket, options)
      end
    end
  end
end

.server_process?Boolean

Returns true if the current process is the Spin server process.

Returns:

  • (Boolean)


108
109
110
# File 'lib/spin.rb', line 108

def server_process?
  @server_process_pid == Process.pid
end

.set_server_process_pidObject

Called by the Spin server process to store its process pid.



103
104
105
# File 'lib/spin.rb', line 103

def set_server_process_pid
  @server_process_pid = Process.pid
end

.sigint_handler(queue) ⇒ Object

This method is called when a SIGINT ought to be handled.

Given the self-pipe queue, adds a SIGINT message to it. Message is not queued if either of these are true:

1. The current process is not the Spin server process (i.e. it's a test
   process). Instead, the signal is "bubbled up" by exiting.

2. The Spin server is not ready for a new command.


91
92
93
94
95
96
# File 'lib/spin.rb', line 91

def sigint_handler(queue)
  exit unless server_process?
  return unless ready?

  queue.puts(SIGINT_MESSAGE)
end

.sigquit_handler(queue) ⇒ Object

This method is called when a SIGQUIT ought to be handled.

Given the self-pipe queue, adds a SIGQUIT message to it. Message is not queued if the current process is not the Spin server process (i.e. it’s a test process). Otherwise, more than one message would be added to the queue when Ctrl+\ is pressed.



75
76
77
78
79
# File 'lib/spin.rb', line 75

def sigquit_handler(queue)
  return unless server_process?

  queue.puts(SIGQUIT_MESSAGE)
end