rack-unreloader 1.8.0 → 2.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.
@@ -1,515 +0,0 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
2
-
3
- describe Rack::Unreloader do
4
- it "should not reload files automatically if cooldown option is nil" do
5
- ru(:cooldown => nil).call({}).must_equal [1]
6
- update_app(code(2))
7
- ru.call({}).must_equal [1]
8
- @ru.reload!
9
- ru.call({}).must_equal [2]
10
- end
11
-
12
- it "should not setup a reloader if reload option is false" do
13
- @filename = 'spec/app_no_reload.rb'
14
- ru(:reload => false).call({}).must_equal [1]
15
- file = 'spec/app_no_reload2.rb'
16
- File.open(file, 'wb'){|f| f.write('ANR2 = 2')}
17
- ru.require 'spec/app_no_*2.rb'
18
- ANR2.must_equal 2
19
- end
20
-
21
- it "should unload constants contained in file and reload file if file changes" do
22
- ru.call({}).must_equal [1]
23
- update_app(code(2))
24
- ru.call({}).must_equal [2]
25
- log_match %r{\ALoading.*spec/app\.rb\z},
26
- %r{\ANew classes in .*spec/app\.rb: App\z},
27
- %r{\AUnloading.*spec/app\.rb\z},
28
- "Removed constant App",
29
- %r{\ALoading.*spec/app\.rb\z},
30
- %r{\ANew classes in .*spec/app\.rb: App\z}
31
- end
32
-
33
- it "should stop monitoring file for changes if it is deleted constants contained in file and reload file if file changes" do
34
- ru.call({}).must_equal [1]
35
- file_delete('spec/app.rb')
36
- proc{ru.call({})}.must_raise NameError
37
- log_match %r{\ALoading.*spec/app\.rb\z},
38
- %r{\ANew classes in .*spec/app\.rb: App\z},
39
- %r{\AUnloading.*spec/app\.rb\z},
40
- "Removed constant App"
41
- end
42
-
43
- it "should check constants using ObjectSpace if require proc returns :ObjectSpace" do
44
- base_ru
45
- update_app(code(1))
46
- @ru.require(@filename){|f| :ObjectSpace}
47
- ru.call({}).must_equal [1]
48
- update_app(code(2))
49
- ru.call({}).must_equal [2]
50
- log_match %r{\ALoading.*spec/app\.rb\z},
51
- %r{\ANew classes in .*spec/app\.rb: App\z},
52
- %r{\AUnloading.*spec/app\.rb\z},
53
- "Removed constant App",
54
- %r{\ALoading.*spec/app\.rb\z},
55
- %r{\ANew classes in .*spec/app\.rb: App\z}
56
- end
57
-
58
- it "should pickup files added as dependencies" do
59
- ru.call({}).must_equal [1]
60
- update_app("RU.require 'spec/app2.rb'; class App; def self.call(env) [@a, App2.call(env)] end; @a ||= []; @a << 2; end")
61
- update_app("class App2; def self.call(env) @a end; @a ||= []; @a << 3; end", 'spec/app2.rb')
62
- ru.call({}).must_equal [[2], [3]]
63
- update_app("class App2; def self.call(env) @a end; @a ||= []; @a << 4; end", 'spec/app2.rb')
64
- ru.call({}).must_equal [[2], [4]]
65
- log_match %r{\ALoading.*spec/app\.rb\z},
66
- %r{\ANew classes in .*spec/app\.rb: App\z},
67
- %r{\AUnloading.*spec/app\.rb\z},
68
- "Removed constant App",
69
- %r{\ALoading.*spec/app\.rb\z},
70
- %r{\ALoading.*spec/app2\.rb\z},
71
- %r{\ANew classes in .*spec/app2\.rb: App2\z},
72
- %r{\ANew classes in .*spec/app\.rb: (App App2|App2 App)\z},
73
- %r{\ANew features in .*spec/app\.rb: .*spec/app2\.rb\z},
74
- %r{\AUnloading.*spec/app2\.rb\z},
75
- "Removed constant App2",
76
- %r{\ALoading.*spec/app2\.rb\z},
77
- %r{\ANew classes in .*spec/app2\.rb: App2\z}
78
- end
79
-
80
- it "should support :subclasses option and only unload subclasses of given class" do
81
- ru(:subclasses=>'App').call({}).must_equal [1]
82
- update_app("RU.require 'spec/app2.rb'; class App; def self.call(env) [@a, App2.call(env)] end; @a ||= []; @a << 2; end")
83
- update_app("class App2 < App; def self.call(env) @a end; @a ||= []; @a << 3; end", 'spec/app2.rb')
84
- ru.call({}).must_equal [[1, 2], [3]]
85
- update_app("class App2 < App; def self.call(env) @a end; @a ||= []; @a << 4; end", 'spec/app2.rb')
86
- ru.call({}).must_equal [[1, 2], [4]]
87
- update_app("RU.require 'spec/app2.rb'; class App; def self.call(env) [@a, App2.call(env)] end; @a ||= []; @a << 2; end")
88
- log_match %r{\ALoading.*spec/app\.rb\z},
89
- %r{\AUnloading.*spec/app\.rb\z},
90
- %r{\ALoading.*spec/app\.rb\z},
91
- %r{\ALoading.*spec/app2\.rb\z},
92
- %r{\ANew classes in .*spec/app2\.rb: App2\z},
93
- %r{\ANew classes in .*spec/app\.rb: App2\z},
94
- %r{\ANew features in .*spec/app\.rb: .*spec/app2\.rb\z},
95
- %r{\AUnloading.*spec/app2\.rb\z},
96
- "Removed constant App2",
97
- %r{\ALoading.*spec/app2\.rb\z},
98
- %r{\ANew classes in .*spec/app2\.rb: App2\z}
99
- end
100
-
101
- it "should log invalid constant names in :subclasses options" do
102
- ru(:subclasses=>%w'1 Object').call({}).must_equal [1]
103
- logger.uniq!
104
- log_match 'Invalid constant name: 1',
105
- %r{\ALoading.*spec/app\.rb\z},
106
- %r{\ANew classes in .*spec/app\.rb: App\z}
107
- end
108
-
109
- it "should unload modules before reloading similar to classes" do
110
- ru(:code=>"module App; def self.call(env) @a end; @a ||= []; @a << 1; end").call({}).must_equal [1]
111
- update_app("module App; def self.call(env) @a end; @a ||= []; @a << 2; end")
112
- ru.call({}).must_equal [2]
113
- log_match %r{\ALoading.*spec/app\.rb\z},
114
- %r{\ANew classes in .*spec/app\.rb: App\z},
115
- %r{\AUnloading.*spec/app\.rb\z},
116
- "Removed constant App",
117
- %r{\ALoading.*spec/app\.rb\z},
118
- %r{\ANew classes in .*spec/app\.rb: App\z}
119
- end
120
-
121
- it "should unload specific modules by name via :subclasses option" do
122
- ru(:subclasses=>'App', :code=>"module App; def self.call(env) @a end; @a ||= []; @a << 1; end").call({}).must_equal [1]
123
- update_app("module App; def self.call(env) @a end; @a ||= []; @a << 2; end")
124
- ru.call({}).must_equal [2]
125
- log_match %r{\ALoading.*spec/app\.rb\z},
126
- %r{\ANew classes in .*spec/app\.rb: App\z},
127
- %r{\AUnloading.*spec/app\.rb\z},
128
- "Removed constant App",
129
- %r{\ALoading.*spec/app\.rb\z},
130
- %r{\ANew classes in .*spec/app\.rb: App\z}
131
- end
132
-
133
- it "should not unload modules by name if :subclasses option used and module not present" do
134
- ru(:subclasses=>'Foo', :code=>"module App; def self.call(env) @a end; class << self; alias call call; end; @a ||= []; @a << 1; end").call({}).must_equal [1]
135
- update_app("module App; def self.call(env) @a end; @a ||= []; @a << 2; end")
136
- ru.call({}).must_equal [1, 2]
137
- log_match %r{\ALoading.*spec/app\.rb\z},
138
- %r{\AUnloading.*spec/app\.rb\z},
139
- %r{\ALoading.*spec/app\.rb\z}
140
- end
141
-
142
- it "should unload partially loaded modules if loading fails, and allow future loading" do
143
- ru.call({}).must_equal [1]
144
- update_app("module App; def self.call(env) @a end; @a ||= []; raise 'foo'; end")
145
- proc{ru.call({})}.must_raise RuntimeError
146
- defined?(::App).must_be_nil
147
- update_app(code(2))
148
- ru.call({}).must_equal [2]
149
- log_match %r{\ALoading.*spec/app\.rb\z},
150
- %r{\ANew classes in .*spec/app\.rb: App\z},
151
- %r{\AUnloading.*spec/app\.rb\z},
152
- "Removed constant App",
153
- %r{\ALoading.*spec/app\.rb\z},
154
- %r{\AFailed to load .*spec/app\.rb; removing partially defined constants\z},
155
- "Removed constant App",
156
- %r{\ALoading.*spec/app\.rb\z},
157
- %r{\ANew classes in .*spec/app\.rb: App\z}
158
- end
159
-
160
- it "should support :handle_reload_errors option to return backtrace if there is an error reloading" do
161
- ru(:handle_reload_errors=>true).call({}).must_equal [1]
162
- update_app("module App; def self.call(env) @a end; @a ||= []; raise 'foo'; end")
163
- rack_response = ru.call({})
164
- rack_response[0].must_equal 500
165
- rack_response[1]['Content-Type'].must_equal 'text/plain'
166
- rack_response[1]['Content-Length'].must_match(rack_response[2][0].bytesize.to_s)
167
- rack_response[2][0].must_match(/\/spec\/app\.rb:1/)
168
- defined?(::App).must_be_nil
169
- update_app(code(2))
170
- ru.call({}).must_equal [2]
171
- log_match %r{\ALoading.*spec/app\.rb\z},
172
- %r{\ANew classes in .*spec/app\.rb: App\z},
173
- %r{\AUnloading.*spec/app\.rb\z},
174
- "Removed constant App",
175
- %r{\ALoading.*spec/app\.rb\z},
176
- %r{\AFailed to load .*spec/app\.rb; removing partially defined constants\z},
177
- "Removed constant App",
178
- %r{\ALoading.*spec/app\.rb\z},
179
- %r{\ANew classes in .*spec/app\.rb: App\z}
180
- end
181
-
182
- it "should unload classes in namespaces" do
183
- ru(:code=>"class Array::App; def self.call(env) @a end; @a ||= []; @a << 1; end", :block=>proc{Array::App}).call({}).must_equal [1]
184
- update_app("class Array::App; def self.call(env) @a end; @a ||= []; @a << 2; end")
185
- ru.call({}).must_equal [2]
186
- log_match %r{\ALoading.*spec/app\.rb\z},
187
- %r{\ANew classes in .*spec/app\.rb: Array::App\z},
188
- %r{\AUnloading.*spec/app\.rb\z},
189
- "Removed constant Array::App",
190
- %r{\ALoading.*spec/app\.rb\z},
191
- %r{\ANew classes in .*spec/app\.rb: Array::App\z}
192
- end
193
-
194
- it "should not unload class defined in dependency if already defined in parent" do
195
- base_ru
196
- update_app("class App; def self.call(env) @a end; @a ||= []; @a << 2; RU.require 'spec/app2.rb'; end")
197
- update_app("class App; @a << 3 end", 'spec/app2.rb')
198
- @ru.require 'spec/app.rb'
199
- ru.call({}).must_equal [2, 3]
200
- update_app("class App; @a << 4 end", 'spec/app2.rb')
201
- ru.call({}).must_equal [2, 3, 4]
202
- update_app("class App; def self.call(env) @a end; @a ||= []; @a << 2; RU.require 'spec/app2.rb'; end")
203
- ru.call({}).must_equal [2, 4]
204
- log_match %r{\ALoading.*spec/app\.rb\z},
205
- %r{\ALoading.*spec/app2\.rb\z},
206
- %r{\ANew classes in .*spec/app\.rb: App\z},
207
- %r{\ANew features in .*spec/app\.rb: .*spec/app2\.rb\z},
208
- %r{\AUnloading.*spec/app2\.rb\z},
209
- %r{\ALoading.*spec/app2\.rb\z},
210
- %r{\AUnloading.*spec/app\.rb\z},
211
- %r{\AUnloading.*spec/app2\.rb\z},
212
- "Removed constant App",
213
- %r{\ALoading.*spec/app\.rb\z},
214
- %r{\ALoading.*spec/app2\.rb\z},
215
- %r{\ANew classes in .*spec/app\.rb: App\z},
216
- %r{\ANew features in .*spec/app\.rb: .*spec/app2\.rb\z}
217
- end
218
-
219
- it "should allow specifying proc for which constants get removed" do
220
- base_ru
221
- update_app("class App; def self.call(env) [@a, App2.a] end; class << self; alias call call; end; @a ||= []; @a << 1; end; class App2; def self.a; @a end; class << self; alias a a; end; @a ||= []; @a << 2; end")
222
- @ru.require('spec/app.rb'){|f| File.basename(f).sub(/\.rb/, '').capitalize}
223
- ru.call({}).must_equal [[1], [2]]
224
- update_app("class App; def self.call(env) [@a, App2.a] end; @a ||= []; @a << 3; end; class App2; def self.a; @a end; @a ||= []; @a << 4; end")
225
- ru.call({}).must_equal [[3], [2, 4]]
226
- log_match %r{\ALoading.*spec/app\.rb\z},
227
- %r{\ANew classes in .*spec/app\.rb: App\z},
228
- %r{\AUnloading.*spec/app\.rb\z},
229
- "Removed constant App",
230
- %r{\ALoading.*spec/app\.rb\z},
231
- %r{\ANew classes in .*spec/app\.rb: App\z}
232
- end
233
-
234
- it "should handle anonymous classes" do
235
- base_ru(:block=>proc{$app})
236
- update_app("$app = Class.new do def self.call(env) @a end; @a ||= []; @a << 1; end")
237
- @ru.require('spec/app.rb')
238
- ru.call({}).must_equal [1]
239
- update_app("$app = Class.new do def self.call(env) @a end; @a ||= []; @a << 2; end")
240
- ru.call({}).must_equal [2]
241
- log_match %r{\ALoading.*spec/app\.rb\z},
242
- %r{\AUnloading.*spec/app\.rb\z},
243
- %r{\ALoading.*spec/app\.rb\z}
244
- end
245
-
246
- it "should log when attempting to remove a class that doesn't exist" do
247
- base_ru
248
- update_app(code(1))
249
- @ru.require('spec/app.rb'){|f| 'Foo'}
250
- ru.call({}).must_equal [1]
251
- update_app(code(2))
252
- ru.call({}).must_equal [1, 2]
253
- log_match %r{\ALoading.*spec/app\.rb\z},
254
- %r{\AConstants not defined after loading .*spec/app\.rb: Foo\z},
255
- %r{\AUnloading.*spec/app\.rb\z},
256
- "Error removing constant: Foo",
257
- %r{\ALoading.*spec/app\.rb\z},
258
- %r{\AConstants not defined after loading .*spec/app\.rb: Foo\z}
259
- end
260
-
261
- it "should log when specifying a constant that already exists" do
262
- base_ru
263
- update_app(code(1))
264
- ::App2 = 1
265
- @ru.require('spec/app.rb'){|f| 'App2'}
266
- ru.call({}).must_equal [1]
267
- log_match %r{\AConstants already defined before loading .*spec/app\.rb: App2\z},
268
- %r{\ALoading.*spec/app\.rb\z},
269
- %r{\ANew classes in .*spec/app\.rb: App2\z}
270
- end
271
-
272
- it "should handle recorded dependencies" do
273
- base_ru
274
- update_app("module A; B = 1; end", 'spec/app_mod.rb')
275
- update_app("class App; A = ::A; def self.call(env) A::B end; end")
276
- ru.require 'spec/app_mod.rb'
277
- ru.require 'spec/app.rb'
278
- ru.record_dependency 'spec/app_mod.rb', 'spec/app.rb'
279
- ru.call({}).must_equal 1
280
- update_app("module A; B = 2; end", 'spec/app_mod.rb')
281
- ru.call({}).must_equal 2
282
- update_app("module A; include C; end", 'spec/app_mod.rb')
283
- update_app("module C; B = 3; end", 'spec/app_mod2.rb')
284
- ru.record_dependency 'spec/app_mod2.rb', 'spec/app_mod.rb'
285
- ru.require 'spec/app_mod2.rb'
286
- ru.call({}).must_equal 3
287
- update_app("module C; B = 4; end", 'spec/app_mod2.rb')
288
- ru.call({}).must_equal 4
289
- end
290
-
291
- it "should handle modules where name raises an exception" do
292
- m = Module.new{def self.name; raise end}
293
- ru(:code=>"module App; def self.call(env) @a end; @a ||= []; @a << 1; end").call({}).must_equal [1]
294
- update_app("module App; def self.call(env) @a end; @a ||= []; @a << 2; end")
295
- ru.call({}).must_equal [2]
296
- log_match %r{\ALoading.*spec/app\.rb\z},
297
- %r{\ANew classes in .*spec/app\.rb: App\z},
298
- %r{\AUnloading.*spec/app\.rb\z},
299
- "Removed constant App",
300
- %r{\ALoading.*spec/app\.rb\z},
301
- %r{\ANew classes in .*spec/app\.rb: App\z}
302
- m
303
- end
304
-
305
- describe "with a directory" do
306
- include Minitest::Hooks
307
-
308
- before(:all) do
309
- Dir.mkdir('spec/dir')
310
- Dir.mkdir('spec/dir/subdir')
311
- Dir.mkdir('spec/dir/subdir2')
312
- end
313
-
314
- after do
315
- Dir['spec/dir/**/*.rb'].each{|f| file_delete(f)}
316
- end
317
-
318
- after(:all) do
319
- Dir.rmdir('spec/dir/subdir')
320
- Dir.rmdir('spec/dir/subdir2')
321
- Dir.rmdir('spec/dir')
322
- end
323
-
324
- it "should have unreloader require with directories if reload option is false" do
325
- file = 'spec/dir/app_no_reload3.rb'
326
- File.open(file, 'wb'){|f| f.write('ANR3 = 3')}
327
- base_ru(:reload => false)
328
- ru.require 'spec/dir'
329
- ANR3.must_equal 3
330
- end
331
-
332
- it "should handle recorded dependencies in directories" do
333
- base_ru
334
- update_app("module A; B = 1; end", 'spec/dir/subdir/app_mod.rb')
335
- update_app("class App; A = ::A; def self.call(env) A::B end; end")
336
- ru.require 'spec/dir/subdir'
337
- ru.require 'spec/app.rb'
338
- ru.record_dependency 'spec/dir/subdir', 'spec/app.rb'
339
- ru.call({}).must_equal 1
340
- update_app("module A; B = 2; end", 'spec/dir/subdir/app_mod.rb')
341
- ru.call({}).must_equal 2
342
- update_app("module A; include C; end", 'spec/dir/subdir/app_mod.rb')
343
- update_app("module C; B = 3; end", 'spec/dir/subdir2/app_mod2.rb')
344
- ru.require 'spec/dir/subdir2/app_mod2.rb'
345
- ru.record_dependency 'spec/dir/subdir2/app_mod2.rb', 'spec/dir/subdir'
346
- ru.call({}).must_equal 3
347
- update_app("module C; B = 4; end", 'spec/dir/subdir2/app_mod2.rb')
348
- ru.call({}).must_equal 4
349
- end
350
-
351
- it "should handle recorded dependencies in directories when files are added or removed later" do
352
- base_ru
353
- update_app("class App; A = defined?(::A) ? ::A : Module.new{self::B = 0}; def self.call(env) A::B end; end")
354
- ru.record_dependency 'spec/dir/subdir', 'spec/app.rb'
355
- ru.record_dependency 'spec/dir/subdir2', 'spec/dir/subdir'
356
- ru.require 'spec/app.rb'
357
- ru.require 'spec/dir/subdir'
358
- ru.require 'spec/dir/subdir2'
359
- ru.call({}).must_equal 0
360
- update_app("module A; B = 1; end", 'spec/dir/subdir/app_mod.rb')
361
- ru.call({}).must_equal 1
362
- update_app("module A; B = 2; end", 'spec/dir/subdir/app_mod.rb')
363
- ru.call({}).must_equal 2
364
- update_app("module C; B = 3; end", 'spec/dir/subdir2/app_mod2.rb')
365
- ru.call({}).must_equal 2
366
- update_app("module A; include C; end", 'spec/dir/subdir/app_mod.rb')
367
- ru.call({}).must_equal 3
368
- update_app("module C; B = 4; end", 'spec/dir/subdir2/app_mod2.rb')
369
- ru.call({}).must_equal 4
370
- file_delete 'spec/dir/subdir/app_mod.rb'
371
- ru.call({}).must_equal 0
372
- end
373
-
374
- it "should handle classes split into multiple files" do
375
- base_ru
376
- update_app("class App; RU.require('spec/dir'); def self.call(env) \"\#{a if respond_to?(:a)}\#{b if respond_to?(:b)}1\".to_i end; end")
377
- ru.require 'spec/app.rb'
378
- ru.record_split_class 'spec/app.rb', 'spec/dir'
379
- ru.call({}).must_equal 1
380
- update_app("class App; def self.a; 2 end end", 'spec/dir/appa.rb')
381
- ru.call({}).must_equal 21
382
- update_app("class App; def self.a; 3 end end", 'spec/dir/appa.rb')
383
- ru.call({}).must_equal 31
384
- update_app("class App; def self.b; 4 end end", 'spec/dir/appb.rb')
385
- ru.call({}).must_equal 341
386
- update_app("class App; def self.a; 5 end end", 'spec/dir/appa.rb')
387
- update_app("class App; def self.b; 6 end end", 'spec/dir/appb.rb')
388
- ru.call({}).must_equal 561
389
- update_app("class App; end", 'spec/dir/appa.rb')
390
- ru.call({}).must_equal 61
391
- file_delete 'spec/dir/appb.rb'
392
- ru.call({}).must_equal 1
393
- end
394
-
395
- it "should pick up changes to files in that directory" do
396
- base_ru
397
- update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
398
- update_app("App.call[:foo] = 1", 'spec/dir/a.rb')
399
- @ru.require('spec/app.rb')
400
- ru.call({}).must_equal(:foo=>1)
401
- update_app("App.call[:foo] = 2", 'spec/dir/a.rb')
402
- ru.call({}).must_equal(:foo=>2)
403
- log_match %r{\ALoading.*spec/app\.rb\z},
404
- %r{\ALoading.*spec/dir/a\.rb\z},
405
- %r{\ANew classes in .*spec/app\.rb: App\z},
406
- %r{\ANew features in .*spec/app\.rb: .*spec/dir/a\.rb\z},
407
- %r{\AUnloading .*/spec/dir/a.rb\z},
408
- %r{\ALoading .*/spec/dir/a.rb\z}
409
- end
410
-
411
- it "should pick up changes to files in subdirectories" do
412
- base_ru
413
- update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
414
- update_app("App.call[:foo] = 1", 'spec/dir/subdir/a.rb')
415
- @ru.require('spec/app.rb')
416
- ru.call({}).must_equal(:foo=>1)
417
- update_app("App.call[:foo] = 2", 'spec/dir/subdir/a.rb')
418
- ru.call({}).must_equal(:foo=>2)
419
- log_match %r{\ALoading.*spec/app\.rb\z},
420
- %r{\ALoading.*spec/dir/subdir/a\.rb\z},
421
- %r{\ANew classes in .*spec/app\.rb: App\z},
422
- %r{\ANew features in .*spec/app\.rb: .*spec/dir/subdir/a\.rb\z},
423
- %r{\AUnloading .*/spec/dir/subdir/a.rb\z},
424
- %r{\ALoading .*/spec/dir/subdir/a.rb\z}
425
- end
426
-
427
- it "should pick up new files added to the directory" do
428
- base_ru
429
- update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
430
- @ru.require('spec/app.rb')
431
- ru.call({}).must_equal({})
432
- update_app("App.call[:foo] = 2", 'spec/dir/a.rb')
433
- ru.call({}).must_equal(:foo=>2)
434
- log_match %r{\ALoading.*spec/app\.rb\z},
435
- %r{\ANew classes in .*spec/app\.rb: App\z},
436
- %r{\ALoading.*spec/dir/a\.rb\z}
437
- end
438
-
439
- it "should pick up new files added to subdirectories" do
440
- base_ru
441
- update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
442
- @ru.require('spec/app.rb')
443
- ru.call({}).must_equal({})
444
- update_app("App.call[:foo] = 2", 'spec/dir/subdir/a.rb')
445
- ru.call({}).must_equal(:foo=>2)
446
- log_match %r{\ALoading.*spec/app\.rb\z},
447
- %r{\ANew classes in .*spec/app\.rb: App\z},
448
- %r{\ALoading.*spec/dir/subdir/a\.rb\z}
449
- end
450
-
451
- it "should drop files deleted from the directory" do
452
- base_ru
453
- update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
454
- update_app("App.call[:foo] = 1", 'spec/dir/a.rb')
455
- @ru.require('spec/app.rb')
456
- ru.call({}).must_equal(:foo=>1)
457
- file_delete('spec/dir/a.rb')
458
- update_app("App.call[:foo] = 2", 'spec/dir/b.rb')
459
- ru.call({}).must_equal(:foo=>2)
460
- log_match %r{\ALoading.*spec/app\.rb\z},
461
- %r{\ALoading.*spec/dir/a\.rb\z},
462
- %r{\ANew classes in .*spec/app\.rb: App\z},
463
- %r{\ANew features in .*spec/app\.rb: .*spec/dir/a\.rb\z},
464
- %r{\AUnloading .*/spec/dir/a.rb\z},
465
- %r{\ALoading.*spec/dir/b\.rb\z}
466
- end
467
-
468
- it "should drop files deleted from subdirectories" do
469
- base_ru
470
- update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
471
- update_app("App.call[:foo] = 1", 'spec/dir/subdir/a.rb')
472
- @ru.require('spec/app.rb')
473
- ru.call({}).must_equal(:foo=>1)
474
- file_delete('spec/dir/subdir/a.rb')
475
- update_app("App.call[:foo] = 2", 'spec/dir/subdir/b.rb')
476
- ru.call({}).must_equal(:foo=>2)
477
- log_match %r{\ALoading.*spec/app\.rb\z},
478
- %r{\ALoading.*spec/dir/subdir/a\.rb\z},
479
- %r{\ANew classes in .*spec/app\.rb: App\z},
480
- %r{\ANew features in .*spec/app\.rb: .*spec/dir/subdir/a\.rb\z},
481
- %r{\AUnloading .*/spec/dir/subdir/a.rb\z},
482
- %r{\ALoading.*spec/dir/subdir/b\.rb\z}
483
- end
484
-
485
- it "should call hook when dropping files deleted from the directory" do
486
- base_ru
487
- deletes = []
488
- Object.const_set(:Deletes, deletes)
489
- update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require('spec/dir', :delete_hook=>proc{|f| Deletes << f})")
490
- update_app("App.call[:foo] = 1", 'spec/dir/a.rb')
491
- @ru.require('spec/app.rb', :delete_hook=>proc{|f| deletes << f})
492
- ru.call({}).must_equal(:foo=>1)
493
- file_delete('spec/dir/a.rb')
494
- update_app("App.call[:foo] = 2", 'spec/dir/b.rb')
495
- ru.call({}).must_equal(:foo=>2)
496
- deletes.must_equal [File.expand_path('spec/dir/a.rb')]
497
- file_delete('spec/dir/b.rb')
498
- ru.call({}).must_equal(:foo=>2)
499
- deletes.must_equal [File.expand_path('spec/dir/a.rb'), File.expand_path('spec/dir/b.rb')]
500
- file_delete('spec/app.rb')
501
- proc{ru.call({})}.must_raise NameError
502
- deletes.must_equal [File.expand_path('spec/dir/a.rb'), File.expand_path('spec/dir/b.rb'), File.expand_path('spec/app.rb')]
503
- log_match %r{\ALoading.*spec/app\.rb\z},
504
- %r{\ALoading.*spec/dir/a\.rb\z},
505
- %r{\ANew classes in .*spec/app\.rb: App\z},
506
- %r{\ANew features in .*spec/app\.rb: .*spec/dir/a\.rb\z},
507
- %r{\AUnloading .*/spec/dir/a.rb\z},
508
- %r{\ALoading.*spec/dir/b\.rb\z},
509
- %r{\AUnloading .*/spec/dir/b.rb\z},
510
- %r{\AUnloading .*/spec/app.rb\z},
511
- %r{\ARemoved constant App\z}
512
- Object.send(:remove_const, :Deletes)
513
- end
514
- end
515
- end