sass 3.1.21 → 3.2.0.alpha.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. data/README.md +5 -4
  2. data/REVISION +1 -1
  3. data/Rakefile +6 -15
  4. data/VERSION +1 -1
  5. data/VERSION_NAME +1 -1
  6. data/lib/sass.rb +0 -1
  7. data/lib/sass/cache_stores/base.rb +1 -3
  8. data/lib/sass/cache_stores/filesystem.rb +0 -3
  9. data/lib/sass/css.rb +49 -145
  10. data/lib/sass/engine.rb +23 -47
  11. data/lib/sass/environment.rb +5 -30
  12. data/lib/sass/exec.rb +7 -30
  13. data/lib/sass/importers/base.rb +1 -2
  14. data/lib/sass/importers/filesystem.rb +13 -18
  15. data/lib/sass/less.rb +1 -1
  16. data/lib/sass/plugin.rb +8 -4
  17. data/lib/sass/plugin/compiler.rb +67 -93
  18. data/lib/sass/plugin/configuration.rb +2 -0
  19. data/lib/sass/plugin/staleness_checker.rb +4 -14
  20. data/lib/sass/repl.rb +3 -2
  21. data/lib/sass/script.rb +1 -0
  22. data/lib/sass/script/color.rb +9 -4
  23. data/lib/sass/script/funcall.rb +3 -16
  24. data/lib/sass/script/functions.rb +55 -98
  25. data/lib/sass/script/interpolation.rb +0 -9
  26. data/lib/sass/script/lexer.rb +4 -2
  27. data/lib/sass/script/list.rb +0 -8
  28. data/lib/sass/script/literal.rb +20 -5
  29. data/lib/sass/script/node.rb +0 -8
  30. data/lib/sass/script/number.rb +11 -35
  31. data/lib/sass/script/operation.rb +0 -16
  32. data/lib/sass/script/parser.rb +5 -12
  33. data/lib/sass/script/string_interpolation.rb +0 -9
  34. data/lib/sass/script/unary_operation.rb +0 -7
  35. data/lib/sass/script/variable.rb +1 -5
  36. data/lib/sass/scss/parser.rb +54 -191
  37. data/lib/sass/scss/rx.rb +3 -15
  38. data/lib/sass/scss/static_parser.rb +3 -3
  39. data/lib/sass/selector.rb +3 -15
  40. data/lib/sass/selector/abstract_sequence.rb +2 -11
  41. data/lib/sass/selector/comma_sequence.rb +3 -8
  42. data/lib/sass/selector/sequence.rb +11 -74
  43. data/lib/sass/selector/simple.rb +1 -7
  44. data/lib/sass/selector/simple_sequence.rb +8 -28
  45. data/lib/sass/shared.rb +5 -3
  46. data/lib/sass/tree/comment_node.rb +12 -25
  47. data/lib/sass/tree/debug_node.rb +1 -1
  48. data/lib/sass/tree/directive_node.rb +0 -5
  49. data/lib/sass/tree/each_node.rb +1 -1
  50. data/lib/sass/tree/extend_node.rb +1 -1
  51. data/lib/sass/tree/for_node.rb +2 -2
  52. data/lib/sass/tree/function_node.rb +1 -1
  53. data/lib/sass/tree/if_node.rb +14 -1
  54. data/lib/sass/tree/media_node.rb +4 -4
  55. data/lib/sass/tree/mixin_def_node.rb +1 -1
  56. data/lib/sass/tree/mixin_node.rb +2 -2
  57. data/lib/sass/tree/node.rb +26 -10
  58. data/lib/sass/tree/return_node.rb +1 -1
  59. data/lib/sass/tree/root_node.rb +1 -1
  60. data/lib/sass/tree/rule_node.rb +11 -9
  61. data/lib/sass/tree/variable_node.rb +1 -1
  62. data/lib/sass/tree/visitors/base.rb +1 -1
  63. data/lib/sass/tree/visitors/check_nesting.rb +36 -29
  64. data/lib/sass/tree/visitors/convert.rb +9 -16
  65. data/lib/sass/tree/visitors/cssize.rb +9 -40
  66. data/lib/sass/tree/visitors/perform.rb +23 -79
  67. data/lib/sass/tree/visitors/to_css.rb +21 -23
  68. data/lib/sass/tree/warn_node.rb +1 -1
  69. data/lib/sass/tree/while_node.rb +1 -1
  70. data/lib/sass/util.rb +9 -147
  71. data/lib/sass/version.rb +0 -14
  72. data/test/sass/cache_test.rb +0 -15
  73. data/test/sass/conversion_test.rb +8 -50
  74. data/test/sass/css2sass_test.rb +0 -33
  75. data/test/sass/engine_test.rb +32 -283
  76. data/test/sass/extend_test.rb +0 -315
  77. data/test/sass/functions_test.rb +23 -60
  78. data/test/sass/importer_test.rb +0 -110
  79. data/test/sass/more_results/more_import.css +2 -2
  80. data/test/sass/plugin_test.rb +13 -40
  81. data/test/sass/results/import.css +2 -2
  82. data/test/sass/results/import_charset.css +0 -1
  83. data/test/sass/results/import_charset_1_8.css +0 -1
  84. data/test/sass/results/import_charset_ibm866.css +0 -1
  85. data/test/sass/results/scss_import.css +2 -2
  86. data/test/sass/results/units.css +1 -1
  87. data/test/sass/script_conversion_test.rb +0 -2
  88. data/test/sass/script_test.rb +4 -28
  89. data/test/sass/scss/css_test.rb +1 -79
  90. data/test/sass/scss/scss_test.rb +16 -96
  91. data/test/sass/templates/import_charset.sass +0 -2
  92. data/test/sass/templates/import_charset_1_8.sass +0 -2
  93. data/test/sass/templates/import_charset_ibm866.sass +0 -2
  94. data/test/sass/test_helper.rb +1 -1
  95. data/test/sass/util_test.rb +0 -28
  96. data/test/test_helper.rb +0 -2
  97. data/vendor/{listen → fssm}/LICENSE +1 -1
  98. data/vendor/fssm/README.markdown +55 -0
  99. data/vendor/fssm/Rakefile +59 -0
  100. data/vendor/fssm/VERSION.yml +5 -0
  101. data/vendor/fssm/example.rb +9 -0
  102. data/vendor/fssm/fssm.gemspec +77 -0
  103. data/vendor/fssm/lib/fssm.rb +33 -0
  104. data/vendor/fssm/lib/fssm/backends/fsevents.rb +36 -0
  105. data/vendor/fssm/lib/fssm/backends/inotify.rb +26 -0
  106. data/vendor/fssm/lib/fssm/backends/polling.rb +25 -0
  107. data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +131 -0
  108. data/vendor/fssm/lib/fssm/monitor.rb +26 -0
  109. data/vendor/fssm/lib/fssm/path.rb +91 -0
  110. data/vendor/fssm/lib/fssm/pathname.rb +502 -0
  111. data/vendor/fssm/lib/fssm/state/directory.rb +57 -0
  112. data/vendor/fssm/lib/fssm/state/file.rb +24 -0
  113. data/vendor/fssm/lib/fssm/support.rb +63 -0
  114. data/vendor/fssm/lib/fssm/tree.rb +176 -0
  115. data/vendor/fssm/profile/prof-cache.rb +40 -0
  116. data/vendor/fssm/profile/prof-fssm-pathname.html +1231 -0
  117. data/vendor/fssm/profile/prof-pathname.rb +68 -0
  118. data/vendor/fssm/profile/prof-plain-pathname.html +988 -0
  119. data/vendor/fssm/profile/prof.html +2379 -0
  120. data/vendor/fssm/spec/path_spec.rb +75 -0
  121. data/vendor/fssm/spec/root/duck/quack.txt +0 -0
  122. data/vendor/fssm/spec/root/file.css +0 -0
  123. data/vendor/fssm/spec/root/file.rb +0 -0
  124. data/vendor/fssm/spec/root/file.yml +0 -0
  125. data/vendor/fssm/spec/root/moo/cow.txt +0 -0
  126. data/vendor/fssm/spec/spec_helper.rb +14 -0
  127. metadata +246 -281
  128. data/VERSION_DATE +0 -1
  129. data/lib/sass/logger.rb +0 -15
  130. data/lib/sass/logger/base.rb +0 -32
  131. data/lib/sass/logger/log_level.rb +0 -49
  132. data/lib/sass/tree/visitors/deep_copy.rb +0 -87
  133. data/lib/sass/tree/visitors/extend.rb +0 -42
  134. data/lib/sass/tree/visitors/set_options.rb +0 -97
  135. data/lib/sass/util/multibyte_string_scanner.rb +0 -134
  136. data/test/Gemfile +0 -4
  137. data/test/Gemfile.lock +0 -19
  138. data/test/sass/fixtures/test_staleness_check_across_importers.css +0 -1
  139. data/test/sass/fixtures/test_staleness_check_across_importers.scss +0 -1
  140. data/test/sass/logger_test.rb +0 -58
  141. data/test/sass/templates/_double_import_loop2.sass +0 -1
  142. data/test/sass/templates/bork5.sass +0 -3
  143. data/test/sass/templates/double_import_loop1.sass +0 -1
  144. data/test/sass/templates/nested_bork5.sass +0 -2
  145. data/test/sass/templates/single_import_loop.sass +0 -1
  146. data/test/sass/util/multibyte_string_scanner_test.rb +0 -147
  147. data/vendor/listen/CHANGELOG.md +0 -147
  148. data/vendor/listen/Gemfile +0 -23
  149. data/vendor/listen/Guardfile +0 -8
  150. data/vendor/listen/README.md +0 -312
  151. data/vendor/listen/Rakefile +0 -47
  152. data/vendor/listen/Vagrantfile +0 -96
  153. data/vendor/listen/lib/listen.rb +0 -38
  154. data/vendor/listen/lib/listen/adapter.rb +0 -167
  155. data/vendor/listen/lib/listen/adapters/darwin.rb +0 -84
  156. data/vendor/listen/lib/listen/adapters/linux.rb +0 -110
  157. data/vendor/listen/lib/listen/adapters/polling.rb +0 -66
  158. data/vendor/listen/lib/listen/adapters/windows.rb +0 -81
  159. data/vendor/listen/lib/listen/directory_record.rb +0 -318
  160. data/vendor/listen/lib/listen/listener.rb +0 -203
  161. data/vendor/listen/lib/listen/multi_listener.rb +0 -121
  162. data/vendor/listen/lib/listen/turnstile.rb +0 -28
  163. data/vendor/listen/lib/listen/version.rb +0 -3
  164. data/vendor/listen/listen.gemspec +0 -26
  165. data/vendor/listen/spec/listen/adapter_spec.rb +0 -142
  166. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -31
  167. data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -41
  168. data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
  169. data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -24
  170. data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1138
  171. data/vendor/listen/spec/listen/listener_spec.rb +0 -155
  172. data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -156
  173. data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
  174. data/vendor/listen/spec/listen_spec.rb +0 -73
  175. data/vendor/listen/spec/spec_helper.rb +0 -18
  176. data/vendor/listen/spec/support/adapter_helper.rb +0 -716
  177. data/vendor/listen/spec/support/directory_record_helper.rb +0 -55
  178. data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
  179. data/vendor/listen/spec/support/listeners_helper.rb +0 -144
  180. data/vendor/listen/spec/support/platform_helper.rb +0 -11
