sass 3.2.1 → 3.2.2

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.
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