haml-edge 3.1.73 → 3.1.74
Sign up to get free protection for your applications and to get access to all the features.
- data/EDGE_GEM_VERSION +1 -1
- data/VERSION +1 -1
- data/lib/haml/exec.rb +7 -7
- data/lib/haml/util.rb +37 -0
- data/lib/sass/cache_store.rb +213 -0
- data/lib/sass/callbacks.rb +14 -0
- data/lib/sass/engine.rb +98 -15
- data/lib/sass/error.rb +4 -1
- data/lib/sass/importers/base.rb +138 -0
- data/lib/sass/importers/filesystem.rb +121 -0
- data/lib/sass/importers.rb +22 -0
- data/lib/sass/plugin/compiler.rb +351 -0
- data/lib/sass/plugin/configuration.rb +114 -212
- data/lib/sass/plugin/merb.rb +24 -13
- data/lib/sass/plugin/rails.rb +16 -7
- data/lib/sass/plugin/staleness_checker.rb +55 -33
- data/lib/sass/plugin.rb +25 -173
- data/lib/sass/script/node.rb +3 -3
- data/lib/sass/selector/simple.rb +1 -1
- data/lib/sass/tree/import_node.rb +44 -22
- data/lib/sass/tree/node.rb +17 -2
- data/lib/sass.rb +43 -0
- data/test/haml/util_test.rb +32 -0
- data/test/sass/cache_test.rb +67 -0
- data/test/sass/engine_test.rb +47 -16
- data/test/sass/importer_test.rb +82 -0
- data/test/sass/plugin_test.rb +21 -15
- data/test/sass/test_helper.rb +5 -0
- metadata +12 -3
- data/lib/sass/files.rb +0 -160
data/lib/sass/plugin.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
|
3
3
|
require 'sass'
|
4
|
-
require 'sass/plugin/
|
5
|
-
require 'sass/plugin/staleness_checker'
|
4
|
+
require 'sass/plugin/compiler'
|
6
5
|
|
7
6
|
module Sass
|
8
|
-
# This module
|
9
|
-
# It provides global options and checks whether CSS files
|
7
|
+
# This module provides a single interface to the compilation of Sass/SCSS files
|
8
|
+
# for an application. It provides global options and checks whether CSS files
|
10
9
|
# need to be updated.
|
11
10
|
#
|
12
11
|
# This module is used as the primary interface with Sass
|
@@ -20,6 +19,9 @@ module Sass
|
|
20
19
|
# All callback methods are of the form `on_#{name}`,
|
21
20
|
# and they all take a block that's called when the given action occurs.
|
22
21
|
#
|
22
|
+
# Note that this class proxies almost all methods to its {Sass::Plugin::Compiler} instance.
|
23
|
+
# See \{#compiler}.
|
24
|
+
#
|
23
25
|
# @example Using a callback
|
24
26
|
# Sass::Plugin.on_updating_stylesheet do |template, css|
|
25
27
|
# puts "Compiling #{template} to #{css}"
|
@@ -28,8 +30,9 @@ module Sass
|
|
28
30
|
# #=> Compiling app/sass/screen.scss to public/stylesheets/screen.css
|
29
31
|
# #=> Compiling app/sass/print.scss to public/stylesheets/print.css
|
30
32
|
# #=> Compiling app/sass/ie.scss to public/stylesheets/ie.css
|
33
|
+
# @see Sass::Plugin::Compiler
|
31
34
|
module Plugin
|
32
|
-
|
35
|
+
extend self
|
33
36
|
|
34
37
|
@checked_for_updates = false
|
35
38
|
|
@@ -50,6 +53,15 @@ module Sass
|
|
50
53
|
update_stylesheets
|
51
54
|
end
|
52
55
|
|
56
|
+
# Returns the singleton compiler instance.
|
57
|
+
# This compiler has been pre-configured according
|
58
|
+
# to the plugin configuration.
|
59
|
+
#
|
60
|
+
# @return [Sass::Plugin::Compiler]
|
61
|
+
def compiler
|
62
|
+
@compiler ||= Compiler.new
|
63
|
+
end
|
64
|
+
|
53
65
|
# Updates out-of-date stylesheets.
|
54
66
|
#
|
55
67
|
# Checks each Sass/SCSS file in {file:SASS_REFERENCE.md#template_location-option `:template_location`}
|
@@ -65,29 +77,7 @@ module Sass
|
|
65
77
|
# the second is the location of the CSS file that it should be compiled to.
|
66
78
|
def update_stylesheets(individual_files = [])
|
67
79
|
return if options[:never_update]
|
68
|
-
|
69
|
-
run_updating_stylesheets individual_files
|
70
|
-
|
71
|
-
individual_files.each {|t, c| update_stylesheet(t, c)}
|
72
|
-
|
73
|
-
@checked_for_updates = true
|
74
|
-
staleness_checker = StalenessChecker.new
|
75
|
-
|
76
|
-
template_location_array.each do |template_location, css_location|
|
77
|
-
|
78
|
-
Dir.glob(File.join(template_location, "**", "*.s[ca]ss")).sort.each do |file|
|
79
|
-
# Get the relative path to the file
|
80
|
-
name = file.sub(template_location.sub(/\/*$/, '/'), "")
|
81
|
-
css = css_filename(name, css_location)
|
82
|
-
|
83
|
-
next if forbid_update?(name)
|
84
|
-
if options[:always_update] || staleness_checker.stylesheet_needs_update?(css, file)
|
85
|
-
update_stylesheet file, css
|
86
|
-
else
|
87
|
-
run_not_updating_stylesheet file, css
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
80
|
+
compiler.update_stylesheets(individual_files)
|
91
81
|
end
|
92
82
|
|
93
83
|
# Updates all stylesheets, even those that aren't out-of-date.
|
@@ -111,156 +101,18 @@ module Sass
|
|
111
101
|
self.options = old_options
|
112
102
|
end
|
113
103
|
|
114
|
-
#
|
115
|
-
# and updates the CSS files whenever the related Sass/SCSS files change.
|
116
|
-
# `watch` never returns.
|
117
|
-
#
|
118
|
-
# Whenever a change is detected to a Sass/SCSS file in
|
119
|
-
# {file:SASS_REFERENCE.md#template_location-option `:template_location`},
|
120
|
-
# the corresponding CSS file in {file:SASS_REFERENCE.md#css_location-option `:css_location`}
|
121
|
-
# will be recompiled.
|
122
|
-
# The CSS files of any Sass/SCSS files that import the changed file will also be recompiled.
|
123
|
-
#
|
124
|
-
# Before the watching starts in earnest, `watch` calls \{#update\_stylesheets}.
|
104
|
+
# All other method invocations are proxied to the \{#compiler}.
|
125
105
|
#
|
126
|
-
#
|
127
|
-
#
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
#
|
132
|
-
# @param individual_files [Array<(String, String)>]
|
133
|
-
# A list of files to watch for updates
|
134
|
-
# **in addition to those specified by the
|
135
|
-
# {file:SASS_REFERENCE.md#template_location-option `:template_location` option}.**
|
136
|
-
# The first string in each pair is the location of the Sass/SCSS file,
|
137
|
-
# the second is the location of the CSS file that it should be compiled to.
|
138
|
-
def watch(individual_files = [])
|
139
|
-
update_stylesheets(individual_files)
|
140
|
-
|
141
|
-
begin
|
142
|
-
require 'fssm'
|
143
|
-
rescue LoadError => e
|
144
|
-
e.message << "\n" <<
|
145
|
-
if File.exists?(scope(".git"))
|
146
|
-
'Run "git submodule update --init" to get the recommended version.'
|
147
|
-
else
|
148
|
-
'Run "gem install fssm" to get it.'
|
149
|
-
end
|
150
|
-
raise e
|
151
|
-
end
|
152
|
-
|
153
|
-
unless individual_files.empty? && FSSM::Backends::Default.name == "FSSM::Backends::FSEvents"
|
154
|
-
# As of FSSM 0.1.4, it doesn't support FSevents on individual files,
|
155
|
-
# but it also isn't smart enough to switch to polling itself.
|
156
|
-
require 'fssm/backends/polling'
|
157
|
-
Haml::Util.silence_warnings do
|
158
|
-
FSSM::Backends.const_set(:Default, FSSM::Backends::Polling)
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
# TODO: Keep better track of what depends on what
|
163
|
-
# so we don't have to run a global update every time anything changes.
|
164
|
-
FSSM.monitor do |mon|
|
165
|
-
template_location_array.each do |template_location, css_location|
|
166
|
-
mon.path template_location do |path|
|
167
|
-
path.glob '**/*.s[ac]ss'
|
168
|
-
|
169
|
-
path.update do |base, relative|
|
170
|
-
run_template_modified File.join(base, relative)
|
171
|
-
update_stylesheets(individual_files)
|
172
|
-
end
|
173
|
-
|
174
|
-
path.create do |base, relative|
|
175
|
-
run_template_created File.join(base, relative)
|
176
|
-
update_stylesheets(individual_files)
|
177
|
-
end
|
178
|
-
|
179
|
-
path.delete do |base, relative|
|
180
|
-
run_template_deleted File.join(base, relative)
|
181
|
-
css = File.join(css_location, relative.gsub(/\.s[ac]ss$/, '.css'))
|
182
|
-
try_delete_css css
|
183
|
-
update_stylesheets(individual_files)
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
individual_files.each do |template, css|
|
189
|
-
mon.file template do |path|
|
190
|
-
path.update do
|
191
|
-
run_template_modified template
|
192
|
-
update_stylesheets(individual_files)
|
193
|
-
end
|
194
|
-
|
195
|
-
path.create do
|
196
|
-
run_template_created template
|
197
|
-
update_stylesheets(individual_files)
|
198
|
-
end
|
199
|
-
|
200
|
-
path.delete do
|
201
|
-
run_template_deleted template
|
202
|
-
try_delete_css css
|
203
|
-
update_stylesheets(individual_files)
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
private
|
211
|
-
|
212
|
-
def update_stylesheet(filename, css)
|
213
|
-
dir = File.dirname(css)
|
214
|
-
unless File.exists?(dir)
|
215
|
-
run_creating_directory dir
|
216
|
-
FileUtils.mkdir_p dir
|
217
|
-
end
|
218
|
-
|
219
|
-
begin
|
220
|
-
result = Sass::Files.tree_for(filename, engine_options(:css_filename => css, :filename => filename)).render
|
221
|
-
rescue Exception => e
|
222
|
-
run_compilation_error e, filename, css
|
223
|
-
result = Sass::SyntaxError.exception_to_css(e, options)
|
106
|
+
# @see #compiler
|
107
|
+
# @see Sass::Plugin::Compiler
|
108
|
+
def method_missing(method, *args, &block)
|
109
|
+
if compiler.respond_to?(method)
|
110
|
+
compiler.send(method, *args, &block)
|
224
111
|
else
|
225
|
-
|
112
|
+
super
|
226
113
|
end
|
227
|
-
|
228
|
-
# Finally, write the file
|
229
|
-
flag = 'w'
|
230
|
-
flag = 'wb' if Haml::Util.windows? && options[:unix_newlines]
|
231
|
-
File.open(css, flag) {|file| file.print(result)}
|
232
114
|
end
|
233
115
|
|
234
|
-
def try_delete_css(css)
|
235
|
-
return unless File.exists?(css)
|
236
|
-
run_deleting_css css
|
237
|
-
File.delete css
|
238
|
-
end
|
239
|
-
|
240
|
-
def load_paths(opts = options)
|
241
|
-
(opts[:load_paths] || []) + template_locations
|
242
|
-
end
|
243
|
-
|
244
|
-
def template_locations
|
245
|
-
template_location_array.to_a.map {|l| l.first}
|
246
|
-
end
|
247
|
-
|
248
|
-
def css_locations
|
249
|
-
template_location_array.to_a.map {|l| l.last}
|
250
|
-
end
|
251
|
-
|
252
|
-
def css_filename(name, path)
|
253
|
-
"#{path}/#{name}".gsub(/\.s[ac]ss$/, '.css')
|
254
|
-
end
|
255
|
-
|
256
|
-
def forbid_update?(name)
|
257
|
-
name.sub(/^.*\//, '')[0] == ?_
|
258
|
-
end
|
259
|
-
|
260
|
-
# Compass expects this to exist
|
261
|
-
def stylesheet_needs_update?(css_file, template_file)
|
262
|
-
StalenessChecker.stylesheet_needs_update?(css_file, template_file)
|
263
|
-
end
|
264
116
|
end
|
265
117
|
end
|
266
118
|
|
data/lib/sass/script/node.rb
CHANGED
@@ -68,14 +68,14 @@ module Sass::Script
|
|
68
68
|
#
|
69
69
|
# @return [Array<Node>]
|
70
70
|
def children
|
71
|
-
|
71
|
+
Haml::Util.abstract(self)
|
72
72
|
end
|
73
73
|
|
74
74
|
# Returns the text of this SassScript expression.
|
75
75
|
#
|
76
76
|
# @return [String]
|
77
77
|
def to_sass(opts = {})
|
78
|
-
|
78
|
+
Haml::Util.abstract(self)
|
79
79
|
end
|
80
80
|
|
81
81
|
protected
|
@@ -95,7 +95,7 @@ module Sass::Script
|
|
95
95
|
# @return [Literal] The SassScript object that is the value of the SassScript
|
96
96
|
# @see #perform
|
97
97
|
def _perform(environment)
|
98
|
-
|
98
|
+
Haml::Util.abstract(self)
|
99
99
|
end
|
100
100
|
end
|
101
101
|
end
|
data/lib/sass/selector/simple.rb
CHANGED
@@ -22,7 +22,7 @@ module Sass
|
|
22
22
|
#
|
23
23
|
# @return [Array<String, Sass::Script::Node>]
|
24
24
|
def to_a
|
25
|
-
|
25
|
+
Haml::Util.abstract(self)
|
26
26
|
end
|
27
27
|
|
28
28
|
# Returns a string representation of the node.
|
@@ -17,15 +17,12 @@ module Sass
|
|
17
17
|
|
18
18
|
def invisible?; to_s.empty?; end
|
19
19
|
|
20
|
-
# Returns the
|
21
|
-
# as returned by \{Sass::Files#find\_file\_to\_import}.
|
20
|
+
# Returns the imported file.
|
22
21
|
#
|
23
|
-
# @return [
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
def full_filename
|
28
|
-
@full_filename ||= import
|
22
|
+
# @return [Sass::Engine]
|
23
|
+
# @raise [Sass::SyntaxError] If no file could be found to import.
|
24
|
+
def imported_file
|
25
|
+
@imported_file ||= import
|
29
26
|
end
|
30
27
|
|
31
28
|
# @see Node#to_sass
|
@@ -43,6 +40,17 @@ module Sass
|
|
43
40
|
super.first
|
44
41
|
end
|
45
42
|
|
43
|
+
# Returns whether or not this import should emit a CSS @import declaration
|
44
|
+
#
|
45
|
+
# @return [Boolean] Whether or not this is a simple CSS @import declaration.
|
46
|
+
def css_import?
|
47
|
+
if @imported_filename =~ /\.css$/
|
48
|
+
@imported_filename
|
49
|
+
elsif imported_file.is_a?(String) && imported_file =~ /\.css$/
|
50
|
+
imported_file
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
46
54
|
protected
|
47
55
|
|
48
56
|
# @see Node#_cssize
|
@@ -60,7 +68,9 @@ module Sass
|
|
60
68
|
# @param environment [Sass::Environment] The lexical environment containing
|
61
69
|
# variable and mixin values
|
62
70
|
def _perform(environment)
|
63
|
-
|
71
|
+
if path = css_import?
|
72
|
+
return DirectiveNode.new("@import url(#{path})")
|
73
|
+
end
|
64
74
|
super
|
65
75
|
end
|
66
76
|
|
@@ -70,14 +80,12 @@ module Sass
|
|
70
80
|
# variable and mixin values
|
71
81
|
def perform!(environment)
|
72
82
|
environment.push_frame(:filename => @filename, :line => @line)
|
73
|
-
|
74
|
-
|
75
|
-
root = Sass::Files.tree_for(full_filename, options)
|
76
|
-
@template = root.template
|
83
|
+
# TODO: re-enable caching
|
84
|
+
root = imported_file.to_tree
|
77
85
|
self.children = root.children
|
78
86
|
self.children = perform_children(environment)
|
79
87
|
rescue Sass::SyntaxError => e
|
80
|
-
e.modify_backtrace(:filename =>
|
88
|
+
e.modify_backtrace(:filename => imported_file.options[:filename])
|
81
89
|
e.add_backtrace(:filename => @filename, :line => @line)
|
82
90
|
raise e
|
83
91
|
ensure
|
@@ -86,15 +94,29 @@ module Sass
|
|
86
94
|
|
87
95
|
private
|
88
96
|
|
89
|
-
def import_paths
|
90
|
-
paths = (@options[:load_paths] || []).dup
|
91
|
-
paths.unshift(File.dirname(@options[:filename])) if @options[:filename]
|
92
|
-
paths
|
93
|
-
end
|
94
|
-
|
95
97
|
def import
|
96
|
-
|
97
|
-
|
98
|
+
paths = @options[:load_paths]
|
99
|
+
|
100
|
+
if @options[:importer]
|
101
|
+
f = @options[:importer].find_relative(
|
102
|
+
@imported_filename, @options[:filename], @options.dup)
|
103
|
+
return f if f
|
104
|
+
end
|
105
|
+
|
106
|
+
paths.each do |p|
|
107
|
+
if f = p.find(@imported_filename, @options.dup)
|
108
|
+
return f
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
message = "File to import not found or unreadable: #{@imported_filename}.\n"
|
113
|
+
if paths.size == 1
|
114
|
+
message << "Load path: #{paths.first}"
|
115
|
+
else
|
116
|
+
message << "Load paths:\n " << paths.join("\n ")
|
117
|
+
end
|
118
|
+
raise SyntaxError.new(message)
|
119
|
+
rescue SyntaxError => e
|
98
120
|
raise SyntaxError.new(e.message, :line => self.line, :filename => @filename)
|
99
121
|
end
|
100
122
|
end
|
data/lib/sass/tree/node.rb
CHANGED
@@ -244,6 +244,21 @@ module Sass
|
|
244
244
|
to_src(tabs, opts, :scss)
|
245
245
|
end
|
246
246
|
|
247
|
+
# Names of options that are saved when the node is serialized and cached.
|
248
|
+
SAVED_OPTIONS = [:importer]
|
249
|
+
|
250
|
+
# Ensures that only {SAVED_OPTIONS} get saved.
|
251
|
+
def _around_dump
|
252
|
+
old_options = @options
|
253
|
+
@options = {}
|
254
|
+
SAVED_OPTIONS.each do |opt|
|
255
|
+
@options[opt] = old_options[opt]
|
256
|
+
end
|
257
|
+
yield
|
258
|
+
ensure
|
259
|
+
options = old_options
|
260
|
+
end
|
261
|
+
|
247
262
|
protected
|
248
263
|
|
249
264
|
# Computes the CSS corresponding to this particular Sass node.
|
@@ -258,7 +273,7 @@ module Sass
|
|
258
273
|
# @see #to_s
|
259
274
|
# @see Sass::Tree
|
260
275
|
def _to_s
|
261
|
-
|
276
|
+
Haml::Util.abstract(self)
|
262
277
|
end
|
263
278
|
|
264
279
|
# Converts this static Sass node into a static CSS node,
|
@@ -383,7 +398,7 @@ module Sass
|
|
383
398
|
# @param fmt [Symbol] `:sass` or `:scss`
|
384
399
|
# @return [String] The Sass or SCSS code corresponding to the node
|
385
400
|
def to_src(tabs, opts, fmt)
|
386
|
-
|
401
|
+
Haml::Util.abstract(self)
|
387
402
|
end
|
388
403
|
|
389
404
|
# Converts the children of this node to a Sass or SCSS string.
|
data/lib/sass.rb
CHANGED
@@ -18,6 +18,49 @@ module Sass
|
|
18
18
|
# A more fine-grained representation is available from {Haml::Version#version Sass.version}.
|
19
19
|
# @api public
|
20
20
|
VERSION = version[:string] unless defined?(Sass::VERSION)
|
21
|
+
|
22
|
+
# Compile a Sass or SCSS string to CSS.
|
23
|
+
# Defaults to SCSS.
|
24
|
+
#
|
25
|
+
# @param contents [String] The contents of the Sass file.
|
26
|
+
# @param options [{Symbol => Object}] An options hash;
|
27
|
+
# see {file:SASS_REFERENCE.md#sass_options the Sass options documentation}
|
28
|
+
# @raise [Sass::SyntaxError] if there's an error in the document
|
29
|
+
# @raise [Encoding::UndefinedConversionError] if the source encoding
|
30
|
+
# cannot be converted to UTF-8
|
31
|
+
# @raise [ArgumentError] if the document uses an unknown encoding with `@charset`
|
32
|
+
def self.compile(contents, options = {})
|
33
|
+
options[:syntax] ||= :scss
|
34
|
+
Engine.new(contents, options).to_css
|
35
|
+
end
|
36
|
+
|
37
|
+
# Compile a file on disk to CSS.
|
38
|
+
#
|
39
|
+
# @param filename [String] The path to the Sass, SCSS, or CSS file on disk.
|
40
|
+
# @param options [{Symbol => Object}] An options hash;
|
41
|
+
# see {file:SASS_REFERENCE.md#sass_options the Sass options documentation}
|
42
|
+
# @raise [Sass::SyntaxError] if there's an error in the document
|
43
|
+
# @raise [Encoding::UndefinedConversionError] if the source encoding
|
44
|
+
# cannot be converted to UTF-8
|
45
|
+
# @raise [ArgumentError] if the document uses an unknown encoding with `@charset`
|
46
|
+
#
|
47
|
+
# @overload compile_file(filename, options = {})
|
48
|
+
# @return [String] The compiled CSS.
|
49
|
+
#
|
50
|
+
# @overload compile_file(filename, css_filename, options = {})
|
51
|
+
# @param css_filename [String] The location to which to write the compiled CSS.
|
52
|
+
def self.compile_file(filename, *args)
|
53
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
54
|
+
css_filename ||= args.shift
|
55
|
+
options[:css_filename] = css_filename
|
56
|
+
result = Sass::Files.engine_for(filename, options).render
|
57
|
+
if css_filename
|
58
|
+
open(css_filename,"w") {|css_file| css_file.write(result) }
|
59
|
+
nil
|
60
|
+
else
|
61
|
+
result
|
62
|
+
end
|
63
|
+
end
|
21
64
|
end
|
22
65
|
|
23
66
|
require 'haml/util'
|
data/test/haml/util_test.rb
CHANGED
@@ -5,6 +5,19 @@ require 'pathname'
|
|
5
5
|
class UtilTest < Test::Unit::TestCase
|
6
6
|
include Haml::Util
|
7
7
|
|
8
|
+
class Dumpable
|
9
|
+
attr_reader :arr
|
10
|
+
def initialize; @arr = []; end
|
11
|
+
def _before_dump; @arr << :before; end
|
12
|
+
def _after_dump; @arr << :after; end
|
13
|
+
def _around_dump
|
14
|
+
@arr << :around_before
|
15
|
+
yield
|
16
|
+
@arr << :around_after
|
17
|
+
end
|
18
|
+
def _after_load; @arr << :loaded; end
|
19
|
+
end
|
20
|
+
|
8
21
|
def test_scope
|
9
22
|
assert(File.exist?(scope("Rakefile")))
|
10
23
|
end
|
@@ -240,6 +253,25 @@ class UtilTest < Test::Unit::TestCase
|
|
240
253
|
assert(!version_gt(v2, v1), "Expected #{v2} = #{v1}")
|
241
254
|
end
|
242
255
|
|
256
|
+
def test_dump_and_load
|
257
|
+
obj = Dumpable.new
|
258
|
+
data = dump(obj)
|
259
|
+
assert_equal([:before, :around_before, :around_after, :after], obj.arr)
|
260
|
+
obj2 = load(data)
|
261
|
+
assert_equal([:before, :around_before, :loaded], obj2.arr)
|
262
|
+
end
|
263
|
+
|
264
|
+
class FooBar
|
265
|
+
def foo
|
266
|
+
Haml::Util.abstract(self)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def test_abstract
|
271
|
+
assert_raise_message(NotImplementedError,
|
272
|
+
"UtilTest::FooBar must implement #foo") {FooBar.new.foo}
|
273
|
+
end
|
274
|
+
|
243
275
|
def test_def_static_method
|
244
276
|
klass = Class.new
|
245
277
|
def_static_method(klass, :static_method, [:arg1, :arg2],
|
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
3
|
+
require 'sass/engine'
|
4
|
+
|
5
|
+
class CacheTest < Test::Unit::TestCase
|
6
|
+
@@cache_dir = "tmp/file_cache"
|
7
|
+
|
8
|
+
def setup
|
9
|
+
FileUtils.mkdir_p @@cache_dir
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
FileUtils.rm_rf @@cache_dir
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_file_cache_writes_a_file
|
17
|
+
file_store = Sass::FileCacheStore.new(@@cache_dir)
|
18
|
+
file_store.store("asdf/foo.scssc", "fakesha1", root_node)
|
19
|
+
assert File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_file_cache_reads_a_file
|
23
|
+
file_store = Sass::FileCacheStore.new(@@cache_dir)
|
24
|
+
assert !File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
25
|
+
file_store.store("asdf/foo.scssc", "fakesha1", root_node)
|
26
|
+
assert File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
27
|
+
assert_kind_of Sass::Tree::RootNode, file_store.retrieve("asdf/foo.scssc", "fakesha1")
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_file_cache_miss_returns_nil
|
31
|
+
file_store = Sass::FileCacheStore.new(@@cache_dir)
|
32
|
+
assert !File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
33
|
+
assert_nil file_store.retrieve("asdf/foo.scssc", "fakesha1")
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_sha_change_invalidates_cache_and_cleans_up
|
37
|
+
file_store = Sass::FileCacheStore.new(@@cache_dir)
|
38
|
+
assert !File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
39
|
+
file_store.store("asdf/foo.scssc", "fakesha1", root_node)
|
40
|
+
assert File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
41
|
+
assert_nil file_store.retrieve("asdf/foo.scssc", "differentsha1")
|
42
|
+
assert !File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_version_change_invalidates_cache_and_cleans_up
|
46
|
+
file_store = Sass::FileCacheStore.new(@@cache_dir)
|
47
|
+
assert !File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
48
|
+
file_store.store("asdf/foo.scssc", "fakesha1", root_node)
|
49
|
+
assert File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
50
|
+
real_version = Sass::VERSION
|
51
|
+
begin
|
52
|
+
Sass::VERSION.replace("a different version")
|
53
|
+
assert_nil file_store.retrieve("asdf/foo.scssc", "fakesha1")
|
54
|
+
assert !File.exists?("#{@@cache_dir}/asdf/foo.scssc")
|
55
|
+
ensure
|
56
|
+
Sass::VERSION.replace(real_version)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def root_node
|
62
|
+
Sass::Engine.new(<<-SCSS, :syntax => :scss).to_tree
|
63
|
+
@mixin color($c) { color: $c}
|
64
|
+
div { @include color(red); }
|
65
|
+
SCSS
|
66
|
+
end
|
67
|
+
end
|