spring 1.1.3 → 1.2.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.
@@ -1,3 +1,3 @@
1
1
  module Spring
2
- VERSION = "1.1.3"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -9,15 +9,11 @@ module Spring
9
9
  end
10
10
 
11
11
  def self.watch_method=(method)
12
- case method
13
- when :polling
14
- require_relative "watcher/polling"
15
- @watch_method = Watcher::Polling
16
- when :listen
17
- require_relative "watcher/listen"
18
- @watch_method = Watcher::Listen
19
- else
12
+ if method.is_a?(Class)
20
13
  @watch_method = method
14
+ else
15
+ require "spring/watcher/#{method}"
16
+ @watch_method = Watcher.const_get(method.to_s.gsub(/(^.|_.)/) { $1[-1].upcase })
21
17
  end
22
18
  end
23
19
 
@@ -1,3 +1,5 @@
1
+ require "spring/watcher"
2
+
1
3
  module Spring
2
4
  module Watcher
3
5
  class Polling < Abstract
@@ -0,0 +1,4 @@
1
+ require "helper"
2
+
3
+ class AcceptanceTest < Spring::Test::AcceptanceTest
4
+ end
@@ -1,7 +1,7 @@
1
1
  $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
2
 
3
3
  require "bundler/setup"
4
- require "active_support/test_case"
5
4
  require "minitest/autorun"
6
5
 
7
- TEST_ROOT = File.expand_path('..', __FILE__)
6
+ require "spring/test"
7
+ Spring::Test.root = File.expand_path('..', __FILE__)
@@ -7,7 +7,17 @@ class CommandsTest < ActiveSupport::TestCase
7
7
  assert_equal 'test', command.env(['test'])
8
8
  end
9
9
 
10
- test 'console command ignores first argument if it is a flag' do
10
+ test 'console command sets rails environment from -e option' do
11
+ command = Spring::Commands::RailsConsole.new
12
+ assert_equal 'test', command.env(['-e', 'test'])
13
+ end
14
+
15
+ test 'console command sets rails environment from --environment option' do
16
+ command = Spring::Commands::RailsConsole.new
17
+ assert_equal 'test', command.env(['--environment=test'])
18
+ end
19
+
20
+ test 'console command ignores first argument if it is a flag except -e and --environment' do
11
21
  command = Spring::Commands::RailsConsole.new
12
22
  assert_nil command.env(['--sandbox'])
13
23
  end
@@ -1,194 +1,8 @@
1
1
  require "helper"
2
- require "tmpdir"
3
- require "fileutils"
4
- require "timeout"
5
- require "active_support/core_ext/numeric/time"
6
- require "spring/watcher"
2
+ require "spring/test/watcher_test"
7
3
  require "spring/watcher/polling"
