spring 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|