@@ -1,31 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Listen::Adapters::Darwin do
4
- if mac?
5
- if Listen::Adapters::Darwin.usable?
6
- it "is usable on Mac OS X >= 10.6" do
7
- described_class.should be_usable
8
- end
9
-
10
- it_should_behave_like 'a filesystem adapter'
11
- it_should_behave_like 'an adapter that call properly listener#on_change'
12
- else
13
- it "isn't usable on Mac OS X with #{RbConfig::CONFIG['RUBY_INSTALL_NAME']}" do
14
- described_class.should_not be_usable
15
- end
16
- end
17
-
18
- end
19
-
20
- if windows?
21
- it "isn't usable on Windows" do
22
- described_class.should_not be_usable
23
- end
24
- end
25
-
26
- if linux?
27
- it "isn't usable on Linux" do
28
- described_class.should_not be_usable
29
- end
30
- end
31
- end
@@ -1,41 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Listen::Adapters::Linux do
4
- if linux?
5
- if Listen::Adapters::Linux.usable?
6
- it "is usable on Linux" do
7
- described_class.should be_usable
8
- end
9
-
10
- it_should_behave_like 'a filesystem adapter'
11
- it_should_behave_like 'an adapter that call properly listener#on_change'
12
-
13
- describe '#initialize' do
14
- context 'when the inotify limit for watched files is not enough' do
15
- before { INotify::Notifier.any_instance.should_receive(:watch).and_raise(Errno::ENOSPC) }
16
-
17
- it 'fails gracefully' do
18
- described_class.any_instance.should_receive(:abort).with(described_class::INOTIFY_LIMIT_MESSAGE)
19
- described_class.new(File.dirname(__FILE__))
20
- end
21
- end
22
- end
23
- else
24
- it "isn't usable on Linux with #{RbConfig::CONFIG['RUBY_INSTALL_NAME']}" do
25
- described_class.should_not be_usable
26
- end
27
- end
28
- end
29
-
30
- if mac?
31
- it "isn't usable on Mac OS X" do
32
- described_class.should_not be_usable
33
- end
34
- end
35
-
36
- if windows?
37
- it "isn't usable on Windows" do
38
- described_class.should_not be_usable
39
- end
40
- end
41
- end
@@ -1,68 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Listen::Adapters::Polling do
4
- subject { described_class.new('dir') }
5
-
6
- it_should_behave_like 'a filesystem adapter'
7
-
8
- describe '#initialize' do
9
- it 'sets the latency to the default polling one' do
10
- subject.latency.should eq Listen::Adapters::DEFAULT_POLLING_LATENCY
11
- end
12
- end
13
-
14
- describe '#poll' do
15
- let(:listener) { mock(Listen::Listener) }
16
- let(:callback) { lambda { |changed_dirs, options| @called = true; listener.on_change(changed_dirs, options) } }
17
-
18
- after { subject.stop }
19
-
20
- context 'with one directory to watch' do
21
- subject { Listen::Adapters::Polling.new('dir', {}, &callback) }
22
-
23
- it 'calls listener.on_change' do
24
- listener.should_receive(:on_change).at_least(1).times.with(['dir'], :recursive => true)
25
- subject.start(false)
26
- subject.wait_for_callback
27
- end
28
-
29
- it 'calls listener.on_change continuously' do
30
- subject.latency = 0.001
31
- listener.should_receive(:on_change).at_least(10).times.with(['dir'], :recursive => true)
32
- subject.start(false)
33
- 10.times { subject.wait_for_callback }
34
- end
35
-
36
- it "doesn't call listener.on_change if paused" do
37
- subject.paused = true
38
- subject.start(false)
39
- subject.wait_for_callback
40
- @called.should be_nil
41
- end
42
- end
43
-
44
- context 'with multiple directories to watch' do
45
- subject { Listen::Adapters::Polling.new(%w{dir1 dir2}, {}, &callback) }
46
-
47
- it 'calls listener.on_change' do
48
- listener.should_receive(:on_change).at_least(1).times.with(%w{dir1 dir2}, :recursive => true)
49
- subject.start(false)
50
- subject.wait_for_callback
51
- end
52
-
53
- it 'calls listener.on_change continuously' do
54
- subject.latency = 0.001
55
- listener.should_receive(:on_change).at_least(10).times.with(%w{dir1 dir2}, :recursive => true)
56
- subject.start(false)
57
- 10.times { subject.wait_for_callback }
58
- end
59
-
60
- it "doesn't call listener.on_change if paused" do
61
- subject.paused = true
62
- subject.start(false)
63
- subject.wait_for_callback
64
- @called.should be_nil
65
- end
66
- end
67
- end
68
- end
@@ -1,24 +0,0 @@
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
@@ -1,1138 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Listen::DirectoryRecord do
4
- let(:base_directory) { File.dirname(__FILE__) }
5
-
6
- subject { described_class.new(base_directory) }
7
-
8
- describe '.generate_default_ignoring_patterns' do
9
- it 'creates regexp patterns from the default ignored directories and extensions' do
10
- described_class.generate_default_ignoring_patterns.should include(
11
- %r{^(?:\.rbx|\.bundle|\.git|\.svn|log|tmp|vendor)/},
12
- %r{(?:\.DS_Store)$}
13
- )
14
- end
15
-
16
- it 'memoizes the generated results' do
17
- described_class.generate_default_ignoring_patterns.should equal described_class.generate_default_ignoring_patterns
18
- end
19
- end
20
-
21
- describe '#initialize' do
22
- it 'sets the base directory' do
23
- subject.directory.should eq base_directory
24
- end
25
-
26
- it 'sets the default ignoring patterns' do
27
- subject.ignoring_patterns.should =~ described_class.generate_default_ignoring_patterns
28
- end
29
-
30
- it 'sets the default filtering patterns' do
31
- subject.filtering_patterns.should eq []
32
- end
33
-
34
- it 'raises an error when the passed path does not exist' do
35
- expect { described_class.new('no way I exist') }.to raise_error(ArgumentError)
36
- end
37
-
38
- it 'raises an error when the passed path is not a directory' do
39
- expect { described_class.new(__FILE__) }.to raise_error(ArgumentError)
40
- end
41
- end
42
-
43
- describe '#ignore' do
44
- it 'adds the passed paths to the list of ignoted paths in the record' do
45
- subject.ignore(%r{^\.old/}, %r{\.pid$})
46
- subject.ignoring_patterns.should include(%r{^\.old/}, %r{\.pid$})
47
- end
48
- end
49
-
50
- describe '#filter' do
51
- it 'adds the passed regexps to the list of filters that determine the stored paths' do
52
- subject.filter(%r{\.(?:jpe?g|gif|png)}, %r{\.(?:mp3|ogg|a3c)})
53
- subject.filtering_patterns.should include(%r{\.(?:jpe?g|gif|png)}, %r{\.(?:mp3|ogg|a3c)})
54
- end
55
- end
56
-
57
- describe '#ignored?' do
58
- before { subject.stub(:relative_to_base) { |path| path } }
59
-
60
- it 'tests paths relative to the base directory' do
61
- subject.should_receive(:relative_to_base).with('file.txt')
62
- subject.ignored?('file.txt')
63
- end
64
-
65
- it 'returns true when the passed path is a default ignored path' do
66
- subject.ignored?('tmp/some_process.pid').should be_true
67
- subject.ignored?('dir/.DS_Store').should be_true
68
- subject.ignored?('.git/config').should be_true
69
- end
70
-
71
- it 'returns false when the passed path is not a default ignored path' do
72
- subject.ignored?('nested/tmp/some_process.pid').should be_false
73
- subject.ignored?('nested/.git').should be_false
74
- subject.ignored?('dir/.DS_Store/file').should be_false
75
- subject.ignored?('file.git').should be_false
76
- end
77
-
78
- it 'returns true when the passed path is ignored' do
79
- subject.ignore(%r{\.pid$})
80
- subject.ignored?('dir/some_process.pid').should be_true
81
- end
82
-
83
- it 'returns false when the passed path is not ignored' do
84
- subject.ignore(%r{\.pid$})
85
- subject.ignored?('dir/some_file.txt').should be_false
86
- end
87
- end
88
-
89
- describe '#filtered?' do
90
- before { subject.stub(:relative_to_base) { |path| path } }
91
-
92
- context 'when no filtering patterns are set' do
93
- it 'returns true for any path' do
94
- subject.filtered?('file.txt').should be_true
95
- end
96
- end
97
-
98
- context 'when filtering patterns are set' do
99
- before { subject.filter(%r{\.(?:jpe?g|gif|png)}) }
100
-
101
- it 'tests paths relative to the base directory' do
102
- subject.should_receive(:relative_to_base).with('file.txt')
103
- subject.filtered?('file.txt')
104
- end
105
-
106
- it 'returns true when the passed path is filtered' do
107
- subject.filter(%r{\.(?:jpe?g|gif|png)})
108
- subject.filtered?('dir/picture.jpeg').should be_true
109
- end
110
-
111
- it 'returns false when the passed path is not filtered' do
112
- subject.filter(%r{\.(?:jpe?g|gif|png)})
113
- subject.filtered?('dir/song.mp3').should be_false
114
- end
115
- end
116
- end
117
-
118
- describe '#build' do
119
- it 'stores all files' do
120
- fixtures do |path|
121
- touch 'file.rb'
122
- mkdir 'a_directory'
123
- touch 'a_directory/file.txt'
124
-
125
- record = described_class.new(path)
126
- record.build
127
-
128
- record.paths[path]['file.rb'].type.should eq 'File'
129
- record.paths[path]['a_directory'].type.should eq 'Dir'
130
- record.paths["#{path}/a_directory"]['file.txt'].type.should eq 'File'
131
- end
132
- end
133
-
134
- context 'with ignored path set' do
135
- it 'does not store ignored directory or its childs' do
136
- fixtures do |path|
137
- mkdir 'ignored_directory'
138
- mkdir 'ignored_directory/child_directory'
139
- touch 'ignored_directory/file.txt'
140
-
141
- record = described_class.new(path)
142
- record.ignore %r{^ignored_directory/}
143
- record.build
144
-
145
- record.paths[path]['/a_ignored_directory'].should be_nil
146
- record.paths["#{path}/a_ignored_directory"]['child_directory'].should be_nil
147
- record.paths["#{path}/a_ignored_directory"]['file.txt'].should be_nil
148
- end
149
- end
150
-
151
- it 'does not store ignored files' do
152
- fixtures do |path|
153
- touch 'ignored_file.rb'
154
-
155
- record = described_class.new(path)
156
- record.ignore %r{^ignored_file.rb$}
157
- record.build
158
-
159
- record.paths[path]['ignored_file.rb'].should be_nil
160
- end
161
- end
162
- end
163
-
164
- context 'with filters set' do
165
- it 'only stores filterd files' do
166
- fixtures do |path|
167
- touch 'file.rb'
168
- touch 'file.zip'
169
- mkdir 'a_directory'
170
- touch 'a_directory/file.txt'
171
- touch 'a_directory/file.rb'
172
-
173
- record = described_class.new(path)
174
- record.filter(/\.txt$/, /.*\.zip/)
175
- record.build
176
-
177
- record.paths[path]['file.rb'].should be_nil
178
- record.paths[path]['file.zip'].type.should eq 'File'
179
- record.paths[path]['a_directory'].type.should eq 'Dir'
180
- record.paths["#{path}/a_directory"]['file.txt'].type.should eq 'File'
181
- record.paths["#{path}/a_directory"]['file.rb'].should be_nil
182
- end
183
- end
184
- end
185
- end
186
-
187
- describe '#relative_to_base' do
188
- it 'removes the path of the base-directory from the passed path' do
189
- path = 'dir/to/app/file.rb'
190
- subject.relative_to_base(File.join(base_directory, path)).should eq path
191
- end
192
-
193
- it 'returns nil when the passed path is not inside the base-directory' do
194
- subject.relative_to_base('/tmp/some_random_path').should be_nil
195
- end
196
-
197
- context 'when containing regexp characters in the base directory' do
198
- before do
199
- fixtures do |path|
200
- mkdir 'a_directory$'
201
- @dir = described_class.new(path + '/a_directory$')
202
- @dir.build
203
- end
204
- end
205
-
206
- it 'removes the path of the base-directory from the passed path' do
207
- path = 'dir/to/app/file.rb'
208
- @dir.relative_to_base(File.join(@dir.directory, path)).should eq path
209
- end
210
-
211
- it 'returns nil when the passed path is not inside the base-directory' do
212
- @dir.relative_to_base('/tmp/some_random_path').should be_nil
213
- end
214
- end
215
- end
216
-
217
- describe '#fetch_changes' do
218
- context 'with single file changes' do
219
- context 'when a file is created' do
220
- it 'detects the added file' do
221
- fixtures do |path|
222
- modified, added, removed = changes(path) do
223
- touch 'new_file.rb'
224
- end
225
-
226
- added.should =~ %w(new_file.rb)
227
- modified.should be_empty
228
- removed.should be_empty
229
- end
230
- end
231
-
232
- it 'stores the added file in the record' do
233
- fixtures do |path|
234
- changes(path) do
235
- @record.paths.should be_empty
236
-
237
- touch 'new_file.rb'
238
- end
239
-
240
- @record.paths[path]['new_file.rb'].should_not be_nil
241
- end
242
- end
243
-
244
- context 'given a new created directory' do
245
- it 'detects the added file' do
246
- fixtures do |path|
247
- modified, added, removed = changes(path) do
248
- mkdir 'a_directory'
249
- touch 'a_directory/new_file.rb'
250
- end
251
-
252
- added.should =~ %w(a_directory/new_file.rb)
253
- modified.should be_empty
254
- removed.should be_empty
255
- end
256
- end
257
-
258
- it 'stores the added directory and file in the record' do
259
- fixtures do |path|
260
- changes(path) do
261
- @record.paths.should be_empty
262
-
263
- mkdir 'a_directory'
264
- touch 'a_directory/new_file.rb'
265
- end
266
-
267
- @record.paths[path]['a_directory'].should_not be_nil
268
- @record.paths["#{path}/a_directory"]['new_file.rb'].should_not be_nil
269
- end
270
- end
271
- end
272
-
273
- context 'given an existing directory' do
274
- context 'with recursive option set to true' do
275
- it 'detects the added file' do
276
- fixtures do |path|
277
- mkdir 'a_directory'
278
-
279
- modified, added, removed = changes(path, :recursive => true) do
280
- touch 'a_directory/new_file.rb'
281
- end
282
-
283
- added.should =~ %w(a_directory/new_file.rb)
284
- modified.should be_empty
285
- removed.should be_empty
286
- end
287
- end
288
-
289
- context 'with an ignored directory' do
290
- it "doesn't detect the added file" do
291
- fixtures do |path|
292
- mkdir 'ignored_directory'
293
-
294
- modified, added, removed = changes(path, :ignore => %r{^ignored_directory/}, :recursive => true) do
295
- touch 'ignored_directory/new_file.rb'
296
- end
297
-
298
- added.should be_empty
299
- modified.should be_empty
300
- removed.should be_empty
301
- end
302
- end
303
-
304
- it "doesn't detect the added file when it's asked to fetch the changes of the ignored directory"do
305
- fixtures do |path|
306
- mkdir 'ignored_directory'
307
-
308
- modified, added, removed = changes(path, :paths => ["#{path}/ignored_directory"], :ignore => %r{^ignored_directory/}, :recursive => true) do
309
- touch 'ignored_directory/new_file.rb'
310
- end
311
-
312
- added.should be_empty
313
- modified.should be_empty
314
- removed.should be_empty
315
- end
316
- end
317
- end
318
- end
319
-
320
- context 'with recursive option set to false' do
321
- it "doesn't detect deeply-nested added files" do
322
- fixtures do |path|
323
- mkdir 'a_directory'
324
-
325
- modified, added, removed = changes(path, :recursive => false) do
326
- touch 'a_directory/new_file.rb'
327
- end
328
-
329
- added.should be_empty
330
- modified.should be_empty
331
- removed.should be_empty
332
- end
333
- end
334
- end
335
- end
336
-
337
- context 'given a directory with subdirectories' do
338
- it 'detects the added file' do
339
- fixtures do |path|
340
- mkdir_p 'a_directory/subdirectory'
341
-
342
- modified, added, removed = changes(path, :recursive => true) do
343
- touch 'a_directory/subdirectory/new_file.rb'
344
- end
345
-
346
- added.should =~ %w(a_directory/subdirectory/new_file.rb)
347
- modified.should be_empty
348
- removed.should be_empty
349
- end
350
- end
351
-
352
- context 'with an ignored directory' do
353
- it "doesn't detect added files in neither the directory nor the subdirectory" do
354
- fixtures do |path|
355
- mkdir_p 'ignored_directory/subdirectory'
356
-
357
- modified, added, removed = changes(path, :ignore => %r{^ignored_directory/}, :recursive => true) do
358
- touch 'ignored_directory/new_file.rb'
359
- touch 'ignored_directory/subdirectory/new_file.rb'
360
- end
361
-
362
- added.should be_empty
363
- modified.should be_empty
364
- removed.should be_empty
365
- end
366
- end
367
- end
368
- end
369
- end
370
-
371
- context 'when a file is modified' do
372
- it 'detects the modified file' do
373
- fixtures do |path|
374
- touch 'existing_file.txt'
375
-
376
- modified, added, removed = changes(path) do
377
- sleep 1.5 # make a difference in the mtime of the file
378
- touch 'existing_file.txt'
379
- end
380
-
381
- added.should be_empty
382
- modified.should =~ %w(existing_file.txt)
383
- removed.should be_empty
384
- end
385
- end
386
-
387
- context 'during the same second at which we are checking for changes' do
388
- before { ensure_same_second }
389
-
390
- # The following test can only be run on systems that report
391
- # modification times in milliseconds.
392
- it 'always detects the modified file the first time', :if => described_class::HIGH_PRECISION_SUPPORTED do
393
- fixtures do |path|
394
- touch 'existing_file.txt'
395
-
396
- modified, added, removed = changes(path) do
397
- sleep 0.3 # make sure the mtime is changed a bit
398
- touch 'existing_file.txt'
399
- end
400
-
401
- added.should be_empty
402
- modified.should =~ %w(existing_file.txt)
403
- removed.should be_empty
404
- end
405
- end
406
-
407
- context 'when a file is created and then checked for modifications at the same second - #27' do
408
- # This issue was the result of checking a file for content changes when
409
- # the mtime and the checking time are the same. In this case there
410
- # is no checksum saved, so the file was reported as being changed.
411
- it ' does not report any changes' do
412
- fixtures do |path|
413
- touch 'a_file.rb'
414
-
415
- modified, added, removed = changes(path)
416
-
417
- added.should be_empty
418
- modified.should be_empty
419
- removed.should be_empty
420
- end
421
- end
422
- end
423
-
424
- it "doesn't detects the modified file the second time if the content haven't changed" do
425
- fixtures do |path|
426
- touch 'existing_file.txt'
427
-
428
- changes(path) do
429
- touch 'existing_file.txt'
430
- end
431
-
432
- modified, added, removed = changes(path, :use_last_record => true) do
433
- touch 'existing_file.txt'
434
- end
435
-
436
- added.should be_empty
437
- modified.should be_empty
438
- removed.should be_empty
439
- end
440
- end
441
-
442
- it 'detects the modified file the second time if the content have changed' do
443
- fixtures do |path|
444
- touch 'existing_file.txt'
445
-
446
- changes(path) do
447
- touch 'existing_file.txt'
448
- end
449
-
450
- modified, added, removed = changes(path, :use_last_record => true) do
451
- open('existing_file.txt', 'w') { |f| f.write('foo') }
452
- end
453
-
454
- added.should be_empty
455
- modified.should =~ %w(existing_file.txt)
456
- removed.should be_empty
457
- end
458
- end
459
- end
460
-
461
- context 'given a hidden file' do
462
- it 'detects the modified file' do
463
- fixtures do |path|
464
- touch '.hidden'
465
-
466
- modified, added, removed = changes(path) do
467
- small_time_difference
468
- touch '.hidden'
469
- end
470
-
471
- added.should be_empty
472
- modified.should =~ %w(.hidden)
473
- removed.should be_empty
474
- end
475
- end
476
- end
477
-
478
- context 'given a file mode change' do
479
- it 'does not detect the mode change' do
480
- fixtures do |path|
481
- touch 'run.rb'
482
- sleep 1.5 # make a difference in the mtime of the file
483
-
484
- modified, added, removed = changes(path) do
485
- chmod 0777, 'run.rb'
486
- end
487
-
488
- added.should be_empty
489
- modified.should be_empty
490
- removed.should be_empty
491
- end
492
- end
493
- end
494
-
495
- context 'given an existing directory' do
496
- context 'with recursive option set to true' do
497
- it 'detects the modified file' do
498
- fixtures do |path|
499
- mkdir 'a_directory'
500
- touch 'a_directory/existing_file.txt'
501
-
502
- modified, added, removed = changes(path, :recursive => true) do
503
- small_time_difference
504
- touch 'a_directory/existing_file.txt'
505
- end
506
-
507
- added.should be_empty
508
- modified.should =~ %w(a_directory/existing_file.txt)
509
- removed.should be_empty
510
- end
511
- end
512
- end
513
-
514
- context 'with recursive option set to false' do
515
- it "doesn't detects the modified file" do
516
- fixtures do |path|
517
- mkdir 'a_directory'
518
- touch 'a_directory/existing_file.txt'
519
-
520
- modified, added, removed = changes(path, :recursive => false) do
521
- small_time_difference
522
- touch 'a_directory/existing_file.txt'
523
- end
524
-
525
- added.should be_empty
526
- modified.should be_empty
527
- removed.should be_empty
528
- end
529
- end
530
- end
531
- end
532
-
533
- context 'given a directory with subdirectories' do
534
- it 'detects the modified file' do
535
- fixtures do |path|
536
- mkdir_p 'a_directory/subdirectory'
537
- touch 'a_directory/subdirectory/existing_file.txt'
538
-
539
- modified, added, removed = changes(path, :recursive => true) do
540
- small_time_difference
541
- touch 'a_directory/subdirectory/existing_file.txt'
542
- end
543
-
544
- added.should be_empty
545
- modified.should =~ %w(a_directory/subdirectory/existing_file.txt)
546
- removed.should be_empty
547
- end
548
- end
549
-
550
- context 'with an ignored subdirectory' do
551
- it "doesn't detect the modified files in neither the directory nor the subdirectory" do
552
- fixtures do |path|
553
- mkdir_p 'ignored_directory/subdirectory'
554
- touch 'ignored_directory/existing_file.txt'
555
- touch 'ignored_directory/subdirectory/existing_file.txt'
556
-
557
- modified, added, removed = changes(path, :ignore => %r{^ignored_directory/}, :recursive => true) do
558
- touch 'ignored_directory/existing_file.txt'
559
- touch 'ignored_directory/subdirectory/existing_file.txt'
560
- end
561
-
562
- added.should be_empty
563
- modified.should be_empty
564
- removed.should be_empty
565
- end
566
- end
567
- end
568
- end
569
- end
570
-
571
- context 'when a file is moved' do
572
- it 'detects the file movement' do
573
- fixtures do |path|
574
- touch 'move_me.txt'
575
-
576
- modified, added, removed = changes(path) do
577
- mv 'move_me.txt', 'new_name.txt'
578
- end
579
-
580
- added.should =~ %w(new_name.txt)
581
- modified.should be_empty
582
- removed.should =~ %w(move_me.txt)
583
- end
584
- end
585
-
586
- context 'given an existing directory' do
587
- context 'with recursive option set to true' do
588
- it 'detects the file movement into the directory' do
589
- fixtures do |path|
590
- mkdir 'a_directory'
591
- touch 'move_me.txt'
592
-
593
- modified, added, removed = changes(path, :recursive => true) do
594
- mv 'move_me.txt', 'a_directory/move_me.txt'
595
- end
596
-
597
- added.should =~ %w(a_directory/move_me.txt)
598
- modified.should be_empty
599
- removed.should =~ %w(move_me.txt)
600
- end
601
- end
602
-
603
- it 'detects a file movement out of the directory' do
604
- fixtures do |path|
605
- mkdir 'a_directory'
606
- touch 'a_directory/move_me.txt'
607
-
608
- modified, added, removed = changes(path, :recursive => true) do
609
- mv 'a_directory/move_me.txt', 'i_am_here.txt'
610
- end
611
-
612
- added.should =~ %w(i_am_here.txt)
613
- modified.should be_empty
614
- removed.should =~ %w(a_directory/move_me.txt)
615
- end
616
- end
617
-
618
- it 'detects a file movement between two directories' do
619
- fixtures do |path|
620
- mkdir 'from_directory'
621
- touch 'from_directory/move_me.txt'
622
- mkdir 'to_directory'
623
-
624
- modified, added, removed = changes(path, :recursive => true) do
625
- mv 'from_directory/move_me.txt', 'to_directory/move_me.txt'
626
- end
627
-
628
- added.should =~ %w(to_directory/move_me.txt)
629
- modified.should be_empty
630
- removed.should =~ %w(from_directory/move_me.txt)
631
- end
632
- end
633
- end
634
-
635
- context 'with recursive option set to false' do
636
- it "doesn't detect the file movement into the directory" do
637
- fixtures do |path|
638
- mkdir 'a_directory'
639
- touch 'move_me.txt'
640
-
641
- modified, added, removed = changes(path, :recursive => false) do
642
- mv 'move_me.txt', 'a_directory/move_me.txt'
643
- end
644
-
645
- added.should be_empty
646
- modified.should be_empty
647
- removed.should =~ %w(move_me.txt)
648
- end
649
- end
650
-
651
- it "doesn't detect a file movement out of the directory" do
652
- fixtures do |path|
653
- mkdir 'a_directory'
654
- touch 'a_directory/move_me.txt'
655
-
656
- modified, added, removed = changes(path, :recursive => false) do
657
- mv 'a_directory/move_me.txt', 'i_am_here.txt'
658
- end
659
-
660
- added.should =~ %w(i_am_here.txt)
661
- modified.should be_empty
662
- removed.should be_empty
663
- end
664
- end
665
-
666
- it "doesn't detect a file movement between two directories" do
667
- fixtures do |path|
668
- mkdir 'from_directory'
669
- touch 'from_directory/move_me.txt'
670
- mkdir 'to_directory'
671
-
672
- modified, added, removed = changes(path, :recursive => false) do
673
- mv 'from_directory/move_me.txt', 'to_directory/move_me.txt'
674
- end
675
-
676
- added.should be_empty
677
- modified.should be_empty
678
- removed.should be_empty
679
- end
680
- end
681
-
682
- context 'given a directory with subdirectories' do
683
- it 'detects a file movement between two subdirectories' do
684
- fixtures do |path|
685
- mkdir_p 'a_directory/subdirectory'
686
- mkdir_p 'b_directory/subdirectory'
687
- touch 'a_directory/subdirectory/move_me.txt'
688
-
689
- modified, added, removed = changes(path, :recursive => true) do
690
- mv 'a_directory/subdirectory/move_me.txt', 'b_directory/subdirectory'
691
- end
692
-
693
- added.should =~ %w(b_directory/subdirectory/move_me.txt)
694
- modified.should be_empty
695
- removed.should =~ %w(a_directory/subdirectory/move_me.txt)
696
- end
697
- end
698
-
699
- context 'with an ignored subdirectory' do
700
- it "doesn't detect the file movement between subdirectories" do
701
- fixtures do |path|
702
- mkdir_p 'a_ignored_directory/subdirectory'
703
- mkdir_p 'b_ignored_directory/subdirectory'
704
- touch 'a_ignored_directory/subdirectory/move_me.txt'
705
-
706
- modified, added, removed = changes(path, :ignore => %r{^(?:a|b)_ignored_directory/}, :recursive => true) do
707
- mv 'a_ignored_directory/subdirectory/move_me.txt', 'b_ignored_directory/subdirectory'
708
- end
709
-
710
- added.should be_empty
711
- modified.should be_empty
712
- removed.should be_empty
713
- end
714
- end
715
- end
716
- end
717
-
718
- context 'with all paths passed as params' do
719
- it 'detects the file movement into the directory' do
720
- fixtures do |path|
721
- mkdir 'a_directory'
722
- touch 'move_me.txt'
723
-
724
- modified, added, removed = changes(path, :recursive => false, :paths => [path, "#{path}/a_directory"]) do
725
- mv 'move_me.txt', 'a_directory/move_me.txt'
726
- end
727
-
728
- added.should =~ %w(a_directory/move_me.txt)
729
- modified.should be_empty
730
- removed.should =~ %w(move_me.txt)
731
- end
732
- end
733
-
734
- it 'detects a file moved outside of a directory' do
735
- fixtures do |path|
736
- mkdir 'a_directory'
737
- touch 'a_directory/move_me.txt'
738
-
739
- modified, added, removed = changes(path, :recursive => false, :paths => [path, "#{path}/a_directory"]) do
740
- mv 'a_directory/move_me.txt', 'i_am_here.txt'
741
- end
742
-
743
- added.should =~ %w(i_am_here.txt)
744
- modified.should be_empty
745
- removed.should =~ %w(a_directory/move_me.txt)
746
- end
747
- end
748
-
749
- it 'detects a file movement between two directories' do
750
- fixtures do |path|
751
- mkdir 'from_directory'
752
- touch 'from_directory/move_me.txt'
753
- mkdir 'to_directory'
754
-
755
- modified, added, removed = changes(path, :recursive => false, :paths => [path, "#{path}/from_directory", "#{path}/to_directory"]) do
756
- mv 'from_directory/move_me.txt', 'to_directory/move_me.txt'
757
- end
758
-
759
- added.should =~ %w(to_directory/move_me.txt)
760
- modified.should be_empty
761
- removed.should =~ %w(from_directory/move_me.txt)
762
- end
763
- end
764
- end
765
- end
766
- end
767
- end
768
-
769
- context 'when a file is deleted' do
770
- it 'detects the file removal' do
771
- fixtures do |path|
772
- touch 'unnecessary.txt'
773
-
774
- modified, added, removed = changes(path) do
775
- rm 'unnecessary.txt'
776
- end
777
-
778
- added.should be_empty
779
- modified.should be_empty
780
- removed.should =~ %w(unnecessary.txt)
781
- end
782
- end
783
-
784
- it "deletes the file from the record" do
785
- fixtures do |path|
786
- touch 'unnecessary.txt'
787
-
788
- changes(path) do
789
- @record.paths[path]['unnecessary.txt'].should_not be_nil
790
-
791
- rm 'unnecessary.txt'
792
- end
793
-
794
- @record.paths[path]['unnecessary.txt'].should be_nil
795
- end
796
- end
797
-
798
- it "deletes the path from the paths checksums" do
799
- fixtures do |path|
800
- touch 'unnecessary.txt'
801
-
802
- changes(path) do
803
- @record.sha1_checksums["#{path}/unnecessary.txt"] = 'foo'
804
-
805
- rm 'unnecessary.txt'
806
- end
807
-
808
- @record.sha1_checksums["#{path}/unnecessary.txt"].should be_nil
809
- end
810
- end
811
-
812
- context 'given an existing directory' do
813
- context 'with recursive option set to true' do
814
- it 'detects the file removal' do
815
- fixtures do |path|
816
- mkdir 'a_directory'
817
- touch 'a_directory/do_not_use.rb'
818
-
819
- modified, added, removed = changes(path, :recursive => true) do
820
- rm 'a_directory/do_not_use.rb'
821
- end
822
-
823
- added.should be_empty
824
- modified.should be_empty
825
- removed.should =~ %w(a_directory/do_not_use.rb)
826
- end
827
- end
828
- end
829
-
830
- context 'with recursive option set to false' do
831
- it "doesn't detect the file removal" do
832
- fixtures do |path|
833
- mkdir 'a_directory'
834
- touch 'a_directory/do_not_use.rb'
835
-
836
- modified, added, removed = changes(path, :recursive => false) do
837
- rm 'a_directory/do_not_use.rb'
838
- end
839
-
840
- added.should be_empty
841
- modified.should be_empty
842
- removed.should be_empty
843
- end
844
- end
845
- end
846
- end
847
-
848
- context 'given a directory with subdirectories' do
849
- it 'detects the file removal in subdirectories' do
850
- fixtures do |path|
851
- mkdir_p 'a_directory/subdirectory'
852
- touch 'a_directory/subdirectory/do_not_use.rb'
853
-
854
- modified, added, removed = changes(path, :recursive => true) do
855
- rm 'a_directory/subdirectory/do_not_use.rb'
856
- end
857
-
858
- added.should be_empty
859
- modified.should be_empty
860
- removed.should =~ %w(a_directory/subdirectory/do_not_use.rb)
861
- end
862
- end
863
-
864
- context 'with an ignored subdirectory' do
865
- it "doesn't detect files removals in neither the directory nor its subdirectories" do
866
- fixtures do |path|
867
- mkdir_p 'ignored_directory/subdirectory'
868
- touch 'ignored_directory/do_not_use.rb'
869
- touch 'ignored_directory/subdirectory/do_not_use.rb'
870
-
871
- modified, added, removed = changes(path, :ignore => %r{^ignored_directory/}, :recursive => true) do
872
- rm 'ignored_directory/do_not_use.rb'
873
- rm 'ignored_directory/subdirectory/do_not_use.rb'
874
- end
875
-
876
- added.should be_empty
877
- modified.should be_empty
878
- removed.should be_empty
879
- end
880
- end
881
- end
882
- end
883
- end
884
- end
885
-
886
- context 'multiple file operations' do
887
- it 'detects the added files' do
888
- fixtures do |path|
889
- modified, added, removed = changes(path) do
890
- touch 'a_file.rb'
891
- touch 'b_file.rb'
892
- mkdir 'a_directory'
893
- touch 'a_directory/a_file.rb'
894
- touch 'a_directory/b_file.rb'
895
- end
896
-
897
- added.should =~ %w(a_file.rb b_file.rb a_directory/a_file.rb a_directory/b_file.rb)
898
- modified.should be_empty
899
- removed.should be_empty
900
- end
901
- end
902
-
903
- it 'detects the modified files' do
904
- fixtures do |path|
905
- touch 'a_file.rb'
906
- touch 'b_file.rb'
907
- mkdir 'a_directory'
908
- touch 'a_directory/a_file.rb'
909
- touch 'a_directory/b_file.rb'
910
-
911
- small_time_difference
912
-
913
- modified, added, removed = changes(path) do
914
- touch 'b_file.rb'
915
- touch 'a_directory/a_file.rb'
916
- end
917
-
918
- added.should be_empty
919
- modified.should =~ %w(b_file.rb a_directory/a_file.rb)
920
- removed.should be_empty
921
- end
922
- end
923
-
924
- it 'detects the removed files' do
925
- fixtures do |path|
926
- touch 'a_file.rb'
927
- touch 'b_file.rb'
928
- mkdir 'a_directory'
929
- touch 'a_directory/a_file.rb'
930
- touch 'a_directory/b_file.rb'
931
-
932
- modified, added, removed = changes(path) do
933
- rm 'b_file.rb'
934
- rm 'a_directory/a_file.rb'
935
- end
936
-
937
- added.should be_empty
938
- modified.should be_empty
939
- removed.should =~ %w(b_file.rb a_directory/a_file.rb)
940
- end
941
- end
942
- end
943
-
944
- context 'single directory operations' do
945
- it 'detects a moved directory' do
946
- fixtures do |path|
947
- mkdir 'a_directory'
948
- touch 'a_directory/a_file.rb'
949
- touch 'a_directory/b_file.rb'
950
-
951
- modified, added, removed = changes(path) do
952
- mv 'a_directory', 'renamed'
953
- end
954
-
955
- added.should =~ %w(renamed/a_file.rb renamed/b_file.rb)
956
- modified.should be_empty
957
- removed.should =~ %w(a_directory/a_file.rb a_directory/b_file.rb)
958
- end
959
- end
960
-
961
- it 'detects a removed directory' do
962
- fixtures do |path|
963
- mkdir 'a_directory'
964
- touch 'a_directory/a_file.rb'
965
- touch 'a_directory/b_file.rb'
966
-
967
- modified, added, removed = changes(path) do
968
- rm_rf 'a_directory'
969
- end
970
-
971
- added.should be_empty
972
- modified.should be_empty
973
- removed.should =~ %w(a_directory/a_file.rb a_directory/b_file.rb)
974
- end
975
- end
976
-
977
- it "deletes the directory from the record" do
978
- fixtures do |path|
979
- mkdir 'a_directory'
980
- touch 'a_directory/file.rb'
981
-
982
- changes(path) do
983
- @record.paths.should have(2).paths
984
- @record.paths[path]['a_directory'].should_not be_nil
985
- @record.paths["#{path}/a_directory"]['file.rb'].should_not be_nil
986
-
987
- rm_rf 'a_directory'
988
- end
989
-
990
- @record.paths.should have(1).paths
991
- @record.paths[path]['a_directory'].should be_nil
992
- @record.paths["#{path}/a_directory"]['file.rb'].should be_nil
993
- end
994
- end
995
-
996
- context 'with nested paths' do
997
- it 'detects removals without crashing - #18' do
998
- fixtures do |path|
999
- mkdir_p 'a_directory/subdirectory'
1000
- touch 'a_directory/subdirectory/do_not_use.rb'
1001
-
1002
- modified, added, removed = changes(path) do
1003
- rm_r 'a_directory'
1004
- end
1005
-
1006
- added.should be_empty
1007
- modified.should be_empty
1008
- removed.should =~ %w(a_directory/subdirectory/do_not_use.rb)
1009
- end
1010
- end
1011
- end
1012
- end
1013
-
1014
- context 'with a path outside the directory for which a record is made' do
1015
- it "skips that path and doesn't check for changes" do
1016
- fixtures do |path|
1017
- modified, added, removed = changes(path, :paths => ['some/where/outside']) do
1018
- @record.should_not_receive(:detect_additions)
1019
- @record.should_not_receive(:detect_modifications_and_removals)
1020
-
1021
- touch 'new_file.rb'
1022
- end
1023
-
1024
- added.should be_empty
1025
- modified.should be_empty
1026
- removed.should be_empty
1027
- end
1028
- end
1029
- end
1030
-
1031
- context 'with the relative_paths option set to false' do
1032
- it 'returns full paths in the changes hash' do
1033
- fixtures do |path|
1034
- touch 'a_file.rb'
1035
- touch 'b_file.rb'
1036
-
1037
- modified, added, removed = changes(path, :relative_paths => false) do
1038
- small_time_difference
1039
- rm 'a_file.rb'
1040
- touch 'b_file.rb'
1041
- touch 'c_file.rb'
1042
- mkdir 'a_directory'
1043
- touch 'a_directory/a_file.rb'
1044
- end
1045
-
1046
- added.should =~ ["#{path}/c_file.rb", "#{path}/a_directory/a_file.rb"]
1047
- modified.should =~ ["#{path}/b_file.rb"]
1048
- removed.should =~ ["#{path}/a_file.rb"]
1049
- end
1050
- end
1051
- end
1052
-
1053
- context 'within a directory containing unreadble paths - #32' do
1054
- it 'detects changes more than a second apart' do
1055
- fixtures do |path|
1056
- touch 'unreadable_file.txt'
1057
- chmod 000, 'unreadable_file.txt'
1058
-
1059
- modified, added, removed = changes(path) do
1060
- sleep 1.1
1061
- touch 'unreadable_file.txt'
1062
- end
1063
-
1064
- added.should be_empty
1065
- modified.should =~ %w(unreadable_file.txt)
1066
- removed.should be_empty
1067
- end
1068
- end
1069
-
1070
- context 'with multiple changes within the same second' do
1071
- before { ensure_same_second }
1072
-
1073
- it 'does not detect changes even if content changes', :unless => described_class::HIGH_PRECISION_SUPPORTED do
1074
- fixtures do |path|
1075
- touch 'unreadable_file.txt'
1076
-
1077
- modified, added, removed = changes(path) do
1078
- open('unreadable_file.txt', 'w') { |f| f.write('foo') }
1079
- chmod 000, 'unreadable_file.txt'
1080
- end
1081
-
1082
- added.should be_empty
1083
- modified.should be_empty
1084
- removed.should be_empty
1085
- end
1086
- end
1087
- end
1088
- end
1089
-
1090
- context 'within a directory containing a removed file - #39' do
1091
- it 'does not raise an exception when hashing a removed file' do
1092
-
1093
- # simulate a race condition where the file is removed after the
1094
- # change event is tracked, but before the hash is calculated
1095
- Digest::SHA1.should_receive(:file).and_raise(Errno::ENOENT)
1096
-
1097
- lambda {
1098
- fixtures do |path|
1099
- file = 'removed_file.txt'
1100
- touch file
1101
- changes(path) { touch file }
1102
- end
1103
- }.should_not raise_error(Errno::ENOENT)
1104
- end
1105
- end
1106
-
1107
- context 'with symlinks' do
1108
- it 'looks at symlinks not their targets' do
1109
- fixtures do |path|
1110
- touch 'target'
1111
- symlink 'target', 'symlink'
1112
-
1113
- record = described_class.new(path)
1114
- record.build
1115
-
1116
- sleep 1
1117
- touch 'target'
1118
-
1119
- record.fetch_changes([path], :relative_paths => true)[:modified].should == ['target']
1120
- end
1121
- end
1122
-
1123
- it 'handles broken symlinks' do
1124
- fixtures do |path|
1125
- symlink 'target', 'symlink'
1126
-
1127
- record = described_class.new(path)
1128
- record.build
1129
-
1130
- sleep 1
1131
- rm 'symlink'
1132
- symlink 'new-target', 'symlink'
1133
- record.fetch_changes([path], :relative_paths => true)
1134
- end
1135
- end
1136
- end
1137
- end
1138
- end