sass 3.1.0 → 3.3.0

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 (260) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING +1 -1
  3. data/MIT-LICENSE +2 -2
  4. data/README.md +29 -17
  5. data/Rakefile +43 -9
  6. data/VERSION +1 -1
  7. data/VERSION_DATE +1 -0
  8. data/VERSION_NAME +1 -1
  9. data/bin/sass +6 -1
  10. data/bin/sass-convert +6 -1
  11. data/bin/scss +6 -1
  12. data/ext/mkrf_conf.rb +27 -0
  13. data/lib/sass/cache_stores/base.rb +7 -3
  14. data/lib/sass/cache_stores/chain.rb +3 -2
  15. data/lib/sass/cache_stores/filesystem.rb +5 -7
  16. data/lib/sass/cache_stores/memory.rb +1 -1
  17. data/lib/sass/cache_stores/null.rb +2 -2
  18. data/lib/sass/callbacks.rb +2 -1
  19. data/lib/sass/css.rb +168 -53
  20. data/lib/sass/engine.rb +502 -174
  21. data/lib/sass/environment.rb +151 -111
  22. data/lib/sass/error.rb +7 -7
  23. data/lib/sass/exec.rb +176 -60
  24. data/lib/sass/features.rb +40 -0
  25. data/lib/sass/importers/base.rb +46 -7
  26. data/lib/sass/importers/deprecated_path.rb +51 -0
  27. data/lib/sass/importers/filesystem.rb +113 -30
  28. data/lib/sass/importers.rb +1 -0
  29. data/lib/sass/logger/base.rb +30 -0
  30. data/lib/sass/logger/log_level.rb +45 -0
  31. data/lib/sass/logger.rb +12 -0
  32. data/lib/sass/media.rb +213 -0
  33. data/lib/sass/plugin/compiler.rb +194 -104
  34. data/lib/sass/plugin/configuration.rb +18 -25
  35. data/lib/sass/plugin/merb.rb +1 -1
  36. data/lib/sass/plugin/staleness_checker.rb +37 -11
  37. data/lib/sass/plugin.rb +10 -13
  38. data/lib/sass/railtie.rb +2 -1
  39. data/lib/sass/repl.rb +5 -6
  40. data/lib/sass/script/css_lexer.rb +8 -4
  41. data/lib/sass/script/css_parser.rb +5 -2
  42. data/lib/sass/script/functions.rb +1547 -618
  43. data/lib/sass/script/lexer.rb +122 -72
  44. data/lib/sass/script/parser.rb +304 -135
  45. data/lib/sass/script/tree/funcall.rb +306 -0
  46. data/lib/sass/script/{interpolation.rb → tree/interpolation.rb} +43 -13
  47. data/lib/sass/script/tree/list_literal.rb +77 -0
  48. data/lib/sass/script/tree/literal.rb +45 -0
  49. data/lib/sass/script/tree/map_literal.rb +64 -0
  50. data/lib/sass/script/{node.rb → tree/node.rb} +30 -12
  51. data/lib/sass/script/{operation.rb → tree/operation.rb} +33 -21
  52. data/lib/sass/script/{string_interpolation.rb → tree/string_interpolation.rb} +14 -4
  53. data/lib/sass/script/{unary_operation.rb → tree/unary_operation.rb} +21 -9
  54. data/lib/sass/script/tree/variable.rb +57 -0
  55. data/lib/sass/script/tree.rb +15 -0
  56. data/lib/sass/script/value/arg_list.rb +36 -0
  57. data/lib/sass/script/value/base.rb +238 -0
  58. data/lib/sass/script/value/bool.rb +40 -0
  59. data/lib/sass/script/{color.rb → value/color.rb} +256 -74
  60. data/lib/sass/script/value/deprecated_false.rb +55 -0
  61. data/lib/sass/script/value/helpers.rb +155 -0
  62. data/lib/sass/script/value/list.rb +128 -0
  63. data/lib/sass/script/value/map.rb +70 -0
  64. data/lib/sass/script/value/null.rb +49 -0
  65. data/lib/sass/script/{number.rb → value/number.rb} +115 -62
  66. data/lib/sass/script/{string.rb → value/string.rb} +9 -11
  67. data/lib/sass/script/value.rb +12 -0
  68. data/lib/sass/script.rb +35 -9
  69. data/lib/sass/scss/css_parser.rb +2 -12
  70. data/lib/sass/scss/parser.rb +657 -230
  71. data/lib/sass/scss/rx.rb +17 -12
  72. data/lib/sass/scss/static_parser.rb +37 -6
  73. data/lib/sass/scss.rb +0 -1
  74. data/lib/sass/selector/abstract_sequence.rb +35 -3
  75. data/lib/sass/selector/comma_sequence.rb +29 -14
  76. data/lib/sass/selector/sequence.rb +371 -74
  77. data/lib/sass/selector/simple.rb +28 -13
  78. data/lib/sass/selector/simple_sequence.rb +163 -36
  79. data/lib/sass/selector.rb +138 -36
  80. data/lib/sass/shared.rb +3 -5
  81. data/lib/sass/source/map.rb +196 -0
  82. data/lib/sass/source/position.rb +39 -0
  83. data/lib/sass/source/range.rb +41 -0
  84. data/lib/sass/stack.rb +126 -0
  85. data/lib/sass/supports.rb +228 -0
  86. data/lib/sass/tree/at_root_node.rb +82 -0
  87. data/lib/sass/tree/comment_node.rb +34 -29
  88. data/lib/sass/tree/content_node.rb +9 -0
  89. data/lib/sass/tree/css_import_node.rb +60 -0
  90. data/lib/sass/tree/debug_node.rb +3 -3
  91. data/lib/sass/tree/directive_node.rb +33 -3
  92. data/lib/sass/tree/each_node.rb +9 -9
  93. data/lib/sass/tree/extend_node.rb +20 -6
  94. data/lib/sass/tree/for_node.rb +6 -6
  95. data/lib/sass/tree/function_node.rb +12 -4
  96. data/lib/sass/tree/if_node.rb +2 -15
  97. data/lib/sass/tree/import_node.rb +11 -5
  98. data/lib/sass/tree/media_node.rb +27 -11
  99. data/lib/sass/tree/mixin_def_node.rb +15 -4
  100. data/lib/sass/tree/mixin_node.rb +27 -7
  101. data/lib/sass/tree/node.rb +69 -35
  102. data/lib/sass/tree/prop_node.rb +47 -31
  103. data/lib/sass/tree/return_node.rb +4 -3
  104. data/lib/sass/tree/root_node.rb +20 -4
  105. data/lib/sass/tree/rule_node.rb +37 -26
  106. data/lib/sass/tree/supports_node.rb +38 -0
  107. data/lib/sass/tree/trace_node.rb +33 -0
  108. data/lib/sass/tree/variable_node.rb +10 -4
  109. data/lib/sass/tree/visitors/base.rb +5 -8
  110. data/lib/sass/tree/visitors/check_nesting.rb +67 -52
  111. data/lib/sass/tree/visitors/convert.rb +134 -53
  112. data/lib/sass/tree/visitors/cssize.rb +245 -51
  113. data/lib/sass/tree/visitors/deep_copy.rb +102 -0
  114. data/lib/sass/tree/visitors/extend.rb +68 -0
  115. data/lib/sass/tree/visitors/perform.rb +331 -105
  116. data/lib/sass/tree/visitors/set_options.rb +125 -0
  117. data/lib/sass/tree/visitors/to_css.rb +259 -95
  118. data/lib/sass/tree/warn_node.rb +3 -3
  119. data/lib/sass/tree/while_node.rb +3 -3
  120. data/lib/sass/util/cross_platform_random.rb +19 -0
  121. data/lib/sass/util/multibyte_string_scanner.rb +157 -0
  122. data/lib/sass/util/normalized_map.rb +130 -0
  123. data/lib/sass/util/ordered_hash.rb +192 -0
  124. data/lib/sass/util/subset_map.rb +11 -2
  125. data/lib/sass/util/test.rb +9 -0
  126. data/lib/sass/util.rb +565 -39
  127. data/lib/sass/version.rb +27 -15
  128. data/lib/sass.rb +39 -4
  129. data/test/sass/cache_test.rb +15 -0
  130. data/test/sass/compiler_test.rb +223 -0
  131. data/test/sass/conversion_test.rb +901 -107
  132. data/test/sass/css2sass_test.rb +94 -0
  133. data/test/sass/engine_test.rb +1059 -164
  134. data/test/sass/exec_test.rb +86 -0
  135. data/test/sass/extend_test.rb +933 -837
  136. data/test/sass/fixtures/test_staleness_check_across_importers.css +1 -0
  137. data/test/sass/fixtures/test_staleness_check_across_importers.scss +1 -0
  138. data/test/sass/functions_test.rb +995 -136
  139. data/test/sass/importer_test.rb +338 -18
  140. data/test/sass/logger_test.rb +58 -0
  141. data/test/sass/more_results/more_import.css +2 -2
  142. data/test/sass/plugin_test.rb +114 -30
  143. data/test/sass/results/cached_import_option.css +3 -0
  144. data/test/sass/results/filename_fn.css +3 -0
  145. data/test/sass/results/import.css +2 -2
  146. data/test/sass/results/import_charset.css +1 -0
  147. data/test/sass/results/import_charset_1_8.css +1 -0
  148. data/test/sass/results/import_charset_ibm866.css +1 -0
  149. data/test/sass/results/import_content.css +1 -0
  150. data/test/sass/results/script.css +1 -1
  151. data/test/sass/results/scss_import.css +2 -2
  152. data/test/sass/results/units.css +2 -2
  153. data/test/sass/script_conversion_test.rb +43 -1
  154. data/test/sass/script_test.rb +380 -36
  155. data/test/sass/scss/css_test.rb +257 -75
  156. data/test/sass/scss/scss_test.rb +2322 -110
  157. data/test/sass/source_map_test.rb +887 -0
  158. data/test/sass/templates/_cached_import_option_partial.scss +1 -0
  159. data/test/sass/templates/_double_import_loop2.sass +1 -0
  160. data/test/sass/templates/_filename_fn_import.scss +11 -0
  161. data/test/sass/templates/_imported_content.sass +3 -0
  162. data/test/sass/templates/_same_name_different_partiality.scss +1 -0
  163. data/test/sass/templates/bork5.sass +3 -0
  164. data/test/sass/templates/cached_import_option.scss +3 -0
  165. data/test/sass/templates/double_import_loop1.sass +1 -0
  166. data/test/sass/templates/filename_fn.scss +18 -0
  167. data/test/sass/templates/import_charset.sass +2 -0
  168. data/test/sass/templates/import_charset_1_8.sass +2 -0
  169. data/test/sass/templates/import_charset_ibm866.sass +2 -0
  170. data/test/sass/templates/import_content.sass +4 -0
  171. data/test/sass/templates/same_name_different_ext.sass +2 -0
  172. data/test/sass/templates/same_name_different_ext.scss +1 -0
  173. data/test/sass/templates/same_name_different_partiality.scss +1 -0
  174. data/test/sass/templates/single_import_loop.sass +1 -0
  175. data/test/sass/templates/subdir/import_up1.scss +1 -0
  176. data/test/sass/templates/subdir/import_up2.scss +1 -0
  177. data/test/sass/test_helper.rb +1 -1
  178. data/test/sass/util/multibyte_string_scanner_test.rb +147 -0
  179. data/test/sass/util/normalized_map_test.rb +51 -0
  180. data/test/sass/util_test.rb +183 -0
  181. data/test/sass/value_helpers_test.rb +181 -0
  182. data/test/test_helper.rb +45 -5
  183. data/vendor/listen/CHANGELOG.md +228 -0
  184. data/vendor/listen/CONTRIBUTING.md +38 -0
  185. data/vendor/listen/Gemfile +30 -0
  186. data/vendor/listen/Guardfile +8 -0
  187. data/vendor/{fssm → listen}/LICENSE +1 -1
  188. data/vendor/listen/README.md +315 -0
  189. data/vendor/listen/Rakefile +47 -0
  190. data/vendor/listen/Vagrantfile +96 -0
  191. data/vendor/listen/lib/listen/adapter.rb +214 -0
  192. data/vendor/listen/lib/listen/adapters/bsd.rb +112 -0
  193. data/vendor/listen/lib/listen/adapters/darwin.rb +85 -0
  194. data/vendor/listen/lib/listen/adapters/linux.rb +113 -0
  195. data/vendor/listen/lib/listen/adapters/polling.rb +67 -0
  196. data/vendor/listen/lib/listen/adapters/windows.rb +87 -0
  197. data/vendor/listen/lib/listen/dependency_manager.rb +126 -0
  198. data/vendor/listen/lib/listen/directory_record.rb +371 -0
  199. data/vendor/listen/lib/listen/listener.rb +225 -0
  200. data/vendor/listen/lib/listen/multi_listener.rb +143 -0
  201. data/vendor/listen/lib/listen/turnstile.rb +28 -0
  202. data/vendor/listen/lib/listen/version.rb +3 -0
  203. data/vendor/listen/lib/listen.rb +40 -0
  204. data/vendor/listen/listen.gemspec +22 -0
  205. data/vendor/listen/spec/listen/adapter_spec.rb +183 -0
  206. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +36 -0
  207. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +37 -0
  208. data/vendor/listen/spec/listen/adapters/linux_spec.rb +47 -0
  209. data/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
  210. data/vendor/listen/spec/listen/adapters/windows_spec.rb +30 -0
  211. data/vendor/listen/spec/listen/dependency_manager_spec.rb +107 -0
  212. data/vendor/listen/spec/listen/directory_record_spec.rb +1225 -0
  213. data/vendor/listen/spec/listen/listener_spec.rb +169 -0
  214. data/vendor/listen/spec/listen/multi_listener_spec.rb +174 -0
  215. data/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
  216. data/vendor/listen/spec/listen_spec.rb +73 -0
  217. data/vendor/listen/spec/spec_helper.rb +21 -0
  218. data/vendor/listen/spec/support/adapter_helper.rb +629 -0
  219. data/vendor/listen/spec/support/directory_record_helper.rb +55 -0
  220. data/vendor/listen/spec/support/fixtures_helper.rb +29 -0
  221. data/vendor/listen/spec/support/listeners_helper.rb +156 -0
  222. data/vendor/listen/spec/support/platform_helper.rb +15 -0
  223. metadata +344 -271
  224. data/lib/sass/less.rb +0 -382
  225. data/lib/sass/script/bool.rb +0 -18
  226. data/lib/sass/script/funcall.rb +0 -162
  227. data/lib/sass/script/list.rb +0 -76
  228. data/lib/sass/script/literal.rb +0 -245
  229. data/lib/sass/script/variable.rb +0 -54
  230. data/lib/sass/scss/sass_parser.rb +0 -11
  231. data/test/sass/less_conversion_test.rb +0 -653
  232. data/vendor/fssm/README.markdown +0 -55
  233. data/vendor/fssm/Rakefile +0 -59
  234. data/vendor/fssm/VERSION.yml +0 -5
  235. data/vendor/fssm/example.rb +0 -9
  236. data/vendor/fssm/fssm.gemspec +0 -77
  237. data/vendor/fssm/lib/fssm/backends/fsevents.rb +0 -36
  238. data/vendor/fssm/lib/fssm/backends/inotify.rb +0 -26
  239. data/vendor/fssm/lib/fssm/backends/polling.rb +0 -25
  240. data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +0 -131
  241. data/vendor/fssm/lib/fssm/monitor.rb +0 -26
  242. data/vendor/fssm/lib/fssm/path.rb +0 -91
  243. data/vendor/fssm/lib/fssm/pathname.rb +0 -502
  244. data/vendor/fssm/lib/fssm/state/directory.rb +0 -57
  245. data/vendor/fssm/lib/fssm/state/file.rb +0 -24
  246. data/vendor/fssm/lib/fssm/support.rb +0 -63
  247. data/vendor/fssm/lib/fssm/tree.rb +0 -176
  248. data/vendor/fssm/lib/fssm.rb +0 -33
  249. data/vendor/fssm/profile/prof-cache.rb +0 -40
  250. data/vendor/fssm/profile/prof-fssm-pathname.html +0 -1231
  251. data/vendor/fssm/profile/prof-pathname.rb +0 -68
  252. data/vendor/fssm/profile/prof-plain-pathname.html +0 -988
  253. data/vendor/fssm/profile/prof.html +0 -2379
  254. data/vendor/fssm/spec/path_spec.rb +0 -75
  255. data/vendor/fssm/spec/root/duck/quack.txt +0 -0
  256. data/vendor/fssm/spec/root/file.css +0 -0
  257. data/vendor/fssm/spec/root/file.rb +0 -0
  258. data/vendor/fssm/spec/root/file.yml +0 -0
  259. data/vendor/fssm/spec/root/moo/cow.txt +0 -0
  260. data/vendor/fssm/spec/spec_helper.rb +0 -14
