sass 3.1.15 → 3.1.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/README.md +4 -5
  2. data/Rakefile +2 -2
  3. data/VERSION +1 -1
  4. data/lib/sass/css.rb +144 -48
  5. data/lib/sass/engine.rb +3 -1
  6. data/lib/sass/plugin/compiler.rb +25 -32
  7. data/lib/sass/plugin/listener.rb +59 -0
  8. data/lib/sass/script/lexer.rb +1 -1
  9. data/lib/sass/script/list.rb +1 -0
  10. data/lib/sass/scss/parser.rb +90 -4
  11. data/lib/sass/scss/rx.rb +5 -0
  12. data/lib/sass/scss/static_parser.rb +1 -1
  13. data/lib/sass/selector/abstract_sequence.rb +11 -2
  14. data/lib/sass/selector/simple.rb +6 -0
  15. data/lib/sass/tree/comment_node.rb +1 -1
  16. data/lib/sass/tree/node.rb +2 -2
  17. data/lib/sass/tree/visitors/check_nesting.rb +2 -2
  18. data/lib/sass/tree/visitors/cssize.rb +1 -1
  19. data/lib/sass/util.rb +3 -2
  20. data/test/sass/conversion_test.rb +10 -0
  21. data/test/sass/css2sass_test.rb +24 -0
  22. data/test/sass/engine_test.rb +1 -0
  23. data/test/sass/scss/css_test.rb +53 -0
  24. data/vendor/listen/CHANGELOG.md +72 -0
  25. data/vendor/listen/Gemfile +35 -0
  26. data/vendor/listen/Guardfile +8 -0
  27. data/vendor/{fssm → listen}/LICENSE +1 -1
  28. data/vendor/listen/README.md +297 -0
  29. data/vendor/listen/Rakefile +47 -0
  30. data/vendor/listen/Vagrantfile +96 -0
  31. data/vendor/listen/lib/listen.rb +38 -0
  32. data/vendor/listen/lib/listen/adapter.rb +159 -0
  33. data/vendor/listen/lib/listen/adapters/darwin.rb +84 -0
  34. data/vendor/listen/lib/listen/adapters/linux.rb +99 -0
  35. data/vendor/listen/lib/listen/adapters/polling.rb +66 -0
  36. data/vendor/listen/lib/listen/adapters/windows.rb +82 -0
  37. data/vendor/listen/lib/listen/directory_record.rb +257 -0
  38. data/vendor/listen/lib/listen/listener.rb +186 -0
  39. data/vendor/listen/lib/listen/multi_listener.rb +121 -0
  40. data/vendor/listen/lib/listen/turnstile.rb +28 -0
  41. data/vendor/listen/lib/listen/version.rb +3 -0
  42. data/vendor/listen/listen.gemspec +26 -0
  43. data/vendor/listen/spec/listen/adapter_spec.rb +142 -0
  44. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +31 -0
  45. data/vendor/listen/spec/listen/adapters/linux_spec.rb +30 -0
  46. data/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
  47. data/vendor/listen/spec/listen/adapters/windows_spec.rb +24 -0
  48. data/vendor/listen/spec/listen/directory_record_spec.rb +807 -0
  49. data/vendor/listen/spec/listen/listener_spec.rb +151 -0
  50. data/vendor/listen/spec/listen/multi_listener_spec.rb +151 -0
  51. data/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
  52. data/vendor/listen/spec/listen_spec.rb +73 -0
  53. data/vendor/listen/spec/spec_helper.rb +16 -0
  54. data/vendor/listen/spec/support/adapter_helper.rb +538 -0
  55. data/vendor/listen/spec/support/directory_record_helper.rb +35 -0
  56. data/vendor/listen/spec/support/fixtures_helper.rb +29 -0
  57. data/vendor/listen/spec/support/listeners_helper.rb +133 -0
  58. data/vendor/listen/spec/support/platform_helper.rb +11 -0
  59. metadata +40 -40
  60. data/vendor/fssm/Gemfile +0 -3
  61. data/vendor/fssm/README.markdown +0 -83
  62. data/vendor/fssm/Rakefile +0 -11
  63. data/vendor/fssm/example.rb +0 -12
  64. data/vendor/fssm/ext/rakefile.rb +0 -14
  65. data/vendor/fssm/fssm.gemspec +0 -27
  66. data/vendor/fssm/lib/fssm.rb +0 -74
  67. data/vendor/fssm/lib/fssm/backends/fsevents.rb +0 -36
  68. data/vendor/fssm/lib/fssm/backends/inotify.rb +0 -26
  69. data/vendor/fssm/lib/fssm/backends/polling.rb +0 -25
  70. data/vendor/fssm/lib/fssm/backends/rbfsevent.rb +0 -42
  71. data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +0 -131
  72. data/vendor/fssm/lib/fssm/monitor.rb +0 -36
  73. data/vendor/fssm/lib/fssm/path.rb +0 -94
  74. data/vendor/fssm/lib/fssm/pathname.rb +0 -36
  75. data/vendor/fssm/lib/fssm/state/directory.rb +0 -75
  76. data/vendor/fssm/lib/fssm/state/file.rb +0 -24
  77. data/vendor/fssm/lib/fssm/support.rb +0 -87
  78. data/vendor/fssm/lib/fssm/tree.rb +0 -176
  79. data/vendor/fssm/lib/fssm/version.rb +0 -3
  80. data/vendor/fssm/profile/prof-cache.rb +0 -40
  81. data/vendor/fssm/profile/prof-fssm-pathname.html +0 -1231
  82. data/vendor/fssm/profile/prof-pathname-rubinius.rb +0 -35
  83. data/vendor/fssm/profile/prof-pathname.rb +0 -68
  84. data/vendor/fssm/profile/prof-plain-pathname.html +0 -988
  85. data/vendor/fssm/profile/prof.html +0 -2379
  86. data/vendor/fssm/spec/count_down_latch.rb +0 -151
  87. data/vendor/fssm/spec/monitor_spec.rb +0 -202
  88. data/vendor/fssm/spec/path_spec.rb +0 -96
  89. data/vendor/fssm/spec/root/duck/quack.txt +0 -0
  90. data/vendor/fssm/spec/root/file.css +0 -0
  91. data/vendor/fssm/spec/root/file.rb +0 -0
  92. data/vendor/fssm/spec/root/file.yml +0 -0
  93. data/vendor/fssm/spec/root/moo/cow.txt +0 -0
  94. data/vendor/fssm/spec/spec_helper.rb +0 -14
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Listen::Adapters::Windows do
4
+ if windows? && Listen::Adapters::Windows.usable?
5
+ it "is usable on Windows" do
6
+ described_class.should be_usable
7
+ end
8
+
9
+ it_should_behave_like 'a filesystem adapter'
10
+ it_should_behave_like 'an adapter that call properly listener#on_change', :recursive => true, :adapter => :windows
11
+ end
12
+
13
+ if mac?
14
+ it "isn't usable on Mac OS X" do
15
+ described_class.should_not be_usable
16
+ end
17
+ end
18
+
19
+ if linux?
20
+ it "isn't usable on Linux" do
21
+ described_class.should_not be_usable
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,807 @@
1
+ require 'spec_helper'
2
+
3
+ describe Listen::DirectoryRecord do
4
+ let(:base_directory) { Dir.tmpdir }
5
+
6
+ subject { described_class.new(base_directory) }
7
+
8
+ describe '#initialize' do
9
+ it 'sets the base directory' do
10
+ subject.directory.should eq base_directory
11
+ end
12
+
13
+ it 'sets the default ignored paths' do
14
+ subject.ignored_paths.should =~ described_class::DEFAULT_IGNORED_PATHS
15
+ end
16
+
17
+ it 'sets the default filters' do
18
+ subject.filters.should eq []
19
+ end
20
+
21
+ it 'raises an error when the passed path does not exist' do
22
+ expect { described_class.new('no way I exist') }.to raise_error(ArgumentError)
23
+ end
24
+
25
+ it 'raises an error when the passed path is not a directory' do
26
+ expect { described_class.new(__FILE__) }.to raise_error(ArgumentError)
27
+ end
28
+ end
29
+
30
+ describe '#ignore' do
31
+ it 'adds the passed paths to the list of ignoted paths in the record' do
32
+ subject.ignore('.old', '.pid')
33
+ subject.ignored_paths.should include('.old', '.pid')
34
+ end
35
+ end
36
+
37
+ describe '#filter' do
38
+ it 'adds the passed regexps to the list of filters that determine the stored paths' do
39
+ subject.filter(%r{\.(?:jpe?g|gif|png)}, %r{\.(?:mp3|ogg|a3c)})
40
+ subject.filters.should include(%r{\.(?:jpe?g|gif|png)}, %r{\.(?:mp3|ogg|a3c)})
41
+ end
42
+ end
43
+
44
+ describe '#ignored?' do
45
+ it 'returns true when the passed path is ignored' do
46
+ subject.ignore('.pid')
47
+ subject.ignored?('/tmp/some_process.pid').should be_true
48
+ end
49
+
50
+ it 'returns false when the passed path is not ignored' do
51
+ subject.ignore('.pid')
52
+ subject.ignored?('/tmp/some_file.txt').should be_false
53
+ end
54
+ end
55
+
56
+ describe '#filterd?' do
57
+ it 'returns true when the passed path is filtered' do
58
+ subject.filter(%r{\.(?:jpe?g|gif|png)})
59
+ subject.filtered?('/tmp/picture.jpeg').should be_true
60
+ end
61
+
62
+ it 'returns false when the passed path is not filtered' do
63
+ subject.filter(%r{\.(?:jpe?g|gif|png)})
64
+ subject.filtered?('/tmp/song.mp3').should be_false
65
+ end
66
+ end
67
+
68
+ describe '#build' do
69
+ it 'stores all files' do
70
+ fixtures do |path|
71
+ touch 'file.rb'
72
+ mkdir 'a_directory'
73
+ touch 'a_directory/file.txt'
74
+
75
+ record = described_class.new(path)
76
+ record.build
77
+
78
+ record.paths[path]['file.rb'].should eq 'File'
79
+ record.paths[path]['a_directory'].should eq 'Dir'
80
+ record.paths["#{path}/a_directory"]['file.txt'].should eq 'File'
81
+ end
82
+ end
83
+
84
+ context 'with ignored path set' do
85
+ it 'does not store ignored directory or its childs' do
86
+ fixtures do |path|
87
+ mkdir 'ignored_directory'
88
+ mkdir 'ignored_directory/child_directory'
89
+ touch 'ignored_directory/file.txt'
90
+
91
+ record = described_class.new(path)
92
+ record.ignore 'ignored_directory'
93
+ record.build
94
+
95
+ record.paths[path]['/a_ignored_directory'].should be_nil
96
+ record.paths["#{path}/a_ignored_directory"]['child_directory'].should be_nil
97
+ record.paths["#{path}/a_ignored_directory"]['file.txt'].should be_nil
98
+ end
99
+ end
100
+
101
+ it 'does not store ignored files' do
102
+ fixtures do |path|
103
+ touch 'ignored_file.rb'
104
+
105
+ record = described_class.new(path)
106
+ record.ignore 'ignored_file.rb'
107
+ record.build
108
+
109
+ record.paths[path]['ignored_file.rb'].should be_nil
110
+ end
111
+ end
112
+ end
113
+
114
+ context 'with filters set' do
115
+ it 'only stores filterd files' do
116
+ fixtures do |path|
117
+ touch 'file.rb'
118
+ touch 'file.zip'
119
+ mkdir 'a_directory'
120
+ touch 'a_directory/file.txt'
121
+ touch 'a_directory/file.rb'
122
+
123
+ record = described_class.new(path)
124
+ record.filter(/\.txt$/, /.*\.zip/)
125
+ record.build
126
+
127
+ record.paths[path]['file.rb'].should be_nil
128
+ record.paths[path]['file.zip'].should eq 'File'
129
+ record.paths[path]['a_directory'].should eq 'Dir'
130
+ record.paths["#{path}/a_directory"]['file.txt'].should eq 'File'
131
+ record.paths["#{path}/a_directory"]['file.rb'].should be_nil
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ describe '#fetch_changes' do
138
+ context 'with single file changes' do
139
+ context 'when a file is created' do
140
+ it 'detects the added file' do
141
+ fixtures do |path|
142
+ modified, added, removed = changes(path) do
143
+ touch 'new_file.rb'
144
+ end
145
+
146
+ added.should =~ %w(new_file.rb)
147
+ modified.should be_empty
148
+ removed.should be_empty
149
+ end
150
+ end
151
+
152
+ it 'stores the added file in the record' do
153
+ fixtures do |path|
154
+ changes(path) do
155
+ @record.paths.should be_empty
156
+
157
+ touch 'new_file.rb'
158
+ end
159
+
160
+ @record.paths[path]['new_file.rb'].should_not be_nil
161
+ end
162
+ end
163
+
164
+ context 'given a new created directory' do
165
+ it 'detects the added file' do
166
+ fixtures do |path|
167
+ modified, added, removed = changes(path) do
168
+ mkdir 'a_directory'
169
+ touch 'a_directory/new_file.rb'
170
+ end
171
+
172
+ added.should =~ %w(a_directory/new_file.rb)
173
+ modified.should be_empty
174
+ removed.should be_empty
175
+ end
176
+ end
177
+
178
+ it 'stores the added directory and file in the record' do
179
+ fixtures do |path|
180
+ changes(path) do
181
+ @record.paths.should be_empty
182
+
183
+ mkdir 'a_directory'
184
+ touch 'a_directory/new_file.rb'
185
+ end
186
+
187
+ @record.paths[path]['a_directory'].should_not be_nil
188
+ @record.paths["#{path}/a_directory"]['new_file.rb'].should_not be_nil
189
+ end
190
+ end
191
+ end
192
+
193
+ context 'given an existing directory' do
194
+ context 'with recursive option set to true' do
195
+ it 'detects the added file' do
196
+ fixtures do |path|
197
+ mkdir 'a_directory'
198
+
199
+ modified, added, removed = changes(path, :recursive => true) do
200
+ touch 'a_directory/new_file.rb'
201
+ end
202
+
203
+ added.should =~ %w(a_directory/new_file.rb)
204
+ modified.should be_empty
205
+ removed.should be_empty
206
+ end
207
+ end
208
+
209
+ context 'with an ignored directory' do
210
+ it "doesn't detect the added file" do
211
+ fixtures do |path|
212
+ mkdir 'ignored_directory'
213
+
214
+ modified, added, removed = changes(path, :ignore => 'ignored_directory', :recursive => true) do
215
+ touch 'ignored_directory/new_file.rb'
216
+ end
217
+
218
+ added.should be_empty
219
+ modified.should be_empty
220
+ removed.should be_empty
221
+ end
222
+ end
223
+
224
+ it "doesn't detect the added file when it's asked to fetch the changes of the ignored directory"do
225
+ fixtures do |path|
226
+ mkdir 'ignored_directory'
227
+
228
+ modified, added, removed = changes(path, :paths => ["#{path}/ignored_directory"], :ignore => 'ignored_directory', :recursive => true) do
229
+ touch 'ignored_directory/new_file.rb'
230
+ end
231
+
232
+ added.should be_empty
233
+ modified.should be_empty
234
+ removed.should be_empty
235
+ end
236
+ end
237
+ end
238
+ end
239
+
240
+ context 'with recursive option set to false' do
241
+ it "doesn't detect deeply-nested added files" do
242
+ fixtures do |path|
243
+ mkdir 'a_directory'
244
+
245
+ modified, added, removed = changes(path, :recursive => false) do
246
+ touch 'a_directory/new_file.rb'
247
+ end
248
+
249
+ added.should be_empty
250
+ modified.should be_empty
251
+ removed.should be_empty
252
+ end
253
+ end
254
+ end
255
+ end
256
+ end
257
+
258
+ context 'when a file is modified' do
259
+ it 'detects the modified file' do
260
+ fixtures do |path|
261
+ touch 'existing_file.txt'
262
+
263
+ modified, added, removed = changes(path) do
264
+ sleep 1.5 # make a diffrence in the mtime of the file
265
+ touch 'existing_file.txt'
266
+ end
267
+
268
+ added.should be_empty
269
+ modified.should =~ %w(existing_file.txt)
270
+ removed.should be_empty
271
+ end
272
+ end
273
+
274
+ context 'during the same second' do
275
+ before { ensure_same_second }
276
+
277
+ it 'always detects the modified file the first time' do
278
+ fixtures do |path|
279
+ touch 'existing_file.txt'
280
+
281
+ modified, added, removed = changes(path) do
282
+ touch 'existing_file.txt'
283
+ end
284
+
285
+ added.should be_empty
286
+ modified.should =~ %w(existing_file.txt)
287
+ removed.should be_empty
288
+ end
289
+ end
290
+
291
+ it "doesn't detects the modified file the second time if the content haven't changed" do
292
+ fixtures do |path|
293
+ touch 'existing_file.txt'
294
+
295
+ changes(path) do
296
+ touch 'existing_file.txt'
297
+ end
298
+
299
+ modified, added, removed = changes(path, :use_last_record => true) do
300
+ touch 'existing_file.txt'
301
+ end
302
+
303
+ added.should be_empty
304
+ modified.should be_empty
305
+ removed.should be_empty
306
+ end
307
+ end
308
+
309
+ it "detects the modified file the second time if the content have changed" do
310
+ fixtures do |path|
311
+ touch 'existing_file.txt'
312
+
313
+ changes(path) do
314
+ touch 'existing_file.txt'
315
+ end
316
+
317
+ modified, added, removed = changes(path, :use_last_record => true) do
318
+ open('existing_file.txt', 'w') { |f| f.write('foo') }
319
+ end
320
+
321
+ added.should be_empty
322
+ modified.should =~ %w(existing_file.txt)
323
+ removed.should be_empty
324
+ end
325
+ end
326
+ end
327
+
328
+ context 'given a hidden file' do
329
+ it 'detects the modified file' do
330
+ fixtures do |path|
331
+ touch '.hidden'
332
+
333
+ modified, added, removed = changes(path) do
334
+ touch '.hidden'
335
+ end
336
+
337
+ added.should be_empty
338
+ modified.should =~ %w(.hidden)
339
+ removed.should be_empty
340
+ end
341
+ end
342
+ end
343
+
344
+ context 'given a file mode change' do
345
+ it 'does not detect the mode change' do
346
+ fixtures do |path|
347
+ touch 'run.rb'
348
+ sleep 1.5 # make a diffrence in the mtime of the file
349
+
350
+ modified, added, removed = changes(path) do
351
+ chmod 0777, 'run.rb'
352
+ end
353
+
354
+ added.should be_empty
355
+ modified.should be_empty
356
+ removed.should be_empty
357
+ end
358
+ end
359
+ end
360
+
361
+ context 'given an existing directory' do
362
+ context 'with recursive option set to true' do
363
+ it 'detects the modified file' do
364
+ fixtures do |path|
365
+ mkdir 'a_directory'
366
+ touch 'a_directory/existing_file.txt'
367
+
368
+ modified, added, removed = changes(path, :recursive => true) do
369
+ touch 'a_directory/existing_file.txt'
370
+ end
371
+
372
+ added.should be_empty
373
+ modified.should =~ %w(a_directory/existing_file.txt)
374
+ removed.should be_empty
375
+ end
376
+ end
377
+ end
378
+
379
+ context 'with recursive option set to false' do
380
+ it "doesn't detects the modified file" do
381
+ fixtures do |path|
382
+ mkdir 'a_directory'
383
+ touch 'a_directory/existing_file.txt'
384
+
385
+ modified, added, removed = changes(path, :recursive => false) do
386
+ touch 'a_directory/existing_file.txt'
387
+ end
388
+
389
+ added.should be_empty
390
+ modified.should be_empty
391
+ removed.should be_empty
392
+ end
393
+ end
394
+ end
395
+ end
396
+ end
397
+
398
+ context 'when a file is moved' do
399
+ it 'detects the file movement' do
400
+ fixtures do |path|
401
+ touch 'move_me.txt'
402
+
403
+ modified, added, removed = changes(path) do
404
+ mv 'move_me.txt', 'new_name.txt'
405
+ end
406
+
407
+ added.should =~ %w(new_name.txt)
408
+ modified.should be_empty
409
+ removed.should =~ %w(move_me.txt)
410
+ end
411
+ end
412
+
413
+ context 'given an existing directory' do
414
+ context 'with recursive option set to true' do
415
+ it 'detects the file movement into the directory' do
416
+ fixtures do |path|
417
+ mkdir 'a_directory'
418
+ touch 'move_me.txt'
419
+
420
+ modified, added, removed = changes(path, :recursive => true) do
421
+ mv 'move_me.txt', 'a_directory/move_me.txt'
422
+ end
423
+
424
+ added.should =~ %w(a_directory/move_me.txt)
425
+ modified.should be_empty
426
+ removed.should =~ %w(move_me.txt)
427
+ end
428
+ end
429
+
430
+ it 'detects a file movement out of the directory' do
431
+ fixtures do |path|
432
+ mkdir 'a_directory'
433
+ touch 'a_directory/move_me.txt'
434
+
435
+ modified, added, removed = changes(path, :recursive => true) do
436
+ mv 'a_directory/move_me.txt', 'i_am_here.txt'
437
+ end
438
+
439
+ added.should =~ %w(i_am_here.txt)
440
+ modified.should be_empty
441
+ removed.should =~ %w(a_directory/move_me.txt)
442
+ end
443
+ end
444
+
445
+ it 'detects a file movement between two directories' do
446
+ fixtures do |path|
447
+ mkdir 'from_directory'
448
+ touch 'from_directory/move_me.txt'
449
+ mkdir 'to_directory'
450
+
451
+ modified, added, removed = changes(path, :recursive => true) do
452
+ mv 'from_directory/move_me.txt', 'to_directory/move_me.txt'
453
+ end
454
+
455
+ added.should =~ %w(to_directory/move_me.txt)
456
+ modified.should be_empty
457
+ removed.should =~ %w(from_directory/move_me.txt)
458
+ end
459
+ end
460
+ end
461
+
462
+ context 'with recursive option set to false' do
463
+ it "doesn't detect the file movement into the directory" do
464
+ fixtures do |path|
465
+ mkdir 'a_directory'
466
+ touch 'move_me.txt'
467
+
468
+ modified, added, removed = changes(path, :recursive => false) do
469
+ mv 'move_me.txt', 'a_directory/move_me.txt'
470
+ end
471
+
472
+ added.should be_empty
473
+ modified.should be_empty
474
+ removed.should =~ %w(move_me.txt)
475
+ end
476
+ end
477
+
478
+ it "doesn't detect a file movement out of the directory" do
479
+ fixtures do |path|
480
+ mkdir 'a_directory'
481
+ touch 'a_directory/move_me.txt'
482
+
483
+ modified, added, removed = changes(path, :recursive => false) do
484
+ mv 'a_directory/move_me.txt', 'i_am_here.txt'
485
+ end
486
+
487
+ added.should =~ %w(i_am_here.txt)
488
+ modified.should be_empty
489
+ removed.should be_empty
490
+ end
491
+ end
492
+
493
+ it "doesn't detect a file movement between two directories" do
494
+ fixtures do |path|
495
+ mkdir 'from_directory'
496
+ touch 'from_directory/move_me.txt'
497
+ mkdir 'to_directory'
498
+
499
+ modified, added, removed = changes(path, :recursive => false) do
500
+ mv 'from_directory/move_me.txt', 'to_directory/move_me.txt'
501
+ end
502
+
503
+ added.should be_empty
504
+ modified.should be_empty
505
+ removed.should be_empty
506
+ end
507
+ end
508
+
509
+ context 'with all paths are passed as params' do
510
+ it 'detects the file movement into the directory' do
511
+ fixtures do |path|
512
+ mkdir 'a_directory'
513
+ touch 'move_me.txt'
514
+
515
+ modified, added, removed = changes(path, :recursive => false, :paths => [path, "#{path}/a_directory"]) do
516
+ mv 'move_me.txt', 'a_directory/move_me.txt'
517
+ end
518
+
519
+ added.should =~ %w(a_directory/move_me.txt)
520
+ modified.should be_empty
521
+ removed.should =~ %w(move_me.txt)
522
+ end
523
+ end
524
+
525
+ it 'detects a file moved outside of a directory' do
526
+ fixtures do |path|
527
+ mkdir 'a_directory'
528
+ touch 'a_directory/move_me.txt'
529
+
530
+ modified, added, removed = changes(path, :recursive => false, :paths => [path, "#{path}/a_directory"]) do
531
+ mv 'a_directory/move_me.txt', 'i_am_here.txt'
532
+ end
533
+
534
+ added.should =~ %w(i_am_here.txt)
535
+ modified.should be_empty
536
+ removed.should =~ %w(a_directory/move_me.txt)
537
+ end
538
+ end
539
+
540
+ it 'detects a file movement between two directories' do
541
+ fixtures do |path|
542
+ mkdir 'from_directory'
543
+ touch 'from_directory/move_me.txt'
544
+ mkdir 'to_directory'
545
+
546
+ modified, added, removed = changes(path, :recursive => false, :paths => [path, "#{path}/from_directory", "#{path}/to_directory"]) do
547
+ mv 'from_directory/move_me.txt', 'to_directory/move_me.txt'
548
+ end
549
+
550
+ added.should =~ %w(to_directory/move_me.txt)
551
+ modified.should be_empty
552
+ removed.should =~ %w(from_directory/move_me.txt)
553
+ end
554
+ end
555
+ end
556
+ end
557
+ end
558
+ end
559
+
560
+ context 'when a file is deleted' do
561
+ it 'detects the file removal' do
562
+ fixtures do |path|
563
+ touch 'unnecessary.txt'
564
+
565
+ modified, added, removed = changes(path) do
566
+ rm 'unnecessary.txt'
567
+ end
568
+
569
+ added.should be_empty
570
+ modified.should be_empty
571
+ removed.should =~ %w(unnecessary.txt)
572
+ end
573
+ end
574
+
575
+ it "deletes the file from the record" do
576
+ fixtures do |path|
577
+ touch 'unnecessary.txt'
578
+
579
+ changes(path) do
580
+ @record.paths[path]['unnecessary.txt'].should_not be_nil
581
+
582
+ rm 'unnecessary.txt'
583
+ end
584
+
585
+ @record.paths[path]['unnecessary.txt'].should be_nil
586
+ end
587
+ end
588
+
589
+ it "deletes the path from the paths checksums" do
590
+ fixtures do |path|
591
+ touch 'unnecessary.txt'
592
+
593
+ changes(path) do
594
+ @record.sha1_checksums["#{path}/unnecessary.txt"] = 'foo'
595
+
596
+ rm 'unnecessary.txt'
597
+ end
598
+
599
+ @record.sha1_checksums["#{path}/unnecessary.txt"].should be_nil
600
+ end
601
+ end
602
+
603
+ context 'given an existing directory' do
604
+ context 'with recursive option set to true' do
605
+ it 'detects the file removal' do
606
+ fixtures do |path|
607
+ mkdir 'a_directory'
608
+ touch 'a_directory/do_not_use.rb'
609
+
610
+ modified, added, removed = changes(path, :recursive => true) do
611
+ rm 'a_directory/do_not_use.rb'
612
+ end
613
+
614
+ added.should be_empty
615
+ modified.should be_empty
616
+ removed.should =~ %w(a_directory/do_not_use.rb)
617
+ end
618
+ end
619
+ end
620
+
621
+ context 'with recursive option set to false' do
622
+ it "doesn't detect the file removal" do
623
+ fixtures do |path|
624
+ mkdir 'a_directory'
625
+ touch 'a_directory/do_not_use.rb'
626
+
627
+ modified, added, removed = changes(path, :recursive => false) do
628
+ rm 'a_directory/do_not_use.rb'
629
+ end
630
+
631
+ added.should be_empty
632
+ modified.should be_empty
633
+ removed.should be_empty
634
+ end
635
+ end
636
+ end
637
+ end
638
+ end
639
+ end
640
+
641
+ context 'multiple file operations' do
642
+ it 'detects the added files' do
643
+ fixtures do |path|
644
+ modified, added, removed = changes(path) do
645
+ touch 'a_file.rb'
646
+ touch 'b_file.rb'
647
+ mkdir 'a_directory'
648
+ touch 'a_directory/a_file.rb'
649
+ touch 'a_directory/b_file.rb'
650
+ end
651
+
652
+ added.should =~ %w(a_file.rb b_file.rb a_directory/a_file.rb a_directory/b_file.rb)
653
+ modified.should be_empty
654
+ removed.should be_empty
655
+ end
656
+ end
657
+
658
+ it 'detects the modified files' do
659
+ fixtures do |path|
660
+ touch 'a_file.rb'
661
+ touch 'b_file.rb'
662
+ mkdir 'a_directory'
663
+ touch 'a_directory/a_file.rb'
664
+ touch 'a_directory/b_file.rb'
665
+ sleep 1.5 # make files mtime old
666
+
667
+ modified, added, removed = changes(path) do
668
+ touch 'b_file.rb'
669
+ touch 'a_directory/a_file.rb'
670
+ end
671
+
672
+ added.should be_empty
673
+ modified.should =~ %w(b_file.rb a_directory/a_file.rb)
674
+ removed.should be_empty
675
+ end
676
+ end
677
+
678
+ it 'detects the removed files' do
679
+ fixtures do |path|
680
+ touch 'a_file.rb'
681
+ touch 'b_file.rb'
682
+ mkdir 'a_directory'
683
+ touch 'a_directory/a_file.rb'
684
+ touch 'a_directory/b_file.rb'
685
+ sleep 1.5 # make files mtime old
686
+
687
+ modified, added, removed = changes(path) do
688
+ rm 'b_file.rb'
689
+ rm 'a_directory/a_file.rb'
690
+ end
691
+
692
+ added.should be_empty
693
+ modified.should be_empty
694
+ removed.should =~ %w(b_file.rb a_directory/a_file.rb)
695
+ end
696
+ end
697
+ end
698
+
699
+ context 'single directory operations' do
700
+ it 'detects a moved directory' do
701
+ fixtures do |path|
702
+ mkdir 'a_directory'
703
+ touch 'a_directory/a_file.rb'
704
+ touch 'a_directory/b_file.rb'
705
+
706
+ modified, added, removed = changes(path) do
707
+ mv 'a_directory', 'renamed'
708
+ end
709
+
710
+ added.should =~ %w(renamed/a_file.rb renamed/b_file.rb)
711
+ modified.should be_empty
712
+ removed.should =~ %w(a_directory/a_file.rb a_directory/b_file.rb)
713
+ end
714
+ end
715
+
716
+ it 'detects a removed directory' do
717
+ fixtures do |path|
718
+ mkdir 'a_directory'
719
+ touch 'a_directory/a_file.rb'
720
+ touch 'a_directory/b_file.rb'
721
+
722
+ modified, added, removed = changes(path) do
723
+ rm_rf 'a_directory'
724
+ end
725
+
726
+ added.should be_empty
727
+ modified.should be_empty
728
+ removed.should =~ %w(a_directory/a_file.rb a_directory/b_file.rb)
729
+ end
730
+ end
731
+
732
+ it "deletes the directory from the record" do
733
+ fixtures do |path|
734
+ mkdir 'a_directory'
735
+ touch 'a_directory/file.rb'
736
+
737
+ changes(path) do
738
+ @record.paths.should have(2).paths
739
+ @record.paths[path]['a_directory'].should_not be_nil
740
+ @record.paths["#{path}/a_directory"]['file.rb'].should_not be_nil
741
+
742
+ rm_rf 'a_directory'
743
+ end
744
+
745
+ @record.paths.should have(1).paths
746
+ @record.paths[path]['a_directory'].should be_nil
747
+ @record.paths["#{path}/a_directory"]['file.rb'].should be_nil
748
+ end
749
+ end
750
+
751
+ context 'with nested paths' do
752
+ it 'detects removals without crashing - #18' do
753
+ fixtures do |path|
754
+ mkdir_p 'a_directory/b_directory'
755
+ touch 'a_directory/b_directory/do_not_use.rb'
756
+
757
+ modified, added, removed = changes(path, :paths => [path, "#{path}/a_directory", "#{path}/b_directory"]) do
758
+ rm_r 'a_directory'
759
+ end
760
+
761
+ added.should be_empty
762
+ modified.should be_empty
763
+ removed.should =~ %w(a_directory/b_directory/do_not_use.rb)
764
+ end
765
+ end
766
+ end
767
+ end
768
+
769
+ context 'with a path outside the directory for which a record is made' do
770
+ it "skips that path and doesn't check for changes" do
771
+ fixtures do |path|
772
+ modified, added, removed = changes(path, :paths => ['some/where/outside']) do
773
+ @record.should_not_receive(:detect_additions)
774
+ @record.should_not_receive(:detect_modifications_and_removals)
775
+
776
+ touch 'new_file.rb'
777
+ end
778
+
779
+ added.should be_empty
780
+ modified.should be_empty
781
+ removed.should be_empty
782
+ end
783
+ end
784
+ end
785
+
786
+ context 'with the relative_paths option set to false' do
787
+ it 'returns full paths in the changes hash' do
788
+ fixtures do |path|
789
+ touch 'a_file.rb'
790
+ touch 'b_file.rb'
791
+
792
+ modified, added, removed = changes(path, :relative_paths => false) do
793
+ rm 'a_file.rb'
794
+ touch 'b_file.rb'
795
+ touch 'c_file.rb'
796
+ mkdir 'a_directory'
797
+ touch 'a_directory/a_file.rb'
798
+ end
799
+
800
+ added.should =~ ["#{path}/c_file.rb", "#{path}/a_directory/a_file.rb"]
801
+ modified.should =~ ["#{path}/b_file.rb"]
802
+ removed.should =~ ["#{path}/a_file.rb"]
803
+ end
804
+ end
805
+ end
806
+ end
807
+ end