rack-unreloader 1.8.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,858 +0,0 @@
1
- require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
2
-
3
- describe Rack::Unreloader do
4
- def self.it(*)
5
- exit(1) unless Process.waitpid2(fork{super}).last.success?
6
- end
7
-
8
- def chroot
9
- @ru.strip_path_prefix(Dir.pwd)
10
- Dir.chroot(Dir.pwd)
11
- end
12
-
13
- it "should not reload files automatically if cooldown option is nil" do
14
- ru(:cooldown => nil).call({}).must_equal [1]
15
- chroot
16
- update_app(code(2))
17
- ru.call({}).must_equal [1]
18
- @ru.reload!
19
- ru.call({}).must_equal [2]
20
- end
21
-
22
- it "should not setup a reloader if reload option is false" do
23
- @filename = 'spec/app_no_reload.rb'
24
- ru(:reload => false).call({}).must_equal [1]
25
- file = 'spec/app_no_reload2.rb'
26
- File.open(file, 'wb'){|f| f.write('ANR2 = 2')}
27
- chroot
28
- ru.require 'spec/app_no_*2.rb'
29
- ANR2.must_equal 2
30
- end
31
-
32
- it "should unload constants contained in file and reload file if file changes" do
33
- ru.call({}).must_equal [1]
34
- chroot
35
- update_app(code(2))
36
- ru.call({}).must_equal [2]
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
- %r{\ALoading /spec/app\.rb\z},
42
- %r{\ANew classes in /spec/app\.rb: App\z}
43
- end
44
-
45
- it "should stop monitoring file for changes if it is deleted constants contained in file and reload file if file changes" do
46
- ru.call({}).must_equal [1]
47
- chroot
48
- File.delete('spec/app.rb')
49
- proc{ru.call({})}.must_raise NameError
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
- end
55
-
56
- it "should check constants using ObjectSpace if require proc returns :ObjectSpace" do
57
- base_ru
58
- update_app(code(1))
59
- @ru.require(@filename){|f| :ObjectSpace}
60
- ru.call({}).must_equal [1]
61
- chroot
62
- update_app(code(2))
63
- ru.call({}).must_equal [2]
64
- log_match %r{\ALoading.*spec/app\.rb\z},
65
- %r{\ANew classes in .*spec/app\.rb: App\z},
66
- %r{\AUnloading /spec/app\.rb\z},
67
- "Removed constant App",
68
- %r{\ALoading /spec/app\.rb\z},
69
- %r{\ANew classes in /spec/app\.rb: App\z}
70
- end
71
-
72
- it "should pickup files added as dependencies when chrooting early" do
73
- ru.call({}).must_equal [1]
74
- chroot
75
- update_app("RU.require 'spec/app2.rb'; class App; def self.call(env) [@a, App2.call(env)] end; @a ||= []; @a << 2; end")
76
- update_app("class App2; def self.call(env) @a end; @a ||= []; @a << 3; end", 'spec/app2.rb')
77
- ru.call({}).must_equal [[2], [3]]
78
- update_app("class App2; def self.call(env) @a end; @a ||= []; @a << 4; end", 'spec/app2.rb')
79
- ru.call({}).must_equal [[2], [4]]
80
- log_match %r{\ALoading.*spec/app\.rb\z},
81
- %r{\ANew classes in .*spec/app\.rb: App\z},
82
- %r{\AUnloading /spec/app\.rb\z},
83
- "Removed constant App",
84
- %r{\ALoading /spec/app\.rb\z},
85
- %r{\ALoading /spec/app2\.rb\z},
86
- %r{\ANew classes in /spec/app2\.rb: App2\z},
87
- %r{\ANew classes in /spec/app\.rb: (App App2|App2 App)\z},
88
- %r{\ANew features in /spec/app\.rb: /spec/app2\.rb\z},
89
- %r{\AUnloading /spec/app2\.rb\z},
90
- "Removed constant App2",
91
- %r{\ALoading /spec/app2\.rb\z},
92
- %r{\ANew classes in /spec/app2\.rb: App2\z}
93
- end
94
-
95
- it "should pickup files added as dependencies when chrooting late" do
96
- ru.call({}).must_equal [1]
97
- update_app("RU.require 'spec/app2.rb'; class App; def self.call(env) [@a, App2.call(env)] end; @a ||= []; @a << 2; end")
98
- update_app("class App2; def self.call(env) @a end; @a ||= []; @a << 3; end", 'spec/app2.rb')
99
- ru.call({}).must_equal [[2], [3]]
100
- chroot
101
- update_app("class App2; def self.call(env) @a end; @a ||= []; @a << 4; end", 'spec/app2.rb')
102
- ru.call({}).must_equal [[2], [4]]
103
- log_match %r{\ALoading.*spec/app\.rb\z},
104
- %r{\ANew classes in .*spec/app\.rb: App\z},
105
- %r{\AUnloading.*spec/app\.rb\z},
106
- "Removed constant App",
107
- %r{\ALoading.*spec/app\.rb\z},
108
- %r{\ALoading.*spec/app2\.rb\z},
109
- %r{\ANew classes in .*spec/app2\.rb: App2\z},
110
- %r{\ANew classes in .*spec/app\.rb: (App App2|App2 App)\z},
111
- %r{\ANew features in .*spec/app\.rb: .*spec/app2\.rb\z},
112
- %r{\AUnloading /spec/app2\.rb\z},
113
- "Removed constant App2",
114
- %r{\ALoading /spec/app2\.rb\z},
115
- %r{\ANew classes in /spec/app2\.rb: App2\z}
116
- end
117
-
118
- it "should support :subclasses option and only unload subclasses of given class when chrooting early" do
119
- ru(:subclasses=>'App').call({}).must_equal [1]
120
- chroot
121
- update_app("RU.require 'spec/app2.rb'; class App; def self.call(env) [@a, App2.call(env)] end; @a ||= []; @a << 2; end")
122
- update_app("class App2 < App; def self.call(env) @a end; @a ||= []; @a << 3; end", 'spec/app2.rb')
123
- ru.call({}).must_equal [[1, 2], [3]]
124
- update_app("class App2 < App; def self.call(env) @a end; @a ||= []; @a << 4; end", 'spec/app2.rb')
125
- ru.call({}).must_equal [[1, 2], [4]]
126
- update_app("RU.require 'spec/app2.rb'; class App; def self.call(env) [@a, App2.call(env)] end; @a ||= []; @a << 2; end")
127
- log_match %r{\ALoading.*spec/app\.rb\z},
128
- %r{\AUnloading /spec/app\.rb\z},
129
- %r{\ALoading /spec/app\.rb\z},
130
- %r{\ALoading /spec/app2\.rb\z},
131
- %r{\ANew classes in /spec/app2\.rb: App2\z},
132
- %r{\ANew classes in /spec/app\.rb: App2\z},
133
- %r{\ANew features in /spec/app\.rb: /spec/app2\.rb\z},
134
- %r{\AUnloading /spec/app2\.rb\z},
135
- "Removed constant App2",
136
- %r{\ALoading /spec/app2\.rb\z},
137
- %r{\ANew classes in /spec/app2\.rb: App2\z}
138
- end
139
-
140
- it "should support :subclasses option and only unload subclasses of given class when chrooting late" do
141
- ru(:subclasses=>'App').call({}).must_equal [1]
142
- update_app("RU.require 'spec/app2.rb'; class App; def self.call(env) [@a, App2.call(env)] end; @a ||= []; @a << 2; end")
143
- update_app("class App2 < App; def self.call(env) @a end; @a ||= []; @a << 3; end", 'spec/app2.rb')
144
- ru.call({}).must_equal [[1, 2], [3]]
145
- chroot
146
- update_app("class App2 < App; def self.call(env) @a end; @a ||= []; @a << 4; end", 'spec/app2.rb')
147
- ru.call({}).must_equal [[1, 2], [4]]
148
- update_app("RU.require 'spec/app2.rb'; class App; def self.call(env) [@a, App2.call(env)] end; @a ||= []; @a << 2; end")
149
- log_match %r{\ALoading.*spec/app\.rb\z},
150
- %r{\AUnloading.*spec/app\.rb\z},
151
- %r{\ALoading.*spec/app\.rb\z},
152
- %r{\ALoading.*spec/app2\.rb\z},
153
- %r{\ANew classes in .*spec/app2\.rb: App2\z},
154
- %r{\ANew classes in .*spec/app\.rb: App2\z},
155
- %r{\ANew features in .*spec/app\.rb: .*spec/app2\.rb\z},
156
- %r{\AUnloading /spec/app2\.rb\z},
157
- "Removed constant App2",
158
- %r{\ALoading /spec/app2\.rb\z},
159
- %r{\ANew classes in /spec/app2\.rb: App2\z}
160
- end
161
-
162
-
163
- it "should unload modules before reloading similar to classes" do
164
- ru(:code=>"module App; def self.call(env) @a end; @a ||= []; @a << 1; end").call({}).must_equal [1]
165
- chroot
166
- update_app("module App; def self.call(env) @a end; @a ||= []; @a << 2; end")
167
- ru.call({}).must_equal [2]
168
- log_match %r{\ALoading.*spec/app\.rb\z},
169
- %r{\ANew classes in .*spec/app\.rb: App\z},
170
- %r{\AUnloading /spec/app\.rb\z},
171
- "Removed constant App",
172
- %r{\ALoading /spec/app\.rb\z},
173
- %r{\ANew classes in /spec/app\.rb: App\z}
174
- end
175
-
176
- it "should unload specific modules by name via :subclasses option" do
177
- ru(:subclasses=>'App', :code=>"module App; def self.call(env) @a end; @a ||= []; @a << 1; end").call({}).must_equal [1]
178
- chroot
179
- update_app("module App; def self.call(env) @a end; @a ||= []; @a << 2; end")
180
- ru.call({}).must_equal [2]
181
- log_match %r{\ALoading.*spec/app\.rb\z},
182
- %r{\ANew classes in .*spec/app\.rb: App\z},
183
- %r{\AUnloading /spec/app\.rb\z},
184
- "Removed constant App",
185
- %r{\ALoading /spec/app\.rb\z},
186
- %r{\ANew classes in /spec/app\.rb: App\z}
187
- end
188
-
189
- it "should not unload modules by name if :subclasses option used and module not present" do
190
- ru(:subclasses=>'Foo', :code=>"module App; def self.call(env) @a end; @a ||= []; @a << 1; end").call({}).must_equal [1]
191
- chroot
192
- update_app("module App; def self.call(env) @a end; @a ||= []; @a << 2; end")
193
- ru.call({}).must_equal [1, 2]
194
- log_match %r{\ALoading.*spec/app\.rb\z},
195
- %r{\AUnloading /spec/app\.rb\z},
196
- %r{\ALoading /spec/app\.rb\z}
197
- end
198
-
199
- it "should unload partially loaded modules if loading fails, and allow future loading when chrooting early" do
200
- ru.call({}).must_equal [1]
201
- chroot
202
- update_app("module App; def self.call(env) @a end; @a ||= []; raise 'foo'; end")
203
- proc{ru.call({})}.must_raise RuntimeError
204
- defined?(::App).must_be_nil
205
- update_app(code(2))
206
- ru.call({}).must_equal [2]
207
- log_match %r{\ALoading.*spec/app\.rb\z},
208
- %r{\ANew classes in .*spec/app\.rb: App\z},
209
- %r{\AUnloading /spec/app\.rb\z},
210
- "Removed constant App",
211
- %r{\ALoading /spec/app\.rb\z},
212
- %r{\AFailed to load /spec/app\.rb; removing partially defined constants\z},
213
- "Removed constant App",
214
- %r{\ALoading /spec/app\.rb\z},
215
- %r{\ANew classes in /spec/app\.rb: App\z}
216
- end
217
-
218
- it "should unload partially loaded modules if loading fails, and allow future loading when chrooting late" do
219
- ru.call({}).must_equal [1]
220
- update_app("module App; def self.call(env) @a end; @a ||= []; raise 'foo'; end")
221
- proc{ru.call({})}.must_raise RuntimeError
222
- defined?(::App).must_be_nil
223
- chroot
224
- update_app(code(2))
225
- ru.call({}).must_equal [2]
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{\AFailed to load .*spec/app\.rb; removing partially defined constants\z},
232
- "Removed constant App",
233
- %r{\ALoading /spec/app\.rb\z},
234
- %r{\ANew classes in /spec/app\.rb: App\z}
235
- end
236
-
237
- it "should unload classes in namespaces" do
238
- ru(:code=>"class Array::App; def self.call(env) @a end; @a ||= []; @a << 1; end", :block=>proc{Array::App}).call({}).must_equal [1]
239
- chroot
240
- update_app("class Array::App; def self.call(env) @a end; @a ||= []; @a << 2; end")
241
- ru.call({}).must_equal [2]
242
- log_match %r{\ALoading.*spec/app\.rb\z},
243
- %r{\ANew classes in .*spec/app\.rb: Array::App\z},
244
- %r{\AUnloading /spec/app\.rb\z},
245
- "Removed constant Array::App",
246
- %r{\ALoading /spec/app\.rb\z},
247
- %r{\ANew classes in /spec/app\.rb: Array::App\z}
248
- end
249
-
250
- it "should not unload class defined in dependency if already defined in parent when chrooting early" do
251
- base_ru
252
- update_app("class App; def self.call(env) @a end; @a ||= []; @a << 2; RU.require 'spec/app2.rb'; end")
253
- update_app("class App; @a << 3 end", 'spec/app2.rb')
254
- @ru.require 'spec/app.rb'
255
- ru.call({}).must_equal [2, 3]
256
- chroot
257
- update_app("class App; @a << 4 end", 'spec/app2.rb')
258
- ru.call({}).must_equal [2, 3, 4]
259
- update_app("class App; def self.call(env) @a end; @a ||= []; @a << 2; RU.require 'spec/app2.rb'; end")
260
- ru.call({}).must_equal [2, 4]
261
- log_match %r{\ALoading.*spec/app\.rb\z},
262
- %r{\ALoading.*spec/app2\.rb\z},
263
- %r{\ANew classes in .*spec/app\.rb: App\z},
264
- %r{\ANew features in .*spec/app\.rb: .*spec/app2\.rb\z},
265
- %r{\AUnloading /spec/app2\.rb\z},
266
- %r{\ALoading /spec/app2\.rb\z},
267
- %r{\AUnloading /spec/app\.rb\z},
268
- %r{\AUnloading /spec/app2\.rb\z},
269
- "Removed constant App",
270
- %r{\ALoading /spec/app\.rb\z},
271
- %r{\ALoading /spec/app2\.rb\z},
272
- %r{\ANew classes in /spec/app\.rb: App\z},
273
- %r{\ANew features in /spec/app\.rb: /spec/app2\.rb\z}
274
- end
275
-
276
- it "should not unload class defined in dependency if already defined in parent when chrooting late" do
277
- base_ru
278
- update_app("class App; def self.call(env) @a end; @a ||= []; @a << 2; RU.require 'spec/app2.rb'; end")
279
- update_app("class App; @a << 3 end", 'spec/app2.rb')
280
- @ru.require 'spec/app.rb'
281
- ru.call({}).must_equal [2, 3]
282
- update_app("class App; @a << 4 end", 'spec/app2.rb')
283
- ru.call({}).must_equal [2, 3, 4]
284
- chroot
285
- update_app("class App; def self.call(env) @a end; @a ||= []; @a << 2; RU.require 'spec/app2.rb'; end")
286
- ru.call({}).must_equal [2, 4]
287
- log_match %r{\ALoading.*spec/app\.rb\z},
288
- %r{\ALoading.*spec/app2\.rb\z},
289
- %r{\ANew classes in .*spec/app\.rb: App\z},
290
- %r{\ANew features in .*spec/app\.rb: .*spec/app2\.rb\z},
291
- %r{\AUnloading.*spec/app2\.rb\z},
292
- %r{\ALoading.*spec/app2\.rb\z},
293
- %r{\AUnloading.*spec/app\.rb\z},
294
- %r{\AUnloading.*spec/app2\.rb\z},
295
- "Removed constant App",
296
- %r{\ALoading /spec/app\.rb\z},
297
- %r{\ALoading /spec/app2\.rb\z},
298
- %r{\ANew classes in /spec/app\.rb: App\z},
299
- %r{\ANew features in /spec/app\.rb: /spec/app2\.rb\z}
300
- end
301
-
302
- it "should allow specifying proc for which constants get removed" do
303
- base_ru
304
- update_app("class App; def self.call(env) [@a, App2.a] end; @a ||= []; @a << 1; end; class App2; def self.a; @a end; @a ||= []; @a << 2; end")
305
- @ru.require('spec/app.rb'){|f| File.basename(f).sub(/\.rb/, '').capitalize}
306
- ru.call({}).must_equal [[1], [2]]
307
- chroot
308
- 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")
309
- ru.call({}).must_equal [[3], [2, 4]]
310
- log_match %r{\ALoading.*spec/app\.rb\z},
311
- %r{\ANew classes in .*spec/app\.rb: App\z},
312
- %r{\AUnloading /spec/app\.rb\z},
313
- "Removed constant App",
314
- %r{\ALoading /spec/app\.rb\z},
315
- %r{\ANew classes in /spec/app\.rb: App\z}
316
- end
317
-
318
- it "should handle anonymous classes" do
319
- base_ru(:block=>proc{$app})
320
- update_app("$app = Class.new do def self.call(env) @a end; @a ||= []; @a << 1; end")
321
- @ru.require('spec/app.rb')
322
- ru.call({}).must_equal [1]
323
- chroot
324
- update_app("$app = Class.new do def self.call(env) @a end; @a ||= []; @a << 2; end")
325
- ru.call({}).must_equal [2]
326
- log_match %r{\ALoading.*spec/app\.rb\z},
327
- %r{\AUnloading /spec/app\.rb\z},
328
- %r{\ALoading /spec/app\.rb\z}
329
- end
330
-
331
- it "should log when attempting to remove a class that doesn't exist" do
332
- base_ru
333
- update_app(code(1))
334
- @ru.require('spec/app.rb'){|f| 'Foo'}
335
- ru.call({}).must_equal [1]
336
- chroot
337
- update_app(code(2))
338
- ru.call({}).must_equal [1, 2]
339
- log_match %r{\ALoading.*spec/app\.rb\z},
340
- %r{\AConstants not defined after loading .*spec/app\.rb: Foo\z},
341
- %r{\AUnloading /spec/app\.rb\z},
342
- "Error removing constant: Foo",
343
- %r{\ALoading /spec/app\.rb\z},
344
- %r{\AConstants not defined after loading /spec/app\.rb: Foo\z}
345
- end
346
-
347
- it "should handle recorded dependencies when chrooting early" do
348
- base_ru
349
- update_app("module A; B = 1; end", 'spec/app_mod.rb')
350
- update_app("class App; A = ::A; def self.call(env) A::B end; end")
351
- ru.require 'spec/app_mod.rb'
352
- ru.require 'spec/app.rb'
353
- ru.record_dependency 'spec/app_mod.rb', 'spec/app.rb'
354
- ru.call({}).must_equal 1
355
- chroot
356
- update_app("module A; B = 2; end", 'spec/app_mod.rb')
357
- ru.call({}).must_equal 2
358
- update_app("module A; include C; end", 'spec/app_mod.rb')
359
- update_app("module C; B = 3; end", 'spec/app_mod2.rb')
360
- ru.record_dependency 'spec/app_mod2.rb', 'spec/app_mod.rb'
361
- ru.require 'spec/app_mod2.rb'
362
- ru.call({}).must_equal 3
363
- update_app("module C; B = 4; end", 'spec/app_mod2.rb')
364
- ru.call({}).must_equal 4
365
- end
366
-
367
- it "should handle recorded dependencies when chrooting middle" do
368
- base_ru
369
- update_app("module A; B = 1; end", 'spec/app_mod.rb')
370
- update_app("class App; A = ::A; def self.call(env) A::B end; end")
371
- ru.require 'spec/app_mod.rb'
372
- ru.require 'spec/app.rb'
373
- ru.record_dependency 'spec/app_mod.rb', 'spec/app.rb'
374
- ru.call({}).must_equal 1
375
- update_app("module A; B = 2; end", 'spec/app_mod.rb')
376
- ru.call({}).must_equal 2
377
- chroot
378
- update_app("module A; include C; end", 'spec/app_mod.rb')
379
- update_app("module C; B = 3; end", 'spec/app_mod2.rb')
380
- ru.record_dependency 'spec/app_mod2.rb', 'spec/app_mod.rb'
381
- ru.require 'spec/app_mod2.rb'
382
- ru.call({}).must_equal 3
383
- update_app("module C; B = 4; end", 'spec/app_mod2.rb')
384
- ru.call({}).must_equal 4
385
- end
386
-
387
- it "should handle recorded dependencies when chrooting late" do
388
- base_ru
389
- update_app("module A; B = 1; end", 'spec/app_mod.rb')
390
- update_app("class App; A = ::A; def self.call(env) A::B end; end")
391
- ru.require 'spec/app_mod.rb'
392
- ru.require 'spec/app.rb'
393
- ru.record_dependency 'spec/app_mod.rb', 'spec/app.rb'
394
- ru.call({}).must_equal 1
395
- update_app("module A; B = 2; end", 'spec/app_mod.rb')
396
- ru.call({}).must_equal 2
397
- update_app("module A; include C; end", 'spec/app_mod.rb')
398
- update_app("module C; B = 3; end", 'spec/app_mod2.rb')
399
- ru.record_dependency 'spec/app_mod2.rb', 'spec/app_mod.rb'
400
- ru.require 'spec/app_mod2.rb'
401
- ru.call({}).must_equal 3
402
- chroot
403
- update_app("module C; B = 4; end", 'spec/app_mod2.rb')
404
- ru.call({}).must_equal 4
405
- end
406
-
407
- describe "with a directory" do
408
- include Minitest::Hooks
409
-
410
- before(:all) do
411
- Dir.mkdir('spec/dir')
412
- Dir.mkdir('spec/dir/subdir')
413
- Dir.mkdir('spec/dir/subdir2')
414
- end
415
-
416
- after do
417
- Dir['spec/dir/**/*.rb'].each{|f| File.delete(f)}
418
- end
419
-
420
- after(:all) do
421
- Dir.rmdir('spec/dir/subdir')
422
- Dir.rmdir('spec/dir/subdir2')
423
- Dir.rmdir('spec/dir')
424
- end
425
-
426
- it "should handle recorded dependencies in directories when chrooting early" do
427
- base_ru
428
- update_app("module A; B = 1; end", 'spec/dir/subdir/app_mod.rb')
429
- update_app("class App; A = ::A; def self.call(env) A::B end; end")
430
- ru.require 'spec/dir/subdir'
431
- ru.require 'spec/app.rb'
432
- ru.record_dependency 'spec/dir/subdir', 'spec/app.rb'
433
- ru.call({}).must_equal 1
434
- chroot
435
- update_app("module A; B = 2; end", 'spec/dir/subdir/app_mod.rb')
436
- ru.call({}).must_equal 2
437
- update_app("module A; include C; end", 'spec/dir/subdir/app_mod.rb')
438
- update_app("module C; B = 3; end", 'spec/dir/subdir2/app_mod2.rb')
439
- ru.require 'spec/dir/subdir2/app_mod2.rb'
440
- ru.record_dependency 'spec/dir/subdir2/app_mod2.rb', 'spec/dir/subdir'
441
- ru.call({}).must_equal 3
442
- update_app("module C; B = 4; end", 'spec/dir/subdir2/app_mod2.rb')
443
- ru.call({}).must_equal 4
444
- end
445
-
446
- it "should handle recorded dependencies in directories when chrooting middle" do
447
- base_ru
448
- update_app("module A; B = 1; end", 'spec/dir/subdir/app_mod.rb')
449
- update_app("class App; A = ::A; def self.call(env) A::B end; end")
450
- ru.require 'spec/dir/subdir'
451
- ru.require 'spec/app.rb'
452
- ru.record_dependency 'spec/dir/subdir', 'spec/app.rb'
453
- ru.call({}).must_equal 1
454
- update_app("module A; B = 2; end", 'spec/dir/subdir/app_mod.rb')
455
- ru.call({}).must_equal 2
456
- chroot
457
- update_app("module A; include C; end", 'spec/dir/subdir/app_mod.rb')
458
- update_app("module C; B = 3; end", 'spec/dir/subdir2/app_mod2.rb')
459
- ru.require 'spec/dir/subdir2/app_mod2.rb'
460
- ru.record_dependency 'spec/dir/subdir2/app_mod2.rb', 'spec/dir/subdir'
461
- ru.call({}).must_equal 3
462
- update_app("module C; B = 4; end", 'spec/dir/subdir2/app_mod2.rb')
463
- ru.call({}).must_equal 4
464
- end
465
-
466
- it "should handle recorded dependencies in directories when chrooting late" do
467
- base_ru
468
- update_app("module A; B = 1; end", 'spec/dir/subdir/app_mod.rb')
469
- update_app("class App; A = ::A; def self.call(env) A::B end; end")
470
- ru.require 'spec/dir/subdir'
471
- ru.require 'spec/app.rb'
472
- ru.record_dependency 'spec/dir/subdir', 'spec/app.rb'
473
- ru.call({}).must_equal 1
474
- update_app("module A; B = 2; end", 'spec/dir/subdir/app_mod.rb')
475
- ru.call({}).must_equal 2
476
- update_app("module A; include C; end", 'spec/dir/subdir/app_mod.rb')
477
- update_app("module C; B = 3; end", 'spec/dir/subdir2/app_mod2.rb')
478
- ru.require 'spec/dir/subdir2/app_mod2.rb'
479
- ru.record_dependency 'spec/dir/subdir2/app_mod2.rb', 'spec/dir/subdir'
480
- ru.call({}).must_equal 3
481
- chroot
482
- update_app("module C; B = 4; end", 'spec/dir/subdir2/app_mod2.rb')
483
- ru.call({}).must_equal 4
484
- end
485
-
486
- it "should handle recorded dependencies in directories when files are added or removed later when chrooting 1" do
487
- base_ru
488
- update_app("class App; A = defined?(::A) ? ::A : Module.new{self::B = 0}; def self.call(env) A::B end; end")
489
- ru.record_dependency 'spec/dir/subdir', 'spec/app.rb'
490
- ru.record_dependency 'spec/dir/subdir2', 'spec/dir/subdir'
491
- ru.require 'spec/app.rb'
492
- ru.require 'spec/dir/subdir'
493
- ru.require 'spec/dir/subdir2'
494
- ru.call({}).must_equal 0
495
- chroot
496
- update_app("module A; B = 1; end", 'spec/dir/subdir/app_mod.rb')
497
- ru.call({}).must_equal 1
498
- update_app("module A; B = 2; end", 'spec/dir/subdir/app_mod.rb')
499
- ru.call({}).must_equal 2
500
- update_app("module C; B = 3; end", 'spec/dir/subdir2/app_mod2.rb')
501
- ru.call({}).must_equal 2
502
- update_app("module A; include C; end", 'spec/dir/subdir/app_mod.rb')
503
- ru.call({}).must_equal 3
504
- update_app("module C; B = 4; end", 'spec/dir/subdir2/app_mod2.rb')
505
- ru.call({}).must_equal 4
506
- File.delete 'spec/dir/subdir/app_mod.rb'
507
- ru.call({}).must_equal 0
508
- end
509
-
510
- it "should handle recorded dependencies in directories when files are added or removed later when chrooting 2" do
511
- base_ru
512
- update_app("class App; A = defined?(::A) ? ::A : Module.new{self::B = 0}; def self.call(env) A::B end; end")
513
- ru.record_dependency 'spec/dir/subdir', 'spec/app.rb'
514
- ru.record_dependency 'spec/dir/subdir2', 'spec/dir/subdir'
515
- ru.require 'spec/app.rb'
516
- ru.require 'spec/dir/subdir'
517
- ru.require 'spec/dir/subdir2'
518
- ru.call({}).must_equal 0
519
- update_app("module A; B = 1; end", 'spec/dir/subdir/app_mod.rb')
520
- ru.call({}).must_equal 1
521
- chroot
522
- update_app("module A; B = 2; end", 'spec/dir/subdir/app_mod.rb')
523
- ru.call({}).must_equal 2
524
- update_app("module C; B = 3; end", 'spec/dir/subdir2/app_mod2.rb')
525
- ru.call({}).must_equal 2
526
- update_app("module A; include C; end", 'spec/dir/subdir/app_mod.rb')
527
- ru.call({}).must_equal 3
528
- update_app("module C; B = 4; end", 'spec/dir/subdir2/app_mod2.rb')
529
- ru.call({}).must_equal 4
530
- File.delete 'spec/dir/subdir/app_mod.rb'
531
- ru.call({}).must_equal 0
532
- end
533
-
534
- it "should handle recorded dependencies in directories when files are added or removed later when chrooting 3" do
535
- base_ru
536
- update_app("class App; A = defined?(::A) ? ::A : Module.new{self::B = 0}; def self.call(env) A::B end; end")
537
- ru.record_dependency 'spec/dir/subdir', 'spec/app.rb'
538
- ru.record_dependency 'spec/dir/subdir2', 'spec/dir/subdir'
539
- ru.require 'spec/app.rb'
540
- ru.require 'spec/dir/subdir'
541
- ru.require 'spec/dir/subdir2'
542
- ru.call({}).must_equal 0
543
- update_app("module A; B = 1; end", 'spec/dir/subdir/app_mod.rb')
544
- ru.call({}).must_equal 1
545
- update_app("module A; B = 2; end", 'spec/dir/subdir/app_mod.rb')
546
- ru.call({}).must_equal 2
547
- chroot
548
- update_app("module C; B = 3; end", 'spec/dir/subdir2/app_mod2.rb')
549
- ru.call({}).must_equal 2
550
- update_app("module A; include C; end", 'spec/dir/subdir/app_mod.rb')
551
- ru.call({}).must_equal 3
552
- update_app("module C; B = 4; end", 'spec/dir/subdir2/app_mod2.rb')
553
- ru.call({}).must_equal 4
554
- File.delete 'spec/dir/subdir/app_mod.rb'
555
- ru.call({}).must_equal 0
556
- end
557
-
558
- it "should handle recorded dependencies in directories when files are added or removed later when chrooting 4" do
559
- base_ru
560
- update_app("class App; A = defined?(::A) ? ::A : Module.new{self::B = 0}; def self.call(env) A::B end; end")
561
- ru.record_dependency 'spec/dir/subdir', 'spec/app.rb'
562
- ru.record_dependency 'spec/dir/subdir2', 'spec/dir/subdir'
563
- ru.require 'spec/app.rb'
564
- ru.require 'spec/dir/subdir'
565
- ru.require 'spec/dir/subdir2'
566
- ru.call({}).must_equal 0
567
- update_app("module A; B = 1; end", 'spec/dir/subdir/app_mod.rb')
568
- ru.call({}).must_equal 1
569
- update_app("module A; B = 2; end", 'spec/dir/subdir/app_mod.rb')
570
- ru.call({}).must_equal 2
571
- update_app("module C; B = 3; end", 'spec/dir/subdir2/app_mod2.rb')
572
- ru.call({}).must_equal 2
573
- chroot
574
- update_app("module A; include C; end", 'spec/dir/subdir/app_mod.rb')
575
- ru.call({}).must_equal 3
576
- update_app("module C; B = 4; end", 'spec/dir/subdir2/app_mod2.rb')
577
- ru.call({}).must_equal 4
578
- File.delete 'spec/dir/subdir/app_mod.rb'
579
- ru.call({}).must_equal 0
580
- end
581
-
582
- it "should handle recorded dependencies in directories when files are added or removed later when chrooting 5" do
583
- base_ru
584
- update_app("class App; A = defined?(::A) ? ::A : Module.new{self::B = 0}; def self.call(env) A::B end; end")
585
- ru.record_dependency 'spec/dir/subdir', 'spec/app.rb'
586
- ru.record_dependency 'spec/dir/subdir2', 'spec/dir/subdir'
587
- ru.require 'spec/app.rb'
588
- ru.require 'spec/dir/subdir'
589
- ru.require 'spec/dir/subdir2'
590
- ru.call({}).must_equal 0
591
- update_app("module A; B = 1; end", 'spec/dir/subdir/app_mod.rb')
592
- ru.call({}).must_equal 1
593
- update_app("module A; B = 2; end", 'spec/dir/subdir/app_mod.rb')
594
- ru.call({}).must_equal 2
595
- update_app("module C; B = 3; end", 'spec/dir/subdir2/app_mod2.rb')
596
- ru.call({}).must_equal 2
597
- update_app("module A; include C; end", 'spec/dir/subdir/app_mod.rb')
598
- ru.call({}).must_equal 3
599
- chroot
600
- update_app("module C; B = 4; end", 'spec/dir/subdir2/app_mod2.rb')
601
- ru.call({}).must_equal 4
602
- File.delete 'spec/dir/subdir/app_mod.rb'
603
- ru.call({}).must_equal 0
604
- end
605
-
606
- it "should handle recorded dependencies in directories when files are added or removed later when chrooting 6" do
607
- base_ru
608
- update_app("class App; A = defined?(::A) ? ::A : Module.new{self::B = 0}; def self.call(env) A::B end; end")
609
- ru.record_dependency 'spec/dir/subdir', 'spec/app.rb'
610
- ru.record_dependency 'spec/dir/subdir2', 'spec/dir/subdir'
611
- ru.require 'spec/app.rb'
612
- ru.require 'spec/dir/subdir'
613
- ru.require 'spec/dir/subdir2'
614
- ru.call({}).must_equal 0
615
- update_app("module A; B = 1; end", 'spec/dir/subdir/app_mod.rb')
616
- ru.call({}).must_equal 1
617
- update_app("module A; B = 2; end", 'spec/dir/subdir/app_mod.rb')
618
- ru.call({}).must_equal 2
619
- update_app("module C; B = 3; end", 'spec/dir/subdir2/app_mod2.rb')
620
- ru.call({}).must_equal 2
621
- update_app("module A; include C; end", 'spec/dir/subdir/app_mod.rb')
622
- ru.call({}).must_equal 3
623
- update_app("module C; B = 4; end", 'spec/dir/subdir2/app_mod2.rb')
624
- ru.call({}).must_equal 4
625
- chroot
626
- File.delete 'spec/dir/subdir/app_mod.rb'
627
- ru.call({}).must_equal 0
628
- end
629
-
630
- it "should handle classes split into multiple files when chrooting 1" do
631
- base_ru
632
- 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")
633
- ru.require 'spec/app.rb'
634
- ru.record_split_class 'spec/app.rb', 'spec/dir'
635
- ru.call({}).must_equal 1
636
- chroot
637
- update_app("class App; def self.a; 2 end end", 'spec/dir/appa.rb')
638
- ru.call({}).must_equal 21
639
- update_app("class App; def self.a; 3 end end", 'spec/dir/appa.rb')
640
- ru.call({}).must_equal 31
641
- update_app("class App; def self.b; 4 end end", 'spec/dir/appb.rb')
642
- ru.call({}).must_equal 341
643
- update_app("class App; def self.a; 5 end end", 'spec/dir/appa.rb')
644
- update_app("class App; def self.b; 6 end end", 'spec/dir/appb.rb')
645
- ru.call({}).must_equal 561
646
- update_app("class App; end", 'spec/dir/appa.rb')
647
- ru.call({}).must_equal 61
648
- File.delete 'spec/dir/appb.rb'
649
- ru.call({}).must_equal 1
650
- end
651
-
652
- it "should handle classes split into multiple files when chrooting 2" do
653
- base_ru
654
- 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")
655
- ru.require 'spec/app.rb'
656
- ru.record_split_class 'spec/app.rb', 'spec/dir'
657
- ru.call({}).must_equal 1
658
- update_app("class App; def self.a; 2 end end", 'spec/dir/appa.rb')
659
- ru.call({}).must_equal 21
660
- chroot
661
- update_app("class App; def self.a; 3 end end", 'spec/dir/appa.rb')
662
- ru.call({}).must_equal 31
663
- update_app("class App; def self.b; 4 end end", 'spec/dir/appb.rb')
664
- ru.call({}).must_equal 341
665
- update_app("class App; def self.a; 5 end end", 'spec/dir/appa.rb')
666
- update_app("class App; def self.b; 6 end end", 'spec/dir/appb.rb')
667
- ru.call({}).must_equal 561
668
- update_app("class App; end", 'spec/dir/appa.rb')
669
- ru.call({}).must_equal 61
670
- File.delete 'spec/dir/appb.rb'
671
- ru.call({}).must_equal 1
672
- end
673
-
674
- it "should handle classes split into multiple files when chrooting 3" do
675
- base_ru
676
- 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")
677
- ru.require 'spec/app.rb'
678
- ru.record_split_class 'spec/app.rb', 'spec/dir'
679
- ru.call({}).must_equal 1
680
- update_app("class App; def self.a; 2 end end", 'spec/dir/appa.rb')
681
- ru.call({}).must_equal 21
682
- update_app("class App; def self.a; 3 end end", 'spec/dir/appa.rb')
683
- ru.call({}).must_equal 31
684
- chroot
685
- update_app("class App; def self.b; 4 end end", 'spec/dir/appb.rb')
686
- ru.call({}).must_equal 341
687
- update_app("class App; def self.a; 5 end end", 'spec/dir/appa.rb')
688
- update_app("class App; def self.b; 6 end end", 'spec/dir/appb.rb')
689
- ru.call({}).must_equal 561
690
- update_app("class App; end", 'spec/dir/appa.rb')
691
- ru.call({}).must_equal 61
692
- File.delete 'spec/dir/appb.rb'
693
- ru.call({}).must_equal 1
694
- end
695
-
696
- it "should handle classes split into multiple files when chrooting 4" do
697
- base_ru
698
- 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")
699
- ru.require 'spec/app.rb'
700
- ru.record_split_class 'spec/app.rb', 'spec/dir'
701
- ru.call({}).must_equal 1
702
- update_app("class App; def self.a; 2 end end", 'spec/dir/appa.rb')
703
- ru.call({}).must_equal 21
704
- update_app("class App; def self.a; 3 end end", 'spec/dir/appa.rb')
705
- ru.call({}).must_equal 31
706
- update_app("class App; def self.b; 4 end end", 'spec/dir/appb.rb')
707
- ru.call({}).must_equal 341
708
- chroot
709
- update_app("class App; def self.a; 5 end end", 'spec/dir/appa.rb')
710
- update_app("class App; def self.b; 6 end end", 'spec/dir/appb.rb')
711
- ru.call({}).must_equal 561
712
- update_app("class App; end", 'spec/dir/appa.rb')
713
- ru.call({}).must_equal 61
714
- File.delete 'spec/dir/appb.rb'
715
- ru.call({}).must_equal 1
716
- end
717
-
718
- it "should handle classes split into multiple files when chrooting 5" do
719
- base_ru
720
- 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")
721
- ru.require 'spec/app.rb'
722
- ru.record_split_class 'spec/app.rb', 'spec/dir'
723
- ru.call({}).must_equal 1
724
- update_app("class App; def self.a; 2 end end", 'spec/dir/appa.rb')
725
- ru.call({}).must_equal 21
726
- update_app("class App; def self.a; 3 end end", 'spec/dir/appa.rb')
727
- ru.call({}).must_equal 31
728
- update_app("class App; def self.b; 4 end end", 'spec/dir/appb.rb')
729
- ru.call({}).must_equal 341
730
- update_app("class App; def self.a; 5 end end", 'spec/dir/appa.rb')
731
- update_app("class App; def self.b; 6 end end", 'spec/dir/appb.rb')
732
- ru.call({}).must_equal 561
733
- chroot
734
- update_app("class App; end", 'spec/dir/appa.rb')
735
- ru.call({}).must_equal 61
736
- File.delete 'spec/dir/appb.rb'
737
- ru.call({}).must_equal 1
738
- end
739
-
740
- it "should handle classes split into multiple files when chrooting 6" do
741
- base_ru
742
- 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")
743
- ru.require 'spec/app.rb'
744
- ru.record_split_class 'spec/app.rb', 'spec/dir'
745
- ru.call({}).must_equal 1
746
- update_app("class App; def self.a; 2 end end", 'spec/dir/appa.rb')
747
- ru.call({}).must_equal 21
748
- update_app("class App; def self.a; 3 end end", 'spec/dir/appa.rb')
749
- ru.call({}).must_equal 31
750
- update_app("class App; def self.b; 4 end end", 'spec/dir/appb.rb')
751
- ru.call({}).must_equal 341
752
- update_app("class App; def self.a; 5 end end", 'spec/dir/appa.rb')
753
- update_app("class App; def self.b; 6 end end", 'spec/dir/appb.rb')
754
- ru.call({}).must_equal 561
755
- update_app("class App; end", 'spec/dir/appa.rb')
756
- ru.call({}).must_equal 61
757
- chroot
758
- File.delete 'spec/dir/appb.rb'
759
- ru.call({}).must_equal 1
760
- end
761
-
762
- it "should pick up changes to files in that directory" do
763
- base_ru
764
- update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
765
- update_app("App.call[:foo] = 1", 'spec/dir/a.rb')
766
- @ru.require('spec/app.rb')
767
- ru.call({}).must_equal(:foo=>1)
768
- chroot
769
- update_app("App.call[:foo] = 2", 'spec/dir/a.rb')
770
- ru.call({}).must_equal(:foo=>2)
771
- log_match %r{\ALoading.*spec/app\.rb\z},
772
- %r{\ALoading.*spec/dir/a\.rb\z},
773
- %r{\ANew classes in .*spec/app\.rb: App\z},
774
- %r{\ANew features in .*spec/app\.rb: .*spec/dir/a\.rb\z},
775
- %r{\AUnloading /spec/dir/a.rb\z},
776
- %r{\ALoading /spec/dir/a.rb\z}
777
- end
778
-
779
- it "should pick up changes to files in subdirectories" do
780
- base_ru
781
- update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
782
- update_app("App.call[:foo] = 1", 'spec/dir/subdir/a.rb')
783
- @ru.require('spec/app.rb')
784
- ru.call({}).must_equal(:foo=>1)
785
- chroot
786
- update_app("App.call[:foo] = 2", 'spec/dir/subdir/a.rb')
787
- ru.call({}).must_equal(:foo=>2)
788
- log_match %r{\ALoading.*spec/app\.rb\z},
789
- %r{\ALoading.*spec/dir/subdir/a\.rb\z},
790
- %r{\ANew classes in .*spec/app\.rb: App\z},
791
- %r{\ANew features in .*spec/app\.rb: .*spec/dir/subdir/a\.rb\z},
792
- %r{\AUnloading /spec/dir/subdir/a.rb\z},
793
- %r{\ALoading /spec/dir/subdir/a.rb\z}
794
- end
795
-
796
- it "should pick up new files added to the directory" do
797
- base_ru
798
- update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
799
- @ru.require('spec/app.rb')
800
- ru.call({}).must_equal({})
801
- chroot
802
- update_app("App.call[:foo] = 2", 'spec/dir/a.rb')
803
- ru.call({}).must_equal(:foo=>2)
804
- log_match %r{\ALoading.*spec/app\.rb\z},
805
- %r{\ANew classes in .*spec/app\.rb: App\z},
806
- %r{\ALoading /spec/dir/a\.rb\z}
807
- end
808
-
809
- it "should pick up new files added to subdirectories" do
810
- base_ru
811
- update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
812
- @ru.require('spec/app.rb')
813
- ru.call({}).must_equal({})
814
- chroot
815
- update_app("App.call[:foo] = 2", 'spec/dir/subdir/a.rb')
816
- ru.call({}).must_equal(:foo=>2)
817
- log_match %r{\ALoading.*spec/app\.rb\z},
818
- %r{\ANew classes in .*spec/app\.rb: App\z},
819
- %r{\ALoading /spec/dir/subdir/a\.rb\z}
820
- end
821
-
822
- it "should drop files deleted from the directory" do
823
- base_ru
824
- update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
825
- update_app("App.call[:foo] = 1", 'spec/dir/a.rb')
826
- @ru.require('spec/app.rb')
827
- ru.call({}).must_equal(:foo=>1)
828
- chroot
829
- File.delete('spec/dir/a.rb')
830
- update_app("App.call[:foo] = 2", 'spec/dir/b.rb')
831
- ru.call({}).must_equal(:foo=>2)
832
- log_match %r{\ALoading.*spec/app\.rb\z},
833
- %r{\ALoading.*spec/dir/a\.rb\z},
834
- %r{\ANew classes in .*spec/app\.rb: App\z},
835
- %r{\ANew features in .*spec/app\.rb: .*spec/dir/a\.rb\z},
836
- %r{\AUnloading /spec/dir/a.rb\z},
837
- %r{\ALoading /spec/dir/b\.rb\z}
838
- end
839
-
840
- it "should drop files deleted from subdirectories" do
841
- base_ru
842
- update_app("class App; @a = {}; def self.call(env=nil) @a end; end; RU.require 'spec/dir'")
843
- update_app("App.call[:foo] = 1", 'spec/dir/subdir/a.rb')
844
- @ru.require('spec/app.rb')
845
- ru.call({}).must_equal(:foo=>1)
846
- chroot
847
- File.delete('spec/dir/subdir/a.rb')
848
- update_app("App.call[:foo] = 2", 'spec/dir/subdir/b.rb')
849
- ru.call({}).must_equal(:foo=>2)
850
- log_match %r{\ALoading.*spec/app\.rb\z},
851
- %r{\ALoading.*spec/dir/subdir/a\.rb\z},
852
- %r{\ANew classes in .*spec/app\.rb: App\z},
853
- %r{\ANew features in .*spec/app\.rb: .*spec/dir/subdir/a\.rb\z},
854
- %r{\AUnloading /spec/dir/subdir/a.rb\z},
855
- %r{\ALoading /spec/dir/subdir/b\.rb\z}
856
- end
857
- end
858
- end