sass 3.3.0 → 3.4.25

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 (208) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +3 -1
  3. data/CODE_OF_CONDUCT.md +10 -0
  4. data/CONTRIBUTING.md +148 -0
  5. data/MIT-LICENSE +1 -1
  6. data/README.md +76 -62
  7. data/Rakefile +104 -24
  8. data/VERSION +1 -1
  9. data/VERSION_DATE +1 -1
  10. data/VERSION_NAME +1 -1
  11. data/bin/sass +1 -1
  12. data/bin/scss +1 -1
  13. data/extra/sass-spec-ref.sh +32 -0
  14. data/extra/update_watch.rb +1 -1
  15. data/lib/sass/cache_stores/filesystem.rb +9 -5
  16. data/lib/sass/cache_stores/memory.rb +4 -5
  17. data/lib/sass/callbacks.rb +2 -2
  18. data/lib/sass/css.rb +12 -13
  19. data/lib/sass/deprecation.rb +55 -0
  20. data/lib/sass/engine.rb +106 -70
  21. data/lib/sass/environment.rb +39 -19
  22. data/lib/sass/error.rb +17 -20
  23. data/lib/sass/exec/base.rb +199 -0
  24. data/lib/sass/exec/sass_convert.rb +283 -0
  25. data/lib/sass/exec/sass_scss.rb +440 -0
  26. data/lib/sass/exec.rb +5 -771
  27. data/lib/sass/features.rb +9 -2
  28. data/lib/sass/importers/base.rb +8 -3
  29. data/lib/sass/importers/filesystem.rb +30 -38
  30. data/lib/sass/logger/base.rb +8 -2
  31. data/lib/sass/logger/delayed.rb +50 -0
  32. data/lib/sass/logger.rb +8 -3
  33. data/lib/sass/media.rb +1 -4
  34. data/lib/sass/plugin/compiler.rb +224 -90
  35. data/lib/sass/plugin/configuration.rb +38 -22
  36. data/lib/sass/plugin/merb.rb +2 -2
  37. data/lib/sass/plugin/rack.rb +3 -3
  38. data/lib/sass/plugin/rails.rb +1 -1
  39. data/lib/sass/plugin/staleness_checker.rb +4 -4
  40. data/lib/sass/plugin.rb +6 -5
  41. data/lib/sass/script/css_lexer.rb +1 -1
  42. data/lib/sass/script/css_parser.rb +2 -3
  43. data/lib/sass/script/css_variable_warning.rb +52 -0
  44. data/lib/sass/script/functions.rb +739 -318
  45. data/lib/sass/script/lexer.rb +134 -54
  46. data/lib/sass/script/parser.rb +252 -56
  47. data/lib/sass/script/tree/funcall.rb +13 -6
  48. data/lib/sass/script/tree/interpolation.rb +127 -4
  49. data/lib/sass/script/tree/list_literal.rb +31 -4
  50. data/lib/sass/script/tree/literal.rb +4 -0
  51. data/lib/sass/script/tree/node.rb +21 -3
  52. data/lib/sass/script/tree/operation.rb +54 -1
  53. data/lib/sass/script/tree/selector.rb +26 -0
  54. data/lib/sass/script/tree/string_interpolation.rb +59 -38
  55. data/lib/sass/script/tree/variable.rb +1 -1
  56. data/lib/sass/script/tree.rb +1 -0
  57. data/lib/sass/script/value/base.rb +17 -14
  58. data/lib/sass/script/value/bool.rb +0 -5
  59. data/lib/sass/script/value/color.rb +78 -42
  60. data/lib/sass/script/value/helpers.rb +119 -2
  61. data/lib/sass/script/value/list.rb +0 -15
  62. data/lib/sass/script/value/map.rb +1 -1
  63. data/lib/sass/script/value/null.rb +0 -5
  64. data/lib/sass/script/value/number.rb +112 -31
  65. data/lib/sass/script/value/string.rb +102 -13
  66. data/lib/sass/script/value.rb +0 -1
  67. data/lib/sass/script.rb +3 -3
  68. data/lib/sass/scss/css_parser.rb +24 -4
  69. data/lib/sass/scss/parser.rb +290 -383
  70. data/lib/sass/scss/rx.rb +17 -9
  71. data/lib/sass/scss/static_parser.rb +306 -4
  72. data/lib/sass/scss.rb +0 -2
  73. data/lib/sass/selector/abstract_sequence.rb +35 -18
  74. data/lib/sass/selector/comma_sequence.rb +114 -19
  75. data/lib/sass/selector/pseudo.rb +266 -0
  76. data/lib/sass/selector/sequence.rb +146 -40
  77. data/lib/sass/selector/simple.rb +22 -33
  78. data/lib/sass/selector/simple_sequence.rb +122 -39
  79. data/lib/sass/selector.rb +57 -197
  80. data/lib/sass/shared.rb +2 -2
  81. data/lib/sass/source/map.rb +31 -14
  82. data/lib/sass/source/position.rb +4 -4
  83. data/lib/sass/stack.rb +2 -8
  84. data/lib/sass/supports.rb +10 -13
  85. data/lib/sass/tree/at_root_node.rb +1 -0
  86. data/lib/sass/tree/charset_node.rb +1 -1
  87. data/lib/sass/tree/comment_node.rb +1 -1
  88. data/lib/sass/tree/css_import_node.rb +9 -1
  89. data/lib/sass/tree/directive_node.rb +8 -2
  90. data/lib/sass/tree/error_node.rb +18 -0
  91. data/lib/sass/tree/extend_node.rb +1 -1
  92. data/lib/sass/tree/function_node.rb +9 -0
  93. data/lib/sass/tree/import_node.rb +6 -5
  94. data/lib/sass/tree/keyframe_rule_node.rb +15 -0
  95. data/lib/sass/tree/node.rb +5 -3
  96. data/lib/sass/tree/prop_node.rb +6 -7
  97. data/lib/sass/tree/rule_node.rb +26 -11
  98. data/lib/sass/tree/visitors/check_nesting.rb +56 -32
  99. data/lib/sass/tree/visitors/convert.rb +59 -44
  100. data/lib/sass/tree/visitors/cssize.rb +34 -30
  101. data/lib/sass/tree/visitors/deep_copy.rb +6 -1
  102. data/lib/sass/tree/visitors/extend.rb +15 -13
  103. data/lib/sass/tree/visitors/perform.rb +87 -50
  104. data/lib/sass/tree/visitors/set_options.rb +15 -1
  105. data/lib/sass/tree/visitors/to_css.rb +72 -43
  106. data/lib/sass/util/multibyte_string_scanner.rb +0 -2
  107. data/lib/sass/util/normalized_map.rb +0 -1
  108. data/lib/sass/util/subset_map.rb +2 -3
  109. data/lib/sass/util.rb +334 -154
  110. data/lib/sass/version.rb +7 -7
  111. data/lib/sass.rb +10 -8
  112. data/test/sass/cache_test.rb +62 -20
  113. data/test/sass/callbacks_test.rb +1 -1
  114. data/test/sass/compiler_test.rb +24 -11
  115. data/test/sass/conversion_test.rb +241 -50
  116. data/test/sass/css2sass_test.rb +73 -5
  117. data/test/sass/css_variable_test.rb +132 -0
  118. data/test/sass/encoding_test.rb +219 -0
  119. data/test/sass/engine_test.rb +343 -260
  120. data/test/sass/exec_test.rb +12 -2
  121. data/test/sass/extend_test.rb +333 -44
  122. data/test/sass/functions_test.rb +353 -260
  123. data/test/sass/importer_test.rb +40 -21
  124. data/test/sass/logger_test.rb +1 -1
  125. data/test/sass/more_results/more_import.css +1 -1
  126. data/test/sass/more_templates/more1.sass +10 -10
  127. data/test/sass/more_templates/more_import.sass +2 -2
  128. data/test/sass/plugin_test.rb +24 -21
  129. data/test/sass/results/compact.css +1 -1
  130. data/test/sass/results/complex.css +4 -4
  131. data/test/sass/results/expanded.css +1 -1
  132. data/test/sass/results/import.css +1 -1
  133. data/test/sass/results/import_charset_ibm866.css +2 -2
  134. data/test/sass/results/mixins.css +17 -17
  135. data/test/sass/results/nested.css +1 -1
  136. data/test/sass/results/parent_ref.css +2 -2
  137. data/test/sass/results/script.css +5 -5
  138. data/test/sass/results/scss_import.css +1 -1
  139. data/test/sass/script_conversion_test.rb +71 -39
  140. data/test/sass/script_test.rb +714 -123
  141. data/test/sass/scss/css_test.rb +213 -30
  142. data/test/sass/scss/rx_test.rb +8 -4
  143. data/test/sass/scss/scss_test.rb +766 -22
  144. data/test/sass/source_map_test.rb +263 -95
  145. data/test/sass/superselector_test.rb +210 -0
  146. data/test/sass/templates/_partial.sass +1 -1
  147. data/test/sass/templates/basic.sass +10 -10
  148. data/test/sass/templates/bork1.sass +1 -1
  149. data/test/sass/templates/bork5.sass +1 -1
  150. data/test/sass/templates/compact.sass +10 -10
  151. data/test/sass/templates/complex.sass +187 -187
  152. data/test/sass/templates/compressed.sass +10 -10
  153. data/test/sass/templates/expanded.sass +10 -10
  154. data/test/sass/templates/import.sass +2 -2
  155. data/test/sass/templates/importee.sass +3 -3
  156. data/test/sass/templates/mixins.sass +22 -22
  157. data/test/sass/templates/multiline.sass +4 -4
  158. data/test/sass/templates/nested.sass +13 -13
  159. data/test/sass/templates/parent_ref.sass +12 -12
  160. data/test/sass/templates/script.sass +70 -70
  161. data/test/sass/templates/scss_import.scss +2 -1
  162. data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +1 -1
  163. data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +2 -2
  164. data/test/sass/templates/subdir/subdir.sass +3 -3
  165. data/test/sass/templates/units.sass +10 -10
  166. data/test/sass/test_helper.rb +1 -1
  167. data/test/sass/util/multibyte_string_scanner_test.rb +11 -3
  168. data/test/sass/util/normalized_map_test.rb +1 -1
  169. data/test/sass/util/subset_map_test.rb +2 -2
  170. data/test/sass/util_test.rb +46 -45
  171. data/test/sass/value_helpers_test.rb +5 -7
  172. data/test/sass-spec.yml +3 -0
  173. data/test/test_helper.rb +7 -6
  174. data/vendor/listen/CHANGELOG.md +1 -228
  175. data/vendor/listen/Gemfile +5 -15
  176. data/vendor/listen/README.md +111 -77
  177. data/vendor/listen/Rakefile +0 -42
  178. data/vendor/listen/lib/listen/adapter.rb +195 -82
  179. data/vendor/listen/lib/listen/adapters/bsd.rb +27 -64
  180. data/vendor/listen/lib/listen/adapters/darwin.rb +21 -58
  181. data/vendor/listen/lib/listen/adapters/linux.rb +23 -55
  182. data/vendor/listen/lib/listen/adapters/polling.rb +25 -34
  183. data/vendor/listen/lib/listen/adapters/windows.rb +50 -46
  184. data/vendor/listen/lib/listen/directory_record.rb +96 -61
  185. data/vendor/listen/lib/listen/listener.rb +135 -37
  186. data/vendor/listen/lib/listen/turnstile.rb +9 -5
  187. data/vendor/listen/lib/listen/version.rb +1 -1
  188. data/vendor/listen/lib/listen.rb +33 -19
  189. data/vendor/listen/listen.gemspec +6 -0
  190. data/vendor/listen/spec/listen/adapter_spec.rb +43 -77
  191. data/vendor/listen/spec/listen/adapters/polling_spec.rb +8 -8
  192. data/vendor/listen/spec/listen/directory_record_spec.rb +81 -56
  193. data/vendor/listen/spec/listen/listener_spec.rb +128 -39
  194. data/vendor/listen/spec/listen_spec.rb +15 -21
  195. data/vendor/listen/spec/spec_helper.rb +4 -0
  196. data/vendor/listen/spec/support/adapter_helper.rb +52 -15
  197. data/vendor/listen/spec/support/directory_record_helper.rb +7 -5
  198. data/vendor/listen/spec/support/listeners_helper.rb +30 -7
  199. metadata +310 -300
  200. data/CONTRIBUTING +0 -3
  201. data/ext/mkrf_conf.rb +0 -27
  202. data/lib/sass/script/value/deprecated_false.rb +0 -55
  203. data/lib/sass/scss/script_lexer.rb +0 -15
  204. data/lib/sass/scss/script_parser.rb +0 -25
  205. data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
  206. data/vendor/listen/lib/listen/multi_listener.rb +0 -143
  207. data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
  208. data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