data/lib/sass/version.rb CHANGED
@@ -1,6 +1,4 @@
1
- # This is necessary for loading Sass when Haml is required in Rails 3.
2
- # Once the split is complete, we can remove it.
3
- require File.dirname(__FILE__) + '/../sass'
1
+ require 'date'
4
2
  require 'sass/util'
5
3
 
6
4
  module Sass
@@ -9,13 +7,13 @@ module Sass
9
7
  # but its Git revision hash as well,
10
8
  # if it was installed from Git.
11
9
  module Version
12
- include Sass::Util
13
-
14
10
  # Returns a hash representing the version of Sass.
15
11
  # The `:major`, `:minor`, and `:teeny` keys have their respective numbers as Fixnums.
16
12
  # The `:name` key has the name of the version.
17
13
  # The `:string` key contains a human-readable string representation of the version.
18
14
  # The `:number` key is the major, minor, and teeny keys separated by periods.
15
+ # The `:date` key, which is not guaranteed to be defined, is the `DateTime`
16
+ # at which this release was cut.
19
17
  # If Sass is checked out from Git, the `:rev` key will have the revision hash.
20
18
  # For example:
21
19
  #
@@ -23,6 +21,7 @@ module Sass
23
21
  # :string => "2.1.0.9616393",
24
22
  # :rev => "9616393b8924ef36639c7e82aa88a51a24d16949",
