Skip to content

Commit 96dfbb4

Browse files
committed
Reorganise tests
Get most of the test code under lib/ This is the first step towards extracting the listen watcher into a separate project.
1 parent 8a75bfd commit 96dfbb4

13 files changed

+652
-628
lines changed

Rakefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace :test do
1010

1111
Rake::TestTask.new(:acceptance) do |t|
1212
t.libs << "test"
13-
t.test_files = FileList["test/acceptance/*_test.rb"]
13+
t.test_files = FileList["test/acceptance_test.rb"]
1414
t.verbose = true
1515
end
1616

lib/spring/test.rb

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
require "active_support/test_case"
2+
3+
module Spring
4+
module Test
5+
class << self
6+
attr_accessor :root
7+
end
8+
9+
require "spring/test/application"
10+
require "spring/test/application_generator"
11+
require "spring/test/rails_version"
12+
require "spring/test/watcher_test"
13+
require "spring/test/acceptance_test"
14+
end
15+
end

lib/spring/test/acceptance_test.rb

+323
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
# encoding: utf-8
2+
3+
require "io/wait"
4+
require "timeout"
5+
require "spring/sid"
6+
require "spring/client"
7+
8+
module Spring
9+
module Test
10+
class AcceptanceTest < ActiveSupport::TestCase
11+
runnables.delete self # prevent Minitest running this class
12+
13+
DEFAULT_SPEEDUP = 0.8
14+
15+
def rails_version
16+
ENV['RAILS_VERSION'] || '~> 4.0.0'
17+
end
18+
19+
def generator
20+
@@generator ||= Spring::Test::ApplicationGenerator.new(rails_version)
21+
end
22+
23+
def app
24+
@app ||= Spring::Test::Application.new("#{Spring::Test.root}/apps/tmp")
25+
end
26+
27+
def assert_output(artifacts, expected)
28+
expected.each do |stream, output|
29+
assert artifacts[stream].include?(output),
30+
"expected #{stream} to include '#{output}'.\n\n#{app.debug(artifacts)}"
31+
end
32+
end
33+
34+
def assert_success(command, expected_output = nil)
35+
artifacts = app.run(*Array(command))
36+
assert artifacts[:status].success?, "expected successful exit status\n\n#{app.debug(artifacts)}"
37+
assert_output artifacts, expected_output if expected_output
38+
end
39+
40+
def assert_failure(command, expected_output = nil)
41+
artifacts = app.run(*Array(command))
42+
assert !artifacts[:status].success?, "expected unsuccessful exit status\n\n#{app.debug(artifacts)}"
43+
assert_output artifacts, expected_output if expected_output
44+
end
45+
46+
def assert_speedup(ratio = DEFAULT_SPEEDUP)
47+
if ENV['CI']
48+
yield
49+
else
50+
app.with_timing do
51+
yield
52+
assert app.timing_ratio < ratio, "#{app.last_time} was not less than #{ratio} of #{app.first_time}"
53+
end
54+
end
55+
end
56+
57+
setup do
58+
generator.generate_if_missing
59+
generator.install_spring
60+
generator.copy_to(app.root)
61+
end
62+
63+
teardown do
64+
app.stop_spring
65+
end
66+
67+
test "basic" do
68+
assert_speedup do
69+
2.times { app.run app.spring_test_command }
70+
end
71+
end
72+
73+
test "help message when called without arguments" do
74+
assert_success "bin/spring", stdout: 'Usage: spring COMMAND [ARGS]'
75+
end
76+
77+
test "test changes are picked up" do
78+
assert_speedup do
79+
assert_success app.spring_test_command, stdout: "0 failures"
80+
81+
File.write(app.test, app.test.read.sub("get :index", "raise 'omg'"))
82+
assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
83+
end
84+
end
85+
86+
test "code changes are picked up" do
87+
assert_speedup do
88+
assert_success app.spring_test_command, stdout: "0 failures"
89+
90+
File.write(app.controller, app.controller.read.sub("@posts = Post.all", "raise 'omg'"))
91+
assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
92+
end
93+
end
94+
95+
test "code changes in pre-referenced app files are picked up" do
96+
File.write(app.path("config/initializers/load_posts_controller.rb"), "PostsController\n")
97+
98+
assert_speedup do
99+
assert_success app.spring_test_command, stdout: "0 failures"
100+
101+
File.write(app.controller, app.controller.read.sub("@posts = Post.all", "raise 'omg'"))
102+
assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
103+
end
104+
end
105+
106+
test "app gets reloaded when preloaded files change" do
107+
assert_success app.spring_test_command
108+
109+
File.write(app.application_config, app.application_config.read + <<-CODE)
110+
class Foo
111+
def self.omg
112+
raise "omg"
113+
end
114+
end
115+
CODE
116+
File.write(app.test, app.test.read.sub("get :index", "Foo.omg"))
117+
118+
app.await_reload
119+
assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
120+
end
121+
122+
test "app recovers when a boot-level error is introduced" do
123+
config = app.application_config.read
124+
125+
assert_success app.spring_test_command
126+
127+
File.write(app.application_config, "#{config}\nomg")
128+
app.await_reload
129+
130+
assert_failure app.spring_test_command
131+
132+
File.write(app.application_config, config)
133+
assert_success app.spring_test_command
134+
end
135+
136+
test "stop command kills server" do
137+
app.run app.spring_test_command
138+
assert app.spring_env.server_running?, "The server should be running but it isn't"
139+
140+
assert_success "bin/spring stop"
141+
assert !app.spring_env.server_running?, "The server should not be running but it is"
142+
end
143+
144+
test "custom commands" do
145+
File.write(app.spring_config, <<-CODE)
146+
class CustomCommand
147+
def call
148+
puts "omg"
149+
end
150+
151+
def exec_name
152+
"rake"
153+
end
154+
end
155+
156+
Spring.register_command "custom", CustomCommand.new
157+
CODE
158+
159+
assert_success "bin/spring custom", stdout: "omg"
160+
161+
assert_success "bin/spring binstub custom"
162+
assert_success "bin/custom", stdout: "omg"
163+
164+
app.env["DISABLE_SPRING"] = "1"
165+
assert_success %{bin/custom -e 'puts "foo"'}, stdout: "foo"
166+
end
167+
168+
test "binstub" do
169+
assert_success "bin/rails server --help", stdout: "Usage: rails server" # rails command fallback
170+
171+
assert_success "#{app.spring} binstub rake", stdout: "bin/rake: spring already present"
172+
173+
assert_success "#{app.spring} binstub --remove rake", stdout: "bin/rake: spring removed"
174+
assert !app.path("bin/rake").read.include?(Spring::Client::Binstub::LOADER)
175+
assert_success "bin/rake -T", stdout: "rake db:migrate"
176+
end
177+
178+
test "binstub when spring is uninstalled" do
179+
app.run! "gem uninstall --ignore-dependencies spring"
180+
File.write(app.gemfile, app.gemfile.read.gsub(/gem 'spring.*/, ""))
181+
assert_success "bin/rake -T", stdout: "rake db:migrate"
182+
end
183+
184+
test "binstub upgrade" do
185+
File.write(app.path("bin/rake"), <<CODE)
186+
#!/usr/bin/env ruby
187+
188+
if !Process.respond_to?(:fork) || Gem::Specification.find_all_by_name("spring").empty?
189+
exec "bundle", "exec", "rake", *ARGV
190+
else
191+
ARGV.unshift "rake"
192+
load Gem.bin_path("spring", "spring")
193+
end
194+
CODE
195+
196+
File.write(app.path("bin/rails"), <<CODE)
197+
#!/usr/bin/env ruby
198+
199+
if !Process.respond_to?(:fork) || Gem::Specification.find_all_by_name("spring").empty?
200+
APP_PATH = File.expand_path('../../config/application', __FILE__)
201+
require_relative '../config/boot'
202+
require 'rails/commands'
203+
else
204+
ARGV.unshift "rails"
205+
load Gem.bin_path("spring", "spring")
206+
end
207+
CODE
208+
209+
assert_success "bin/spring binstub --all", stdout: "upgraded"
210+
211+
assert_equal app.path("bin/rake").read, <<CODE
212+
#!/usr/bin/env ruby
213+
#{Spring::Client::Binstub::LOADER.strip}
214+
require 'bundler/setup'
215+
load Gem.bin_path('rake', 'rake')
216+
CODE
217+
218+
assert_equal app.path("bin/rails").read, <<CODE
219+
#!/usr/bin/env ruby
220+
#{Spring::Client::Binstub::LOADER.strip}
221+
APP_PATH = File.expand_path('../../config/application', __FILE__)
222+
require_relative '../config/boot'
223+
require 'rails/commands'
224+
CODE
225+
end
226+
227+
test "after fork callback" do
228+
File.write(app.spring_config, "Spring.after_fork { puts '!callback!' }")
229+
assert_success "bin/rails runner 'puts 2'", stdout: "!callback!\n2"
230+
end
231+
232+
test "global config file evaluated" do
233+
File.write("#{app.user_home}/.spring.rb", "Spring.after_fork { puts '!callback!' }")
234+
assert_success "bin/rails runner 'puts 2'", stdout: "!callback!\n2"
235+
end
236+
237+
test "missing config/application.rb" do
238+
app.application_config.delete
239+
assert_failure "bin/rake -T", stderr: "unable to find your config/application.rb"
240+
end
241+
242+
test "piping" do
243+
assert_success "bin/rake -T | grep db", stdout: "rake db:migrate"
244+
end
245+
246+
test "status" do
247+
assert_success "bin/spring status", stdout: "Spring is not running"
248+
assert_success "bin/rails runner ''"
249+
assert_success "bin/spring status", stdout: "Spring is running"
250+
end
251+
252+
test "runner command sets Rails environment from command-line options" do
253+
assert_success "bin/rails runner -e test 'puts Rails.env'", stdout: "test"
254+
assert_success "bin/rails runner --environment=test 'puts Rails.env'", stdout: "test"
255+
end
256+
257+
test "forcing rails env via environment variable" do
258+
app.env['RAILS_ENV'] = 'test'
259+
assert_success "bin/rake -p 'Rails.env'", stdout: "test"
260+
end
261+
262+
test "setting env vars with rake" do
263+
File.write(app.path("lib/tasks/env.rake"), <<-'CODE')
264+
task :print_rails_env => :environment do
265+
puts Rails.env
266+
end
267+
268+
task :print_env do
269+
ENV.each { |k, v| puts "#{k}=#{v}" }
270+
end
271+
272+
task(:default).clear.enhance [:print_rails_env]
273+
CODE
274+
275+
assert_success "bin/rake RAILS_ENV=test print_rails_env", stdout: "test"
276+
assert_success "bin/rake FOO=bar print_env", stdout: "FOO=bar"
277+
assert_success "bin/rake", stdout: "test"
278+
end
279+
280+
test "changing the Gemfile works" do
281+
assert_success %(bin/rails runner 'require "sqlite3"')
282+
283+
File.write(app.gemfile, app.gemfile.read.sub(%{gem 'sqlite3'}, %{# gem 'sqlite3'}))
284+
app.await_reload
285+
286+
assert_failure %(bin/rails runner 'require "sqlite3"'), stderr: "sqlite3"
287+
end
288+
289+
test "changing the Gemfile works when spring calls into itself" do
290+
File.write(app.path("script.rb"), <<-CODE)
291+
gemfile = Rails.root.join("Gemfile")
292+
File.write(gemfile, "\#{gemfile.read}gem 'devise'\\n")
293+
Bundler.with_clean_env do
294+
system(#{app.env.inspect}, "bundle install")
295+
end
296+
output = `\#{Rails.root.join('bin/rails')} runner 'require "devise"; puts "done";'`
297+
exit output == "done\n"
298+
CODE
299+
300+
assert_success [%(bin/rails runner 'load Rails.root.join("script.rb")'), timeout: 60]
301+
end
302+
303+
test "changing the environment between runs" do
304+
File.write(app.application_config, "#{app.application_config.read}\nENV['BAR'] = 'bar'")
305+
306+
app.env["OMG"] = "1"
307+
app.env["FOO"] = "1"
308+
app.env["RUBYOPT"] = "-rubygems"
309+
310+
assert_success %(bin/rails runner 'p ENV["OMG"]'), stdout: "1"
311+
assert_success %(bin/rails runner 'p ENV["BAR"]'), stdout: "bar"
312+
assert_success %(bin/rails runner 'p ENV.key?("BUNDLE_GEMFILE")'), stdout: "true"
313+
assert_success %(bin/rails runner 'p ENV["RUBYOPT"]'), stdout: "bundler"
314+
315+
app.env["OMG"] = "2"
316+
app.env.delete "FOO"
317+
318+
assert_success %(bin/rails runner 'p ENV["OMG"]'), stdout: "2"
319+
assert_success %(bin/rails runner 'p ENV.key?("FOO")'), stdout: "false"
320+
end
321+
end
322+
end
323+
end

0 commit comments

Comments
 (0)