data/CONTRIBUTING DELETED
@@ -1,3 +0,0 @@
1
- Contributions are welcomed. Please see the following sites for guidelines:
2
-
3
- http://sass-lang.com/community#Contribute
data/ext/mkrf_conf.rb DELETED
@@ -1,27 +0,0 @@
1
- require 'rubygems'
2
- require 'rubygems/command.rb'
3
- require 'rubygems/dependency_installer.rb'
4
-
5
- require '../lib/sass'
6
-
7
- # This script installs the correct version of listen. Listen versions
8
- # beyond 1.1 don't support Ruby 1.8, any RubyGems isn't clever enough
9
- # to install the most recent version that works, so we have to do it
10
- # manually.
11
-
12
- puts "Ensuring you have the right version of listen installed."
13
-
14
- Gem::Command.build_args = ARGV
15
- inst = Gem::DependencyInstaller.new
16
- if Sass::Util.version_geq(RUBY_VERSION, "1.9.3")
17
- puts "Installing listen >= 1.1.0, < 3.0.0"
18
- inst.install "listen", Gem::Requirement.new(">= 1.1.0", "< 3.0.0")
19
- else
20
- puts "Installing listen ~> 1.1.0"
21
- inst.install "listen", "~> 1.1.0"
22
- end
23
-
24
- # Create a dummy rakefile to indicate success.
25
- f = File.open(File.join(File.dirname(__FILE__), "Rakefile"), "w")
26
- f.write("task :default\n")
27
- f.close
@@ -1,55 +0,0 @@
1
- module Sass::Script::Value
2
- # A SassScript object representing a `false` value that came from a call to
3
- # `index()`. It will print deprecation warnings if it's used with `==`.
4
- class DeprecatedFalse < Bool
5
- def self.new(environment)
6
- obj = allocate
7
- obj.send(:initialize, environment)
8
- obj
9
- end
10
-
11
- def initialize(environment)
12
- @value = false
13
- @global_env = environment.global_env
14
- if (frame = environment.stack.frames.last)
15
- @filename = frame.filename
16
- @line = frame.line
17
- end
18
- end
19
-
20
- def eq(other)
21
- if other.value == false && !warned?
22
- self.warned = true
23
- Sass::Util.sass_warn <<WARNING + @global_env.stack.to_s.gsub(/^/, ' ')
24
- DEPRECATION WARNING: The return value of index() will change from "false" to
25
- "null" in future versions of Sass. For compatibility, avoid using "== false" on
26
- the return value. For example, instead of "@if index(...) == false", just write
27
- "@if index(...)".
28
- WARNING
29
- end
30
- Bool.new(other.value == false)
31
- end
32
-
33
- def neq(other)
34
- if other.value.nil? && !warned?
35
- self.warned = true
36
- Sass::Util.sass_warn <<WARNING + @global_env.stack.to_s.gsub(/^/, ' ')
37
- DEPRECATION WARNING: The return value of index() will change from "false" to
38
- "null" in future versions of Sass. For compatibility, avoid using "!= null" on
39
- the return value.
40
- WARNING
41
- end
42
- Bool.new(other.value != false)
43
- end
44
-
45
- private
46
-
47
- def warned?
48
- @global_env.deprecated_false_warning_given.include?([@filename, @line])
49
- end
50
-
51
- def warned=(value)
52
- @global_env.deprecated_false_warning_given << [@filename, @line]
53
- end
54
- end
55
- end
@@ -1,15 +0,0 @@
1
- module Sass
2
- module SCSS
3
- # A mixin for subclasses of {Sass::Script::Lexer}
4
- # that makes them usable by {SCSS::Parser} to parse SassScript.
5
- # In particular, the lexer doesn't support `!` for a variable prefix.
6
- module ScriptLexer
7
- private
8
-
9
- def variable
10
- return [:raw, "!important"] if scan(Sass::SCSS::RX::IMPORTANT)
11
- _variable(Sass::SCSS::RX::VARIABLE)
12
- end
13
- end
14
- end
15
- end
@@ -1,25 +0,0 @@
1
- module Sass
2
- module SCSS
3
- # A mixin for subclasses of {Sass::Script::Parser}
4
- # that makes them usable by {SCSS::Parser} to parse SassScript.
5
- # In particular, the parser won't raise an error
6
- # when there's more content in the lexer once lexing is done.
7
- # In addition, the parser doesn't support `!` for a variable prefix.
8
- module ScriptParser
9
- private
10
-
11
- # @private
12
- def lexer_class
13
- klass = Class.new(super)
14
- klass.send(:include, ScriptLexer)
15
- klass
16
- end
17
-
18
- # Instead of raising an error when the parser is done,
19
- # rewind the StringScanner so that it hasn't consumed the final token.
20
- def assert_done
21
- @lexer.unpeek!
22
- end
23
- end
24
- end
25
- end
@@ -1,126 +0,0 @@
1
- require 'set'
2
-
3
- module Listen
4
-
5
- # The dependency-manager offers a simple DSL which allows
6
- # classes to declare their gem dependencies and load them when
7
- # needed.
8
- # It raises a user-friendly exception when the dependencies
9
- # can't be loaded which has the install command in the message.
10
- #
11
- module DependencyManager
12
-
13
- GEM_LOAD_MESSAGE = <<-EOS.gsub(/^ {6}/, '')
14
- Missing dependency '%s' (version '%s')!
15
- EOS
16
-
17
- GEM_INSTALL_COMMAND = <<-EOS.gsub(/^ {6}/, '')
18
- Please run the following to satisfy the dependency:
19
- gem install --version '%s' %s
20
- EOS
21
-
22
- BUNDLER_DECLARE_GEM = <<-EOS.gsub(/^ {6}/, '')
23
- Please add the following to your Gemfile to satisfy the dependency:
24
- gem '%s', '%s'
25
- EOS
26
-
27
- Dependency = Struct.new(:name, :version)
28
-
29
- # The error raised when a dependency can't be loaded.
30
- class Error < StandardError; end
31
-
32
- # A list of all loaded dependencies in the dependency manager.
33
- @_loaded_dependencies = Set.new
34
-
35
- # class methods
36
- class << self
37
-
38
- # Initializes the extended class.
39
- #
40
- # @param [Class] the class for which some dependencies must be managed
41
- #
42
- def extended(base)
43
- base.class_eval do
44
- @_dependencies = Set.new
45
- end
46
- end
47
-
48
- # Adds a loaded dependency to a list so that it doesn't have
49
- # to be loaded again by another classes.
50
- #
51
- # @param [Dependency] dependency
52
- #
53
- def add_loaded(dependency)
54
- @_loaded_dependencies << dependency
55
- end
56
-
57
- # Returns whether the dependency is alread loaded or not.
58
- #
59
- # @param [Dependency] dependency
60
- # @return [Boolean]
61
- #
62
- def already_loaded?(dependency)
63
- @_loaded_dependencies.include?(dependency)
64
- end
65
-
66
- # Clears the list of loaded dependencies.
67
- #
68
- def clear_loaded
69
- @_loaded_dependencies.clear
70
- end
71
- end
72
-
73
- # Registers a new dependency.
74
- #
75
- # @param [String] name the name of the gem
76
- # @param [String] version the version of the gem
77
- #
78
- def dependency(name, version)
79
- @_dependencies << Dependency.new(name, version)
80
- end
81
-
82
- # Loads the registered dependencies.
83
- #
84
- # @raise DependencyManager::Error if the dependency can't be loaded.
85
- #
86
- def load_depenencies
87
- @_dependencies.each do |dependency|
88
- begin
89
- next if DependencyManager.already_loaded?(dependency)
90
- gem(dependency.name, dependency.version)
91
- require(dependency.name)
92
- DependencyManager.add_loaded(dependency)
93
- @_dependencies.delete(dependency)
94
- rescue Gem::LoadError
95
- args = [dependency.name, dependency.version]
96
- command = if running_under_bundler?
97
- BUNDLER_DECLARE_GEM % args
98
- else
99
- GEM_INSTALL_COMMAND % args.reverse
100
- end
101
- message = GEM_LOAD_MESSAGE % args
102
-
103
- raise Error.new(message + command)
104
- end
105
- end
106
- end
107
-
108
- # Returns whether all the dependencies has been loaded or not.
109
- #
110
- # @return [Boolean]
111
- #
112
- def dependencies_loaded?
113
- @_dependencies.empty?
114
- end
115
-
116
- private
117
-
118
- # Returns whether we are running under bundler or not
119
- #
120
- # @return [Boolean]
121
- #
122
- def running_under_bundler?
123
- !!(File.exists?('Gemfile') && ENV['BUNDLE_GEMFILE'])
124
- end
125
- end
126
- end
@@ -1,143 +0,0 @@
1
- module Listen
2
- class MultiListener < Listener
3
- attr_reader :directories, :directories_records, :adapter
4
-
5
- # Initializes the multiple directories listener.
6
- #
7
- # @param [String] directories the directories to listen to
8
- # @param [Hash] options the listen options
9
- # @option options [Regexp] ignore a pattern for ignoring paths
10
- # @option options [Regexp] filter a pattern for filtering paths
11
- # @option options [Float] latency the delay between checking for changes in seconds
12
- # @option options [Boolean] force_polling whether to force the polling adapter or not
13
- # @option options [String, Boolean] polling_fallback_message to change polling fallback message or remove it
14
- #
15
- # @yield [modified, added, removed] the changed files
16
- # @yieldparam [Array<String>] modified the list of modified files
17
- # @yieldparam [Array<String>] added the list of added files
18
- # @yieldparam [Array<String>] removed the list of removed files
19
- #
20
- def initialize(*args, &block)
21
- options = args.last.is_a?(Hash) ? args.pop : {}
22
- directories = args
23
-
24
- @block = block
25
- @directories = directories.map { |d| Pathname.new(d).realpath.to_s }
26
- @directories_records = @directories.map { |d| DirectoryRecord.new(d) }
27
-
28
- ignore(*options.delete(:ignore)) if options[:ignore]
29
- filter(*options.delete(:filter)) if options[:filter]
30
-
31
- @adapter_options = options
32
- end
33
-
34
- # Starts the listener by initializing the adapter and building
35
- # the directory record concurrently, then it starts the adapter to watch
36
- # for changes.
37
- #
38
- # @param [Boolean] blocking whether or not to block the current thread after starting
39
- #
40
- def start(blocking = true)
41
- t = Thread.new { @directories_records.each { |r| r.build } }
42
- @adapter = initialize_adapter
43
- t.join
44
- @adapter.start(blocking)
45
- end
46
-
47
- # Unpauses the listener.
48
- #
49
- # @return [Listen::Listener] the listener
50
- #
51
- def unpause
52
- @directories_records.each { |r| r.build }
53
- @adapter.paused = false
54
- self
55
- end
56
-
57
- # Adds ignored paths to the listener.
58
- #
59
- # @param (see Listen::DirectoryRecord#ignore)
60
- #
61
- # @return [Listen::Listener] the listener
62
- #
63
- def ignore(*paths)
64
- @directories_records.each { |r| r.ignore(*paths) }
65
- self
66
- end
67
-
68
- # Replaces ignored paths in the listener.
69
- #
70
- # @param (see Listen::DirectoryRecord#ignore!)
71
- #
72
- # @return [Listen::Listener] the listener
73
- #
74
- def ignore!(*paths)
75
- @directories_records.each { |r| r.ignore!(*paths) }
76
- self
77
- end
78
-
79
- # Adds file filters to the listener.
80
- #
81
- # @param (see Listen::DirectoryRecord#filter)
82
- #
83
- # @return [Listen::Listener] the listener
84
- #
85
- def filter(*regexps)
86
- @directories_records.each { |r| r.filter(*regexps) }
87
- self
88
- end
89
-
90
- # Replaces file filters in the listener.
91
- #
92
- # @param (see Listen::DirectoryRecord#filter!)
93
- #
94
- # @return [Listen::Listener] the listener
95
- #
96
- def filter!(*regexps)
97
- @directories_records.each { |r| r.filter!(*regexps) }
98
- self
99
- end
100
-
101
- # Runs the callback passing it the changes if there are any.
102
- #
103
- # @param (see Listen::DirectoryRecord#fetch_changes)
104
- #
105
- def on_change(directories_to_search, options = {})
106
- changes = fetch_records_changes(directories_to_search, options)
107
- unless changes.values.all? { |paths| paths.empty? }
108
- @block.call(changes[:modified],changes[:added],changes[:removed])
109
- end
110
- end
111
-
112
- private
113
-
114
- # Initializes an adapter passing it the callback and adapters' options.
115
- #
116
- def initialize_adapter
117
- callback = lambda { |changed_dirs, options| self.on_change(changed_dirs, options) }
118
- Adapter.select_and_initialize(@directories, @adapter_options, &callback)
119
- end
120
-
121
- # Returns the sum of all the changes to the directories records
122
- #
123
- # @param (see Listen::DirectoryRecord#fetch_changes)
124
- #
125
- # @return [Hash] the changes
126
- #
127
- def fetch_records_changes(directories_to_search, options)
128
- @directories_records.inject({}) do |h, r|
129
- # directory records skips paths outside their range, so passing the
130
- # whole `directories` array is not a problem.
131
- record_changes = r.fetch_changes(directories_to_search, options.merge(:relative_paths => DEFAULT_TO_RELATIVE_PATHS))
132
-
133
- if h.empty?
134
- h.merge!(record_changes)
135
- else
136
- h.each { |k, v| h[k] += record_changes[k] }
137
- end
138
-
139
- h
140
- end
141
- end
142
- end
143
- end
@@ -1,107 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Listen::DependencyManager do
4
- let(:dependency) { Listen::DependencyManager::Dependency.new('listen', '~> 0.0.1') }
5
-
6
- subject { Class.new { extend Listen::DependencyManager } }
7
-
8
- before { described_class.clear_loaded }
9
-
10
- describe '.add_loaded' do
11
- it 'adds a dependency to the list of loaded dependencies' do
12
- described_class.add_loaded dependency
13
- described_class.already_loaded?(dependency).should be_true
14
- end
15
- end
16
-
17
- describe '.already_loaded?' do
18
- it 'returns false when a dependency is not in the list of loaded dependencies' do
19
- described_class.already_loaded?(dependency).should be_false
20
- end
21
-
22
- it 'returns true when a dependency is in the list of loaded dependencies' do
23
- described_class.add_loaded dependency
24
- described_class.already_loaded?(dependency).should be_true
25
- end
26
- end
27
-
28
- describe '.clear_loaded' do
29
- it 'clears the whole list of loaded dependencies' do
30
- described_class.add_loaded dependency
31
- described_class.already_loaded?(dependency).should be_true
32
- described_class.clear_loaded
33
- described_class.already_loaded?(dependency).should be_false
34
- end
35
- end
36
-
37
- describe '#dependency' do
38
- it 'registers a new dependency for the managed class' do
39
- subject.dependency 'listen', '~> 0.0.1'
40
- subject.dependencies_loaded?.should be_false
41
- end
42
- end
43
-
44
- describe '#load_depenencies' do
45
- before { subject.dependency 'listen', '~> 0.0.1' }
46
-
47
- context 'when dependencies can be loaded' do
48
- before { subject.stub(:gem, :require) }
49
-
50
- it 'loads all the registerd dependencies' do
51
- subject.load_depenencies
52
- subject.dependencies_loaded?.should be_true
53
- end
54
- end
55
-
56
- context 'when dependencies can not be loaded' do
57
- it 'raises an error' do
58
- expect {
59
- subject.load_depenencies
60
- }.to raise_error(described_class::Error)
61
- end
62
-
63
- context 'when running under bundler' do
64
- before { subject.should_receive(:running_under_bundler?).and_return(true) }
65
-
66
- it 'includes the Gemfile declaration to satisfy the dependency' do
67
- begin
68
- subject.load_depenencies
69
- rescue described_class::Error => e
70
- e.message.should include("gem 'listen', '~> 0.0.1'")
71
- end
72
- end
73
- end
74
-
75
- context 'when not running under bundler' do
76
- before { subject.should_receive(:running_under_bundler?).and_return(false) }
77
-
78
- it 'includes the command to install the dependency' do
79
- begin
80
- subject.load_depenencies
81
- rescue described_class::Error => e
82
- e.message.should include("gem install --version '~> 0.0.1' listen")
83
- end
84
- end
85
- end
86
- end
87
- end
88
-
89
- describe '#dependencies_loaded?' do
90
- it 'return false when dependencies are not loaded' do
91
- subject.dependency 'listen', '~> 0.0.1'
92
- subject.dependencies_loaded?.should be_false
93
- end
94
-
95
- it 'return true when dependencies are loaded' do
96
- subject.stub(:gem, :require)
97
-
98
- subject.dependency 'listen', '~> 0.0.1'
99
- subject.load_depenencies
100
- subject.dependencies_loaded?.should be_true
101
- end
102
-
103
- it 'return true when there are no dependencies to load' do
104
- subject.dependencies_loaded?.should be_true
105
- end
106
- end
107
- end
@@ -1,174 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Listen::MultiListener do
4
- let(:adapter) { mock(Listen::Adapter, :start => true).as_null_object }
5
- let(:watched_directories) { [File.dirname(__FILE__), File.expand_path('../..', __FILE__)] }
6
-
7
- subject { described_class.new(*watched_directories) }
8
-
9
- before do
10
- Listen::Adapter.stub(:select_and_initialize) { adapter }
11
- # Don't build a record of the files inside the base directory.
12
- Listen::DirectoryRecord.any_instance.stub(:build)
13
- end
14
-
15
- it_should_behave_like 'a listener to changes on a file-system'
16
-
17
- describe '#initialize' do
18
- context 'with no options' do
19
- it 'sets the directories' do
20
- subject.directories.should =~ watched_directories
21
- end
22
-
23
- it 'converts the passed paths into absolute paths - #21' do
24
- paths = watched_directories.map { |d| File.join(d, '..') }
25
- described_class.new(*paths).directories.should =~ watched_directories.map{ |d| File.expand_path('..', d) }
26
- end
27
- end
28
-
29
- context 'with custom options' do
30
- subject do
31
- args = watched_directories << {:ignore => /\.ssh/, :filter => [/.*\.rb/,/.*\.md/], :latency => 0.5, :force_polling => true}
32
- described_class.new(*args)
33
- end
34
-
35
- it 'passes the custom ignored paths to each directory record' do
36
- subject.directories_records.each do |r|
37
- r.ignoring_patterns.should include /\.ssh/
38
- end
39
- end
40
-
41
- it 'passes the custom filters to each directory record' do
42
- subject.directories_records.each do |r|
43
- r.filtering_patterns.should =~ [/.*\.rb/,/.*\.md/]
44
- end
45
- end
46
-
47
- it 'sets adapter_options' do
48
- subject.instance_variable_get(:@adapter_options).should eq(:latency => 0.5, :force_polling => true)
49
- end
50
- end
51
- end
52
-
53
- describe '#start' do
54
- it 'selects and initializes an adapter' do
55
- Listen::Adapter.should_receive(:select_and_initialize).with(watched_directories, {}) { adapter }
56
- subject.start
57
- end
58
-
59
- it 'builds all directories records' do
60
- subject.directories_records.each do |r|
61
- r.should_receive(:build)
62
- end
63
- subject.start
64
- end
65
- end
66
-
67
- context 'with a started listener' do
68
- before do
69
- subject.stub(:initialize_adapter) { adapter }
70
- subject.start
71
- end
72
-
73
- describe '#unpause' do
74
- it 'rebuilds all directories records' do
75
- subject.directories_records.each do |r|
76
- r.should_receive(:build)
77
- end
78
- subject.unpause
79
- end
80
- end
81
- end
82
-
83
- describe '#ignore' do
84
- it 'delegates the work to each directory record' do
85
- subject.directories_records.each do |r|
86
- r.should_receive(:ignore).with 'some_directory'
87
- end
88
- subject.ignore 'some_directory'
89
- end
90
- end
91
-
92
- describe '#ignore!' do
93
- it 'delegates the work to each directory record' do
94
- subject.directories_records.each do |r|
95
- r.should_receive(:ignore!).with 'some_directory'
96
- end
97
- subject.ignore! 'some_directory'
98
- end
99
- end
100
-
101
- describe '#filter' do
102
- it 'delegates the work to each directory record' do
103
- subject.directories_records.each do |r|
104
- r.should_receive(:filter).with /\.txt$/
105
- end
106
- subject.filter /\.txt$/
107
- end
108
- end
109
-
110
- describe '#filter!' do
111
- it 'delegates the work to each directory record' do
112
- subject.directories_records.each do |r|
113
- r.should_receive(:filter!).with /\.txt$/
114
- end
115
- subject.filter! /\.txt$/
116
- end
117
- end
118
-
119
- describe '#on_change' do
120
- let(:directories) { %w{dir1 dir2 dir3} }
121
- let(:changes) { {:modified => [], :added => [], :removed => []} }
122
- let(:callback) { Proc.new { @called = true } }
123
-
124
- before do
125
- @called = false
126
- subject.stub(:fetch_records_changes => changes)
127
- end
128
-
129
- it 'fetches the changes of all directories records' do
130
- subject.unstub(:fetch_records_changes)
131
-
132
- subject.directories_records.each do |record|
133
- record.should_receive(:fetch_changes).with(
134
- directories, hash_including(:relative_paths => described_class::DEFAULT_TO_RELATIVE_PATHS)
135
- ).and_return(changes)
136
- end
137
- subject.on_change(directories)
138
- end
139
-
140
- context 'with no changes to report' do
141
- if RUBY_VERSION[/^1.8/]
142
- it 'does not run the callback' do
143
- subject.change(&callback)
144
- subject.on_change(directories)
145
- @called.should be_false
146
- end
147
- else
148
- it 'does not run the callback' do
149
- callback.should_not_receive(:call)
150
- subject.change(&callback)
151
- subject.on_change(directories)
152
- end
153
- end
154
- end
155
-
156
- context 'with changes to report' do
157
- let(:changes) { {:modified => %w{path1}, :added => [], :removed => %w{path2}} }
158
-
159
- if RUBY_VERSION[/^1.8/]
160
- it 'runs the callback passing it the changes' do
161
- subject.change(&callback)
162
- subject.on_change(directories)
163
- @called.should be_true
164
- end
165
- else
166
- it 'runs the callback passing it the changes' do
167
- callback.should_receive(:call).with(changes[:modified], changes[:added], changes[:removed])
168
- subject.change(&callback)
169
- subject.on_change(directories)
170
- end
171
- end
172
- end
173
- end
174
- end