sass 3.1.21 → 3.2.0.alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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