spring 0.0.8 → 1.0.0
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.
- checksums.yaml +7 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +113 -0
- data/Gemfile +1 -3
- data/README.md +129 -187
- data/bin/spring +27 -0
- data/lib/spring/application.rb +121 -20
- data/lib/spring/application_manager.rb +21 -13
- data/lib/spring/client/binstub.rb +45 -41
- data/lib/spring/client/help.rb +4 -1
- data/lib/spring/client/rails.rb +8 -3
- data/lib/spring/client/run.rb +33 -10
- data/lib/spring/client/status.rb +2 -2
- data/lib/spring/client.rb +3 -3
- data/lib/spring/commands/rails.rb +60 -0
- data/lib/spring/commands/rake.rb +34 -0
- data/lib/spring/commands.rb +12 -195
- data/lib/spring/configuration.rb +6 -2
- data/lib/spring/env.rb +27 -18
- data/lib/spring/errors.rb +1 -1
- data/lib/spring/json.rb +626 -0
- data/lib/spring/server.rb +60 -29
- data/lib/spring/version.rb +1 -1
- data/lib/spring/watcher/abstract.rb +11 -7
- data/lib/spring/watcher/listen.rb +8 -10
- data/lib/spring/watcher/polling.rb +1 -1
- data/lib/spring/watcher.rb +17 -11
- data/spring.gemspec +1 -0
- data/test/acceptance/app_test.rb +270 -73
- data/test/apps/.gitignore +3 -0
- data/test/unit/client/help_test.rb +2 -0
- data/test/unit/commands_test.rb +8 -49
- data/test/unit/watcher_test.rb +22 -2
- metadata +18 -151
- data/lib/spring/client/start.rb +0 -17
- data/test/apps/rails-3-2/.gitignore +0 -18
- data/test/apps/rails-3-2/Gemfile +0 -9
- data/test/apps/rails-3-2/README.rdoc +0 -261
- data/test/apps/rails-3-2/Rakefile +0 -7
- data/test/apps/rails-3-2/app/assets/images/rails.png +0 -0
- data/test/apps/rails-3-2/app/assets/javascripts/application.js +0 -15
- data/test/apps/rails-3-2/app/assets/javascripts/posts.js.coffee +0 -3
- data/test/apps/rails-3-2/app/assets/stylesheets/application.css +0 -13
- data/test/apps/rails-3-2/app/assets/stylesheets/posts.css.scss +0 -3
- data/test/apps/rails-3-2/app/assets/stylesheets/scaffolds.css.scss +0 -69
- data/test/apps/rails-3-2/app/controllers/application_controller.rb +0 -3
- data/test/apps/rails-3-2/app/controllers/posts_controller.rb +0 -83
- data/test/apps/rails-3-2/app/helpers/application_helper.rb +0 -2
- data/test/apps/rails-3-2/app/helpers/posts_helper.rb +0 -2
- data/test/apps/rails-3-2/app/mailers/.gitkeep +0 -0
- data/test/apps/rails-3-2/app/models/.gitkeep +0 -0
- data/test/apps/rails-3-2/app/models/post.rb +0 -3
- data/test/apps/rails-3-2/app/views/layouts/application.html.erb +0 -14
- data/test/apps/rails-3-2/app/views/posts/_form.html.erb +0 -21
- data/test/apps/rails-3-2/app/views/posts/edit.html.erb +0 -6
- data/test/apps/rails-3-2/app/views/posts/index.html.erb +0 -23
- data/test/apps/rails-3-2/app/views/posts/new.html.erb +0 -5
- data/test/apps/rails-3-2/app/views/posts/show.html.erb +0 -10
- data/test/apps/rails-3-2/config/application.rb +0 -62
- data/test/apps/rails-3-2/config/boot.rb +0 -6
- data/test/apps/rails-3-2/config/database.yml +0 -25
- data/test/apps/rails-3-2/config/environment.rb +0 -5
- data/test/apps/rails-3-2/config/environments/development.rb +0 -37
- data/test/apps/rails-3-2/config/environments/production.rb +0 -67
- data/test/apps/rails-3-2/config/environments/test.rb +0 -37
- data/test/apps/rails-3-2/config/initializers/backtrace_silencers.rb +0 -7
- data/test/apps/rails-3-2/config/initializers/inflections.rb +0 -15
- data/test/apps/rails-3-2/config/initializers/mime_types.rb +0 -5
- data/test/apps/rails-3-2/config/initializers/secret_token.rb +0 -7
- data/test/apps/rails-3-2/config/initializers/session_store.rb +0 -8
- data/test/apps/rails-3-2/config/initializers/wrap_parameters.rb +0 -14
- data/test/apps/rails-3-2/config/locales/en.yml +0 -5
- data/test/apps/rails-3-2/config/routes.rb +0 -60
- data/test/apps/rails-3-2/config/spring.rb +0 -7
- data/test/apps/rails-3-2/config.ru +0 -4
- data/test/apps/rails-3-2/db/migrate/20121109171227_create_posts.rb +0 -9
- data/test/apps/rails-3-2/db/schema.rb +0 -22
- data/test/apps/rails-3-2/db/seeds.rb +0 -7
- data/test/apps/rails-3-2/lib/assets/.gitkeep +0 -0
- data/test/apps/rails-3-2/lib/tasks/.gitkeep +0 -0
- data/test/apps/rails-3-2/log/.gitkeep +0 -0
- data/test/apps/rails-3-2/public/404.html +0 -26
- data/test/apps/rails-3-2/public/422.html +0 -26
- data/test/apps/rails-3-2/public/500.html +0 -25
- data/test/apps/rails-3-2/public/favicon.ico +0 -0
- data/test/apps/rails-3-2/public/index.html +0 -241
- data/test/apps/rails-3-2/public/robots.txt +0 -5
- data/test/apps/rails-3-2/script/rails +0 -6
- data/test/apps/rails-3-2/test/fixtures/.gitkeep +0 -0
- data/test/apps/rails-3-2/test/fixtures/posts.yml +0 -7
- data/test/apps/rails-3-2/test/functional/.gitkeep +0 -0
- data/test/apps/rails-3-2/test/functional/posts_controller_test.rb +0 -49
- data/test/apps/rails-3-2/test/integration/.gitkeep +0 -0
- data/test/apps/rails-3-2/test/performance/browsing_test.rb +0 -12
- data/test/apps/rails-3-2/test/test_helper.rb +0 -13
- data/test/apps/rails-3-2/test/unit/.gitkeep +0 -0
- data/test/apps/rails-3-2/test/unit/helpers/posts_helper_test.rb +0 -4
- data/test/apps/rails-3-2/test/unit/post_test.rb +0 -7
- data/test/apps/rails-3-2/vendor/assets/javascripts/.gitkeep +0 -0
- data/test/apps/rails-3-2/vendor/assets/stylesheets/.gitkeep +0 -0
- data/test/apps/rails-3-2/vendor/plugins/.gitkeep +0 -0
data/test/acceptance/app_test.rb
CHANGED
|
@@ -1,19 +1,34 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
1
2
|
require 'helper'
|
|
2
3
|
require 'io/wait'
|
|
3
4
|
require "timeout"
|
|
4
5
|
require "spring/sid"
|
|
5
6
|
require "spring/env"
|
|
6
|
-
require "pty"
|
|
7
7
|
|
|
8
8
|
class AppTest < ActiveSupport::TestCase
|
|
9
|
+
DEFAULT_SPEEDUP = 0.8
|
|
10
|
+
DEFAULT_TIMEOUT = ENV['CI'] ? 30 : 10
|
|
11
|
+
|
|
12
|
+
def rails_version
|
|
13
|
+
ENV['RAILS_VERSION'] || '~> 4.0.0'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def rails_3?
|
|
17
|
+
rails_version.split(" ").last =~ /^3/
|
|
18
|
+
end
|
|
19
|
+
|
|
9
20
|
def app_root
|
|
10
|
-
Pathname.new("#{TEST_ROOT}/apps/rails-
|
|
21
|
+
Pathname.new("#{TEST_ROOT}/apps/rails-#{rails_version.scan(/\d/)[0..1].join("-")}")
|
|
11
22
|
end
|
|
12
23
|
|
|
13
24
|
def gem_home
|
|
14
25
|
app_root.join "vendor/gems/#{RUBY_VERSION}"
|
|
15
26
|
end
|
|
16
27
|
|
|
28
|
+
def user_home
|
|
29
|
+
app_root.join "user_home"
|
|
30
|
+
end
|
|
31
|
+
|
|
17
32
|
def spring
|
|
18
33
|
gem_home.join "bin/spring"
|
|
19
34
|
end
|
|
@@ -30,12 +45,27 @@ class AppTest < ActiveSupport::TestCase
|
|
|
30
45
|
@stderr ||= IO.pipe
|
|
31
46
|
end
|
|
32
47
|
|
|
48
|
+
def log_file
|
|
49
|
+
@log_file ||= File.open("/tmp/spring.log", "w+")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def env
|
|
53
|
+
@env ||= {
|
|
54
|
+
"GEM_HOME" => gem_home.to_s,
|
|
55
|
+
"GEM_PATH" => "",
|
|
56
|
+
"HOME" => user_home.to_s,
|
|
57
|
+
"RAILS_ENV" => nil,
|
|
58
|
+
"RACK_ENV" => nil,
|
|
59
|
+
"SPRING_LOG" => log_file.path
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
|
|
33
63
|
def app_run(command, opts = {})
|
|
34
64
|
start_time = Time.now
|
|
35
65
|
|
|
36
66
|
Bundler.with_clean_env do
|
|
37
67
|
Process.spawn(
|
|
38
|
-
|
|
68
|
+
env,
|
|
39
69
|
command.to_s,
|
|
40
70
|
out: stdout.last,
|
|
41
71
|
err: stderr.last,
|
|
@@ -44,106 +74,173 @@ class AppTest < ActiveSupport::TestCase
|
|
|
44
74
|
)
|
|
45
75
|
end
|
|
46
76
|
|
|
47
|
-
_, status = Timeout.timeout(opts.fetch(:timeout,
|
|
77
|
+
_, status = Timeout.timeout(opts.fetch(:timeout, DEFAULT_TIMEOUT)) { Process.wait2 }
|
|
48
78
|
|
|
49
|
-
|
|
50
|
-
|
|
79
|
+
if pid = spring_env.pid
|
|
80
|
+
@server_pid = pid
|
|
81
|
+
lines = `ps -A -o ppid= -o pid= | egrep '^\\s*#{@server_pid}'`.lines
|
|
82
|
+
@application_pids = lines.map { |l| l.split.last.to_i }
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
output = read_streams
|
|
86
|
+
puts dump_streams(command, output) if ENV["SPRING_DEBUG"]
|
|
51
87
|
|
|
52
88
|
@times << (Time.now - start_time) if @times
|
|
53
89
|
|
|
54
|
-
|
|
55
|
-
status: status,
|
|
56
|
-
stdout: stdout,
|
|
57
|
-
stderr: stderr,
|
|
58
|
-
}
|
|
90
|
+
output.merge(status: status, command: command)
|
|
59
91
|
rescue Timeout::Error => e
|
|
60
|
-
raise e, "Output:\n\n#{dump_streams(command,
|
|
92
|
+
raise e, "Output:\n\n#{dump_streams(command, read_streams)}"
|
|
61
93
|
end
|
|
62
94
|
|
|
63
95
|
def read_streams
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
96
|
+
{
|
|
97
|
+
stdout: read_stream(stdout.first),
|
|
98
|
+
stderr: read_stream(stderr.first),
|
|
99
|
+
log: read_stream(log_file)
|
|
100
|
+
}
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def read_stream(stream)
|
|
104
|
+
output = ""
|
|
105
|
+
while IO.select([stream], [], [], 0.5) && !stream.eof?
|
|
106
|
+
output << stream.readpartial(10240)
|
|
68
107
|
end
|
|
108
|
+
output
|
|
69
109
|
end
|
|
70
110
|
|
|
71
|
-
def dump_streams(command,
|
|
111
|
+
def dump_streams(command, streams)
|
|
72
112
|
output = "$ #{command}\n"
|
|
73
113
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
unless stderr.chomp.empty?
|
|
80
|
-
output << "--- stderr ---\n"
|
|
81
|
-
output << "#{stderr.chomp}\n"
|
|
114
|
+
streams.each do |name, stream|
|
|
115
|
+
unless stream.chomp.empty?
|
|
116
|
+
output << "--- #{name} ---\n"
|
|
117
|
+
output << "#{stream.chomp}\n"
|
|
118
|
+
end
|
|
82
119
|
end
|
|
83
120
|
|
|
84
121
|
output << "\n"
|
|
85
122
|
output
|
|
86
123
|
end
|
|
87
124
|
|
|
125
|
+
def alive?(pid)
|
|
126
|
+
Process.kill 0, pid
|
|
127
|
+
true
|
|
128
|
+
rescue Errno::ESRCH
|
|
129
|
+
false
|
|
130
|
+
end
|
|
131
|
+
|
|
88
132
|
def await_reload
|
|
89
|
-
|
|
133
|
+
raise "no pid" if @application_pids.nil? || @application_pids.empty?
|
|
134
|
+
|
|
135
|
+
Timeout.timeout(DEFAULT_TIMEOUT) do
|
|
136
|
+
sleep 0.1 while @application_pids.any? { |p| alive?(p) }
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def debug(artifacts)
|
|
141
|
+
artifacts = artifacts.dup
|
|
142
|
+
artifacts.delete :status
|
|
143
|
+
dump_streams(artifacts.delete(:command), artifacts)
|
|
90
144
|
end
|
|
91
145
|
|
|
92
146
|
def assert_output(artifacts, expected)
|
|
93
147
|
expected.each do |stream, output|
|
|
94
148
|
assert artifacts[stream].include?(output),
|
|
95
|
-
"expected #{stream} to include '#{output}'
|
|
149
|
+
"expected #{stream} to include '#{output}'.\n\n#{debug(artifacts)}"
|
|
96
150
|
end
|
|
97
151
|
end
|
|
98
152
|
|
|
99
153
|
def assert_success(command, expected_output = nil)
|
|
100
|
-
artifacts = app_run(command)
|
|
101
|
-
assert artifacts[:status].success?, "expected successful exit status"
|
|
154
|
+
artifacts = app_run(*Array(command))
|
|
155
|
+
assert artifacts[:status].success?, "expected successful exit status\n\n#{debug(artifacts)}"
|
|
102
156
|
assert_output artifacts, expected_output if expected_output
|
|
103
157
|
end
|
|
104
158
|
|
|
105
159
|
def assert_failure(command, expected_output = nil)
|
|
106
|
-
artifacts = app_run(command)
|
|
107
|
-
assert !artifacts[:status].success?, "expected unsuccessful exit status"
|
|
160
|
+
artifacts = app_run(*Array(command))
|
|
161
|
+
assert !artifacts[:status].success?, "expected unsuccessful exit status\n\n#{debug(artifacts)}"
|
|
108
162
|
assert_output artifacts, expected_output if expected_output
|
|
109
163
|
end
|
|
110
164
|
|
|
111
|
-
def assert_speedup(ratio =
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
165
|
+
def assert_speedup(ratio = DEFAULT_SPEEDUP)
|
|
166
|
+
if ENV['CI']
|
|
167
|
+
yield
|
|
168
|
+
else
|
|
169
|
+
@times = []
|
|
170
|
+
yield
|
|
171
|
+
assert (@times.last / @times.first) < ratio, "#{@times.last} was not less than #{ratio} of #{@times.first}"
|
|
172
|
+
@times = nil
|
|
173
|
+
end
|
|
116
174
|
end
|
|
117
175
|
|
|
118
176
|
def spring_test_command
|
|
119
|
-
"#{spring} testunit #{@test}"
|
|
177
|
+
"#{spring} #{rails_3? ? 'testunit' : 'rake test'} #{@test}"
|
|
120
178
|
end
|
|
121
179
|
|
|
122
|
-
|
|
180
|
+
def generate_app
|
|
181
|
+
Bundler.with_clean_env do
|
|
182
|
+
# Sporadic SSL errors keep causing test failures so there are anti-SSL workarounds here
|
|
123
183
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
184
|
+
assert system("(gem list rails --installed --version '#{rails_version}' || " \
|
|
185
|
+
"gem install rails --clear-sources --source http://rubygems.org --version '#{rails_version}') > /dev/null")
|
|
186
|
+
|
|
187
|
+
# Have to shell out otherwise bundler prevents us finding the gem
|
|
188
|
+
version = `ruby -e 'puts Gem::Specification.find_by_name("rails", "#{rails_version}").version'`.chomp
|
|
189
|
+
|
|
190
|
+
assert system("rails _#{version}_ new #{app_root} --skip-bundle --skip-javascript --skip-sprockets > /dev/null")
|
|
129
191
|
|
|
130
|
-
unless @@installed
|
|
131
192
|
FileUtils.mkdir_p(gem_home)
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
193
|
+
FileUtils.mkdir_p(user_home)
|
|
194
|
+
FileUtils.rm_rf("#{app_root}/test/performance/")
|
|
195
|
+
|
|
196
|
+
if rails_3?
|
|
197
|
+
File.write(
|
|
198
|
+
"#{app_root}/Gemfile",
|
|
199
|
+
File.read("#{app_root}/Gemfile") + "gem 'spring-commands-testunit'\n"
|
|
200
|
+
)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
File.write(
|
|
204
|
+
"#{app_root}/Gemfile",
|
|
205
|
+
File.read("#{app_root}/Gemfile").sub("https://rubygems.org", "http://rubygems.org")
|
|
206
|
+
)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def install
|
|
211
|
+
generate_app unless app_root.exist?
|
|
212
|
+
|
|
213
|
+
assert system("gem build spring.gemspec 2>/dev/null 1>/dev/null")
|
|
214
|
+
|
|
215
|
+
assert_success ["gem install ../../../spring-#{Spring::VERSION}.gem", timeout: nil]
|
|
216
|
+
assert_success ["(gem list bundler | grep bundler) || gem install bundler", timeout: nil]
|
|
217
|
+
assert_success ["bundle check || bundle update", timeout: nil]
|
|
218
|
+
|
|
219
|
+
unless File.exist?(@controller)
|
|
220
|
+
assert_success "bundle exec rails g scaffold post title:string"
|
|
138
221
|
end
|
|
139
222
|
|
|
140
|
-
|
|
223
|
+
assert_success "bundle exec rake db:migrate db:test:clone"
|
|
224
|
+
@@installed = true
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
@@installed = false
|
|
228
|
+
|
|
229
|
+
setup do
|
|
230
|
+
@test = "#{app_root}/test/#{rails_3? ? 'functional' : 'controllers'}/posts_controller_test.rb"
|
|
231
|
+
@controller = "#{app_root}/app/controllers/posts_controller.rb"
|
|
232
|
+
|
|
233
|
+
install unless @@installed
|
|
234
|
+
|
|
235
|
+
@test_contents = File.read(@test)
|
|
236
|
+
@controller_contents = File.read(@controller)
|
|
141
237
|
end
|
|
142
238
|
|
|
143
239
|
teardown do
|
|
144
240
|
app_run "#{spring} stop"
|
|
145
|
-
File.write(@test,
|
|
241
|
+
File.write(@test, @test_contents)
|
|
146
242
|
File.write(@controller, @controller_contents)
|
|
243
|
+
FileUtils.rm_f("#{app_root}/config/spring.rb")
|
|
147
244
|
end
|
|
148
245
|
|
|
149
246
|
test "basic" do
|
|
@@ -206,15 +303,13 @@ class AppTest < ActiveSupport::TestCase
|
|
|
206
303
|
File.write(@test, @test_contents.sub("get :index", "Foo.omg"))
|
|
207
304
|
|
|
208
305
|
await_reload
|
|
209
|
-
|
|
210
|
-
assert_speedup do
|
|
211
|
-
2.times { assert_failure spring_test_command, stdout: "RuntimeError: omg" }
|
|
212
|
-
end
|
|
306
|
+
assert_failure spring_test_command, stdout: "RuntimeError: omg"
|
|
213
307
|
ensure
|
|
214
308
|
File.write(application, application_contents)
|
|
215
309
|
end
|
|
216
310
|
|
|
217
311
|
test "app gets reloaded when preloaded files change (polling watcher)" do
|
|
312
|
+
env["RAILS_ENV"] = "test"
|
|
218
313
|
assert_success "#{spring} rails runner 'puts Spring.watcher.class'", stdout: "Polling"
|
|
219
314
|
assert_app_reloaded
|
|
220
315
|
end
|
|
@@ -223,10 +318,15 @@ class AppTest < ActiveSupport::TestCase
|
|
|
223
318
|
begin
|
|
224
319
|
gemfile = app_root.join("Gemfile")
|
|
225
320
|
gemfile_contents = gemfile.read
|
|
226
|
-
File.write(gemfile, gemfile_contents
|
|
227
|
-
|
|
321
|
+
File.write(gemfile, gemfile_contents + "\ngem 'listen', '~> 1.0'")
|
|
322
|
+
|
|
323
|
+
File.write("#{app_root}/config/spring.rb", "Spring.watch_method = :listen")
|
|
228
324
|
|
|
325
|
+
assert_success ["bundle install", timeout: nil]
|
|
326
|
+
|
|
327
|
+
env["RAILS_ENV"] = "test"
|
|
229
328
|
assert_success "#{spring} rails runner 'puts Spring.watcher.class'", stdout: "Listen"
|
|
329
|
+
|
|
230
330
|
assert_app_reloaded
|
|
231
331
|
ensure
|
|
232
332
|
File.write(gemfile, gemfile_contents)
|
|
@@ -247,8 +347,6 @@ class AppTest < ActiveSupport::TestCase
|
|
|
247
347
|
assert_failure spring_test_command
|
|
248
348
|
|
|
249
349
|
File.write(application, application_contents)
|
|
250
|
-
await_reload
|
|
251
|
-
|
|
252
350
|
assert_success spring_test_command
|
|
253
351
|
ensure
|
|
254
352
|
File.write(application, application_contents)
|
|
@@ -264,32 +362,61 @@ class AppTest < ActiveSupport::TestCase
|
|
|
264
362
|
end
|
|
265
363
|
|
|
266
364
|
test "custom commands" do
|
|
365
|
+
File.write("#{app_root}/config/spring.rb", <<-CODE)
|
|
366
|
+
class CustomCommand
|
|
367
|
+
def call
|
|
368
|
+
puts "omg"
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
Spring.register_command "custom", CustomCommand.new
|
|
373
|
+
CODE
|
|
374
|
+
|
|
267
375
|
assert_success "#{spring} custom", stdout: "omg"
|
|
268
376
|
end
|
|
269
377
|
|
|
270
378
|
test "binstubs" do
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
379
|
+
begin
|
|
380
|
+
FileUtils.mv "#{app_root}/bin", "#{app_root}/bin~" if File.exist?("#{app_root}/bin")
|
|
381
|
+
|
|
382
|
+
app_run "#{spring} binstub rake"
|
|
383
|
+
assert_success "bin/rake -T", stdout: "rake db:migrate"
|
|
384
|
+
|
|
385
|
+
app_run "#{spring} binstub rake rails"
|
|
386
|
+
assert_success "bin/rails runner 'puts %(omg)'", stdout: "omg"
|
|
387
|
+
assert_success "bin/rails server --help", stdout: "Usage: rails server"
|
|
388
|
+
|
|
389
|
+
FileUtils.rm ["#{app_root}/bin/rails", "#{app_root}/bin/rake"]
|
|
390
|
+
|
|
391
|
+
app_run "#{spring} binstub --all"
|
|
392
|
+
assert_success "bin/rake -T", stdout: "rake db:migrate"
|
|
393
|
+
assert_success "bin/rails runner 'puts %(omg)'", stdout: "omg"
|
|
394
|
+
ensure
|
|
395
|
+
if File.exist?("#{app_root}/bin~")
|
|
396
|
+
FileUtils.rm_rf "#{app_root}/bin"
|
|
397
|
+
FileUtils.mv "#{app_root}/bin~", "#{app_root}/bin"
|
|
398
|
+
end
|
|
399
|
+
end
|
|
276
400
|
end
|
|
277
401
|
|
|
278
402
|
test "after fork callback" do
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
403
|
+
File.write("#{app_root}/config/spring.rb", "Spring.after_fork { puts '!callback!' }")
|
|
404
|
+
assert_success "#{spring} rails runner 'puts 2'", stdout: "!callback!\n2"
|
|
405
|
+
end
|
|
282
406
|
|
|
283
|
-
|
|
407
|
+
test "global config file evaluated" do
|
|
408
|
+
begin
|
|
409
|
+
File.write("#{user_home}/.spring.rb", "Spring.after_fork { puts '!callback!' }")
|
|
284
410
|
assert_success "#{spring} rails runner 'puts 2'", stdout: "!callback!\n2"
|
|
285
411
|
ensure
|
|
286
|
-
|
|
412
|
+
FileUtils.rm_r("#{user_home}/.spring.rb")
|
|
287
413
|
end
|
|
288
414
|
end
|
|
289
415
|
|
|
290
416
|
test "missing config/application.rb" do
|
|
291
417
|
begin
|
|
292
418
|
FileUtils.mv app_root.join("config/application.rb"), app_root.join("config/application.rb.bak")
|
|
419
|
+
|
|
293
420
|
assert_failure "#{spring} rake -T", stderr: "unable to find your config/application.rb"
|
|
294
421
|
ensure
|
|
295
422
|
FileUtils.mv app_root.join("config/application.rb.bak"), app_root.join("config/application.rb")
|
|
@@ -307,8 +434,78 @@ class AppTest < ActiveSupport::TestCase
|
|
|
307
434
|
end
|
|
308
435
|
|
|
309
436
|
test "runner command sets Rails environment from command-line options" do
|
|
310
|
-
|
|
311
|
-
assert_success "#{spring} rails runner
|
|
312
|
-
|
|
437
|
+
assert_success "#{spring} rails runner -e production 'puts Rails.env'", stdout: "production"
|
|
438
|
+
assert_success "#{spring} rails runner --environment=production 'puts Rails.env'", stdout: "production"
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
test "forcing rails env via environment variable" do
|
|
442
|
+
env['RAILS_ENV'] = 'production'
|
|
443
|
+
assert_success "#{spring} rake -p 'Rails.env'", stdout: "production"
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
test "setting env vars with rake" do
|
|
447
|
+
begin
|
|
448
|
+
File.write("#{app_root}/lib/tasks/env.rake", <<-'CODE')
|
|
449
|
+
task :print_rails_env => :environment do
|
|
450
|
+
puts Rails.env
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
task :print_env do
|
|
454
|
+
ENV.each { |k, v| puts "#{k}=#{v}" }
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
task(:default).clear.enhance [:print_rails_env]
|
|
458
|
+
CODE
|
|
459
|
+
|
|
460
|
+
assert_success "#{spring} rake RAILS_ENV=test print_rails_env", stdout: "test"
|
|
461
|
+
assert_success "#{spring} rake FOO=bar print_env", stdout: "FOO=bar"
|
|
462
|
+
assert_success "#{spring} rake", stdout: "test"
|
|
463
|
+
ensure
|
|
464
|
+
FileUtils.rm_f("#{app_root}/lib/tasks/env.rake")
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
test "changing the Gemfile restarts the server" do
|
|
469
|
+
begin
|
|
470
|
+
gemfile = app_root.join("Gemfile")
|
|
471
|
+
gemfile_contents = gemfile.read
|
|
472
|
+
|
|
473
|
+
assert_success %(#{spring} rails runner 'require "sqlite3"')
|
|
474
|
+
|
|
475
|
+
File.write(gemfile, gemfile_contents.sub(%{gem 'sqlite3'}, %{# gem 'sqlite3'}))
|
|
476
|
+
app_run "bundle check"
|
|
477
|
+
|
|
478
|
+
await_reload
|
|
479
|
+
assert_failure %(#{spring} rails runner 'require "sqlite3"'), stderr: "sqlite3"
|
|
480
|
+
ensure
|
|
481
|
+
File.write(gemfile, gemfile_contents)
|
|
482
|
+
assert_success "bundle check"
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
test "changing the environment between runs" do
|
|
487
|
+
begin
|
|
488
|
+
application = "#{app_root}/config/application.rb"
|
|
489
|
+
application_contents = File.read(application)
|
|
490
|
+
|
|
491
|
+
File.write(application, "#{application_contents}\nENV['BAR'] = 'bar'")
|
|
492
|
+
|
|
493
|
+
env["OMG"] = "1"
|
|
494
|
+
env["FOO"] = "1"
|
|
495
|
+
env["RUBYOPT"] = "-rubygems"
|
|
496
|
+
|
|
497
|
+
assert_success %(#{spring} rails runner 'p ENV["OMG"]'), stdout: "1"
|
|
498
|
+
assert_success %(#{spring} rails runner 'p ENV["BAR"]'), stdout: "bar"
|
|
499
|
+
assert_success %(#{spring} rails runner 'p ENV.key?("BUNDLE_GEMFILE")'), stdout: "true"
|
|
500
|
+
assert_success %(#{spring} rails runner 'p ENV["RUBYOPT"]'), stdout: "bundler"
|
|
501
|
+
|
|
502
|
+
env["OMG"] = "2"
|
|
503
|
+
env.delete "FOO"
|
|
504
|
+
|
|
505
|
+
assert_success %(#{spring} rails runner 'p ENV["OMG"]'), stdout: "2"
|
|
506
|
+
assert_success %(#{spring} rails runner 'p ENV.key?("FOO")'), stdout: "false"
|
|
507
|
+
ensure
|
|
508
|
+
File.write(application, application_contents)
|
|
509
|
+
end
|
|
313
510
|
end
|
|
314
511
|
end
|
data/test/unit/commands_test.rb
CHANGED
|
@@ -2,55 +2,6 @@ require "helper"
|
|
|
2
2
|
require "spring/commands"
|
|
3
3
|
|
|
4
4
|
class CommandsTest < ActiveSupport::TestCase
|
|
5
|
-
test "test command needs a test name" do
|
|
6
|
-
begin
|
|
7
|
-
real_stderr = $stderr
|
|
8
|
-
$stderr = StringIO.new('')
|
|
9
|
-
|
|
10
|
-
command = Spring::Commands::TestUnit.new
|
|
11
|
-
command.call([])
|
|
12
|
-
|
|
13
|
-
assert_equal "you need to specify what test to run: spring test TEST_NAME\n", $stderr.string
|
|
14
|
-
ensure
|
|
15
|
-
$stderr = real_stderr
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
test 'children of Command have inheritable accessor named "preload"' do
|
|
20
|
-
command1, command2 = 2.times.map { Class.new(Spring::Commands::Command) }
|
|
21
|
-
|
|
22
|
-
command1.preloads << "foo"
|
|
23
|
-
assert_equal ["foo"], command1.preloads
|
|
24
|
-
assert_equal [], command2.preloads
|
|
25
|
-
|
|
26
|
-
command2.preloads << "bar"
|
|
27
|
-
assert_equal ["foo"], command1.preloads
|
|
28
|
-
assert_equal ["bar"], command2.preloads
|
|
29
|
-
|
|
30
|
-
command1.preloads = ["omg"]
|
|
31
|
-
assert_equal ["omg"], command1.preloads
|
|
32
|
-
assert_equal ["bar"], command2.preloads
|
|
33
|
-
|
|
34
|
-
command3 = Class.new(command1)
|
|
35
|
-
command3.preloads << "foo"
|
|
36
|
-
assert_equal ["omg", "foo"], command3.preloads
|
|
37
|
-
assert_equal ["omg"], command1.preloads
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
test "prints error message when preloaded file does not exist" do
|
|
41
|
-
begin
|
|
42
|
-
original_stderr = $stderr
|
|
43
|
-
$stderr = StringIO.new('')
|
|
44
|
-
my_command_class = Class.new(Spring::Commands::Command)
|
|
45
|
-
my_command_class.preloads = %w(i_do_not_exist)
|
|
46
|
-
|
|
47
|
-
my_command_class.new.setup
|
|
48
|
-
assert_match /The #<Class:0x[0-9a-f]+> command tried to preload i_do_not_exist but could not find it./, $stderr.string
|
|
49
|
-
ensure
|
|
50
|
-
$stderr = original_stderr
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
5
|
test 'console command sets rails environment from command-line option' do
|
|
55
6
|
command = Spring::Commands::RailsConsole.new
|
|
56
7
|
assert_equal 'test', command.env(['test'])
|
|
@@ -75,4 +26,12 @@ class CommandsTest < ActiveSupport::TestCase
|
|
|
75
26
|
command = Spring::Commands::RailsRunner.new
|
|
76
27
|
assert_nil command.env(['puts 1+1'])
|
|
77
28
|
end
|
|
29
|
+
|
|
30
|
+
test "rake command has configurable environments" do
|
|
31
|
+
command = Spring::Commands::Rake.new
|
|
32
|
+
assert_nil command.env(["foo"])
|
|
33
|
+
assert_equal "test", command.env(["test"])
|
|
34
|
+
assert_equal "test", command.env(["test:models"])
|
|
35
|
+
assert_nil command.env(["test_foo"])
|
|
36
|
+
end
|
|
78
37
|
end
|
data/test/unit/watcher_test.rb
CHANGED
|
@@ -3,7 +3,8 @@ require "tmpdir"
|
|
|
3
3
|
require "fileutils"
|
|
4
4
|
require "active_support/core_ext/numeric/time"
|
|
5
5
|
require "spring/watcher"
|
|
6
|
-
require "
|
|
6
|
+
require "spring/watcher/polling"
|
|
7
|
+
require "spring/watcher/listen"
|
|
7
8
|
|
|
8
9
|
module WatcherTests
|
|
9
10
|
LATENCY = 0.001
|
|
@@ -41,6 +42,18 @@ module WatcherTests
|
|
|
41
42
|
assert !watcher.stale?
|
|
42
43
|
end
|
|
43
44
|
|
|
45
|
+
def test_starting_with_no_file
|
|
46
|
+
file = "#{@dir}/omg"
|
|
47
|
+
touch file, Time.now - 2.seconds
|
|
48
|
+
|
|
49
|
+
watcher.start
|
|
50
|
+
watcher.add file
|
|
51
|
+
|
|
52
|
+
assert_not_stale
|
|
53
|
+
touch file, Time.now
|
|
54
|
+
assert_stale
|
|
55
|
+
end
|
|
56
|
+
|
|
44
57
|
def test_is_stale_when_a_watched_file_is_updated
|
|
45
58
|
file = "#{@dir}/omg"
|
|
46
59
|
touch file, Time.now - 2.seconds
|
|
@@ -114,12 +127,14 @@ module WatcherTests
|
|
|
114
127
|
watcher.add file
|
|
115
128
|
watcher.start
|
|
116
129
|
|
|
130
|
+
io = watcher.to_io
|
|
131
|
+
|
|
117
132
|
Thread.new {
|
|
118
133
|
sleep LATENCY * 3
|
|
119
134
|
touch file, Time.now
|
|
120
135
|
}
|
|
121
136
|
|
|
122
|
-
assert IO.select([
|
|
137
|
+
assert IO.select([io], [], [], 1), "IO.select timed out before watcher was readable"
|
|
123
138
|
assert watcher.stale?
|
|
124
139
|
end
|
|
125
140
|
|
|
@@ -134,6 +149,11 @@ module WatcherTests
|
|
|
134
149
|
watcher.add "./foo"
|
|
135
150
|
assert_equal ["#{dir}/foo"], watcher.files.to_a
|
|
136
151
|
end
|
|
152
|
+
|
|
153
|
+
def test_add_non_existant_file
|
|
154
|
+
watcher.add './foobar'
|
|
155
|
+
assert watcher.files.empty?
|
|
156
|
+
end
|
|
137
157
|
end
|
|
138
158
|
|
|
139
159
|
class ListenWatcherTest < ActiveSupport::TestCase
|