sass 3.2.1 → 3.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -173,10 +173,11 @@ See `sass-convert --help` for further information and options.
173
173
 
174
174
  ## Authors
175
175
 
176
- Sass was envisioned by [Hampton Catlin](http://hamptoncatlin.com) (hcatlin).
177
- However, Hampton doesn't even know his way around the code anymore and now
178
- occasionally consults on the language issues. Hampton lives in Cambridge, UK and
179
- is the owner of [Catlin Software](http://www.catlinsoftware.com/).
176
+ Sass was envisioned by [Hampton Catlin](http://www.hamptoncatlin.com)
177
+ (@hcatlin). However, Hampton doesn't even know his way around the code anymore
178
+ and now occasionally consults on the language issues. Hampton lives in San
179
+ Francisco, California and works as VP of Technology
180
+ at [Moovweb](http://www.moovweb.com/).
180
181
 
181
182
  [Nathan Weizenbaum](http://nex-3.com) is the primary developer and architect of
182
183
  Sass. His hard work has kept the project alive by endlessly answering forum
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.2.1
1
+ 3.2.2
data/VERSION_DATE CHANGED
@@ -1 +1 @@
1
- 16 August 2012 00:34:28 UTC
1
+ 03 November 2012 01:05:14 UTC
@@ -48,7 +48,7 @@ module Sass
48
48
  # @param name [Symbol] The name of the callback
49
49
  # @return [void]
50
50
  def define_callback(name)
51
- class_eval <<RUBY
51
+ class_eval <<RUBY, __FILE__, __LINE__ + 1
52
52
  def on_#{name}(&block)
53
53
  @_sass_callbacks ||= {}
54
54
  (@_sass_callbacks[#{name.inspect}] ||= []) << block
data/lib/sass/engine.rb CHANGED
@@ -820,7 +820,7 @@ WARNING
820
820
  media_parser = Sass::SCSS::Parser.new(scanner, @options[:filename], @line)
821
821
  media = media_parser.parse_media_query_list
822
822
  Tree::CssImportNode.new(str || uri, media.to_a)
823
- elsif val =~ /^http:\/\//
823
+ elsif val =~ /^(https?:)?\/\//
824
824
  Tree::CssImportNode.new("url(#{val})")
825
825
  else
826
826
  Tree::ImportNode.new(val)
data/lib/sass/exec.rb CHANGED
@@ -125,6 +125,7 @@ module Sass
125
125
  def puts_action(name, color, arg)
126
126
  return if @options[:for_engine][:quiet]
127
127
  printf color(color, "%11s %s\n"), name, arg
128
+ STDOUT.flush
128
129
  end
129
130
 
130
131
  # Same as \{Kernel.puts}, but doesn't print anything if the `--quiet` option is set.
@@ -229,6 +230,10 @@ END
229
230
  'Only meaningful for --watch and --update.') do
230
231
  @options[:stop_on_error] = true
231
232
  end
233
+ opts.on('--poll', 'Check for file changes manually, rather than relying on the OS.',
234
+ 'Only meaningful for --watch.') do
235
+ @options[:poll] = true
236
+ end
232
237
  opts.on('-f', '--force', 'Recompile all Sass files, even if the CSS file is newer.',
233
238
  'Only meaningful for --update.') do
234
239
  @options[:force] = true
@@ -357,6 +362,7 @@ END
357
362
  require 'sass/plugin'
358
363
  ::Sass::Plugin.options.merge! @options[:for_engine]
359
364
  ::Sass::Plugin.options[:unix_newlines] = @options[:unix_newlines]
365
+ ::Sass::Plugin.options[:poll] = @options[:poll]
360
366
 
361
367
  if @options[:force]
362
368
  raise "The --force flag may only be used with --update." unless @options[:update]
@@ -1,4 +1,5 @@
1
1
  require 'pathname'
2
+ require 'set'
2
3
 
3
4
  module Sass
4
5
  module Importers
@@ -14,6 +15,7 @@ module Sass
14
15
  # This importer will import files relative to this path.
15
16
  def initialize(root)
16
17
  @root = File.expand_path(root)
18
+ @same_name_warnings = Set.new
17
19
  end
18
20
 
19
21
  # @see Base#find_relative
@@ -28,7 +30,7 @@ module Sass
28
30
 
29
31
  # @see Base#mtime
30
32
  def mtime(name, options)
31
- file, s = find_real_file(@root, name)
33
+ file, s = Sass::Util.destructure(find_real_file(@root, name, options))
32
34
  File.mtime(file) if file
33
35
  rescue Errno::ENOENT
34
36
  nil
@@ -106,15 +108,46 @@ module Sass
106
108
  # @param dir [String] The directory relative to which to search.
107
109
  # @param name [String] The filename to search for.
108
110
  # @return [(String, Symbol)] A filename-syntax pair.
109
- def find_real_file(dir, name)
110
- for (f,s) in possible_files(remove_root(name))
111
+ def find_real_file(dir, name, options)
112
+ found = possible_files(remove_root(name)).map do |f, s|
111
113
  path = (dir == "." || Pathname.new(f).absolute?) ? f : "#{dir}/#{f}"
112
- if full_path = Dir[path].first
113
- full_path.gsub!(REDUNDANT_DIRECTORY,File::SEPARATOR)
114
- return full_path, s
114
+ Dir[path].map do |full_path|
115
+ full_path.gsub!(REDUNDANT_DIRECTORY, File::SEPARATOR)
116
+ [full_path, s]
115
117
  end
116
118
  end
117
- nil
119
+ found = Sass::Util.flatten(found, 1)
120
+ return if found.empty?
121
+
122
+ if found.size > 1 && !@same_name_warnings.include?(found.first.first)
123
+ found.each {|(f, _)| @same_name_warnings << f}
124
+ relative_to = Pathname.new(dir)
125
+ if options[:_line]
126
+ # If _line exists, we're here due to an actual import in an
127
+ # import_node and we want to print a warning for a user writing an
128
+ # ambiguous import.
129
+ candidates = found.map {|(f, _)| " " + Pathname.new(f).relative_path_from(relative_to).to_s}.join("\n")
130
+ Sass::Util.sass_warn <<WARNING
131
+ WARNING: On line #{options[:_line]}#{" of #{options[:filename]}" if options[:filename]}:
132
+ It's not clear which file to import for '@import "#{name}"'.
133
+ Candidates:
134
+ #{candidates}
135
+ For now I'll choose #{File.basename found.first.first}.
136
+ This will be an error in future versions of Sass.
137
+ WARNING
138
+ else
139
+ # Otherwise, we're here via StalenessChecker, and we want to print a
140
+ # warning for a user running `sass --watch` with two ambiguous files.
141
+ candidates = found.map {|(f, _)| " " + File.basename(f)}.join("\n")
142
+ Sass::Util.sass_warn <<WARNING
143
+ WARNING: In #{File.dirname(name)}:
144
+ There are multiple files that match the name "#{File.basename(name)}":
145
+ #{candidates}
146
+ This will be an error in future versions of Sass.
147
+ WARNING
148
+ end
149
+ end
150
+ found.first
118
151
  end
119
152
 
120
153
  # Splits a filename into three parts, a directory part, a basename, and an extension
@@ -132,7 +165,7 @@ module Sass
132
165
  private
133
166
 
134
167
  def _find(dir, name, options)
135
- full_filename, syntax = find_real_file(dir, name)
168
+ full_filename, syntax = Sass::Util.destructure(find_real_file(dir, name, options))
136
169
  return unless full_filename && File.readable?(full_filename)
137
170
 
138
171
  options[:syntax] = syntax
@@ -36,14 +36,14 @@ module Sass
36
36
  end
37
37
 
38
38
  def define_logger(name, options = {})
39
- class_eval %Q{
39
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
40
40
  def #{name}(message)
41
41
  #{options.fetch(:to, :log)}(#{name.inspect}, message)
42
42
  end
43
- }
43
+ RUBY
44
44
  end
45
45
  end
46
46
 
47
47
  end
48
48
  end
49
- end
49
+ end
@@ -300,7 +300,7 @@ module Sass::Plugin
300
300
 
301
301
  # The native windows listener is much slower than the polling
302
302
  # option, according to https://github.com/nex3/sass/commit/a3031856b22bc834a5417dedecb038b7be9b9e3e#commitcomment-1295118
303
- listener.force_polling(true) if Sass::Util.windows?
303
+ listener.force_polling(true) if @options[:poll] || Sass::Util.windows?
304
304
 
305
305
  begin
306
306
  listener.start
@@ -140,7 +140,7 @@ module Sass
140
140
  end
141
141
 
142
142
  def dependencies(uri, importer)
143
- stored_mtime, dependencies = @dependencies[[uri, importer]]
143
+ stored_mtime, dependencies = Sass::Util.destructure(@dependencies[[uri, importer]])
144
144
 
145
145
  if !stored_mtime || stored_mtime < mtime(uri, importer)
146
146
  dependencies = compute_dependencies(uri, importer)
@@ -90,13 +90,13 @@ module Sass::Script
90
90
  #
91
91
  # ## Other Color Functions
92
92
  #
93
- # \{#adjust_color adjust-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\]}
93
+ # \{#adjust_color adjust-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\])}
94
94
  # : Increase or decrease any of the components of a color.
95
95
  #
96
- # \{#scale_color scale-color($color, \[$red\], \[$green\], \[$blue\], \[$saturation\], \[$lightness\], \[$alpha\]}
96
+ # \{#scale_color scale-color($color, \[$red\], \[$green\], \[$blue\], \[$saturation\], \[$lightness\], \[$alpha\])}
97
97
  # : Fluidly scale one or more components of a color.
98
98
  #
99
- # \{#change_color change-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\]}
99
+ # \{#change_color change-color($color, \[$red\], \[$green\], \[$blue\], \[$hue\], \[$saturation\], \[$lightness\], \[$alpha\])}
100
100
  # : Changes one or more properties of a color.
101
101
  #
102
102
  # \{#ie_hex_str ie-hex-str($color)}
@@ -1235,8 +1235,8 @@ module Sass::Script
1235
1235
  # arguments.
1236
1236
  #
1237
1237
  # @example
1238
- # max(1px, 4px) => 1px
1239
- # max(5em, 3em, 4em) => 3em
1238
+ # max(1px, 4px) => 4px
1239
+ # max(5em, 3em, 4em) => 5em
1240
1240
  # @return [Number] The maximum value
1241
1241
  # @raise [ArgumentError] if any argument isn't a number, or if not all of
1242
1242
  # the arguments have comparable units
@@ -203,7 +203,7 @@ module Sass
203
203
  # sub is the name of the production beneath it,
204
204
  # and ops is a list of operators for this precedence level
205
205
  def production(name, sub, *ops)
206
- class_eval <<RUBY
206
+ class_eval <<RUBY, __FILE__, __LINE__ + 1
207
207
  def #{name}
208
208
  interp = try_ops_after_interp(#{ops.inspect}, #{name.inspect}) and return interp
209
209
  return unless e = #{sub}
@@ -223,7 +223,7 @@ RUBY
223
223
  end
224
224
 
225
225
  def unary(op, sub)
226
- class_eval <<RUBY
226
+ class_eval <<RUBY, __FILE__, __LINE__ + 1
227
227
  def unary_#{op}
228
228
  return #{sub} unless tok = try_tok(:#{op})
229
229
  interp = try_op_before_interp(tok) and return interp
@@ -307,6 +307,7 @@ module Sass
307
307
  end
308
308
 
309
309
  def import_arg
310
+ line = @line
310
311
  return unless (str = tok(STRING)) || (uri = tok?(/url\(/i))
311
312
  if uri
312
313
  str = sass_script(:parse_string)
@@ -319,17 +320,19 @@ module Sass
319
320
  ss
320
321
 
321
322
  media = media_query_list
322
- if path =~ /^http:\/\// || media || use_css_import?
323
- return node(Sass::Tree::CssImportNode.new(str, media.to_a))
323
+ if path =~ /^(https?:)?\/\// || media || use_css_import?
324
+ node = Sass::Tree::CssImportNode.new(str, media.to_a)
325
+ else
326
+ node = Sass::Tree::ImportNode.new(path.strip)
324
327
  end
325
-
326
- node(Sass::Tree::ImportNode.new(path.strip))
328
+ node.line = line
329
+ node
327
330
  end
328
331
 
329
332
  def use_css_import?; false; end
330
333
 
331
334
  def media_directive
332
- block(node(Sass::Tree::MediaNode.new(media_query_list.to_a)), :directive)
335
+ block(node(Sass::Tree::MediaNode.new(expr!(:media_query_list).to_a)), :directive)
333
336
  end
334
337
 
335
338
  # http://www.w3.org/TR/css3-mediaqueries/#syntax
@@ -674,7 +677,7 @@ module Sass
674
677
  expected('"{"') if res.length == 1 && res[0].is_a?(Selector::Universal)
675
678
  throw_error {expected('"{"')}
676
679
  rescue Sass::SyntaxError => e
677
- e.message << "\n\n\"#{sel}\" may only be used at the beginning of a selector."
680
+ e.message << "\n\n\"#{sel}\" may only be used at the beginning of a compound selector."
678
681
  raise e
679
682
  end
680
683
  end
@@ -706,7 +709,7 @@ module Sass
706
709
  end
707
710
 
708
711
  def element_name
709
- ns, name = qualified_name(:allow_star_name)
712
+ ns, name = Sass::Util.destructure(qualified_name(:allow_star_name))
710
713
  return unless ns || name
711
714
 
712
715
  if name == '*'
@@ -797,7 +800,7 @@ module Sass
797
800
  # could start a pseudo expression like "n+1", or it could start a
798
801
  # selector like "n|m". In order to handle this, we must regrettably
799
802
  # backtrack.
800
- expr, sel = nil
803
+ expr, sel = nil, nil
801
804
  pseudo_err = catch_error do
802
805
  expr = pseudo_expr
803
806
  next if tok?(/[,)]/)
@@ -1021,6 +1024,7 @@ MESSAGE
1021
1024
 
1022
1025
  EXPR_NAMES = {
1023
1026
  :media_query => "media query (e.g. print, screen, print and screen)",
1027
+ :media_query_list => "media query (e.g. print, screen, print and screen)",
1024
1028
  :media_expr => "media expression (e.g. (min-device-width: 800px))",
1025
1029
  :pseudo_arg => "expression (e.g. fr, 2n+1)",
1026
1030
  :interp_ident => "identifier",
@@ -9,6 +9,9 @@ module Sass
9
9
  # @return [String]
10
10
  attr_reader :imported_filename
11
11
 
12
+ # Sets the imported file.
13
+ attr_writer :imported_file
14
+
12
15
  # @param imported_filename [String] The name of the imported file
13
16
  def initialize(imported_filename)
14
17
  @imported_filename = imported_filename
@@ -43,12 +46,12 @@ module Sass
43
46
 
44
47
  if @options[:importer]
45
48
  f = @options[:importer].find_relative(
46
- @imported_filename, @options[:filename], @options.dup)
49
+ @imported_filename, @options[:filename], options_for_importer)
47
50
  return f if f
48
51
  end
49
52
 
50
53
  paths.each do |p|
51
- if f = p.find(@imported_filename, @options.dup)
54
+ if f = p.find(@imported_filename, options_for_importer)
52
55
  return f
53
56
  end
54
57
  end
@@ -63,6 +66,10 @@ module Sass
63
66
  rescue SyntaxError => e
64
67
  raise SyntaxError.new(e.message, :line => self.line, :filename => @filename)
65
68
  end
69
+
70
+ def options_for_importer
71
+ @options.merge(:_line => line)
72
+ end
66
73
  end
67
74
  end
68
75
  end
@@ -218,15 +218,17 @@ class Sass::Tree::Visitors::Perform < Sass::Tree::Visitors::Base
218
218
  file = node.imported_file
219
219
  handle_import_loop!(node) if @stack.any? {|e| e[:filename] == file.options[:filename]}
220
220
 
221
- @stack.push(:filename => node.filename, :line => node.line)
222
- root = file.to_tree
223
- Sass::Tree::Visitors::CheckNesting.visit(root)
224
- node.children = root.children.map {|c| visit(c)}.flatten
225
- node
226
- rescue Sass::SyntaxError => e
227
- e.modify_backtrace(:filename => node.imported_file.options[:filename])
228
- e.add_backtrace(:filename => node.filename, :line => node.line)
229
- raise e
221
+ begin
222
+ @stack.push(:filename => node.filename, :line => node.line)
223
+ root = file.to_tree
224
+ Sass::Tree::Visitors::CheckNesting.visit(root)
225
+ node.children = root.children.map {|c| visit(c)}.flatten
226
+ node
227
+ rescue Sass::SyntaxError => e
228
+ e.modify_backtrace(:filename => node.imported_file.options[:filename])
229
+ e.add_backtrace(:filename => node.filename, :line => node.line)
230
+ raise e
231
+ end
230
232
  ensure
231
233
  @stack.pop unless path
232
234
  end
@@ -50,6 +50,14 @@ class Sass::Tree::Visitors::SetOptions < Sass::Tree::Visitors::Base
50
50
  yield
51
51
  end
52
52
 
53
+ def visit_import(node)
54
+ # We have no good way of propagating the new options through an Engine
55
+ # instance, so we just null it out. This also lets us avoid caching an
56
+ # imported Engine along with the importing source tree.
57
+ node.imported_file = nil
58
+ yield
59
+ end
60
+
53
61
  def visit_mixindef(node)
54
62
  node.args.each do |k, v|
55
63
  k.options = @options
data/lib/sass/util.rb CHANGED
@@ -467,6 +467,19 @@ module Sass
467
467
  Dir.glob(path, &block)
468
468
  end
469
469
 
470
+ # Prepare a value for a destructuring assignment (e.g. `a, b =
471
+ # val`). This works around a performance bug when using
472
+ # ActiveSupport, and only needs to be called when `val` is likely
473
+ # to be `nil` reasonably often.
474
+ #
475
+ # See [this bug report](http://redmine.ruby-lang.org/issues/4917).
476
+ #
477
+ # @param val [Object]
478
+ # @return [Object]
479
+ def destructure(val)
480
+ val || []
481
+ end
482
+
470
483
  ## Cross-Ruby-Version Compatibility
471
484
 
472
485
  # Whether or not this is running under Ruby 1.8 or lower.
@@ -145,8 +145,8 @@ MSG
145
145
  "$var: true\n@while $var\n @extend .bar\n $var: false" => ["Extend directives may only be used within rules.", 3],
146
146
  "@for $i from 0 to 1\n @extend .bar" => ["Extend directives may only be used within rules.", 2],
147
147
  "@mixin foo\n @extend .bar\n@include foo" => ["Extend directives may only be used within rules.", 2],
148
- "foo\n &a\n b: c" => ["Invalid CSS after \"&\": expected \"{\", was \"a\"\n\n\"a\" may only be used at the beginning of a selector.", 2],
149
- "foo\n &1\n b: c" => ["Invalid CSS after \"&\": expected \"{\", was \"1\"\n\n\"1\" may only be used at the beginning of a selector.", 2],
148
+ "foo\n &a\n b: c" => ["Invalid CSS after \"&\": expected \"{\", was \"a\"\n\n\"a\" may only be used at the beginning of a compound selector.", 2],
149
+ "foo\n &1\n b: c" => ["Invalid CSS after \"&\": expected \"{\", was \"1\"\n\n\"1\" may only be used at the beginning of a compound selector.", 2],
150
150
  "foo %\n a: b" => ['Invalid CSS after "foo %": expected placeholder name, was ""', 1],
151
151
  "=foo\n @content error" => "Invalid content directive. Trailing characters found: \"error\".",
152
152
  "=foo\n @content\n b: c" => "Illegal nesting: Nothing may be nested beneath @content directives.",
@@ -217,7 +217,47 @@ MSG
217
217
  assert_equal("p {\n a: b; }\n p q {\n c: d; }\n",
218
218
  render("p\n\ta: b\n\tq\n\t\tc: d\n"))
219
219
  end
220
-
220
+
221
+ def test_import_same_name_different_ext
222
+ assert_warning <<WARNING do
223
+ WARNING: On line 1 of test_import_same_name_different_ext_inline.sass:
224
+ It's not clear which file to import for '@import "same_name_different_ext"'.
225
+ Candidates:
226
+ same_name_different_ext.sass
227
+ same_name_different_ext.scss
228
+ For now I'll choose same_name_different_ext.sass.
229
+ This will be an error in future versions of Sass.
230
+ WARNING
231
+ options = {:load_paths => [File.dirname(__FILE__) + '/templates/']}
232
+ munge_filename options
233
+ result = Sass::Engine.new("@import 'same_name_different_ext'", options).render
234
+ assert_equal(<<CSS, result)
235
+ .foo {
236
+ ext: sass; }
237
+ CSS
238
+ end
239
+ end
240
+
241
+ def test_import_same_name_different_partiality
242
+ assert_warning <<WARNING do
243
+ WARNING: On line 1 of test_import_same_name_different_partiality_inline.sass:
244
+ It's not clear which file to import for '@import "same_name_different_partiality"'.
245
+ Candidates:
246
+ _same_name_different_partiality.scss
247
+ same_name_different_partiality.scss
248
+ For now I'll choose _same_name_different_partiality.scss.
249
+ This will be an error in future versions of Sass.
250
+ WARNING
251
+ options = {:load_paths => [File.dirname(__FILE__) + '/templates/']}
252
+ munge_filename options
253
+ result = Sass::Engine.new("@import 'same_name_different_partiality'", options).render
254
+ assert_equal(<<CSS, result)
255
+ .foo {
256
+ partial: yes; }
257
+ CSS
258
+ end
259
+ end
260
+
221
261
  EXCEPTION_MAP.each do |key, value|
222
262
  define_method("test_exception (#{key.inspect})") do
223
263
  line = 10
@@ -625,6 +665,11 @@ CSS
625
665
  render("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\""))
626
666
  end
627
667
 
668
+ def test_protocol_relative_import
669
+ assert_equal("@import url(//fonts.googleapis.com/css?family=Droid+Sans);\n",
670
+ render("@import \"//fonts.googleapis.com/css?family=Droid+Sans\""))
671
+ end
672
+
628
673
  def test_import_with_interpolation
629
674
  assert_equal(<<CSS, render(<<SASS))
630
675
  @import url("http://fonts.googleapis.com/css?family=Droid+Sans");
@@ -9,6 +9,12 @@ module Sass::Script::Functions
9
9
  filename = options[:filename].gsub(%r{.*((/[^/]+){4})}, '\1')
10
10
  Sass::Script::String.new(filename)
11
11
  end
12
+
13
+ def whatever
14
+ custom = options[:custom]
15
+ whatever = custom && custom[:whatever]
16
+ Sass::Script::String.new(whatever || "incorrect")
17
+ end
12
18
  end
13
19
 
14
20
  class SassPluginTest < Test::Unit::TestCase
@@ -123,7 +129,7 @@ CSS
123
129
  File.open(tempfile_loc('single_import_loop')) do |file|
124
130
  assert_equal(<<CSS.strip, file.read.split("\n")[0...2].join("\n"))
125
131
  /*
126
- Sass::SyntaxError: An @import loop has been found: #{template_loc('single_import_loop')} imports itself
132
+ Syntax error: An @import loop has been found: #{template_loc('single_import_loop')} imports itself
127
133
  CSS
128
134
  end
129
135
  end
@@ -134,9 +140,9 @@ CSS
134
140
  File.open(tempfile_loc('double_import_loop1')) do |file|
135
141
  assert_equal(<<CSS.strip, file.read.split("\n")[0...4].join("\n"))
136
142
  /*
137
- Sass::SyntaxError: An @import loop has been found:
138
- #{template_loc('double_import_loop1')} imports #{template_loc('_double_import_loop2')}
139
- #{template_loc('_double_import_loop2')} imports #{template_loc('double_import_loop1')}
143
+ Syntax error: An @import loop has been found:
144
+ #{template_loc('double_import_loop1')} imports #{template_loc('_double_import_loop2')}
145
+ #{template_loc('_double_import_loop2')} imports #{template_loc('double_import_loop1')}
140
146
  CSS
141
147
  end
142
148
  end
@@ -210,6 +216,19 @@ CSS
210
216
  assert_needs_update "basic"
211
217
  end
212
218
 
219
+ def test_import_same_name
220
+ assert_warning <<WARNING do
221
+ WARNING: In #{template_loc}:
222
+ There are multiple files that match the name "same_name_different_partiality.scss":
223
+ _same_name_different_partiality.scss
224
+ same_name_different_partiality.scss
225
+ This will be an error in future versions of Sass.
226
+ WARNING
227
+ touch "_same_name_different_partiality"
228
+ assert_needs_update "same_name_different_partiality"
229
+ end
230
+ end
231
+
213
232
  # Callbacks
214
233
 
215
234
  def test_updating_stylesheets_callback
@@ -333,7 +352,24 @@ CSS
333
352
  check_for_updates!
334
353
  assert_renders_correctly 'if'
335
354
  ensure
336
- set_plugin_opts :cache_store => @@cache_store
355
+ set_plugin_opts
356
+ end
357
+
358
+ def test_cached_import_option
359
+ set_plugin_opts :custom => {:whatever => "correct"}
360
+ check_for_updates!
361
+ assert_renders_correctly "cached_import_option"
362
+
363
+ @@cache_store.reset!
364
+ set_plugin_opts :custom => nil, :always_update => false
365
+ check_for_updates!
366
+ assert_renders_correctly "cached_import_option"
367
+
368
+ set_plugin_opts :custom => {:whatever => "correct"}, :always_update => true
369
+ check_for_updates!
370
+ assert_renders_correctly "cached_import_option"
371
+ ensure
372
+ set_plugin_opts :custom => nil
337
373
  end
338
374
 
339
375
  private
@@ -388,7 +424,7 @@ CSS
388
424
  end
389
425
 
390
426
  if block_given?
391
- yield
427
+ Sass::Util.silence_sass_warnings {yield}
392
428
  else
393
429
  check_for_updates!
394
430
  end
@@ -0,0 +1,3 @@
1
+ partial { value: correct; }
2
+
3
+ main { value: correct; }
@@ -1042,6 +1042,18 @@ body {
1042
1042
  SCSS
1043
1043
  end
1044
1044
 
1045
+ def test_malformed_media
1046
+ render <<SCSS
1047
+ @media {
1048
+ margin: 0;
1049
+ }
1050
+ SCSS
1051
+ assert(false, "Expected syntax error")
1052
+ rescue Sass::SyntaxError => e
1053
+ assert_equal 'Invalid CSS after "@media ": expected media query (e.g. print, screen, print and screen), was "{"', e.message
1054
+ assert_equal 1, e.sass_line
1055
+ end
1056
+
1045
1057
  private
1046
1058
 
1047
1059
  def assert_selector_parses(selector)
@@ -290,6 +290,11 @@ SCSS
290
290
  render("@import \"http://fonts.googleapis.com/css?family=Droid+Sans\";"))
291
291
  end
292
292
 
293
+ def test_protocol_relative_import
294
+ assert_equal("@import \"//fonts.googleapis.com/css?family=Droid+Sans\";\n",
295
+ render("@import \"//fonts.googleapis.com/css?family=Droid+Sans\";"))
296
+ end
297
+
293
298
  def test_import_with_interpolation
294
299
  assert_equal <<CSS, render(<<SCSS)
295
300
  @import url("http://fonts.googleapis.com/css?family=Droid+Sans");
@@ -1664,7 +1669,7 @@ SCSS
1664
1669
  assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
1665
1670
  Invalid CSS after " .foo": expected "{", was "&.bar {a: b}"
1666
1671
 
1667
- "&.bar" may only be used at the beginning of a selector.
1672
+ "&.bar" may only be used at the beginning of a compound selector.
1668
1673
  MESSAGE
1669
1674
  flim {
1670
1675
  .foo&.bar {a: b}
@@ -1676,7 +1681,7 @@ SCSS
1676
1681
  assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
1677
1682
  Invalid CSS after " .foo.bar": expected "{", was "& {a: b}"
1678
1683
 
1679
- "&" may only be used at the beginning of a selector.
1684
+ "&" may only be used at the beginning of a compound selector.
1680
1685
  MESSAGE
1681
1686
  flim {
1682
1687
  .foo.bar& {a: b}
@@ -1688,7 +1693,7 @@ SCSS
1688
1693
  assert_raise_message(Sass::SyntaxError, <<MESSAGE.rstrip) {render <<SCSS}
1689
1694
  Invalid CSS after " &": expected "{", was "& {a: b}"
1690
1695
 
1691
- "&" may only be used at the beginning of a selector.
1696
+ "&" may only be used at the beginning of a compound selector.
1692
1697
  MESSAGE
1693
1698
  flim {
1694
1699
  && {a: b}
@@ -0,0 +1 @@
1
+ partial {value: whatever()}
@@ -0,0 +1 @@
1
+ .foo {partial: yes}
@@ -0,0 +1,3 @@
1
+ @import "cached_import_option_partial";
2
+
3
+ main {value: whatever()}
@@ -0,0 +1,2 @@
1
+ .foo
2
+ ext: sass
@@ -0,0 +1 @@
1
+ .foo {ext: scss}
@@ -0,0 +1 @@
1
+ .foo {partial: no}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sass
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.1
4
+ version: 3.2.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-08-16 00:00:00.000000000 Z
14
+ date: 2012-11-03 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: yard
@@ -224,11 +224,13 @@ files:
224
224
  - test/sass/templates/filename_fn.scss
225
225
  - test/sass/templates/alt.sass
226
226
  - test/sass/templates/nested_bork1.sass
227
+ - test/sass/templates/same_name_different_partiality.scss
227
228
  - test/sass/templates/complex.sass
228
229
  - test/sass/templates/units.sass
229
230
  - test/sass/templates/nested_import.sass
230
231
  - test/sass/templates/importee.sass
231
232
  - test/sass/templates/importee.less
233
+ - test/sass/templates/_cached_import_option_partial.scss
232
234
  - test/sass/templates/scss_importee.scss
233
235
  - test/sass/templates/line_numbers.sass
234
236
  - test/sass/templates/expanded.sass
@@ -242,6 +244,7 @@ files:
242
244
  - test/sass/templates/nested.sass
243
245
  - test/sass/templates/compact.sass
244
246
  - test/sass/templates/single_import_loop.sass
247
+ - test/sass/templates/_same_name_different_partiality.scss
245
248
  - test/sass/templates/multiline.sass
246
249
  - test/sass/templates/_imported_charset_ibm866.sass
247
250
  - test/sass/templates/double_import_loop1.sass
@@ -251,15 +254,18 @@ files:
251
254
  - test/sass/templates/import.sass
252
255
  - test/sass/templates/nested_bork3.sass
253
256
  - test/sass/templates/script.sass
257
+ - test/sass/templates/same_name_different_ext.scss
254
258
  - test/sass/templates/bork4.sass
255
259
  - test/sass/templates/if.sass
256
260
  - test/sass/templates/_partial.sass
257
261
  - test/sass/templates/nested_mixin_bork.sass
258
262
  - test/sass/templates/import_charset_1_8.sass
263
+ - test/sass/templates/same_name_different_ext.sass
259
264
  - test/sass/templates/nested_bork2.sass
260
265
  - test/sass/templates/mixin_bork.sass
261
266
  - test/sass/templates/compressed.sass
262
267
  - test/sass/templates/nested_bork4.sass
268
+ - test/sass/templates/cached_import_option.scss
263
269
  - test/sass/templates/_imported_charset_utf8.sass
264
270
  - test/sass/conversion_test.rb
265
271
  - test/sass/script_test.rb
@@ -288,6 +294,7 @@ files:
288
294
  - test/sass/results/parent_ref.css
289
295
  - test/sass/results/script.css
290
296
  - test/sass/results/complex.css
297
+ - test/sass/results/cached_import_option.css
291
298
  - test/sass/results/import_charset.css
292
299
  - test/sass/results/alt.css
293
300
  - test/sass/results/if.css