25
23
  # :number => "2.1.0",
24
+ # :date => DateTime.parse("Apr 30 13:52:01 2009 -0700"),
26
25
  # :major => 2, :minor => 1, :teeny => 0
27
26
  # }
28
27
  #
@@ -36,18 +35,21 @@ module Sass
36
35
  # {
37
36
  # :string => "3.0.beta.1",
38
37
  # :number => "3.0.beta.1",
38
+ # :date => DateTime.parse("Mar 31 00:38:04 2010 -0700"),
39
39
  # :major => 3, :minor => 0, :teeny => -1,
40
40
  # :prerelease => "beta",
41
41
  # :prerelease_number => 1
42
42
  # }
43
43
  #
44
44
  # @return [{Symbol => String/Fixnum}] The version hash
45
+ # @comment
46
+ # rubocop:disable ClassVars
45
47
  def version
46
48
  return @@version if defined?(@@version)
47
49
 
48
- numbers = File.read(scope('VERSION')).strip.split('.').
50
+ numbers = File.read(Sass::Util.scope('VERSION')).strip.split('.').
49
51
  map {|n| n =~ /^[0-9]+$/ ? n.to_i : n}
50
- name = File.read(scope('VERSION_NAME')).strip
52
+ name = File.read(Sass::Util.scope('VERSION_NAME')).strip
51
53
  @@version = {
52
54
  :major => numbers[0],
53
55
  :minor => numbers[1],
@@ -55,6 +57,10 @@ module Sass
55
57
  :name => name
56
58
  }
