spring 2.0.2 → 4.1.1

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.
@@ -1,558 +0,0 @@
1
- require "io/wait"
2
- require "timeout"
3
- require "spring/sid"
4
- require "spring/client"
5
- require "active_support/core_ext/string/strip"
6
-
7
- module Spring
8
- module Test
9
- class AcceptanceTest < ActiveSupport::TestCase
10
- runnables.delete self # prevent Minitest running this class
11
-
12
- DEFAULT_SPEEDUP = 0.8
13
-
14
- def rails_version
15
- ENV['RAILS_VERSION'] || '~> 5.0.0'
16
- end
17
-
18
- # Extension point for spring-watchers-listen
19
- def generator_klass
20
- Spring::Test::ApplicationGenerator
21
- end
22
-
23
- def generator
24
- @@generator ||= generator_klass.new(rails_version)
25
- end
26
-
27
- def app
28
- @app ||= Spring::Test::Application.new("#{Spring::Test.root}/apps/tmp")
29
- end
30
-
31
- def spring_env
32
- app.spring_env
33
- end
34
-
35
- def assert_output(artifacts, expected)
36
- expected.each do |stream, output|
37
- assert artifacts[stream].include?(output),
38
- "expected #{stream} to include '#{output}'.\n\n#{app.debug(artifacts)}"
39
- end
40
- end
41
-
42
- def assert_success(command, expected_output = nil)
43
- artifacts = app.run(*Array(command))
44
- assert artifacts[:status].success?, "expected successful exit status\n\n#{app.debug(artifacts)}"
45
- assert_output artifacts, expected_output if expected_output
46
- end
47
-
48
- def assert_failure(command, expected_output = nil)
49
- artifacts = app.run(*Array(command))
50
- assert !artifacts[:status].success?, "expected unsuccessful exit status\n\n#{app.debug(artifacts)}"
51
- assert_output artifacts, expected_output if expected_output
52
- end
53
-
54
- def refute_output_includes(command, not_expected)
55
- artifacts = app.run(*Array(command))
56
- not_expected.each do |stream, output|
57
- assert !artifacts[stream].include?(output),
58
- "expected #{stream} to not include '#{output}'.\n\n#{app.debug(artifacts)}"
59
- end
60
- end
61
-
62
- def assert_speedup(ratio = DEFAULT_SPEEDUP)
63
- if ENV['CI']
64
- yield
65
- else
66
- app.with_timing do
67
- yield
68
- assert app.timing_ratio < ratio, "#{app.last_time} was not less than #{ratio} of #{app.first_time}"
69
- end
70
- end
71
- end
72
-
73
- def without_gem(name)
74
- gem_home = app.gem_home.join('gems')
75
- FileUtils.mv(gem_home.join(name), app.root)
76
- yield
77
- ensure
78
- FileUtils.mv(app.root.join(name), gem_home)
79
- end
80
-
81
- setup do
82
- generator.generate_if_missing
83
- generator.install_spring
84
- generator.copy_to(app.root)
85
- end
86
-
87
- teardown do
88
- app.stop_spring
89
- end
90
-
91
- test "basic" do
92
- assert_speedup do
93
- 2.times { app.run app.spring_test_command }
94
- end
95
- end
96
-
97
- test "help message when called without arguments" do
98
- assert_success "bin/spring", stdout: 'Usage: spring COMMAND [ARGS]'
99
- assert spring_env.server_running?
100
- end
101
-
102
- test "shows help" do
103
- assert_success "bin/spring help", stdout: 'Usage: spring COMMAND [ARGS]'
104
- assert_success "bin/spring -h", stdout: 'Usage: spring COMMAND [ARGS]'
105
- assert_success "bin/spring --help", stdout: 'Usage: spring COMMAND [ARGS]'
106
- refute spring_env.server_running?
107
- end
108
-
109
- test "tells the user that spring is being used when used automatically via binstubs" do
110
- assert_success "bin/rails runner ''", stderr: "Running via Spring preloader in process"
111
- assert_success app.spring_test_command, stderr: "Running via Spring preloader in process"
112
- end
113
-
114
- test "does not tell the user that spring is being used when used automatically via binstubs but quiet is enabled" do
115
- File.write("#{app.user_home}/.spring.rb", "Spring.quiet = true")
116
- assert_success "bin/rails runner ''"
117
- refute_output_includes "bin/rails runner ''", stderr: 'Running via Spring preloader in process'
118
- end
119
-
120
- test "test changes are picked up" do
121
- assert_speedup do
122
- assert_success app.spring_test_command, stdout: "0 failures"
123
-
124
- app.insert_into_test "raise 'omg'"
125
- assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
126
- end
127
- end
128
-
129
- test "code changes are picked up" do
130
- assert_speedup do
131
- assert_success app.spring_test_command, stdout: "0 failures"
132
-
133
- File.write(app.controller, app.controller.read.sub("@posts = Post.all", "raise 'omg'"))
134
- assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
135
- end
136
- end
137
-
138
- test "code changes in pre-referenced app files are picked up" do
139
- File.write(app.path("config/initializers/load_posts_controller.rb"), "PostsController\n")
140
-
141
- assert_speedup do
142
- assert_success app.spring_test_command, stdout: "0 failures"
143
-
144
- File.write(app.controller, app.controller.read.sub("@posts = Post.all", "raise 'omg'"))
145
- assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
146
- end
147
- end
148
-
149
- test "app gets reloaded when preloaded files change" do
150
- assert_success app.spring_test_command
151
-
152
- File.write(app.application_config, app.application_config.read + <<-RUBY.strip_heredoc)
153
- class Foo
154
- def self.omg
155
- raise "omg"
156
- end
157
- end
158
- RUBY
159
- app.insert_into_test "Foo.omg"
160
-
161
- app.await_reload
162
- assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
163
- end
164
-
165
- test "app gets reloaded even with a ton of boot output" do
166
- limit = UNIXSocket.pair.first.getsockopt(:SOCKET, :SNDBUF).int
167
-
168
- assert_success app.spring_test_command
169
- File.write(app.path("config/initializers/verbose.rb"), "#{limit}.times { puts 'x' }")
170
-
171
- app.await_reload
172
- assert_success app.spring_test_command
173
- end
174
-
175
- test "app gets reloaded even with abort_on_exception=true" do
176
- assert_success app.spring_test_command
177
- File.write(app.path("config/initializers/thread_config.rb"), "Thread.abort_on_exception = true")
178
-
179
- app.await_reload
180
- assert_success app.spring_test_command
181
- end
182
-
183
- test "app recovers when a boot-level error is introduced" do
184
- config = app.application_config.read
185
-
186
- assert_success app.spring_test_command
187
-
188
- File.write(app.application_config, "#{config}\nomg")
189
- app.await_reload
190
-
191
- assert_failure app.spring_test_command
192
-
193
- File.write(app.application_config, config)
194
- assert_success app.spring_test_command
195
- end
196
-
197
- test "stop command kills server" do
198
- app.run app.spring_test_command
199
- assert spring_env.server_running?, "The server should be running but it isn't"
200
-
201
- assert_success "bin/spring stop"
202
- assert !spring_env.server_running?, "The server should not be running but it is"
203
- end
204
-
205
- test "custom commands" do
206
- # Start spring before setting up the command, to test that it gracefully upgrades itself
207
- assert_success "bin/rails runner ''"
208
-
209
- File.write(app.spring_config, <<-RUBY.strip_heredoc)
210
- class CustomCommand
211
- def call
212
- puts "omg"
213
- end
214
-
215
- def exec_name
216
- "rake"
217
- end
218
- end
219
-
220
- Spring.register_command "custom", CustomCommand.new
221
- RUBY
222
-
223
- assert_success "bin/spring custom", stdout: "omg"
224
-
225
- assert_success "bin/spring binstub custom"
226
- assert_success "bin/custom", stdout: "omg"
227
-
228
- app.env["DISABLE_SPRING"] = "1"
229
- assert_success %{bin/custom -e 'puts "foo"'}, stdout: "foo"
230
- end
231
-
232
- test "binstub" do
233
- assert_success "bin/rails server --help", stdout: "Usage: rails server" # rails command fallback
234
-
235
- assert_success "#{app.spring} binstub rake", stdout: "bin/rake: spring already present"
236
-
237
- assert_success "#{app.spring} binstub --remove rake", stdout: "bin/rake: spring removed"
238
- assert !app.path("bin/rake").read.include?(Spring::Client::Binstub::LOADER)
239
- assert_success "bin/rake -T", stdout: "rake db:migrate"
240
- end
241
-
242
- test "binstub remove all" do
243
- assert_success "bin/spring binstub --remove --all"
244
- refute File.exist?(app.path("bin/spring"))
245
- end
246
-
247
- test "binstub when spring gem is missing" do
248
- without_gem "spring-#{Spring::VERSION}" do
249
- File.write(app.gemfile, app.gemfile.read.gsub(/gem 'spring.*/, ""))
250
- assert_success "bin/rake -T", stdout: "rake db:migrate"
251
- end
252
- end
253
-
254
- test "binstub when spring binary is missing" do
255
- begin
256
- File.rename(app.path("bin/spring"), app.path("bin/spring.bak"))
257
- assert_success "bin/rake -T", stdout: "rake db:migrate"
258
- ensure
259
- File.rename(app.path("bin/spring.bak"), app.path("bin/spring"))
260
- end
261
- end
262
-
263
- test "binstub upgrade with old binstub" do
264
- File.write(app.path("bin/rake"), <<-RUBY.strip_heredoc)
265
- #!/usr/bin/env ruby
266
-
267
- if !Process.respond_to?(:fork) || Gem::Specification.find_all_by_name("spring").empty?
268
- exec "bundle", "exec", "rake", *ARGV
269
- else
270
- ARGV.unshift "rake"
271
- load Gem.bin_path("spring", "spring")
272
- end
273
- RUBY
274
-
275
- File.write(app.path("bin/rails"), <<-RUBY.strip_heredoc)
276
- #!/usr/bin/env ruby
277
-
278
- if !Process.respond_to?(:fork) || Gem::Specification.find_all_by_name("spring").empty?
279
- APP_PATH = File.expand_path('../../config/application', __FILE__)
280
- require_relative '../config/boot'
281
- require 'rails/commands'
282
- else
283
- ARGV.unshift "rails"
284
- load Gem.bin_path("spring", "spring")
285
- end
286
- RUBY
287
-
288
- assert_success "bin/spring binstub --all", stdout: "upgraded"
289
-
290
- expected = <<-RUBY.gsub(/^ /, "")
291
- #!/usr/bin/env ruby
292
- #{Spring::Client::Binstub::LOADER.strip}
293
- require 'bundler/setup'
294
- load Gem.bin_path('rake', 'rake')
295
- RUBY
296
- assert_equal expected, app.path("bin/rake").read
297
-
298
- expected = <<-RUBY.gsub(/^ /, "")
299
- #!/usr/bin/env ruby
300
- #{Spring::Client::Binstub::LOADER.strip}
301
- APP_PATH = File.expand_path('../../config/application', __FILE__)
302
- require_relative '../config/boot'
303
- require 'rails/commands'
304
- RUBY
305
- assert_equal expected, app.path("bin/rails").read
306
- end
307
-
308
- test "binstub upgrade with new binstub variations" do
309
- expected = <<-RUBY.gsub(/^ /, "")
310
- #!/usr/bin/env ruby
311
- #{Spring::Client::Binstub::LOADER.strip}
312
- require 'bundler/setup'
313
- load Gem.bin_path('rake', 'rake')
314
- RUBY
315
-
316
- # older variation with double quotes
317
- File.write(app.path("bin/rake"), <<-RUBY.strip_heredoc)
318
- #!/usr/bin/env ruby
319
- begin
320
- load File.expand_path("../spring", __FILE__)
321
- rescue LoadError
322
- end
323
- require 'bundler/setup'
324
- load Gem.bin_path('rake', 'rake')
325
- RUBY
326
-
327
- assert_success "bin/spring binstub rake", stdout: "bin/rake: upgraded"
328
- assert_equal expected, app.path("bin/rake").read
329
-
330
- # newer variation with single quotes
331
- File.write(app.path("bin/rake"), <<-RUBY.strip_heredoc)
332
- #!/usr/bin/env ruby
333
- begin
334
- load File.expand_path('../spring', __FILE__)
335
- rescue LoadError
336
- end
337
- require 'bundler/setup'
338
- load Gem.bin_path('rake', 'rake')
339
- RUBY
340
-
341
- assert_success "bin/spring binstub rake", stdout: "bin/rake: upgraded"
342
- assert_equal expected, app.path("bin/rake").read
343
-
344
- # newer variation which checks end of exception message
345
- File.write(app.path("bin/rake"), <<-RUBY.strip_heredoc)
346
- #!/usr/bin/env ruby
347
- begin
348
- spring_bin_path = File.expand_path('../spring', __FILE__)
349
- load spring_bin_path
350
- rescue LoadError => e
351
- raise unless e.message.end_with? spring_bin_path, 'spring/binstub'
352
- end
353
- require 'bundler/setup'
354
- load Gem.bin_path('rake', 'rake')
355
- RUBY
356
-
357
- assert_success "bin/spring binstub rake", stdout: "bin/rake: upgraded"
358
- assert_equal expected, app.path("bin/rake").read
359
- end
360
-
361
- test "binstub remove with new binstub variations" do
362
- # older variation with double quotes
363
- File.write(app.path("bin/rake"), <<-RUBY.strip_heredoc)
364
- #!/usr/bin/env ruby
365
- begin
366
- load File.expand_path("../spring", __FILE__)
367
- rescue LoadError
368
- end
369
- require 'bundler/setup'
370
- load Gem.bin_path('rake', 'rake')
371
- RUBY
372
-
373
- # newer variation with single quotes
374
- File.write(app.path("bin/rails"), <<-RUBY.strip_heredoc)
375
- #!/usr/bin/env ruby
376
- begin
377
- load File.expand_path('../spring', __FILE__)
378
- rescue LoadError
379
- end
380
- APP_PATH = File.expand_path('../../config/application', __FILE__)
381
- require_relative '../config/boot'
382
- require 'rails/commands'
383
- RUBY
384
-
385
- assert_success "bin/spring binstub --remove rake", stdout: "bin/rake: spring removed"
386
- assert_success "bin/spring binstub --remove rails", stdout: "bin/rails: spring removed"
387
-
388
- expected = <<-RUBY.strip_heredoc
389
- #!/usr/bin/env ruby
390
- require 'bundler/setup'
391
- load Gem.bin_path('rake', 'rake')
392
- RUBY
393
- assert_equal expected, app.path("bin/rake").read
394
-
395
- expected = <<-RUBY.strip_heredoc
396
- #!/usr/bin/env ruby
397
- APP_PATH = File.expand_path('../../config/application', __FILE__)
398
- require_relative '../config/boot'
399
- require 'rails/commands'
400
- RUBY
401
- assert_equal expected, app.path("bin/rails").read
402
- end
403
-
404
- test "after fork callback" do
405
- File.write(app.spring_config, "Spring.after_fork { puts '!callback!' }")
406
- assert_success "bin/rails runner 'puts 2'", stdout: "!callback!\n2"
407
- end
408
-
409
- test "global config file evaluated" do
410
- File.write("#{app.user_home}/.spring.rb", "Spring.after_fork { puts '!callback!' }")
411
- assert_success "bin/rails runner 'puts 2'", stdout: "!callback!\n2"
412
- end
413
-
414
- test "can define client tasks" do
415
- File.write("#{app.spring_client_config}", <<-RUBY)
416
- Spring::Client::COMMANDS["foo"] = lambda { |args| puts "bar -- \#{args.inspect}" }
417
- RUBY
418
- assert_success "bin/spring foo --baz", stdout: "bar -- [\"foo\", \"--baz\"]\n"
419
- end
420
-
421
- test "missing config/application.rb" do
422
- app.application_config.delete
423
- assert_failure "bin/rake -T", stderr: "unable to find your config/application.rb"
424
- end
425
-
426
- test "piping with boot-level error" do
427
- config = app.application_config.read
428
- File.write(app.application_config, "#{config}\nomg")
429
- assert_success "bin/rake -T | cat"
430
- end
431
-
432
- test "piping" do
433
- assert_success "bin/rake -T | grep db", stdout: "rake db:migrate"
434
- end
435
-
436
- test "status" do
437
- assert_success "bin/spring status", stdout: "Spring is not running"
438
- assert_success "bin/rails runner ''"
439
- assert_success "bin/spring status", stdout: "Spring is running"
440
- end
441
-
442
- test "runner command sets Rails environment from command-line options" do
443
- assert_success "bin/rails runner -e test 'puts Rails.env'", stdout: "test"
444
- assert_success "bin/rails runner --environment=test 'puts Rails.env'", stdout: "test"
445
- end
446
-
447
- test "forcing rails env via environment variable" do
448
- app.env['RAILS_ENV'] = 'test'
449
- assert_success "bin/rake -p 'Rails.env'", stdout: "test"
450
- end
451
-
452
- test "setting env vars with rake" do
453
- File.write(app.path("lib/tasks/env.rake"), <<-RUBY.strip_heredoc)
454
- task :print_rails_env => :environment do
455
- puts Rails.env
456
- end
457
-
458
- task :print_env do
459
- ENV.each { |k, v| puts "\#{k}=\#{v}" }
460
- end
461
-
462
- task(:default).clear.enhance [:print_rails_env]
463
- RUBY
464
-
465
- assert_success "bin/rake RAILS_ENV=test print_rails_env", stdout: "test"
466
- assert_success "bin/rake FOO=bar print_env", stdout: "FOO=bar"
467
- assert_success "bin/rake", stdout: "test"
468
- end
469
-
470
- test "changing the Gemfile works" do
471
- assert_success %(bin/rails runner 'require "sqlite3"')
472
-
473
- File.write(app.gemfile, app.gemfile.read.sub(%{gem 'sqlite3'}, %{# gem 'sqlite3'}))
474
- app.await_reload
475
-
476
- assert_failure %(bin/rails runner 'require "sqlite3"'), stderr: "sqlite3"
477
- end
478
-
479
- test "changing the Gemfile works when spring calls into itself" do
480
- File.write(app.path("script.rb"), <<-RUBY.strip_heredoc)
481
- gemfile = Rails.root.join("Gemfile")
482
- File.write(gemfile, "\#{gemfile.read}gem 'text'\\n")
483
- Bundler.with_clean_env do
484
- system(#{app.env.inspect}, "bundle install")
485
- end
486
- output = `\#{Rails.root.join('bin/rails')} runner 'require "text"; puts "done";'`
487
- exit output.include? "done\n"
488
- RUBY
489
-
490
- assert_success [%(bin/rails runner 'load Rails.root.join("script.rb")'), timeout: 60]
491
- end
492
-
493
- test "changing the environment between runs" do
494
- File.write(app.application_config, "#{app.application_config.read}\nENV['BAR'] = 'bar'")
495
-
496
- app.env["OMG"] = "1"
497
- app.env["FOO"] = "1"
498
- app.env["RUBYOPT"] = "-rubygems"
499
-
500
- assert_success %(bin/rails runner 'p ENV["OMG"]'), stdout: "1"
501
- assert_success %(bin/rails runner 'p ENV["BAR"]'), stdout: "bar"
502
- assert_success %(bin/rails runner 'p ENV.key?("BUNDLE_GEMFILE")'), stdout: "true"
503
- assert_success %(bin/rails runner 'p ENV["RUBYOPT"]'), stdout: "bundler"
504
-
505
- app.env["OMG"] = "2"
506
- app.env.delete "FOO"
507
-
508
- assert_success %(bin/rails runner 'p ENV["OMG"]'), stdout: "2"
509
- assert_success %(bin/rails runner 'p ENV.key?("FOO")'), stdout: "false"
510
- end
511
-
512
- test "Kernel.raise remains private" do
513
- expr = "p Kernel.private_instance_methods.include?(:raise)"
514
- assert_success %(bin/rails runner '#{expr}'), stdout: "true"
515
- end
516
-
517
- test "custom bundle path" do
518
- bundle_path = app.path(".bundle/#{Bundler.ruby_scope}")
519
- bundle_path.dirname.mkpath
520
-
521
- FileUtils.cp_r "#{app.gem_home}/", bundle_path.to_s
522
-
523
- app.run! "bundle install --path .bundle --clean --local"
524
-
525
- assert_speedup do
526
- 2.times { assert_success "bundle exec rails runner ''" }
527
- end
528
- end
529
-
530
- test "booting a foreground server" do
531
- FileUtils.cd(app.root) do
532
- assert !spring_env.server_running?
533
- assert_success "bin/spring server &"
534
-
535
- Timeout.timeout(10) do
536
- sleep 0.1 until spring_env.server_running? && spring_env.socket_path.exist?
537
- end
538
-
539
- assert_success app.spring_test_command
540
- end
541
- end
542
-
543
- test "server boot timeout" do
544
- app.env["SPRING_SERVER_COMMAND"] = "sleep 1"
545
- File.write("#{app.spring_client_config}", %(
546
- Spring::Client::Run.const_set(:BOOT_TIMEOUT, 0.1)
547
- ))
548
-
549
- assert_failure "bin/rails runner ''", stderr: "timed out"
550
- end
551
-
552
- test "no warnings are shown for unsprung commands" do
553
- app.env["DISABLE_SPRING"] = "1"
554
- refute_output_includes "bin/rails runner ''", stderr: "WARN"
555
- end
556
- end
557
- end
558
- end