sass 3.4.25 → 3.5.0.pre.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -1
  3. data/README.md +1 -1
  4. data/Rakefile +13 -157
  5. data/VERSION +1 -1
  6. data/VERSION_DATE +1 -1
  7. data/VERSION_NAME +1 -1
  8. data/lib/sass.rb +3 -10
  9. data/lib/sass/cache_stores/filesystem.rb +1 -1
  10. data/lib/sass/css.rb +2 -3
  11. data/lib/sass/engine.rb +46 -32
  12. data/lib/sass/environment.rb +27 -6
  13. data/lib/sass/error.rb +5 -5
  14. data/lib/sass/exec/base.rb +3 -12
  15. data/lib/sass/features.rb +1 -0
  16. data/lib/sass/importers/filesystem.rb +2 -2
  17. data/lib/sass/plugin.rb +1 -1
  18. data/lib/sass/plugin/compiler.rb +21 -51
  19. data/lib/sass/plugin/configuration.rb +1 -1
  20. data/lib/sass/plugin/rack.rb +3 -3
  21. data/lib/sass/plugin/staleness_checker.rb +3 -3
  22. data/lib/sass/railtie.rb +1 -1
  23. data/lib/sass/script.rb +3 -3
  24. data/lib/sass/script/functions.rb +238 -47
  25. data/lib/sass/script/lexer.rb +8 -6
  26. data/lib/sass/script/parser.rb +76 -75
  27. data/lib/sass/script/tree/funcall.rb +35 -30
  28. data/lib/sass/script/tree/list_literal.rb +23 -8
  29. data/lib/sass/script/tree/map_literal.rb +2 -2
  30. data/lib/sass/script/tree/node.rb +2 -10
  31. data/lib/sass/script/tree/operation.rb +16 -50
  32. data/lib/sass/script/value.rb +2 -0
  33. data/lib/sass/script/value/arg_list.rb +1 -1
  34. data/lib/sass/script/value/base.rb +20 -3
  35. data/lib/sass/script/value/callable.rb +25 -0
  36. data/lib/sass/script/value/color.rb +10 -10
  37. data/lib/sass/script/value/function.rb +19 -0
  38. data/lib/sass/script/value/helpers.rb +16 -7
  39. data/lib/sass/script/value/list.rb +33 -12
  40. data/lib/sass/script/value/map.rb +2 -2
  41. data/lib/sass/script/value/number.rb +3 -3
  42. data/lib/sass/script/value/string.rb +12 -5
  43. data/lib/sass/scss/parser.rb +101 -45
  44. data/lib/sass/scss/rx.rb +5 -11
  45. data/lib/sass/scss/static_parser.rb +0 -7
  46. data/lib/sass/selector.rb +4 -0
  47. data/lib/sass/selector/abstract_sequence.rb +5 -5
  48. data/lib/sass/selector/comma_sequence.rb +3 -15
  49. data/lib/sass/selector/pseudo.rb +4 -0
  50. data/lib/sass/selector/sequence.rb +30 -3
  51. data/lib/sass/selector/simple.rb +13 -7
  52. data/lib/sass/selector/simple_sequence.rb +1 -1
  53. data/lib/sass/shared.rb +3 -5
  54. data/lib/sass/source/map.rb +4 -4
  55. data/lib/sass/source/position.rb +4 -4
  56. data/lib/sass/stack.rb +21 -1
  57. data/lib/sass/tree/charset_node.rb +1 -1
  58. data/lib/sass/tree/comment_node.rb +1 -1
  59. data/lib/sass/tree/node.rb +3 -3
  60. data/lib/sass/tree/prop_node.rb +46 -54
  61. data/lib/sass/tree/rule_node.rb +7 -15
  62. data/lib/sass/tree/visitors/check_nesting.rb +1 -1
  63. data/lib/sass/tree/visitors/convert.rb +2 -3
  64. data/lib/sass/tree/visitors/cssize.rb +1 -10
  65. data/lib/sass/tree/visitors/deep_copy.rb +2 -2
  66. data/lib/sass/tree/visitors/perform.rb +23 -12
  67. data/lib/sass/tree/visitors/set_options.rb +1 -1
  68. data/lib/sass/tree/visitors/to_css.rb +46 -12
  69. data/lib/sass/util.rb +16 -321
  70. data/lib/sass/util/multibyte_string_scanner.rb +127 -131
  71. data/lib/sass/util/normalized_map.rb +1 -8
  72. data/lib/sass/version.rb +2 -2
  73. data/test/sass-spec.yml +1 -1
  74. data/test/sass/compiler_test.rb +4 -14
  75. data/test/sass/conversion_test.rb +113 -162
  76. data/test/sass/css2sass_test.rb +17 -19
  77. data/test/sass/css_variable_test.rb +176 -70
  78. data/test/sass/encoding_test.rb +2 -32
  79. data/test/sass/engine_test.rb +114 -65
  80. data/test/sass/extend_test.rb +37 -51
  81. data/test/sass/functions_test.rb +57 -15
  82. data/test/sass/importer_test.rb +2 -2
  83. data/test/sass/more_templates/more1.sass +10 -10
  84. data/test/sass/more_templates/more_import.sass +2 -2
  85. data/test/sass/plugin_test.rb +9 -12
  86. data/test/sass/script_conversion_test.rb +9 -0
  87. data/test/sass/script_test.rb +38 -48
  88. data/test/sass/scss/css_test.rb +5 -19
  89. data/test/sass/scss/scss_test.rb +58 -39
  90. data/test/sass/source_map_test.rb +26 -28
  91. data/test/sass/templates/_partial.sass +1 -1
  92. data/test/sass/templates/basic.sass +10 -10
  93. data/test/sass/templates/bork1.sass +1 -1
  94. data/test/sass/templates/bork5.sass +1 -1
  95. data/test/sass/templates/compact.sass +10 -10
  96. data/test/sass/templates/complex.sass +187 -187
  97. data/test/sass/templates/compressed.sass +10 -10
  98. data/test/sass/templates/expanded.sass +10 -10
  99. data/test/sass/templates/import.sass +2 -2
  100. data/test/sass/templates/importee.sass +3 -3
  101. data/test/sass/templates/mixins.sass +22 -22
  102. data/test/sass/templates/multiline.sass +4 -4
  103. data/test/sass/templates/nested.sass +13 -13
  104. data/test/sass/templates/parent_ref.sass +12 -12
  105. data/test/sass/templates/script.sass +70 -70
  106. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +1 -1
  107. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +2 -2
  108. data/test/sass/templates/subdir/subdir.sass +3 -3
  109. data/test/sass/templates/units.sass +10 -10
  110. data/test/sass/util/multibyte_string_scanner_test.rb +139 -149
  111. data/test/sass/util_test.rb +0 -36
  112. data/test/test_helper.rb +39 -0
  113. metadata +30 -57
  114. data/extra/sass-spec-ref.sh +0 -32
  115. data/lib/sass/deprecation.rb +0 -55
  116. data/lib/sass/script/css_variable_warning.rb +0 -52
  117. data/lib/sass/util/cross_platform_random.rb +0 -19
  118. data/lib/sass/util/ordered_hash.rb +0 -192
  119. data/test/sass/results/import_charset_1_8.css +0 -5
  120. data/test/sass/templates/import_charset_1_8.sass +0 -6
  121. data/vendor/listen/CHANGELOG.md +0 -1
  122. data/vendor/listen/CONTRIBUTING.md +0 -38
  123. data/vendor/listen/Gemfile +0 -20
  124. data/vendor/listen/Guardfile +0 -8
  125. data/vendor/listen/LICENSE +0 -20
  126. data/vendor/listen/README.md +0 -349
  127. data/vendor/listen/Rakefile +0 -5
  128. data/vendor/listen/Vagrantfile +0 -96
  129. data/vendor/listen/lib/listen.rb +0 -54
  130. data/vendor/listen/lib/listen/adapter.rb +0 -327
  131. data/vendor/listen/lib/listen/adapters/bsd.rb +0 -75
  132. data/vendor/listen/lib/listen/adapters/darwin.rb +0 -48
  133. data/vendor/listen/lib/listen/adapters/linux.rb +0 -81
  134. data/vendor/listen/lib/listen/adapters/polling.rb +0 -58
  135. data/vendor/listen/lib/listen/adapters/windows.rb +0 -91
  136. data/vendor/listen/lib/listen/directory_record.rb +0 -406
  137. data/vendor/listen/lib/listen/listener.rb +0 -323
  138. data/vendor/listen/lib/listen/turnstile.rb +0 -32
  139. data/vendor/listen/lib/listen/version.rb +0 -3
  140. data/vendor/listen/listen.gemspec +0 -28
  141. data/vendor/listen/spec/listen/adapter_spec.rb +0 -149
  142. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
  143. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
  144. data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
  145. data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
  146. data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
  147. data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1250
  148. data/vendor/listen/spec/listen/listener_spec.rb +0 -258
  149. data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
  150. data/vendor/listen/spec/listen_spec.rb +0 -67
  151. data/vendor/listen/spec/spec_helper.rb +0 -25
  152. data/vendor/listen/spec/support/adapter_helper.rb +0 -666
  153. data/vendor/listen/spec/support/directory_record_helper.rb +0 -57
  154. data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
  155. data/vendor/listen/spec/support/listeners_helper.rb +0 -179
  156. data/vendor/listen/spec/support/platform_helper.rb +0 -15