57
59
 
60
+ if (date = version_date)
61
+ @@version[:date] = date
62
+ end
63
+
58
64
  if numbers[3].is_a?(String)
59
65
  @@version[:teeny] = -1
60
66
  @@version[:prerelease] = numbers[3]
@@ -64,7 +70,7 @@ module Sass
64
70
  @@version[:number] = numbers.join('.')
65
71
  @@version[:string] = @@version[:number].dup
66
72
 
67
- if rev = revision_number
73
+ if (rev = revision_number)
68
74
  @@version[:rev] = rev
69
75
  unless rev[0] == ?(
70
76
  @@version[:string] << "." << rev[0...7]
@@ -74,22 +80,23 @@ module Sass
74
80
  @@version[:string] << " (#{name})"
75
81
  @@version
76
82
  end
83
+ # rubocop:enable ClassVars
77
84
 
78
85
  private
79
86
 
80
87
  def revision_number
81
- if File.exists?(scope('REVISION'))
82
- rev = File.read(scope('REVISION')).strip
88
+ if File.exists?(Sass::Util.scope('REVISION'))
89
+ rev = File.read(Sass::Util.scope('REVISION')).strip
83
90
  return rev unless rev =~ /^([a-f0-9]+|\(.*\))$/ || rev == '(unknown)'
84
91
  end
85
92
 
86
- return unless File.exists?(scope('.git/HEAD'))
87
- rev = File.read(scope('.git/HEAD')).strip
93
+ return unless File.exists?(Sass::Util.scope('.git/HEAD'))
94
+ rev = File.read(Sass::Util.scope('.git/HEAD')).strip
88
95
  return rev unless rev =~ /^ref: (.*)$/
89
96
 
90
97
  ref_name = $1
91
- ref_file = scope(".git/#{ref_name}")
92
- info_file = scope(".git/info/refs")
98
+ ref_file = Sass::Util.scope(".git/#{ref_name}")
99
+ info_file = Sass::Util.scope(".git/info/refs")
93
100
  return File.read(ref_file).strip if File.exists?(ref_file)
94
101
  return unless File.exists?(info_file)
95
102
  File.open(info_file) do |f|
@@ -99,7 +106,12 @@ module Sass
99
106
  return sha
100
107
  end
101
108
  end
102
- return nil
109
+ nil
110
+ end
111
+
112
+ def version_date
113
+ return unless File.exists?(Sass::Util.scope('VERSION_DATE'))
114
+ DateTime.parse(File.read(Sass::Util.scope('VERSION_DATE')).strip)
103
115
  end
104
116
  end
105
117
 
data/lib/sass.rb CHANGED
@@ -17,6 +17,36 @@ require 'sass/version'
17
17
  #
18
18
  # Also see the {file:SASS_REFERENCE.md full Sass reference}.
19
19
  module Sass
20
+ class << self
21
+ # @private
22
+ attr_accessor :tests_running
23
+ end
24
+
25
+ # The global load paths for Sass files. This is meant for plugins and
26
+ # libraries to register the paths to their Sass stylesheets to that they may
27
+ # be `@imported`. This load path is used by every instance of {Sass::Engine}.
28
+ # They are lower-precedence than any load paths passed in via the
29
+ # {file:SASS_REFERENCE.md#load_paths-option `:load_paths` option}.
30
+ #
31
+ # If the `SASS_PATH` environment variable is set,
32
+ # the initial value of `load_paths` will be initialized based on that.
33
+ # The variable should be a colon-separated list of path names
34
+ # (semicolon-separated on Windows).
35
+ #
36
+ # Note that files on the global load path are never compiled to CSS
37
+ # themselves, even if they aren't partials. They exist only to be imported.
38
+ #
39
+ # @example
40
+ # Sass.load_paths << File.dirname(__FILE__ + '/sass')
41
+ # @return [Array<String, Pathname, Sass::Importers::Base>]
42
+ def self.load_paths
43
+ @load_paths ||= if ENV['SASS_PATH']
44
+ ENV['SASS_PATH'].split(Sass::Util.windows? ? ';' : ':')
45
+ else
46
+ []
47
+ end
48
+ end
49
+
20
50
  # Compile a Sass or SCSS string to CSS.
21
51
  # Defaults to SCSS.
22
52
  #
@@ -34,9 +64,6 @@ module Sass
34
64
 
35
65
  # Compile a file on disk to CSS.
36
66
  #
37
- # @param filename [String] The path to the Sass, SCSS, or CSS file on disk.
38
- # @param options [{Symbol => Object}] An options hash;
39
- # see {file:SASS_REFERENCE.md#sass_options the Sass options documentation}
40
67
  # @raise [Sass::SyntaxError] if there's an error in the document
41
68
  # @raise [Encoding::UndefinedConversionError] if the source encoding
42
69
  # cannot be converted to UTF-8
@@ -45,11 +72,17 @@ module Sass
45
72
  # @overload compile_file(filename, options = {})
46
73
  # Return the compiled CSS rather than writing it to a file.
47
74
  #
75
+ # @param filename [String] The path to the Sass, SCSS, or CSS file on disk.
76
+ # @param options [{Symbol => Object}] An options hash;
77
+ # see {file:SASS_REFERENCE.md#sass_options the Sass options documentation}
48
78
  # @return [String] The compiled CSS.
49
79
  #
50
80
  # @overload compile_file(filename, css_filename, options = {})
51
81
  # Write the compiled CSS to a file.
52
82
  #
83
+ # @param filename [String] The path to the Sass, SCSS, or CSS file on disk.
84
+ # @param options [{Symbol => Object}] An options hash;
85
+ # see {file:SASS_REFERENCE.md#sass_options the Sass options documentation}
53
86
  # @param css_filename [String] The location to which to write the compiled CSS.
54
87
  def self.compile_file(filename, *args)
55
88
  options = args.last.is_a?(Hash) ? args.pop : {}
@@ -57,7 +90,7 @@ module Sass
57
90
  result = Sass::Engine.for_file(filename, options).render
58
91
  if css_filename
59
92
  options[:css_filename] ||= css_filename
60
- open(css_filename,"w") {|css_file| css_file.write(result)}
93
+ open(css_filename, "w") {|css_file| css_file.write(result)}
61
94
  nil
62
95
  else
63
96
  result
@@ -65,8 +98,10 @@ module Sass
65
98
  end
66
99
  end
67
100
 
101
+ require 'sass/logger'
68
102
  require 'sass/util'
69
103
 
70
104
  require 'sass/engine'
71
105
  require 'sass/plugin' if defined?(Merb::Plugins)
72
106
  require 'sass/railtie'
107
+ require 'sass/features'
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  require File.dirname(__FILE__) + '/../test_helper'
3
+ require File.dirname(__FILE__) + '/test_helper'
3
4
  require 'sass/engine'
4
5
 
5
6
  class CacheTest < Test::Unit::TestCase
@@ -11,6 +12,7 @@ class CacheTest < Test::Unit::TestCase
11
12
 
12
13
  def teardown
13
14
  FileUtils.rm_rf @@cache_dir
15
+ clean_up_sassc
14
16
  end
15
17
 
16
18
  def test_file_cache_writes_a_file
@@ -64,6 +66,19 @@ class CacheTest < Test::Unit::TestCase
64
66
  assert_equal an_object, cache.retrieve("an_object", "")
65
67
  end
66
68
 
69
+ class Unmarshalable
70
+ def _dump(_)
71
+ raise 'Unmarshalable'
72
+ end
73
+ end
74
+
75
+ def test_cache_node_with_unmarshalable_option
76
+ engine = Sass::Engine.new("foo {a: b + c}",
77
+ :syntax => :scss, :object => Unmarshalable.new, :filename => 'file.scss',
78
+ :importer => Sass::Importers::Filesystem.new(absolutize('templates')))
79
+ engine.to_tree
80
+ end
81
+
67
82
  private
68
83
  def root_node
69
84
  Sass::Engine.new(<<-SCSS, :syntax => :scss).to_tree
@@ -0,0 +1,223 @@
1
+ #!/usr/bin/env ruby
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../test_helper'
4
+ require 'sass/plugin'
5
+ require 'sass/plugin/compiler'
6
+
7
+ class CompilerTest < Test::Unit::TestCase
8
+ class FakeListener
9
+ attr_accessor :options
10
+ attr_accessor :directories
11
+ attr_reader :start_called
12
+ attr_reader :thread
13
+
14
+ def initialize(*args, &on_filesystem_event)
15
+ self.options = args.last.is_a?(Hash) ? args.pop : {}
16
+ self.directories = args
17
+ @on_filesystem_event = on_filesystem_event
18
+ @start_called = false
19
+ reset_events!
20
+ end
21
+
22
+ def fire_events!(*args)
23
+ @on_filesystem_event.call(@modified, @added, @removed)
24
+ reset_events!
25
+ end
26
+
27
+ def changed(filename)
28
+ @modified << File.expand_path(filename)
29
+ end
30
+
31
+ def added(filename)
32
+ @added << File.expand_path(filename)
33
+ end
34
+
35
+ def removed(filename)
36
+ @removed << File.expand_path(filename)
37
+ end
38
+
39
+ def on_start!(&run_during_start)
40
+ @run_during_start = run_during_start
41
+ end
42
+
43
+ # used for Listen < 2.0
44
+ def start!
45
+ @run_during_start.call(self) if @run_during_start
46
+ end
47
+
48
+ # used for Listen >= 2.0
49
+ def start
50
+ @thread = Thread.new {@run_during_start.call(self) if @run_during_start}
51
+ end
52
+
53
+ def stop
54
+ end
55
+
56
+ def reset_events!
57
+ @modified = []
58
+ @added = []
59
+ @removed = []
60
+ end
61
+ end
62
+
63
+ module MockWatcher
64
+ attr_accessor :run_during_start
65
+ attr_accessor :update_stylesheets_times
66
+ attr_accessor :update_stylesheets_called_with
67
+ attr_accessor :deleted_css_files
68
+
69
+ def fake_listener
70
+ @fake_listener
71
+ end
72
+
73
+ def update_stylesheets(individual_files)
74
+ @update_stylesheets_times ||= 0
75
+ @update_stylesheets_times += 1
76
+ (@update_stylesheets_called_with ||= []) << individual_files
77
+ end
78
+
79
+ def try_delete_css(css_filename)
80
+ (@deleted_css_files ||= []) << css_filename
81
+ end
82
+
83
+ private
84
+ def create_listener(*args, &on_filesystem_event)
85
+ @fake_listener = FakeListener.new(*args, &on_filesystem_event)
86
+ @fake_listener.on_start!(&run_during_start)
87
+ @fake_listener
88
+ end
89
+ end
90
+
91
+ def test_initialize
92
+ watcher
93
+ end
94
+
95
+ def test_watch_starts_the_listener
96
+ start_called = false
97
+ c = watcher do |listener|
98
+ start_called = true
99
+ end
100
+ c.watch
101
+ assert start_called, "start! was not called"
102
+ end
103
+
104
+ def test_sass_callbacks_fire_from_listener_events
105
+ c = watcher do |listener|
106
+ listener.changed "changed.scss"
107
+ listener.added "added.scss"
108
+ listener.removed "removed.scss"
109
+ listener.fire_events!
110
+ end
111
+
112
+ modified_fired = false
113
+ c.on_template_modified do |sass_file|
114
+ modified_fired = true
115
+ assert_equal "changed.scss", sass_file
116
+ end
117
+
118
+ added_fired = false
119
+ c.on_template_created do |sass_file|
120
+ added_fired = true
121
+ assert_equal "added.scss", sass_file
122
+ end
123
+
124
+ removed_fired = false
125
+ c.on_template_deleted do |sass_file|
126
+ removed_fired = true
127
+ assert_equal "removed.scss", sass_file
128
+ end
129
+
130
+ c.watch
131
+
132
+ assert_equal 2, c.update_stylesheets_times
133
+ assert modified_fired
134
+ assert added_fired
135
+ assert removed_fired
136
+ end
137
+
138
+ def test_removing_a_sass_file_removes_corresponding_css_file
139
+ c = watcher do |listener|
140
+ listener.removed "remove_me.scss"
141
+ listener.fire_events!
142
+ end
143
+
144
+ c.watch
145
+
146
+ assert_equal "./remove_me.css", c.deleted_css_files.first
147
+ end
148
+
149
+ def test_an_importer_can_watch_an_image
150
+ image_importer = Sass::Importers::Filesystem.new(".")
151
+ class << image_importer
152
+ def watched_file?(filename)
153
+ filename =~ /\.png$/
154
+ end
155
+ end
156
+ c = watcher(:load_paths => [image_importer]) do |listener|
157
+ listener.changed "image.png"
158
+ listener.fire_events!
159
+ end
160
+
161
+ modified_fired = false
162
+ c.on_template_modified do |f|
163
+ modified_fired = true
164
+ assert_equal "image.png", f
165
+ end
166
+
167
+ c.watch
168
+
169
+ assert_equal 2, c.update_stylesheets_times
170
+ assert modified_fired
171
+ end
172
+
173
+ def test_watching_specific_files_and_one_is_deleted
174
+ directories = nil
175
+ c = watcher do |listener|
176
+ directories = listener.directories
177
+ listener.removed "/asdf/foobar/sass/foo.scss"
178
+ listener.fire_events!
179
+ end
180
+ c.watch([["/asdf/foobar/sass/foo.scss", "/asdf/foobar/css/foo.css", nil]])
181
+ assert directories.include?("/asdf/foobar/sass"), directories.inspect
182
+ assert_equal "/asdf/foobar/css/foo.css", c.deleted_css_files.first, "the corresponding css file was not deleted"
183
+ assert_equal [], c.update_stylesheets_called_with[1], "the sass file should not have been compiled"
184
+ end
185
+
186
+ def test_watched_directories_are_dedupped
187
+ directories = nil
188
+ c = watcher(:load_paths => [".", "./foo", "."]) do |listener|
189
+ directories = listener.directories
190
+ end
191
+ c.watch
192
+ assert_equal [File.expand_path(".")], directories
193
+ end
194
+
195
+ def test_a_changed_css_in_a_watched_directory_does_not_force_a_compile
196
+ c = watcher do |listener|
197
+ listener.changed "foo.css"
198
+ listener.fire_events!
199
+ end
200
+
201
+ c.on_template_modified do |f|
202
+ assert false, "Should not have been called"
203
+ end
204
+
205
+ c.watch
206
+
207
+ assert_equal 1, c.update_stylesheets_times
208
+ end
209
+
210
+ private
211
+
212
+ def default_options
213
+ {:template_location => [[".","."]]}
214
+ end
215
+
216
+ def watcher(options = {}, &run_during_start)
217
+ options = default_options.merge(options)
218
+ watcher = Sass::Plugin::Compiler.new(options)
219
+ watcher.extend(MockWatcher)
220
+ watcher.run_during_start = run_during_start
221
+ watcher
222
+ end
223
+ end