8
- require "spring/watcher/listen"
9
-
10
- module WatcherTests
11
- LATENCY = 0.001
12
- TIMEOUT = 1
13
-
14
- attr_accessor :dir
15
-
16
- def watcher
17
- @watcher ||= watcher_class.new(dir, LATENCY)
18
- end
19
-
20
- def setup
21
- @dir = File.realpath(Dir.mktmpdir)
22
- end
23
-
24
- def teardown
25
- FileUtils.remove_entry_secure @dir
26
- watcher.stop
27
- end
28
-
29
- def touch(file, mtime = nil)
30
- options = {}
31
- options[:mtime] = mtime if mtime
32
- FileUtils.touch(file, options)
33
- end
34
-
35
- def assert_stale
36
- timeout = Time.now + TIMEOUT
37
- sleep LATENCY until watcher.stale? || Time.now > timeout
38
- assert watcher.stale?
39
- end
40
-
41
- def assert_not_stale
42
- sleep LATENCY * 10
43
- assert !watcher.stale?
44
- end
45
-
46
- def test_starting_with_no_file
47
- file = "#{@dir}/omg"
48
- touch file, Time.now - 2.seconds
49
-
50
- watcher.start
51
- watcher.add file
52
-
53
- assert_not_stale
54
- touch file, Time.now
55
- assert_stale
56
- end
57
-
58
- def test_is_stale_when_a_watched_file_is_updated
59
- file = "#{@dir}/omg"
60
- touch file, Time.now - 2.seconds
61
-
62
- watcher.add file
63
- watcher.start
64
-
65
- assert_not_stale
66
- touch file, Time.now
67
- assert_stale
68
- end
69
-
70
- def test_is_stale_when_removing_files
71
- file = "#{@dir}/omg"
72
- touch file, Time.now
73
-
74
- watcher.add file
75
- watcher.start
76
-
77
- assert_not_stale
78
- FileUtils.rm(file)
79
- assert_stale
80
- end
81
-
82
- def test_is_stale_when_files_are_added_to_a_watched_directory
83
- subdir = "#{@dir}/subdir"
84
- FileUtils.mkdir(subdir)
85
-
86
- watcher.add subdir
87
- watcher.start
88
-
89
- assert_not_stale
90
- touch "#{subdir}/foo", Time.now - 1.minute
91
- assert_stale
92
- end
93
-
94
- def test_is_stale_when_a_file_is_changed_in_a_watched_directory
95
- subdir = "#{@dir}/subdir"
96
- FileUtils.mkdir(subdir)
97
- touch "#{subdir}/foo", Time.now - 1.minute
98
-
99
- watcher.add subdir
100
- watcher.start
101
-
102
- assert_not_stale
103
- touch "#{subdir}/foo", Time.now
104
- assert_stale
105
- end
106
-
107
- def test_adding_doesnt_wipe_stale_state
108
- file = "#{@dir}/omg"
109
- file2 = "#{@dir}/foo"
110
- touch file, Time.now - 2.seconds
111
- touch file2, Time.now - 2.seconds
112
-
113
- watcher.add file
114
- watcher.start
115
-
116
- assert_not_stale
117
-
118
- touch file, Time.now
119
- watcher.add file2
120
-
121
- assert_stale
122
- end
123
-
124
- def test_on_stale
125
- file = "#{@dir}/omg"
126
- touch file, Time.now - 2.seconds
127
-
128
- stale = false
129
- watcher.on_stale { stale = true }
130
-
131
- watcher.add file
132
- watcher.start
133
-
134
- touch file, Time.now
135
-
136
- Timeout.timeout(1) { sleep 0.01 until stale }
137
- assert stale
138
-
139
- # Check that we only get notified once
140
- stale = false
141
- sleep LATENCY * 3
142
- assert !stale
143
- end
144
-
145
- def test_add_relative_path
146
- File.write("#{dir}/foo", "foo")
147
- watcher.add "foo"
148
- assert_equal ["#{dir}/foo"], watcher.files.to_a
149
- end
150
-
151
- def test_add_dot_relative_path
152
- File.write("#{dir}/foo", "foo")
153
- watcher.add "./foo"
154
- assert_equal ["#{dir}/foo"], watcher.files.to_a
155
- end
156
-
157
- def test_add_non_existant_file
158
- watcher.add './foobar'
159
- assert watcher.files.empty?
160
- end
161
- end
162
-
163
- class ListenWatcherTest < ActiveSupport::TestCase
164
- include WatcherTests
165
-
166
- def watcher_class
167
- Spring::Watcher::Listen
168
- end
169
-
170
- test "root directories" do
171
- begin
172
- other_dir_1 = File.realpath(Dir.mktmpdir)
173
- other_dir_2 = File.realpath(Dir.mktmpdir)
174
- File.write("#{other_dir_1}/foo", "foo")
175
- File.write("#{dir}/foo", "foo")
176
-
177
- watcher.add "#{other_dir_1}/foo"
178
- watcher.add other_dir_2
179
- watcher.add "#{dir}/foo"
180
-
181
- assert_equal [dir, other_dir_1, other_dir_2].sort, watcher.base_directories.sort
182
- ensure
183
- FileUtils.rmdir other_dir_1
184
- FileUtils.rmdir other_dir_2
185
- end
186
- end
187
- end
188
-
189
- class PollingWatcherTest < ActiveSupport::TestCase
190
- include WatcherTests
191
4
 