@@ -1,258 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Listen::Listener do
4
- let(:adapter) { double(Listen::Adapter, :start => true).as_null_object }
5
- let(:watched_directories) { [File.dirname(__FILE__), File.expand_path('../..', __FILE__)] }
6
-
7
- before do
8
- Listen::Adapter.stub(:select_and_initialize) { adapter }
9
- # Don't build a record of the files inside the base directory.
10
- Listen::DirectoryRecord.any_instance.stub(:build)
11
- Kernel.stub(:warn)
12
- end
13
- subject { described_class.new(watched_directories) }
14
-
15
- it_should_behave_like 'a listener to changes on a file-system'
16
-
17
- describe '#initialize' do
18
- context 'listening to a single directory' do
19
- let(:watched_directory) { File.dirname(__FILE__) }
20
- let(:watched_directories) { nil }
21
- subject { described_class.new(watched_directory) }
22
-
23
- it 'sets the directories' do
24
- subject.directories.should eq [watched_directory]
25
- end
26
-
27
- context 'with no options' do
28
- it 'sets the option for using relative paths in the callback to false' do
29
- subject.instance_variable_get(:@use_relative_paths).should eq false
30
- end
31
- end
32
-
33
- context 'with :relative_paths => false' do
34
- it 'sets the option for using relative paths in the callback to false' do
35
- listener = described_class.new(watched_directory, :relative_paths => false)
36
- listener.instance_variable_get(:@use_relative_paths).should eq false
37
- end
38
- end
39
-
40
- context 'with :relative_paths => true' do
41
- it 'sets the option for using relative paths in the callback to true' do
42
- listener = described_class.new(watched_directory, :relative_paths => true)
43
- listener.instance_variable_get(:@use_relative_paths).should eq true
44
- end
45
- end
46
- end
47
-
48
- context 'listening to multiple directories' do
49
- subject { described_class.new(watched_directories) }
50
-
51
- it 'sets the directories' do
52
- subject.directories.should eq watched_directories
53
- end
54
-
55
- context 'with no options' do
56
- it 'sets the option for using relative paths in the callback to false' do
57
- subject.instance_variable_get(:@use_relative_paths).should eq false
58
- end
59
- end
60
-
61
- context 'with :relative_paths => false' do
62
- it 'sets the option for using relative paths in the callback to false' do
63
- listener = described_class.new(watched_directories, :relative_paths => false)
64
- listener.instance_variable_get(:@use_relative_paths).should eq false
65
- end
66
- end
67
-
68
- context 'with :relative_paths => true' do
69
- it 'warns' do
70
- Kernel.should_receive(:warn).with("[Listen warning]: #{Listen::Listener::RELATIVE_PATHS_WITH_MULTIPLE_DIRECTORIES_WARNING_MESSAGE}")
71
- listener = described_class.new(watched_directories, :relative_paths => true)
72
- end
73
-
74
- it 'sets the option for using relative paths in the callback to false' do
75
- listener = described_class.new(watched_directories, :relative_paths => true)
76
- listener.instance_variable_get(:@use_relative_paths).should eq false
77
- end
78
- end
79
- end
80
-
81
- context 'with a directory' do
82
- let(:watched_directory) { File.dirname(__FILE__) }
83
- it 'converts the passed path into an absolute path - #21' do
84
- described_class.new(File.join(watched_directory, '..')).directories.should eq [File.expand_path('..', watched_directory)]
85
- end
86
- end
87
-
88
- context 'with custom options' do
89
- let(:watched_directory) { File.dirname(__FILE__) }
90
- let(:adapter_class) { double('adapter class') }
91
-
92
- let(:options) do
93
- {
94
- :ignore => /\.ssh/, :filter => [/.*\.rb/, /.*\.md/],
95
- :latency => 0.5, :force_polling => true, :relative_paths => true,
96
- :force_adapter => adapter_class
97
- }
98
- end
99
- subject { described_class.new(watched_directory, options) }
100
-
101
- it 'passes the custom ignored paths to the directory record' do
102
- subject.directories_records.each do |directory_record|
103
- directory_record.ignoring_patterns.should include /\.ssh/
104
- end
105
- end
106
-
107
- it 'passes the custom filters to the directory record' do
108
- subject.directories_records.each do |directory_record|
109
- directory_record.filtering_patterns.should =~ [/.*\.rb/,/.*\.md/]
110
- end
111
- end
112
-
113
- it 'sets adapter_options' do
114
- subject.instance_variable_get(:@adapter_options).should eq(:latency => 0.5, :force_polling => true, :force_adapter => adapter_class)
115
- end
116
- end
117
- end
118
-
119
- describe '#start' do
120
- it 'selects and initializes an adapter' do
121
- Listen::Adapter.should_receive(:select_and_initialize).with(watched_directories, {}) { adapter }
122
- subject.start
123
- end
124
-
125
- it 'builds the directory record' do
126
- subject.directories_records.each do |directory_record|
127
- directory_record.should_receive(:build)
128
- end
129
- subject.start
130
- end
131
- end
132
-
133
- context 'with a started listener' do
134
- before do
135
- subject.stub(:initialize_adapter) { adapter }
136
- subject.start
137
- end
138
-
139
- describe '#unpause' do
140
- it 'rebuilds the directory record' do
141
- subject.directories_records.each do |directory_record|
142
- directory_record.should_receive(:build)
143
- end
144
- subject.unpause
145
- end
146
- end
147
- end
148
-
149
- describe '#ignore'do
150
- it 'delegates the work to the directory record' do
151
- subject.directories_records.each do |directory_record|
152
- directory_record.should_receive(:ignore).with 'some_directory'
153
- end
154
- subject.ignore 'some_directory'
155
- end
156
- end
157
-
158
- describe '#ignore!'do
159
- it 'delegates the work to the directory record' do
160
- subject.directories_records.each do |directory_record|
161
- directory_record.should_receive(:ignore!).with 'some_directory'
162
- end
163
- subject.ignore! 'some_directory'
164
- end
165
- end
166
-
167
- describe '#filter' do
168
- it 'delegates the work to the directory record' do
169
- subject.directories_records.each do |directory_record|
170
- directory_record.should_receive(:filter).with /\.txt$/
171
- end
172
- subject.filter /\.txt$/
173
- end
174
- end
175
-
176
- describe '#filter!' do
177
- it 'delegates the work to the directory record' do
178
- subject.directories_records.each do |directory_record|
179
- directory_record.should_receive(:filter!).with /\.txt$/
180
- end
181
- subject.filter! /\.txt$/
182
- end
183
- end
184
-
185
- describe '#on_change' do
186
- let(:directories) { %w{dir1 dir2 dir3} }
187
- let(:changes) { {:modified => [], :added => [], :removed => []} }
188
- let(:callback) { Proc.new { @called = true } }
189
-
190
- before do
191
- @called = false
192
- subject.stub(:fetch_records_changes => changes)
193
- end
194
-
195
- it 'fetches the changes of all directories records' do
196
- subject.unstub(:fetch_records_changes)
197
-
198
- subject.directories_records.each do |record|
199
- record.should_receive(:fetch_changes).with(directories, an_instance_of(Hash)).and_return(changes)
200
- end
201
- subject.on_change(directories)
202
- end
203
-
204
- context "with a callback raising an exception" do
205
- let(:callback) { Proc.new { raise 'foo' } }
206
-
207
- before do
208
- subject.change(&callback)
209
- subject.stub(:fetch_records_changes => { :modified => ['foo'], :added => [], :removed => [] } )
210
- end
211
-
212
- it "stops the adapter and warns" do
213
- Kernel.should_receive(:warn).with("[Listen warning]: Change block raise an execption: foo")
214
- Kernel.should_receive(:warn).with(/^Backtrace:.*/)
215
- subject.on_change(directories)
216
- end
217
-
218
- end
219
-
220
- context 'with no changes to report' do
221
- if RUBY_VERSION[/^1.8/]
222
- it 'does not run the callback' do
223
- subject.change(&callback)
224
- subject.on_change(directories)
225
- @called.should be_false
226
- end
227
- else
228
- it 'does not run the callback' do
229
- callback.should_not_receive(:call)
230
- subject.change(&callback)
231
- subject.on_change(directories)
232
- end
233
- end
234
- end
235
-
236
- context 'with changes to report' do
237
- let(:changes) do
238
- {
239
- :modified => %w{path1}, :added => [], :removed => %w{path2}
240
- }
241
- end
242
-
243
- if RUBY_VERSION[/^1.8/]
244
- it 'runs the callback passing it the changes' do
245
- subject.change(&callback)
246
- subject.on_change(directories)
247
- @called.should be_true
248
- end
249
- else
250
- it 'runs the callback passing it the changes' do
251
- callback.should_receive(:call).with(changes[:modified], changes[:added], changes[:removed])
252
- subject.change(&callback)
253
- subject.on_change(directories)
254
- end
255
- end
256
- end
257
- end
258
- end
@@ -1,56 +0,0 @@
1
- require 'spec_helper'
2
-
3
- def run_in_two_threads(proc1, proc2)
4
- t1 = Thread.new &proc1
5
- sleep test_latency # t1 must run before t2
6
- t2 = Thread.new { proc2.call; Thread.kill t1 }
7
- t2.join(test_latency * 2)
8
- ensure
9
- Thread.kill t1 if t1
10
- Thread.kill t2 if t2
11
- end
12
-
13
- describe Listen::Turnstile do
14
- before { @called = false }
15
-
16
- describe '#wait' do
17
- context 'without a signal' do
18
- it 'blocks one thread indefinitely' do
19
- run_in_two_threads lambda {
20
- subject.wait
21
- @called = true
22
- }, lambda {
23
- sleep test_latency
24
- }
25
- @called.should be_false
26
- end
27
- end
28
-
29
- context 'with a signal' do
30
- it 'blocks one thread until it recieves a signal from another thread' do
31
- run_in_two_threads lambda {
32
- subject.wait
33
- @called = true
34
- }, lambda {
35
- subject.signal
36
- sleep test_latency
37
- }
38
- @called.should be_true
39
- end
40
- end
41
- end
42
-
43
- describe '#signal' do
44
- context 'without a wait-call before' do
45
- it 'does nothing' do
46
- run_in_two_threads lambda {
47
- subject.signal
48
- @called = true
49
- }, lambda {
50
- sleep test_latency
51
- }
52
- @called.should be_true
53
- end
54
- end
55
- end
56
- end
@@ -1,67 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Listen do
4
- describe '#to' do
5
- let(:listener) { double(Listen::Listener) }
6
- let(:listener_class) { Listen::Listener }
7
- before { listener_class.stub(:new => listener) }
8
-
9
- context 'with one path to listen to' do
10
- context 'without options' do
11
- it 'creates an instance of Listener' do
12
- listener_class.should_receive(:new).with('/path')
13
- described_class.to('/path')
14
- end
15
- end
16
-
17
- context 'with options' do
18
- it 'creates an instance of Listener with the passed params' do
19
- listener_class.should_receive(:new).with('/path', :filter => '**/*')
20
- described_class.to('/path', :filter => '**/*')
21
- end
22
- end
23
-
24
- context 'without a block' do
25
- it 'returns the listener' do
26
- described_class.to('/path', :filter => '**/*').should eq listener
27
- end
28
- end
29
-
30
- context 'with a block' do
31
- it 'starts the listener after creating it' do
32
- listener.should_receive(:start)
33
- described_class.to('/path', :filter => '**/*') { |modified, added, removed| }
34
- end
35
- end
36
- end
37
-
38
- context 'with multiple paths to listen to' do
39
- context 'without options' do
40
- it 'creates an instance of Listener' do
41
- listener_class.should_receive(:new).with('path1', 'path2')
42
- described_class.to('path1', 'path2')
43
- end
44
- end
45
-
46
- context 'with options' do
47
- it 'creates an instance of Listener with the passed params' do
48
- listener_class.should_receive(:new).with('path1', 'path2', :filter => '**/*')
49
- described_class.to('path1', 'path2', :filter => '**/*')
50
- end
51
- end
52
-
53
- context 'without a block' do
54
- it 'returns a Listener instance created with the passed params' do
55
- described_class.to('path1', 'path2', :filter => '**/*').should eq listener
56
- end
57
- end
58
-
59
- context 'with a block' do
60
- it 'starts a Listener instance after creating it with the passed params' do
61
- listener.should_receive(:start)
62
- described_class.to('path1', 'path2', :filter => '**/*') { |modified, added, removed| }
63
- end
64
- end
65
- end
66
- end
67
- end
@@ -1,25 +0,0 @@
1
- require 'rubygems'
2
- require 'coveralls'
3
- Coveralls.wear!
4
-
5
- require 'listen'
6
-
7
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
8
-
9
- # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
10
- RSpec.configure do |config|
11
- config.color_enabled = true
12
- config.order = :random
13
- config.filter_run :focus => true
14
- config.treat_symbols_as_metadata_keys_with_true_values = true
15
- config.run_all_when_everything_filtered = true
16
- config.filter_run_excluding :broken => true
17
- config.fail_fast = true
18
- end
19
-
20
- def test_latency
21
- 0.1
22
- end
23
-
24
- # Crash loud in tests!
25
- Thread.abort_on_exception = true
@@ -1,666 +0,0 @@
1
- # Adapter watch
2
- #
3
- # @param [Listen::Listener] listener the adapter listener
4
- # @param [String] path the path to watch
5
- #
6
- def watch(listener, expected_changes, *paths)
7
- sleep 0.05 # allow file/creation to be done (!)
8
-
9
- callback = lambda do |changed_directories, options|
10
- @called = true
11
- listener.on_change(changed_directories)
12
- end
13
- @adapter = Listen::Adapter.select_and_initialize(paths, { :latency => test_latency }, &callback)
14
- @adapter.stub(:start_poller) { nil }
15
-
16
- forced_stop = false
17
- prevent_deadlock = lambda do
18
- sleep(10)
19
- puts 'Forcing stop'
20
- @adapter.stop
21
- forced_stop = true
22
- end
23
-
24
- @adapter.start
25
-
26
- yield
27
-
28
- t = Thread.new(&prevent_deadlock)
29
- @adapter.wait_for_changes(expected_changes)
30
-
31
- unless forced_stop
32
- Thread.kill(t)
33
- @adapter.report_changes
34
- end
35
- ensure
36
- unless forced_stop
37
- Thread.kill(t) if t
38
- @adapter.stop
39
- end
40
- end
41
-
42
- shared_examples_for 'a filesystem adapter' do
43
- subject { described_class.new(File.dirname(__FILE__), &Proc.new {}) }
44
-
45
- describe '#start' do
46
- before { Kernel.stub(:warn) }
47
- after { subject.stop }
48
-
49
- it 'do not block the current thread after starting the workers' do
50
- @called = false
51
- t = Thread.new { subject.start; @called = true }
52
- sleep(test_latency * 3)
53
- Thread.kill(t) if t
54
- @called.should be_true
55
- end
56
-
57
- context 'with the blocking hash option set to false' do
58
- subject { described_class.new(File.dirname(__FILE__), { :blocking => false }, &Proc.new {}) }
59
-
60
- it 'does not block the current thread after starting the workers' do
61
- @called = false
62
- t = Thread.new { subject.start; @called = true }
63
- sleep(test_latency * 3)
64
- Thread.kill(t) if t
65
- @called.should be_true
66
- end
67
- end
68
- end
69
-
70
- describe '#start!' do
71
- before { Kernel.stub(:warn) }
72
- after { subject.stop }
73
-
74
- it 'blocks the current thread after starting the workers' do
75
- @called = false
76
- t = Thread.new { subject.start!; @called = true }
77
- sleep(test_latency * 3)
78
- Thread.kill(t) if t
79
- @called.should be_false
80
- end
81
-
82
- context 'with the blocking hash option set to false' do
83
- subject { described_class.new(File.dirname(__FILE__), { :blocking => true }, &Proc.new {}) }
84
-
85
- it 'blocks the current thread after starting the workers' do
86
- @called = false
87
- t = Thread.new { subject.start!; @called = true }
88
- sleep(test_latency * 3)
89
- Thread.kill(t) if t
90
- @called.should be_false
91
- end
92
- end
93
- end
94
-
95
- describe '#started?' do
96
- context 'with a new adapter' do
97
- it 'returns false' do
98
- subject.should_not be_started
99
- end
100
- end
101
-
102
- context 'with a stopped adapter' do
103
- before { subject.start; subject.stop }
104
-
105
- it 'returns false' do
106
- subject.should_not be_started
107
- end
108
- end
109
-
110
- context 'with a started adapter' do
111
- before { subject.start }
112
- after { subject.stop }
113
-
114
- it 'returns true' do
115
- subject.should be_started
116
- end
117
- end
118
- end
119
- end
120
-
121
- shared_examples_for 'an adapter that call properly listener#on_change' do |*args|
122
- options = (args.first && args.first.is_a?(Hash)) ? args.first : {}
123
- let(:listener) { double(Listen::Listener) }
124
- before { described_class.stub(:works?) { true } }
125
-
126
- context 'single file operations' do
127
- context 'when a file is created' do
128
- it 'detects the added file' do
129
- fixtures do |path|
130
- listener.should_receive(:on_change).once.with do |array|
131
- array.should include(path)
132
- end
133
-
134
- watch(listener, 1, path) do
135
- touch 'new_file.rb'
136
- end
137
- end
138
- end
139
-
140
- context 'given a symlink', :unless => windows? do
141
- it 'detects the added file' do
142
- fixtures do |path|
143
- listener.should_receive(:on_change).once.with do |array|
144
- array.should include(path)
145
- end
146
-
147
- touch 'new_file.rb'
148
-
149
- watch(listener, 1, path) do
150
- ln_s 'new_file.rb', 'new_file_symlink.rb'
151
- end
152
- end
153
- end
154
- end
155
-
156
- context 'given a new created directory' do
157
- it 'detects the added file' do
158
- fixtures do |path|
159
- listener.should_receive(:on_change).once.with do |array|
160
- array.should include(path, "#{path}/a_directory")
161
- end
162
-
163
- watch(listener, 2, path) do
164
- mkdir 'a_directory'
165
- # Needed for INotify, because of :recursive rb-inotify custom flag?
166
- sleep 0.05
167
- touch 'a_directory/new_file.rb'
168
- end
169
- end
170
- end
171
- end
172
-
173
- context 'given an existing directory' do
174
- it 'detects the added file' do
175
- fixtures do |path|
176
- listener.should_receive(:on_change).once.with do |array|
177
- array.should include("#{path}/a_directory")
178
- end
179
-
180
- mkdir 'a_directory'
181
-
182
- watch(listener, 1, path) do
183
- touch 'a_directory/new_file.rb'
184
- end
185
- end
186
- end
187
- end
188
-
189
- context 'given a directory with subdirectories' do
190
- it 'detects the added file' do
191
- fixtures do |path|
192
- listener.should_receive(:on_change).once.with do |array|
193
- array.should include("#{path}/a_directory/subdirectory")
194
- end
195
-
196
- mkdir_p 'a_directory/subdirectory'
197
-
198
- watch(listener, 1, path) do
199
- touch 'a_directory/subdirectory/new_file.rb'
200
- end
201
- end
202
- end
203
- end
204
- end
205
-
206
- context 'when a file is modified' do
207
- it 'detects the modified file' do
208
- fixtures do |path|
209
- listener.should_receive(:on_change).once.with do |array|
210
- array.should include(path)
211
- end
212
-
213
- touch 'existing_file.txt'
214
-
215
- watch(listener, 1, path) do
216
- touch 'existing_file.txt'
217
- end
218
- end
219
- end
220
-
221
- context 'given a symlink', :unless => windows? do
222
- it 'detects the modified file' do
223
- fixtures do |path|
224
- listener.should_receive(:on_change).once.with do |array|
225
- array.should include(path)
226
- end
227
-
228
- touch 'existing_file.rb'
229
- ln_s 'existing_file.rb', 'existing_file_symlink.rb'
230
-
231
- watch(listener, 1, path) do
232
- touch 'existing_file.rb'
233
- end
234
- end
235
- end
236
- end
237
-
238
- context 'given a hidden file' do
239
- it 'detects the modified file' do
240
- fixtures do |path|
241
- listener.should_receive(:on_change).once.with do |array|
242
- array.should include(path)
243
- end
244
-
245
- touch '.hidden'
246
-
247
- watch(listener, 1, path) do
248
- touch '.hidden'
249
- end
250
- end
251
- end
252
- end
253
-
254
- context 'given a file mode change', :unless => windows? do
255
- it 'does not detect the mode change' do
256
- fixtures do |path|
257
- listener.should_receive(:on_change).once.with do |array|
258
- array.should include(path)
259
- end
260
-
261
- touch 'run.rb'
262
-
263
- watch(listener, 1, path) do
264
- chmod 0777, 'run.rb'
265
- end
266
- end
267
- end
268
- end
269
-
270
- context 'given an existing directory' do
271
- it 'detects the modified file' do
272
- fixtures do |path|
273
- listener.should_receive(:on_change).once.with do |array|
274
- array.should include("#{path}/a_directory")
275
- end
276
-
277
- mkdir 'a_directory'
278
- touch 'a_directory/existing_file.txt'
279
-
280
- watch(listener, 1, path) do
281
- touch 'a_directory/existing_file.txt'
282
- end
283
- end
284
- end
285
- end
286
-
287
- context 'given a directory with subdirectories' do
288
- it 'detects the modified file' do
289
- fixtures do |path|
290
- listener.should_receive(:on_change).once.with do |array|
291
- array.should include("#{path}/a_directory/subdirectory")
292
- end
293
-
294
- mkdir_p 'a_directory/subdirectory'
295
- touch 'a_directory/subdirectory/existing_file.txt'
296
-
297
- watch(listener, 1, path) do
298
- touch 'a_directory/subdirectory/new_file.rb'
299
- end
300
- end
301
- end
302
- end
303
- end
304
-
305
- context 'when a file is moved' do
306
- it 'detects the file move' do
307
- fixtures do |path|
308
- listener.should_receive(:on_change).once.with do |array|
309
- array.should include(path)
310
- end
311
-
312
- touch 'move_me.txt'
313
-
314
- watch(listener, 1, path) do
315
- mv 'move_me.txt', 'new_name.txt'
316
- end
317
- end
318
- end
319
-
320
- context 'given a symlink', :unless => windows? do
321
- it 'detects the file move' do
322
- fixtures do |path|
323
- listener.should_receive(:on_change).once.with do |array|
324
- array.should include(path)
325
- end
326
-
327
- touch 'move_me.rb'
328
- ln_s 'move_me.rb', 'move_me_symlink.rb'
329
-
330
- watch(listener, 1, path) do
331
- mv 'move_me_symlink.rb', 'new_symlink.rb'
332
- end
333
- end
334
- end
335
- end
336
-
337
- context 'given an existing directory' do
338
- it 'detects the file move into the directory' do
339
- fixtures do |path|
340
- listener.should_receive(:on_change).once.with do |array|
341
- array.should include(path, "#{path}/a_directory")
342
- end
343
-
344
- mkdir 'a_directory'
345
- touch 'move_me.txt'
346
-
347
- watch(listener, 2, path) do
348
- mv 'move_me.txt', 'a_directory/move_me.txt'
349
- end
350
- end
351
- end
352
-
353
- it 'detects a file move out of the directory' do
354
- fixtures do |path|
355
- listener.should_receive(:on_change).once.with do |array|
356
- array.should include(path, "#{path}/a_directory")
357
- end
358
-
359
- mkdir 'a_directory'
360
- touch 'a_directory/move_me.txt'
361
-
362
- watch(listener, 2, path) do
363
- mv 'a_directory/move_me.txt', 'i_am_here.txt'
364
- end
365
- end
366
- end
367
-
368
- it 'detects a file move between two directories' do
369
- fixtures do |path|
370
- listener.should_receive(:on_change).once.with do |array|
371
- array.should include("#{path}/from_directory", "#{path}/to_directory")
372
- end
373
-
374
- mkdir 'from_directory'
375
- touch 'from_directory/move_me.txt'
376
- mkdir 'to_directory'
377
-
378
- watch(listener, 2, path) do
379
- mv 'from_directory/move_me.txt', 'to_directory/move_me.txt'
380
- end
381
- end
382
- end
383
- end
384
-
385
- context 'given a directory with subdirectories' do
386
- it 'detects files movements between subdirectories' do
387
- fixtures do |path|
388
- listener.should_receive(:on_change).once.with do |array|
389
- array.should include("#{path}/a_directory/subdirectory", "#{path}/b_directory/subdirectory")
390
- end
391
-
392
- mkdir_p 'a_directory/subdirectory'
393
- mkdir_p 'b_directory/subdirectory'
394
- touch 'a_directory/subdirectory/move_me.txt'
395
-
396
- watch(listener, 2, path) do
397
- mv 'a_directory/subdirectory/move_me.txt', 'b_directory/subdirectory'
398
- end
399
- end
400
- end
401
- end
402
- end
403
-
404
- context 'when a file is deleted' do
405
- it 'detects the file removal' do
406
- fixtures do |path|
407
- listener.should_receive(:on_change).once.with do |array|
408
- array.should include(path)
409
- end
410
-
411
- touch 'unnecessary.txt'
412
-
413
- watch(listener, 1, path) do
414
- rm 'unnecessary.txt'
415
- end
416
- end
417
- end
418
-
419
- context 'given a symlink', :unless => windows? do
420
- it 'detects the file removal' do
421
- fixtures do |path|
422
- listener.should_receive(:on_change).once.with do |array|
423
- array.should include(path)
424
- end
425
-
426
- touch 'unnecessary.rb'
427
- ln_s 'unnecessary.rb', 'unnecessary_symlink.rb'
428
-
429
- watch(listener, 1, path) do
430
- rm 'unnecessary_symlink.rb'
431
- end
432
- end
433
- end
434
- end
435
-
436
- context 'given an existing directory' do
437
- it 'detects the file removal' do
438
- fixtures do |path|
439
- listener.should_receive(:on_change).once.with do |array|
440
- array.should include("#{path}/a_directory")
441
- end
442
-
443
- mkdir 'a_directory'
444
- touch 'a_directory/do_not_use.rb'
445
-
446
- watch(listener, 1, path) do
447
- rm 'a_directory/do_not_use.rb'
448
- end
449
- end
450
- end
451
- end
452
-
453
- context 'given a directory with subdirectories' do
454
- it 'detects the file removal' do
455
- fixtures do |path|
456
- listener.should_receive(:on_change).once.with do |array|
457
- array.should include("#{path}/a_directory/subdirectory")
458
- end
459
-
460
- mkdir_p 'a_directory/subdirectory'
461
- touch 'a_directory/subdirectory/do_not_use.rb'
462
-
463
- watch(listener, 1, path) do
464
- rm 'a_directory/subdirectory/do_not_use.rb'
465
- end
466
- end
467
- end
468
- end
469
- end
470
- end
471
-
472
- context 'multiple file operations' do
473
- it 'detects the added files' do
474
- fixtures do |path|
475
- listener.should_receive(:on_change).once.with do |array|
476
- array.should include(path, "#{path}/a_directory")
477
- end
478
-
479
- watch(listener, 2, path) do
480
- touch 'a_file.rb'
481
- touch 'b_file.rb'
482
- mkdir 'a_directory'
483
- # Needed for INotify, because of :recursive rb-inotify custom flag?
484
- # Also needed for the osx adapter
485
- sleep 0.05
486
- touch 'a_directory/a_file.rb'
487
- touch 'a_directory/b_file.rb'
488
- end
489
- end
490
- end
491
-
492
- it 'detects the modified files' do
493
- fixtures do |path|
494
- listener.should_receive(:on_change).once.with do |array|
495
- array.should include(path, "#{path}/a_directory")
496
- end
497
-
498
- touch 'a_file.rb'
499
- touch 'b_file.rb'
500
- mkdir 'a_directory'
501
- touch 'a_directory/a_file.rb'
502
- touch 'a_directory/b_file.rb'
503
-
504
- watch(listener, 2, path) do
505
- touch 'b_file.rb'
506
- touch 'a_directory/a_file.rb'
507
- end
508
- end
509
- end
510
-
511
- it 'detects the removed files' do
512
- fixtures do |path|
513
- listener.should_receive(:on_change).once.with do |array|
514
- array.should include(path, "#{path}/a_directory")
515
- end
516
-
517
- touch 'a_file.rb'
518
- touch 'b_file.rb'
519
- mkdir 'a_directory'
520
- touch 'a_directory/a_file.rb'
521
- touch 'a_directory/b_file.rb'
522
-
523
- watch(listener, 2, path) do
524
- rm 'b_file.rb'
525
- rm 'a_directory/a_file.rb'
526
- end
527
- end
528
- end
529
- end
530
-
531
- context 'single directory operations' do
532
- it 'detects a moved directory' do
533
- fixtures do |path|
534
- listener.should_receive(:on_change).once.with do |array|
535
- array.should include(path)
536
- end
537
-
538
- mkdir 'a_directory'
539
- touch 'a_directory/a_file.rb'
540
- touch 'a_directory/b_file.rb'
541
-
542
- watch(listener, 1, path) do
543
- mv 'a_directory', 'renamed'
544
- end
545
- end
546
- end
547
-
548
- it 'detects a removed directory' do
549
- fixtures do |path|
550
- listener.should_receive(:on_change).once.with do |array|
551
- array.should include(path, "#{path}/a_directory")
552
- end
553
-
554
- mkdir 'a_directory'
555
- touch 'a_directory/a_file.rb'
556
- touch 'a_directory/b_file.rb'
557
-
558
- watch(listener, 2, path) do
559
- rm_rf 'a_directory'
560
- end
561
- end
562
- end
563
- end
564
-
565
- context "paused adapter" do
566
- context 'when a file is created' do
567
- it "doesn't detects the added file" do
568
- fixtures do |path|
569
- watch(listener, 1, path) do # The expected changes param is set to one!
570
- @adapter.paused = true
571
- touch 'new_file.rb'
572
- end
573
- @called.should be_nil
574
- end
575
- end
576
- end
577
- end
578
-
579
- context "when multiple directories are listened to" do
580
- context 'when files are added to one of multiple directories' do
581
- it 'detects added files' do
582
- fixtures(2) do |path1, path2|
583
- listener.should_receive(:on_change).once.with do |array|
584
- array.should include(path2)
585
- end
586
-
587
- watch(listener, 1, path1, path2) do
588
- touch "#{path2}/new_file.rb"
589
- end
590
- end
591
- end
592
- end
593
-
594
- context 'when files are added to multiple directories' do
595
- it 'detects added files' do
596
- fixtures(2) do |path1, path2|
597
- listener.should_receive(:on_change).once.with do |array|
598
- array.should include(path1, path2)
599
- end
600
-
601
- watch(listener, 2, path1, path2) do
602
- touch "#{path1}/new_file.rb"
603
- touch "#{path2}/new_file.rb"
604
- end
605
- end
606
- end
607
- end
608
-
609
- context 'given a new and an existing directory on multiple directories' do
610
- it 'detects the added file' do
611
- fixtures(2) do |path1, path2|
612
- listener.should_receive(:on_change).once.with do |array|
613
- array.should include(path2, "#{path1}/a_directory", "#{path2}/b_directory")
614
- end
615
-
616
- mkdir "#{path1}/a_directory"
617
-
618
- watch(listener, 3, path1, path2) do
619
- mkdir "#{path2}/b_directory"
620
- # Needed for INotify
621
- sleep 0.05
622
- touch "#{path1}/a_directory/new_file.rb"
623
- touch "#{path2}/b_directory/new_file.rb"
624
- end
625
- end
626
- end
627
- end
628
-
629
- context 'when a file is moved between the multiple watched directories' do
630
- it 'detects the movements of the file' do
631
- fixtures(3) do |path1, path2, path3|
632
- listener.should_receive(:on_change).once.with do |array|
633
- array.should include("#{path1}/from_directory", path2, "#{path3}/to_directory")
634
- end
635
-
636
- mkdir "#{path1}/from_directory"
637
- touch "#{path1}/from_directory/move_me.txt"
638
- mkdir "#{path3}/to_directory"
639
-
640
- watch(listener, 3, path1, path2, path3) do
641
- mv "#{path1}/from_directory/move_me.txt", "#{path2}/move_me.txt"
642
- mv "#{path2}/move_me.txt", "#{path3}/to_directory/move_me.txt"
643
- end
644
- end
645
- end
646
- end
647
-
648
- context 'when files are deleted from the multiple watched directories' do
649
- it 'detects the files removal' do
650
- fixtures(2) do |path1, path2|
651
- listener.should_receive(:on_change).once.with do |array|
652
- array.should include(path1, path2)
653
- end
654
-
655
- touch "#{path1}/unnecessary.txt"
656
- touch "#{path2}/unnecessary.txt"
657
-
658
- watch(listener, 2, path1, path2) do
659
- rm "#{path1}/unnecessary.txt"
660
- rm "#{path2}/unnecessary.txt"
661
- end
662
- end
663
- end
664
- end
665
- end
666
- end