spring 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +1 -0
- data/README.md +69 -11
- data/Rakefile +1 -1
- data/lib/spring/application.rb +36 -34
- data/lib/spring/application_manager.rb +3 -1
- data/lib/spring/client.rb +3 -1
- data/lib/spring/client/binstub.rb +4 -0
- data/lib/spring/client/help.rb +69 -13
- data/lib/spring/client/run.rb +7 -9
- data/lib/spring/client/status.rb +30 -0
- data/lib/spring/client/stop.rb +27 -1
- data/lib/spring/commands.rb +46 -10
- data/lib/spring/configuration.rb +8 -0
- data/lib/spring/env.rb +5 -2
- data/lib/spring/process_title_updater.rb +65 -0
- data/lib/spring/server.rb +34 -3
- data/lib/spring/sid.rb +31 -8
- data/lib/spring/version.rb +1 -1
- data/test/acceptance/app_test.rb +119 -116
- data/test/apps/rails-3-2/.gitignore +1 -1
- data/test/unit/client/help_test.rb +50 -0
- data/test/unit/commands_test.rb +21 -2
- data/test/unit/process_title_updater_test.rb +24 -0
- metadata +9 -5
data/lib/spring/commands.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/class/attribute'
|
2
|
-
|
3
1
|
module Spring
|
4
2
|
@commands = {}
|
5
3
|
|
@@ -25,8 +23,19 @@ module Spring
|
|
25
23
|
|
26
24
|
module Commands
|
27
25
|
class Command
|
28
|
-
|
29
|
-
|
26
|
+
@preloads = []
|
27
|
+
|
28
|
+
def self.preloads
|
29
|
+
@preloads ||= superclass.preloads.dup
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.preloads=(val)
|
33
|
+
@preloads = val
|
34
|
+
end
|
35
|
+
|
36
|
+
def preloads
|
37
|
+
self.class.preloads
|
38
|
+
end
|
30
39
|
|
31
40
|
def setup
|
32
41
|
preload_files
|
@@ -50,7 +59,7 @@ MESSAGE
|
|
50
59
|
end
|
51
60
|
|
52
61
|
class Test < Command
|
53
|
-
|
62
|
+
preloads << "test_helper"
|
54
63
|
|
55
64
|
def env
|
56
65
|
"test"
|
@@ -75,11 +84,15 @@ MESSAGE
|
|
75
84
|
$stderr.puts "you need to specify what test to run: spring test TEST_NAME"
|
76
85
|
end
|
77
86
|
end
|
87
|
+
|
88
|
+
def description
|
89
|
+
"Execute a Test::Unit test."
|
90
|
+
end
|
78
91
|
end
|
79
92
|
Spring.register_command "test", Test.new
|
80
93
|
|
81
94
|
class RSpec < Command
|
82
|
-
|
95
|
+
preloads << "spec_helper"
|
83
96
|
|
84
97
|
def env
|
85
98
|
"test"
|
@@ -95,6 +108,10 @@ MESSAGE
|
|
95
108
|
$0 = "rspec"
|
96
109
|
::RSpec::Core::Runner.run(args)
|
97
110
|
end
|
111
|
+
|
112
|
+
def description
|
113
|
+
"Execute an RSpec spec."
|
114
|
+
end
|
98
115
|
end
|
99
116
|
Spring.register_command "rspec", RSpec.new
|
100
117
|
|
@@ -111,6 +128,10 @@ MESSAGE
|
|
111
128
|
def call(args)
|
112
129
|
::Cucumber::Cli::Main.execute(args)
|
113
130
|
end
|
131
|
+
|
132
|
+
def description
|
133
|
+
"Execute a Cucumber feature."
|
134
|
+
end
|
114
135
|
end
|
115
136
|
Spring.register_command "cucumber", Cucumber.new
|
116
137
|
|
@@ -124,19 +145,27 @@ MESSAGE
|
|
124
145
|
ARGV.replace args
|
125
146
|
::Rake.application.run
|
126
147
|
end
|
148
|
+
|
149
|
+
def description
|
150
|
+
"Run a rake task."
|
151
|
+
end
|
127
152
|
end
|
128
153
|
Spring.register_command "rake", Rake.new
|
129
154
|
|
130
155
|
|
131
156
|
class Console < Command
|
132
|
-
def
|
133
|
-
# This cannot be preloaded as it messes up the IRB prompt on OS X
|
134
|
-
# for unknown reasons. See discussion in issue #34.
|
157
|
+
def setup
|
135
158
|
require "rails/commands/console"
|
159
|
+
end
|
136
160
|
|
161
|
+
def call(args)
|
137
162
|
ARGV.replace args
|
138
163
|
::Rails::Console.start(::Rails.application)
|
139
164
|
end
|
165
|
+
|
166
|
+
def description
|
167
|
+
"Start the Rails console."
|
168
|
+
end
|
140
169
|
end
|
141
170
|
Spring.register_command "console", Console.new, alias: "c"
|
142
171
|
|
@@ -150,6 +179,10 @@ MESSAGE
|
|
150
179
|
ARGV.replace args
|
151
180
|
require "rails/commands/generate"
|
152
181
|
end
|
182
|
+
|
183
|
+
def description
|
184
|
+
"Trigger a Rails generator."
|
185
|
+
end
|
153
186
|
end
|
154
187
|
Spring.register_command "generate", Generate.new, alias: "g"
|
155
188
|
|
@@ -159,6 +192,10 @@ MESSAGE
|
|
159
192
|
ARGV.replace args
|
160
193
|
require "rails/commands/runner"
|
161
194
|
end
|
195
|
+
|
196
|
+
def description
|
197
|
+
"Execute a command with the Rails runner."
|
198
|
+
end
|
162
199
|
end
|
163
200
|
Spring.register_command "runner", Runner.new, alias: "r"
|
164
201
|
end
|
@@ -167,5 +204,4 @@ MESSAGE
|
|
167
204
|
# needs to be at the end to allow modification of existing commands.
|
168
205
|
config = File.expand_path("./config/spring.rb")
|
169
206
|
require config if File.exist?(config)
|
170
|
-
|
171
207
|
end
|
data/lib/spring/configuration.rb
CHANGED
@@ -4,6 +4,14 @@ module Spring
|
|
4
4
|
class << self
|
5
5
|
attr_accessor :application_root
|
6
6
|
|
7
|
+
def after_fork_callbacks
|
8
|
+
@after_fork_callbacks ||= []
|
9
|
+
end
|
10
|
+
|
11
|
+
def after_fork(&block)
|
12
|
+
after_fork_callbacks << block
|
13
|
+
end
|
14
|
+
|
7
15
|
def verify_environment!
|
8
16
|
application_root_path
|
9
17
|
end
|
data/lib/spring/env.rb
CHANGED
@@ -25,7 +25,7 @@ module Spring
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def socket_path
|
28
|
-
tmp_path.join(
|
28
|
+
tmp_path.join("spring")
|
29
29
|
end
|
30
30
|
|
31
31
|
def socket_name
|
@@ -33,11 +33,14 @@ module Spring
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def pidfile_path
|
36
|
-
tmp_path.join("
|
36
|
+
tmp_path.join("spring.pid")
|
37
37
|
end
|
38
38
|
|
39
39
|
def pid
|
40
40
|
pidfile_path.exist? ? pidfile_path.read.to_i : nil
|
41
|
+
rescue Errno::ENOENT
|
42
|
+
# This can happen if the pidfile is removed after we check it
|
43
|
+
# exists
|
41
44
|
end
|
42
45
|
|
43
46
|
def app_name
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Spring
|
2
|
+
# Yes, I know this reimplements a bunch of stuff in Active Support, but
|
3
|
+
# I don't want the spring client to depend on AS, in order to keep its
|
4
|
+
# load time down.
|
5
|
+
class ProcessTitleUpdater
|
6
|
+
SECOND = 1
|
7
|
+
MINUTE = 60
|
8
|
+
HOUR = 60*60
|
9
|
+
|
10
|
+
def self.run(&block)
|
11
|
+
updater = new(&block)
|
12
|
+
|
13
|
+
Thread.new {
|
14
|
+
$0 = updater.value
|
15
|
+
loop { $0 = updater.next }
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :block
|
20
|
+
|
21
|
+
def initialize(start = Time.now, &block)
|
22
|
+
@start = start
|
23
|
+
@block = block
|
24
|
+
end
|
25
|
+
|
26
|
+
def interval
|
27
|
+
distance = Time.now - @start
|
28
|
+
|
29
|
+
if distance < MINUTE
|
30
|
+
SECOND
|
31
|
+
elsif distance < HOUR
|
32
|
+
MINUTE
|
33
|
+
else
|
34
|
+
HOUR
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def next
|
39
|
+
sleep interval
|
40
|
+
value
|
41
|
+
end
|
42
|
+
|
43
|
+
def value
|
44
|
+
block.call(distance_in_words)
|
45
|
+
end
|
46
|
+
|
47
|
+
def distance_in_words(now = Time.now)
|
48
|
+
distance = now - @start
|
49
|
+
|
50
|
+
if distance < MINUTE
|
51
|
+
pluralize(distance, "sec")
|
52
|
+
elsif distance < HOUR
|
53
|
+
pluralize(distance / MINUTE, "min")
|
54
|
+
else
|
55
|
+
pluralize(distance / HOUR, "hour")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def pluralize(amount, unit)
|
62
|
+
"#{amount.to_i} #{amount.to_i == 1 ? unit : "#{unit}s"}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/spring/server.rb
CHANGED
@@ -2,6 +2,11 @@ require "socket"
|
|
2
2
|
|
3
3
|
require "spring/env"
|
4
4
|
require "spring/application_manager"
|
5
|
+
require "spring/process_title_updater"
|
6
|
+
|
7
|
+
# readline must be required before we setpgid, otherwise the require may hang,
|
8
|
+
# if readline has been built against libedit. See issue #70.
|
9
|
+
require "readline"
|
5
10
|
|
6
11
|
module Spring
|
7
12
|
class Server
|
@@ -18,14 +23,19 @@ module Spring
|
|
18
23
|
end
|
19
24
|
|
20
25
|
def boot
|
26
|
+
# Boot the server into the process group of the current session.
|
27
|
+
# This will cause it to be automatically killed once the session
|
28
|
+
# ends (i.e. when the user closes their terminal).
|
29
|
+
Process.setpgid(0, SID.pgid)
|
30
|
+
|
21
31
|
# Ignore SIGINT and SIGQUIT otherwise the user typing ^C or ^\ on the command line
|
22
32
|
# will kill the server/application.
|
23
33
|
IGNORE_SIGNALS.each { |sig| trap(sig, "IGNORE") }
|
24
34
|
|
25
35
|
set_exit_hook
|
26
36
|
write_pidfile
|
27
|
-
|
28
|
-
|
37
|
+
redirect_output
|
38
|
+
set_process_title
|
29
39
|
|
30
40
|
server = UNIXServer.open(env.socket_name)
|
31
41
|
loop { serve server.accept }
|
@@ -62,9 +72,30 @@ module Spring
|
|
62
72
|
@pidfile.write("#{Process.pid}\n")
|
63
73
|
@pidfile.fsync
|
64
74
|
else
|
65
|
-
|
75
|
+
$stderr.puts "#{@pidfile.path} is locked; it looks like a server is already running"
|
66
76
|
exit 1
|
67
77
|
end
|
68
78
|
end
|
79
|
+
|
80
|
+
# We can't leave STDOUT, STDERR as they as because then they will
|
81
|
+
# never get closed for the lifetime of the server. This means that
|
82
|
+
# piping, e.g. "spring rake -T | grep db" won't work correctly
|
83
|
+
# because grep will hang while waiting for its stdin to reach EOF.
|
84
|
+
#
|
85
|
+
# However we do want server output to go to the terminal in case
|
86
|
+
# there are exceptions etc, so we just open the current terminal
|
87
|
+
# device directly.
|
88
|
+
def redirect_output
|
89
|
+
# ruby doesn't expose ttyname()
|
90
|
+
file = open(STDIN.tty? ? `tty`.chomp : "/dev/null", "a")
|
91
|
+
STDOUT.reopen(file)
|
92
|
+
STDERR.reopen(file)
|
93
|
+
end
|
94
|
+
|
95
|
+
def set_process_title
|
96
|
+
ProcessTitleUpdater.run { |distance|
|
97
|
+
"spring server | #{env.app_name} | started #{distance} ago"
|
98
|
+
}
|
99
|
+
end
|
69
100
|
end
|
70
101
|
end
|
data/lib/spring/sid.rb
CHANGED
@@ -1,15 +1,38 @@
|
|
1
|
-
|
1
|
+
begin
|
2
|
+
# If rubygems is present, keep it out of the way when loading fiddle,
|
3
|
+
# otherwise if fiddle is not installed then rubygems will load all
|
4
|
+
# gemspecs in its (futile) search for fiddle, which is slow.
|
5
|
+
if respond_to?(:gem_original_require, true)
|
6
|
+
gem_original_require 'fiddle'
|
7
|
+
else
|
8
|
+
require 'fiddle'
|
9
|
+
end
|
10
|
+
rescue LoadError
|
11
|
+
end
|
2
12
|
|
3
13
|
module Spring
|
4
14
|
module SID
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
15
|
+
def self.fiddle_func
|
16
|
+
@fiddle_func ||= Fiddle::Function.new(
|
17
|
+
DL::Handle::DEFAULT['getsid'],
|
18
|
+
[Fiddle::TYPE_INT],
|
19
|
+
Fiddle::TYPE_INT
|
20
|
+
)
|
21
|
+
end
|
10
22
|
|
11
|
-
def self.sid
|
12
|
-
|
23
|
+
def self.sid
|
24
|
+
@sid ||= begin
|
25
|
+
if Process.respond_to?(:getsid)
|
26
|
+
# Ruby 2
|
27
|
+
Process.getsid
|
28
|
+
elsif defined?(Fiddle)
|
29
|
+
# Ruby 1.9.3 compiled with libffi support
|
30
|
+
fiddle_func.call(0)
|
31
|
+
else
|
32
|
+
# last resort: shell out
|
33
|
+
`ps -p #{Process.pid} -o sess=`.to_i
|
34
|
+
end
|
35
|
+
end
|
13
36
|
end
|
14
37
|
|
15
38
|
def self.pgid
|
data/lib/spring/version.rb
CHANGED
data/test/acceptance/app_test.rb
CHANGED
@@ -3,26 +3,23 @@ require 'io/wait'
|
|
3
3
|
require "timeout"
|
4
4
|
require "spring/sid"
|
5
5
|
require "spring/env"
|
6
|
+
require "pty"
|
6
7
|
|
7
8
|
class AppTest < ActiveSupport::TestCase
|
8
9
|
def app_root
|
9
10
|
Pathname.new("#{TEST_ROOT}/apps/rails-3-2")
|
10
11
|
end
|
11
12
|
|
12
|
-
def
|
13
|
-
"
|
13
|
+
def gem_home
|
14
|
+
app_root.join "vendor/gems/#{RUBY_VERSION}"
|
14
15
|
end
|
15
16
|
|
16
|
-
def
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
def server_pid
|
21
|
-
spring_env.pid
|
17
|
+
def spring
|
18
|
+
gem_home.join "bin/spring"
|
22
19
|
end
|
23
20
|
|
24
|
-
def
|
25
|
-
spring_env.
|
21
|
+
def spring_env
|
22
|
+
@spring_env ||= Spring::Env.new(app_root)
|
26
23
|
end
|
27
24
|
|
28
25
|
def stdout
|
@@ -38,90 +35,83 @@ class AppTest < ActiveSupport::TestCase
|
|
38
35
|
|
39
36
|
Bundler.with_clean_env do
|
40
37
|
Process.spawn(
|
41
|
-
{
|
42
|
-
|
43
|
-
"GEM_PATH" => "",
|
44
|
-
"PATH" => "#{app_root}/vendor/gems/bin:#{ENV["PATH"]}"
|
45
|
-
},
|
46
|
-
command,
|
38
|
+
{ "GEM_HOME" => gem_home.to_s, "GEM_PATH" => "" },
|
39
|
+
command.to_s,
|
47
40
|
out: stdout.last,
|
48
41
|
err: stderr.last,
|
42
|
+
in: :close,
|
49
43
|
chdir: app_root.to_s,
|
50
44
|
)
|
51
45
|
end
|
52
46
|
|
53
47
|
_, status = Timeout.timeout(opts.fetch(:timeout, 5)) { Process.wait2 }
|
54
48
|
|
55
|
-
|
49
|
+
stdout, stderr = read_streams
|
50
|
+
puts dump_streams(stdout, stderr) if ENV["SPRING_DEBUG"]
|
56
51
|
|
57
52
|
@times << (Time.now - start_time) if @times
|
58
53
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
54
|
+
{
|
55
|
+
status: status,
|
56
|
+
stdout: stdout,
|
57
|
+
stderr: stderr,
|
58
|
+
}
|
59
|
+
rescue Timeout::Error => e
|
60
|
+
raise e, "Output:\n\n#{dump_streams(*read_streams)}"
|
65
61
|
end
|
66
62
|
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
63
|
+
def read_streams
|
64
|
+
[stdout, stderr].map(&:first).map do |stream|
|
65
|
+
output = ""
|
66
|
+
output << stream.readpartial(10240) while IO.select([stream], [], [], 0.1)
|
67
|
+
output
|
68
|
+
end
|
73
69
|
end
|
74
70
|
|
75
|
-
def
|
76
|
-
|
71
|
+
def dump_streams(stdout, stderr)
|
72
|
+
output = "--- stdout ---\n"
|
73
|
+
output << "#{stdout.chomp}\n"
|
74
|
+
output << "--- stderr ---\n"
|
75
|
+
output << "#{stderr.chomp}\n"
|
76
|
+
output << "\n"
|
77
|
+
output
|
77
78
|
end
|
78
79
|
|
79
80
|
def await_reload
|
80
81
|
sleep 0.4
|
81
82
|
end
|
82
83
|
|
83
|
-
def
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
def assert_unsuccessful_run(*args)
|
89
|
-
status, _, _ = app_run(*args)
|
90
|
-
assert !status.success?, "The run should not be successful but it was"
|
91
|
-
end
|
92
|
-
|
93
|
-
def assert_stdout(command, expected)
|
94
|
-
_, stdout, _ = app_run(command)
|
95
|
-
assert stdout.include?(expected), "expected '#{expected}' to be printed to stdout. But it wasn't, the stdout is:\n#{stdout}"
|
84
|
+
def assert_output(artifacts, expected)
|
85
|
+
expected.each do |stream, output|
|
86
|
+
assert artifacts[stream].include?(output),
|
87
|
+
"expected #{stream} to include '#{output}', but it was:\n\n#{artifacts[stream]}"
|
88
|
+
end
|
96
89
|
end
|
97
90
|
|
98
|
-
def
|
99
|
-
|
100
|
-
assert
|
91
|
+
def assert_success(command, expected_output = nil)
|
92
|
+
artifacts = app_run(command)
|
93
|
+
assert artifacts[:status].success?, "expected successful exit status"
|
94
|
+
assert_output artifacts, expected_output if expected_output
|
101
95
|
end
|
102
96
|
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
second = @times[from + 1]
|
108
|
-
|
109
|
-
assert (second / first) < ratio, "#{second} was not less than #{ratio} of #{first}"
|
97
|
+
def assert_failure(command, expected_output = nil)
|
98
|
+
artifacts = app_run(command)
|
99
|
+
assert !artifacts[:status].success?, "expected unsuccessful exit status"
|
100
|
+
assert_output artifacts, expected_output if expected_output
|
110
101
|
end
|
111
102
|
|
112
|
-
def
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
assert !server_running?, "The server should not be running but it is"
|
103
|
+
def assert_speedup(ratio = 0.6)
|
104
|
+
@times = []
|
105
|
+
yield
|
106
|
+
assert (@times.last / @times.first) < ratio, "#{@times.last} was not less than #{ratio} of #{@times.first}"
|
107
|
+
@times = nil
|
118
108
|
end
|
119
109
|
|
120
|
-
def
|
121
|
-
"spring test #{@test}"
|
110
|
+
def spring_test_command
|
111
|
+
"#{spring} test #{@test}"
|
122
112
|
end
|
123
113
|
|
124
|
-
@@
|
114
|
+
@@installed = false
|
125
115
|
|
126
116
|
setup do
|
127
117
|
@test = "#{app_root}/test/functional/posts_controller_test.rb"
|
@@ -129,59 +119,51 @@ class AppTest < ActiveSupport::TestCase
|
|
129
119
|
@controller = "#{app_root}/app/controllers/posts_controller.rb"
|
130
120
|
@controller_contents = File.read(@controller)
|
131
121
|
|
132
|
-
|
133
|
-
|
134
|
-
unless @@installed_spring
|
122
|
+
unless @@installed
|
123
|
+
FileUtils.mkdir_p(gem_home)
|
135
124
|
system "gem build spring.gemspec 2>/dev/null 1>/dev/null"
|
136
|
-
app_run "gem install ../../../spring
|
137
|
-
|
125
|
+
app_run "gem install ../../../spring-#{Spring::VERSION}.gem"
|
126
|
+
app_run "(gem list bundler | grep bundler) || gem install bundler #{'--pre' if RUBY_VERSION >= "2.0"}", timeout: nil
|
127
|
+
app_run "bundle check || bundle update", timeout: nil
|
128
|
+
app_run "bundle exec rake db:migrate db:test:clone"
|
129
|
+
@@installed = true
|
138
130
|
end
|
139
131
|
|
140
132
|
FileUtils.rm_rf "#{app_root}/bin"
|
141
|
-
app_run "(gem list bundler | grep bundler) || gem install bundler", timeout: nil
|
142
|
-
app_run "bundle check || bundle update", timeout: nil
|
143
|
-
app_run "bundle exec rake db:migrate"
|
144
|
-
|
145
|
-
@times = []
|
146
133
|
end
|
147
134
|
|
148
135
|
teardown do
|
149
|
-
|
150
|
-
Process.kill('TERM', pid)
|
151
|
-
end
|
152
|
-
|
136
|
+
app_run "#{spring} stop"
|
153
137
|
File.write(@test, @test_contents)
|
154
138
|
File.write(@controller, @controller_contents)
|
155
139
|
end
|
156
140
|
|
157
141
|
test "basic" do
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
assert_successful_run test_command
|
162
|
-
assert_speedup
|
142
|
+
assert_speedup do
|
143
|
+
2.times { app_run spring_test_command }
|
144
|
+
end
|
163
145
|
end
|
164
146
|
|
165
147
|
test "help message when called without arguments" do
|
166
|
-
|
148
|
+
assert_success spring, stdout: 'Usage: spring COMMAND [ARGS]'
|
167
149
|
end
|
168
150
|
|
169
151
|
test "test changes are picked up" do
|
170
|
-
|
171
|
-
|
172
|
-
File.write(@test, @test_contents.sub("get :index", "raise 'omg'"))
|
173
|
-
assert_stdout test_command, "RuntimeError: omg"
|
152
|
+
assert_speedup do
|
153
|
+
assert_success spring_test_command, stdout: "0 failures"
|
174
154
|
|
175
|
-
|
155
|
+
File.write(@test, @test_contents.sub("get :index", "raise 'omg'"))
|
156
|
+
assert_failure spring_test_command, stdout: "RuntimeError: omg"
|
157
|
+
end
|
176
158
|
end
|
177
159
|
|
178
160
|
test "code changes are picked up" do
|
179
|
-
|
161
|
+
assert_speedup do
|
162
|
+
assert_success spring_test_command, stdout: "0 failures"
|
180
163
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
assert_speedup
|
164
|
+
File.write(@controller, @controller_contents.sub("@posts = Post.all", "raise 'omg'"))
|
165
|
+
assert_failure spring_test_command, stdout: "RuntimeError: omg"
|
166
|
+
end
|
185
167
|
end
|
186
168
|
|
187
169
|
test "code changes in pre-referenced app files are picked up" do
|
@@ -189,12 +171,12 @@ class AppTest < ActiveSupport::TestCase
|
|
189
171
|
initializer = "#{app_root}/config/initializers/load_posts_controller.rb"
|
190
172
|
File.write(initializer, "PostsController\n")
|
191
173
|
|
192
|
-
|
193
|
-
|
194
|
-
File.write(@controller, @controller_contents.sub("@posts = Post.all", "raise 'omg'"))
|
195
|
-
assert_stdout test_command, "RuntimeError: omg"
|
174
|
+
assert_speedup do
|
175
|
+
assert_success spring_test_command, stdout: "0 failures"
|
196
176
|
|
197
|
-
|
177
|
+
File.write(@controller, @controller_contents.sub("@posts = Post.all", "raise 'omg'"))
|
178
|
+
assert_failure spring_test_command, stdout: "RuntimeError: omg"
|
179
|
+
end
|
198
180
|
ensure
|
199
181
|
FileUtils.rm_f(initializer)
|
200
182
|
end
|
@@ -205,7 +187,7 @@ class AppTest < ActiveSupport::TestCase
|
|
205
187
|
application = "#{app_root}/config/application.rb"
|
206
188
|
application_contents = File.read(application)
|
207
189
|
|
208
|
-
|
190
|
+
assert_success spring_test_command
|
209
191
|
|
210
192
|
File.write(application, application_contents + <<-CODE)
|
211
193
|
class Foo
|
@@ -218,10 +200,9 @@ class AppTest < ActiveSupport::TestCase
|
|
218
200
|
|
219
201
|
await_reload
|
220
202
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
assert_speedup from: 1
|
203
|
+
assert_speedup do
|
204
|
+
2.times { assert_failure spring_test_command, stdout: "RuntimeError: omg" }
|
205
|
+
end
|
225
206
|
ensure
|
226
207
|
File.write(application, application_contents)
|
227
208
|
end
|
@@ -232,50 +213,72 @@ class AppTest < ActiveSupport::TestCase
|
|
232
213
|
application = "#{app_root}/config/application.rb"
|
233
214
|
application_contents = File.read(application)
|
234
215
|
|
235
|
-
|
216
|
+
assert_success spring_test_command
|
236
217
|
|
237
218
|
File.write(application, application_contents + "\nomg")
|
238
219
|
await_reload
|
239
220
|
|
240
|
-
|
221
|
+
assert_failure spring_test_command
|
241
222
|
|
242
223
|
File.write(application, application_contents)
|
243
224
|
await_reload
|
244
225
|
|
245
|
-
|
226
|
+
assert_success spring_test_command
|
246
227
|
ensure
|
247
228
|
File.write(application, application_contents)
|
248
229
|
end
|
249
230
|
end
|
250
231
|
|
251
232
|
test "stop command kills server" do
|
252
|
-
|
253
|
-
|
233
|
+
app_run spring_test_command
|
234
|
+
assert spring_env.server_running?, "The server should be running but it isn't"
|
254
235
|
|
255
|
-
|
256
|
-
|
236
|
+
assert_success "#{spring} stop"
|
237
|
+
assert !spring_env.server_running?, "The server should not be running but it is"
|
257
238
|
end
|
258
239
|
|
259
240
|
test "custom commands" do
|
260
|
-
|
241
|
+
assert_success "#{spring} custom", stdout: "omg"
|
261
242
|
end
|
262
243
|
|
263
244
|
test "runner alias" do
|
264
|
-
|
245
|
+
assert_success "#{spring} r 'puts 1'", stdout: "1"
|
265
246
|
end
|
266
247
|
|
267
248
|
test "binstubs" do
|
268
|
-
app_run "spring binstub rake"
|
269
|
-
|
270
|
-
|
249
|
+
app_run "#{spring} binstub rake"
|
250
|
+
assert_success "bin/spring help"
|
251
|
+
assert_success "bin/rake -T", stdout: "rake db:migrate"
|
252
|
+
end
|
253
|
+
|
254
|
+
test "after fork callback" do
|
255
|
+
begin
|
256
|
+
config_path = "#{app_root}/config/spring.rb"
|
257
|
+
config_contents = File.read(config_path)
|
258
|
+
|
259
|
+
File.write(config_path, config_contents + "\nSpring.after_fork { puts '!callback!' }")
|
260
|
+
assert_success "#{spring} r 'puts 2'", stdout: "!callback!\n2"
|
261
|
+
ensure
|
262
|
+
File.write(config_path, config_contents)
|
263
|
+
end
|
271
264
|
end
|
272
265
|
|
273
266
|
test "missing config/application.rb" do
|
274
267
|
begin
|
275
268
|
FileUtils.mv app_root.join("config/application.rb"), app_root.join("config/application.rb.bak")
|
276
|
-
|
269
|
+
assert_failure "#{spring} rake -T", stderr: "unable to find your config/application.rb"
|
277
270
|
ensure
|
278
271
|
FileUtils.mv app_root.join("config/application.rb.bak"), app_root.join("config/application.rb")
|
279
272
|
end
|
280
273
|
end
|
274
|
+
|
275
|
+
test "piping" do
|
276
|
+
assert_success "#{spring} rake -T | grep db", stdout: "rake db:migrate"
|
277
|
+
end
|
278
|
+
|
279
|
+
test "status" do
|
280
|
+
assert_success "#{spring} status", stdout: "Spring is not running"
|
281
|
+
app_run "#{spring} runner ''"
|
282
|
+
assert_success "#{spring} status", stdout: "Spring is running"
|
283
|
+
end
|
281
284
|
end
|