5
+ class PollingWatcherTest < Spring::Test::WatcherTest
192
6
  def watcher_class
193
7
  Spring::Watcher::Polling
194
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spring
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Leighton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-13 00:00:00.000000000 Z
11
+ date: 2014-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -80,14 +80,18 @@ files:
80
80
  - lib/spring/process_title_updater.rb
81
81
  - lib/spring/server.rb
82
82
  - lib/spring/sid.rb
83
+ - lib/spring/test.rb
84
+ - lib/spring/test/acceptance_test.rb
85
+ - lib/spring/test/application.rb
86
+ - lib/spring/test/application_generator.rb
87
+ - lib/spring/test/rails_version.rb
88
+ - lib/spring/test/watcher_test.rb
83
89
  - lib/spring/version.rb
84
90
  - lib/spring/watcher.rb
85
91
  - lib/spring/watcher/abstract.rb
86
- - lib/spring/watcher/listen.rb
87
92
  - lib/spring/watcher/polling.rb
88
93
  - spring.gemspec
89
- - test/acceptance/app_test.rb
90
- - test/acceptance/helper.rb
94
+ - test/acceptance_test.rb
91
95
  - test/apps/.gitignore
92
96
  - test/helper.rb
93
97
  - test/unit/client/help_test.rb
@@ -120,8 +124,7 @@ signing_key:
120
124
  specification_version: 4
121
125
  summary: Rails application preloader
122
126
  test_files:
123
- - test/acceptance/app_test.rb
124
- - test/acceptance/helper.rb
127
+ - test/acceptance_test.rb
125
128
  - test/apps/.gitignore
126
129
  - test/helper.rb
127
130
  - test/unit/client/help_test.rb
@@ -1,52 +0,0 @@
1
- gem "listen", "~> 1.0"
2
- require "listen"
3
- require "listen/version"
4
-
5
- module Spring
6
- module Watcher
7
- class Listen < Abstract
8
- attr_reader :listener
9
-
10
- def start
11
- unless @listener
12
- @listener = ::Listen.to(*base_directories, relative_paths: false)
13
- @listener.latency(latency)
14
- @listener.change(&method(:changed))
15
- @listener.start
16
- end
17
- end
18
-
19
- def stop
20
- if @listener
21
- @listener.stop
22
- @listener = nil
23
- end
24
- end
25
-
26
- def subjects_changed
27
- if @listener && @listener.directories.sort != base_directories.sort
28
- restart
29
- end
30
- end
31
-
32
- def watching?(file)
33
- files.include?(file) || file.start_with?(*directories)
34
- end
35
-
36
- def changed(modified, added, removed)
37
- synchronize do
38
- if (modified + added + removed).any? { |f| watching? f }
39
- mark_stale
40
- end
41
- end
42
- end
43
-
44
- def base_directories
45
- ([root] +
46
- files.reject { |f| f.start_with? root }.map { |f| File.expand_path("#{f}/..") } +
47
- directories.reject { |d| d.start_with? root }
48
- ).uniq
49
- end
50
- end
51
- end
52
- end
@@ -1,334 +0,0 @@
1
- # encoding: utf-8
2
- require "helper"
3
- require "acceptance/helper"
4
- require "io/wait"
5
- require "timeout"
6
- require "spring/sid"
7
- require "spring/client"
8
-
9
- class AppTest < ActiveSupport::TestCase
10
- DEFAULT_SPEEDUP = 0.8
11
-
12
- def rails_version
13
- ENV['RAILS_VERSION'] || '~> 4.0.0'
14
- end
15
-
16
- def generator
17
- @@generator ||= Spring::Test::ApplicationGenerator.new(rails_version)
18
- end
19
-
20
- def app
21
- @app ||= Spring::Test::Application.new("#{TEST_ROOT}/apps/tmp")
22
- end
23
-
24
- def assert_output(artifacts, expected)
25
- expected.each do |stream, output|
26
- assert artifacts[stream].include?(output),
27
- "expected #{stream} to include '#{output}'.\n\n#{app.debug(artifacts)}"
28
- end
29
- end
30
-
31
- def assert_success(command, expected_output = nil)
32
- artifacts = app.run(*Array(command))
33
- assert artifacts[:status].success?, "expected successful exit status\n\n#{app.debug(artifacts)}"
34
- assert_output artifacts, expected_output if expected_output
35
- end
36
-
37
- def assert_failure(command, expected_output = nil)
38
- artifacts = app.run(*Array(command))
39
- assert !artifacts[:status].success?, "expected unsuccessful exit status\n\n#{app.debug(artifacts)}"
40
- assert_output artifacts, expected_output if expected_output
41
- end
42
-
43
- def assert_speedup(ratio = DEFAULT_SPEEDUP)
44
- if ENV['CI']
45
- yield
46
- else
47
- app.with_timing do
48
- yield
49
- assert app.timing_ratio < ratio, "#{app.last_time} was not less than #{ratio} of #{app.first_time}"
50
- end
51
- end
52
- end
53
-
54
- def assert_app_reloaded
55
- assert_success app.spring_test_command
56
-
57
- File.write(app.application_config, app.application_config.read + <<-CODE)
58
- class Foo
59
- def self.omg
60
- raise "omg"
61
- end
62
- end
63
- CODE
64
- File.write(app.test, app.test.read.sub("get :index", "Foo.omg"))
65
-
66
- app.await_reload
67
- assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
68
- end
69
-
70
- setup do
71
- generator.generate_if_missing
72
- generator.install_spring
73
- generator.copy_to(app.root)
74
- end
75
-
76
- teardown do
77
- app.stop_spring
78
- end
79
-
80
- test "basic" do
81
- assert_speedup do
82
- 2.times { app.run app.spring_test_command }
83
- end
84
- end
85
-
86
- test "help message when called without arguments" do
87
- assert_success "bin/spring", stdout: 'Usage: spring COMMAND [ARGS]'
88
- end
89
-
90
- test "test changes are picked up" do
91
- assert_speedup do
92
- assert_success app.spring_test_command, stdout: "0 failures"
93
-
94
- File.write(app.test, app.test.read.sub("get :index", "raise 'omg'"))
95
- assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
96
- end
97
- end
98
-
99
- test "code changes are picked up" do
100
- assert_speedup do
101
- assert_success app.spring_test_command, stdout: "0 failures"
102
-
103
- File.write(app.controller, app.controller.read.sub("@posts = Post.all", "raise 'omg'"))
104
- assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
105
- end
106
- end
107
-
108
- test "code changes in pre-referenced app files are picked up" do
109
- File.write(app.path("config/initializers/load_posts_controller.rb"), "PostsController\n")
110
-
111
- assert_speedup do
112
- assert_success app.spring_test_command, stdout: "0 failures"
113
-
114
- File.write(app.controller, app.controller.read.sub("@posts = Post.all", "raise 'omg'"))
115
- assert_failure app.spring_test_command, stdout: "RuntimeError: omg"
116
- end
117
- end
118
-
119
- test "app gets reloaded when preloaded files change (polling watcher)" do
120
- app.env["RAILS_ENV"] = "test"
121
- assert_success "bin/rails runner 'puts Spring.watcher.class'", stdout: "Polling"
122
- assert_app_reloaded
123
- end
124
-
125
- test "app gets reloaded when preloaded files change (listen watcher)" do
126
- File.write(app.gemfile, "#{app.gemfile.read}gem 'listen', '~> 1.0'")
127
- File.write(app.spring_config, "Spring.watch_method = :listen")
128
- app.bundle
129
-
130
- app.env["RAILS_ENV"] = "test"
131
- assert_success "bin/rails runner 'puts Spring.watcher.class'", stdout: "Listen"
132
- assert_app_reloaded
133
- end
134
-
135
- test "app recovers when a boot-level error is introduced" do
136
- config = app.application_config.read
137
-
138
- assert_success app.spring_test_command
139
-
140
- File.write(app.application_config, "#{config}\nomg")
141
- app.await_reload
142
-
143
- assert_failure app.spring_test_command
144
-
145
- File.write(app.application_config, config)
146
- assert_success app.spring_test_command
147
- end
148
-
149
- test "stop command kills server" do
150
- app.run app.spring_test_command
151
- assert app.spring_env.server_running?, "The server should be running but it isn't"
152
-
153
- assert_success "bin/spring stop"
154
- assert !app.spring_env.server_running?, "The server should not be running but it is"
155
- end
156
-
157
- test "custom commands" do
158
- File.write(app.spring_config, <<-CODE)
159
- class CustomCommand
160
- def call
161
- puts "omg"
162
- end
163
-
164
- def exec_name
165
- "rake"
166
- end
167
- end
168
-
169
- Spring.register_command "custom", CustomCommand.new
170
- CODE
171
-
172
- assert_success "bin/spring custom", stdout: "omg"
173
-
174
- assert_success "bin/spring binstub custom"
175
- assert_success "bin/custom", stdout: "omg"
176
-
177
- app.env["DISABLE_SPRING"] = "1"
178
- assert_success %{bin/custom -e 'puts "foo"'}, stdout: "foo"
179
- end
180
-
181
- test "binstub" do
182
- assert_success "bin/rails server --help", stdout: "Usage: rails server" # rails command fallback
183
-
184
- assert_success "#{app.spring} binstub rake", stdout: "bin/rake: spring already present"
185
-
186
- assert_success "#{app.spring} binstub --remove rake", stdout: "bin/rake: spring removed"
187
- assert !app.path("bin/rake").read.include?(Spring::Client::Binstub::LOADER)
188
- assert_success "bin/rake -T", stdout: "rake db:migrate"
189
- end
190
-
191
- test "binstub when spring is uninstalled" do
192
- app.run! "gem uninstall --ignore-dependencies spring"
193
- File.write(app.gemfile, app.gemfile.read.gsub(/gem 'spring.*/, ""))
194
- assert_success "bin/rake -T", stdout: "rake db:migrate"
195
- end
196
-
197
- test "binstub upgrade" do
198
- File.write(app.path("bin/rake"), <<CODE)
199
- #!/usr/bin/env ruby
200
-
201
- if !Process.respond_to?(:fork) || Gem::Specification.find_all_by_name("spring").empty?
202
- exec "bundle", "exec", "rake", *ARGV
203
- else
204
- ARGV.unshift "rake"
205
- load Gem.bin_path("spring", "spring")
206
- end
207
- CODE
208
-
209
- File.write(app.path("bin/rails"), <<CODE)
210
- #!/usr/bin/env ruby
211
-
212
- if !Process.respond_to?(:fork) || Gem::Specification.find_all_by_name("spring").empty?
213
- APP_PATH = File.expand_path('../../config/application', __FILE__)
214
- require_relative '../config/boot'
215
- require 'rails/commands'
216
- else
217
- ARGV.unshift "rails"
218
- load Gem.bin_path("spring", "spring")
219
- end
220
- CODE
221
-
222
- assert_success "bin/spring binstub --all", stdout: "upgraded"
223
-
224
- assert_equal app.path("bin/rake").read, <<CODE
225
- #!/usr/bin/env ruby
226
- #{Spring::Client::Binstub::LOADER.strip}
227
- require 'bundler/setup'
228
- load Gem.bin_path('rake', 'rake')
229
- CODE
230
-
231
- assert_equal app.path("bin/rails").read, <<CODE
232
- #!/usr/bin/env ruby
233
- #{Spring::Client::Binstub::LOADER.strip}
234
- APP_PATH = File.expand_path('../../config/application', __FILE__)
235
- require_relative '../config/boot'
236
- require 'rails/commands'
237
- CODE
238
- end
239
-
240
- test "after fork callback" do
241
- File.write(app.spring_config, "Spring.after_fork { puts '!callback!' }")
242
- assert_success "bin/rails runner 'puts 2'", stdout: "!callback!\n2"
243
- end
244
-
245
- test "global config file evaluated" do
246
- File.write("#{app.user_home}/.spring.rb", "Spring.after_fork { puts '!callback!' }")
247
- assert_success "bin/rails runner 'puts 2'", stdout: "!callback!\n2"
248
- end
249
-
250
- test "missing config/application.rb" do
251
- app.application_config.delete
252
- assert_failure "bin/rake -T", stderr: "unable to find your config/application.rb"
253
- end
254
-
255
- test "piping" do
256
- assert_success "bin/rake -T | grep db", stdout: "rake db:migrate"
257
- end
258
-
259
- test "status" do
260
- assert_success "bin/spring status", stdout: "Spring is not running"
261
- assert_success "bin/rails runner ''"
262
- assert_success "bin/spring status", stdout: "Spring is running"
263
- end
264
-
265
- test "runner command sets Rails environment from command-line options" do
266
- assert_success "bin/rails runner -e test 'puts Rails.env'", stdout: "test"
267
- assert_success "bin/rails runner --environment=test 'puts Rails.env'", stdout: "test"
268
- end
269
-
270
- test "forcing rails env via environment variable" do
271
- app.env['RAILS_ENV'] = 'test'
272
- assert_success "bin/rake -p 'Rails.env'", stdout: "test"
273
- end
274
-
275
- test "setting env vars with rake" do
276
- File.write(app.path("lib/tasks/env.rake"), <<-'CODE')
277
- task :print_rails_env => :environment do
278
- puts Rails.env
279
- end
280
-
281
- task :print_env do
282
- ENV.each { |k, v| puts "#{k}=#{v}" }
283
- end
284
-
285
- task(:default).clear.enhance [:print_rails_env]
286
- CODE
287
-
288
- assert_success "bin/rake RAILS_ENV=test print_rails_env", stdout: "test"
289
- assert_success "bin/rake FOO=bar print_env", stdout: "FOO=bar"
290
- assert_success "bin/rake", stdout: "test"
291
- end
292
-
293
- test "changing the Gemfile works" do
294
- assert_success %(bin/rails runner 'require "sqlite3"')
295
-
296
- File.write(app.gemfile, app.gemfile.read.sub(%{gem 'sqlite3'}, %{# gem 'sqlite3'}))
297
- app.await_reload
298
-
299
- assert_failure %(bin/rails runner 'require "sqlite3"'), stderr: "sqlite3"
300
- end
301
-
302
- test "changing the Gemfile works when spring calls into itself" do
303
- File.write(app.path("script.rb"), <<-CODE)
304
- gemfile = Rails.root.join("Gemfile")
305
- File.write(gemfile, "\#{gemfile.read}gem 'devise'\\n")
306
- Bundler.with_clean_env do
307
- system(#{app.env.inspect}, "bundle install")
308
- end
309
- output = `\#{Rails.root.join('bin/rails')} runner 'require "devise"; puts "done";'`
310
- exit output == "done\n"
311
- CODE
312
-
313
- assert_success [%(bin/rails runner 'load Rails.root.join("script.rb")'), timeout: 60]
314
- end
315
-
316
- test "changing the environment between runs" do
317
- File.write(app.application_config, "#{app.application_config.read}\nENV['BAR'] = 'bar'")
318
-
319
- app.env["OMG"] = "1"
320
- app.env["FOO"] = "1"
321
- app.env["RUBYOPT"] = "-rubygems"
322
-
323
- assert_success %(bin/rails runner 'p ENV["OMG"]'), stdout: "1"
324
- assert_success %(bin/rails runner 'p ENV["BAR"]'), stdout: "bar"
325
- assert_success %(bin/rails runner 'p ENV.key?("BUNDLE_GEMFILE")'), stdout: "true"
326
- assert_success %(bin/rails runner 'p ENV["RUBYOPT"]'), stdout: "bundler"
327
-
328
- app.env["OMG"] = "2"
329
- app.env.delete "FOO"
330
-
331
- assert_success %(bin/rails runner 'p ENV["OMG"]'), stdout: "2"
332
- assert_success %(bin/rails runner 'p ENV.key?("FOO")'), stdout: "false"
333
- end
334
- end