sass 3.1.0.alpha.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/.yardopts +11 -0
- data/CONTRIBUTING +3 -0
- data/EDGE_GEM_VERSION +1 -0
- data/MIT-LICENSE +20 -0
- data/README.md +201 -0
- data/REVISION +1 -0
- data/Rakefile +353 -0
- data/VERSION +1 -0
- data/VERSION_NAME +1 -0
- data/bin/css2sass +13 -0
- data/bin/sass +8 -0
- data/bin/sass-convert +7 -0
- data/extra/update_watch.rb +13 -0
- data/init.rb +18 -0
- data/lib/sass.rb +71 -0
- data/lib/sass/cache_store.rb +208 -0
- data/lib/sass/callbacks.rb +66 -0
- data/lib/sass/css.rb +294 -0
- data/lib/sass/engine.rb +792 -0
- data/lib/sass/environment.rb +143 -0
- data/lib/sass/error.rb +201 -0
- data/lib/sass/exec.rb +619 -0
- data/lib/sass/importers.rb +22 -0
- data/lib/sass/importers/base.rb +138 -0
- data/lib/sass/importers/filesystem.rb +121 -0
- data/lib/sass/less.rb +363 -0
- data/lib/sass/plugin.rb +126 -0
- data/lib/sass/plugin/compiler.rb +346 -0
- data/lib/sass/plugin/configuration.rb +123 -0
- data/lib/sass/plugin/generic.rb +15 -0
- data/lib/sass/plugin/merb.rb +48 -0
- data/lib/sass/plugin/rack.rb +47 -0
- data/lib/sass/plugin/rails.rb +41 -0
- data/lib/sass/plugin/staleness_checker.rb +145 -0
- data/lib/sass/railtie.rb +8 -0
- data/lib/sass/repl.rb +58 -0
- data/lib/sass/root.rb +7 -0
- data/lib/sass/script.rb +63 -0
- data/lib/sass/script/bool.rb +18 -0
- data/lib/sass/script/color.rb +490 -0
- data/lib/sass/script/css_lexer.rb +29 -0
- data/lib/sass/script/css_parser.rb +31 -0
- data/lib/sass/script/funcall.rb +78 -0
- data/lib/sass/script/functions.rb +852 -0
- data/lib/sass/script/interpolation.rb +70 -0
- data/lib/sass/script/lexer.rb +337 -0
- data/lib/sass/script/literal.rb +236 -0
- data/lib/sass/script/node.rb +101 -0
- data/lib/sass/script/number.rb +420 -0
- data/lib/sass/script/operation.rb +92 -0
- data/lib/sass/script/parser.rb +392 -0
- data/lib/sass/script/string.rb +67 -0
- data/lib/sass/script/string_interpolation.rb +93 -0
- data/lib/sass/script/unary_operation.rb +57 -0
- data/lib/sass/script/variable.rb +48 -0
- data/lib/sass/scss.rb +17 -0
- data/lib/sass/scss/css_parser.rb +51 -0
- data/lib/sass/scss/parser.rb +838 -0
- data/lib/sass/scss/rx.rb +126 -0
- data/lib/sass/scss/sass_parser.rb +11 -0
- data/lib/sass/scss/script_lexer.rb +15 -0
- data/lib/sass/scss/script_parser.rb +25 -0
- data/lib/sass/scss/static_parser.rb +40 -0
- data/lib/sass/selector.rb +361 -0
- data/lib/sass/selector/abstract_sequence.rb +62 -0
- data/lib/sass/selector/comma_sequence.rb +82 -0
- data/lib/sass/selector/sequence.rb +236 -0
- data/lib/sass/selector/simple.rb +113 -0
- data/lib/sass/selector/simple_sequence.rb +135 -0
- data/lib/sass/shared.rb +78 -0
- data/lib/sass/tree/comment_node.rb +128 -0
- data/lib/sass/tree/debug_node.rb +36 -0
- data/lib/sass/tree/directive_node.rb +75 -0
- data/lib/sass/tree/extend_node.rb +65 -0
- data/lib/sass/tree/for_node.rb +67 -0
- data/lib/sass/tree/if_node.rb +81 -0
- data/lib/sass/tree/import_node.rb +124 -0
- data/lib/sass/tree/mixin_def_node.rb +60 -0
- data/lib/sass/tree/mixin_node.rb +123 -0
- data/lib/sass/tree/node.rb +490 -0
- data/lib/sass/tree/prop_node.rb +220 -0
- data/lib/sass/tree/root_node.rb +125 -0
- data/lib/sass/tree/rule_node.rb +273 -0
- data/lib/sass/tree/variable_node.rb +39 -0
- data/lib/sass/tree/warn_node.rb +42 -0
- data/lib/sass/tree/while_node.rb +48 -0
- data/lib/sass/util.rb +687 -0
- data/lib/sass/util/subset_map.rb +101 -0
- data/lib/sass/version.rb +109 -0
- data/rails/init.rb +1 -0
- data/test/sass/cache_test.rb +74 -0
- data/test/sass/callbacks_test.rb +61 -0
- data/test/sass/conversion_test.rb +1210 -0
- data/test/sass/css2sass_test.rb +364 -0
- data/test/sass/data/hsl-rgb.txt +319 -0
- data/test/sass/engine_test.rb +2273 -0
- data/test/sass/extend_test.rb +1348 -0
- data/test/sass/functions_test.rb +565 -0
- data/test/sass/importer_test.rb +104 -0
- data/test/sass/less_conversion_test.rb +632 -0
- data/test/sass/mock_importer.rb +49 -0
- data/test/sass/more_results/more1.css +9 -0
- data/test/sass/more_results/more1_with_line_comments.css +26 -0
- data/test/sass/more_results/more_import.css +29 -0
- data/test/sass/more_templates/_more_partial.sass +2 -0
- data/test/sass/more_templates/more1.sass +23 -0
- data/test/sass/more_templates/more_import.sass +11 -0
- data/test/sass/plugin_test.rb +430 -0
- data/test/sass/results/alt.css +4 -0
- data/test/sass/results/basic.css +9 -0
- data/test/sass/results/compact.css +5 -0
- data/test/sass/results/complex.css +86 -0
- data/test/sass/results/compressed.css +1 -0
- data/test/sass/results/expanded.css +19 -0
- data/test/sass/results/import.css +31 -0
- data/test/sass/results/line_numbers.css +49 -0
- data/test/sass/results/mixins.css +95 -0
- data/test/sass/results/multiline.css +24 -0
- data/test/sass/results/nested.css +22 -0
- data/test/sass/results/options.css +1 -0
- data/test/sass/results/parent_ref.css +13 -0
- data/test/sass/results/script.css +16 -0
- data/test/sass/results/scss_import.css +31 -0
- data/test/sass/results/scss_importee.css +2 -0
- data/test/sass/results/subdir/nested_subdir/nested_subdir.css +1 -0
- data/test/sass/results/subdir/subdir.css +3 -0
- data/test/sass/results/units.css +11 -0
- data/test/sass/results/warn.css +0 -0
- data/test/sass/results/warn_imported.css +0 -0
- data/test/sass/script_conversion_test.rb +254 -0
- data/test/sass/script_test.rb +459 -0
- data/test/sass/scss/css_test.rb +897 -0
- data/test/sass/scss/rx_test.rb +156 -0
- data/test/sass/scss/scss_test.rb +1088 -0
- data/test/sass/scss/test_helper.rb +37 -0
- data/test/sass/templates/_partial.sass +2 -0
- data/test/sass/templates/alt.sass +16 -0
- data/test/sass/templates/basic.sass +23 -0
- data/test/sass/templates/bork1.sass +2 -0
- data/test/sass/templates/bork2.sass +2 -0
- data/test/sass/templates/bork3.sass +2 -0
- data/test/sass/templates/bork4.sass +2 -0
- data/test/sass/templates/compact.sass +17 -0
- data/test/sass/templates/complex.sass +305 -0
- data/test/sass/templates/compressed.sass +15 -0
- data/test/sass/templates/expanded.sass +17 -0
- data/test/sass/templates/import.sass +12 -0
- data/test/sass/templates/importee.less +2 -0
- data/test/sass/templates/importee.sass +19 -0
- data/test/sass/templates/line_numbers.sass +13 -0
- data/test/sass/templates/mixin_bork.sass +5 -0
- data/test/sass/templates/mixins.sass +76 -0
- data/test/sass/templates/multiline.sass +20 -0
- data/test/sass/templates/nested.sass +25 -0
- data/test/sass/templates/nested_bork1.sass +2 -0
- data/test/sass/templates/nested_bork2.sass +2 -0
- data/test/sass/templates/nested_bork3.sass +2 -0
- data/test/sass/templates/nested_bork4.sass +2 -0
- data/test/sass/templates/nested_mixin_bork.sass +6 -0
- data/test/sass/templates/options.sass +2 -0
- data/test/sass/templates/parent_ref.sass +25 -0
- data/test/sass/templates/script.sass +101 -0
- data/test/sass/templates/scss_import.scss +11 -0
- data/test/sass/templates/scss_importee.scss +1 -0
- data/test/sass/templates/subdir/nested_subdir/_nested_partial.sass +2 -0
- data/test/sass/templates/subdir/nested_subdir/nested_subdir.sass +3 -0
- data/test/sass/templates/subdir/subdir.sass +6 -0
- data/test/sass/templates/units.sass +11 -0
- data/test/sass/templates/warn.sass +3 -0
- data/test/sass/templates/warn_imported.sass +4 -0
- data/test/sass/test_helper.rb +8 -0
- data/test/sass/util/subset_map_test.rb +91 -0
- data/test/sass/util_test.rb +275 -0
- data/test/test_helper.rb +64 -0
- data/vendor/fssm/LICENSE +20 -0
- data/vendor/fssm/README.markdown +55 -0
- data/vendor/fssm/Rakefile +59 -0
- data/vendor/fssm/VERSION.yml +5 -0
- data/vendor/fssm/example.rb +9 -0
- data/vendor/fssm/fssm.gemspec +77 -0
- data/vendor/fssm/lib/fssm.rb +33 -0
- data/vendor/fssm/lib/fssm/backends/fsevents.rb +36 -0
- data/vendor/fssm/lib/fssm/backends/inotify.rb +26 -0
- data/vendor/fssm/lib/fssm/backends/polling.rb +25 -0
- data/vendor/fssm/lib/fssm/backends/rubycocoa/fsevents.rb +131 -0
- data/vendor/fssm/lib/fssm/monitor.rb +26 -0
- data/vendor/fssm/lib/fssm/path.rb +91 -0
- data/vendor/fssm/lib/fssm/pathname.rb +502 -0
- data/vendor/fssm/lib/fssm/state/directory.rb +57 -0
- data/vendor/fssm/lib/fssm/state/file.rb +24 -0
- data/vendor/fssm/lib/fssm/support.rb +63 -0
- data/vendor/fssm/lib/fssm/tree.rb +176 -0
- data/vendor/fssm/profile/prof-cache.rb +40 -0
- data/vendor/fssm/profile/prof-fssm-pathname.html +1231 -0
- data/vendor/fssm/profile/prof-pathname.rb +68 -0
- data/vendor/fssm/profile/prof-plain-pathname.html +988 -0
- data/vendor/fssm/profile/prof.html +2379 -0
- data/vendor/fssm/spec/path_spec.rb +75 -0
- data/vendor/fssm/spec/root/duck/quack.txt +0 -0
- data/vendor/fssm/spec/root/file.css +0 -0
- data/vendor/fssm/spec/root/file.rb +0 -0
- data/vendor/fssm/spec/root/file.yml +0 -0
- data/vendor/fssm/spec/root/moo/cow.txt +0 -0
- data/vendor/fssm/spec/spec_helper.rb +14 -0
- metadata +297 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
class MockImporter < Sass::Importers::Base
|
2
|
+
def initialize(name = "mock")
|
3
|
+
@name = name
|
4
|
+
@imports = Hash.new({})
|
5
|
+
end
|
6
|
+
|
7
|
+
def find_relative(uri, base, options)
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def find(uri, options)
|
12
|
+
contents = @imports[uri][:contents]
|
13
|
+
return unless contents
|
14
|
+
options[:syntax] = @imports[uri][:syntax]
|
15
|
+
options[:filename] = uri
|
16
|
+
options[:importer] = self
|
17
|
+
@imports[uri][:engine] = Sass::Engine.new(contents, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def mtime(uri, options)
|
21
|
+
@imports[uri][:mtime]
|
22
|
+
end
|
23
|
+
|
24
|
+
def key(uri, options)
|
25
|
+
["mock", uri]
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
@name
|
30
|
+
end
|
31
|
+
|
32
|
+
# Methods for testing
|
33
|
+
|
34
|
+
def add_import(uri, contents, syntax = :scss, mtime = Time.now - 10)
|
35
|
+
@imports[uri] = {
|
36
|
+
:contents => contents,
|
37
|
+
:mtime => mtime,
|
38
|
+
:syntax => syntax
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def touch(uri)
|
43
|
+
@imports[uri][:mtime] = Time.now
|
44
|
+
end
|
45
|
+
|
46
|
+
def engine(uri)
|
47
|
+
@imports[uri][:engine]
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
body { font: Arial; background: blue; }
|
2
|
+
|
3
|
+
#page { width: 700px; height: 100; }
|
4
|
+
#page #header { height: 300px; }
|
5
|
+
#page #header h1 { font-size: 50px; color: blue; }
|
6
|
+
|
7
|
+
#content.user.show #container.top #column.left { width: 100px; }
|
8
|
+
#content.user.show #container.top #column.right { width: 600px; }
|
9
|
+
#content.user.show #container.bottom { background: brown; }
|
@@ -0,0 +1,26 @@
|
|
1
|
+
/* line 3, ../more_templates/more1.sass */
|
2
|
+
body {
|
3
|
+
font: Arial;
|
4
|
+
background: blue; }
|
5
|
+
|
6
|
+
/* line 7, ../more_templates/more1.sass */
|
7
|
+
#page {
|
8
|
+
width: 700px;
|
9
|
+
height: 100; }
|
10
|
+
/* line 10, ../more_templates/more1.sass */
|
11
|
+
#page #header {
|
12
|
+
height: 300px; }
|
13
|
+
/* line 12, ../more_templates/more1.sass */
|
14
|
+
#page #header h1 {
|
15
|
+
font-size: 50px;
|
16
|
+
color: blue; }
|
17
|
+
|
18
|
+
/* line 18, ../more_templates/more1.sass */
|
19
|
+
#content.user.show #container.top #column.left {
|
20
|
+
width: 100px; }
|
21
|
+
/* line 20, ../more_templates/more1.sass */
|
22
|
+
#content.user.show #container.top #column.right {
|
23
|
+
width: 600px; }
|
24
|
+
/* line 22, ../more_templates/more1.sass */
|
25
|
+
#content.user.show #container.bottom {
|
26
|
+
background: brown; }
|
@@ -0,0 +1,29 @@
|
|
1
|
+
imported { otherconst: hello; myconst: goodbye; pre-mixin: here; }
|
2
|
+
|
3
|
+
body { font: Arial; background: blue; }
|
4
|
+
|
5
|
+
#page { width: 700px; height: 100; }
|
6
|
+
#page #header { height: 300px; }
|
7
|
+
#page #header h1 { font-size: 50px; color: blue; }
|
8
|
+
|
9
|
+
#content.user.show #container.top #column.left { width: 100px; }
|
10
|
+
#content.user.show #container.top #column.right { width: 600px; }
|
11
|
+
#content.user.show #container.bottom { background: brown; }
|
12
|
+
|
13
|
+
midrule { inthe: middle; }
|
14
|
+
|
15
|
+
body { font: Arial; background: blue; }
|
16
|
+
|
17
|
+
#page { width: 700px; height: 100; }
|
18
|
+
#page #header { height: 300px; }
|
19
|
+
#page #header h1 { font-size: 50px; color: blue; }
|
20
|
+
|
21
|
+
#content.user.show #container.top #column.left { width: 100px; }
|
22
|
+
#content.user.show #container.top #column.right { width: 600px; }
|
23
|
+
#content.user.show #container.bottom { background: brown; }
|
24
|
+
|
25
|
+
@import url(basic.css);
|
26
|
+
@import url(../results/complex.css);
|
27
|
+
#foo { background-color: #bbaaff; }
|
28
|
+
|
29
|
+
nonimported { myconst: hello; otherconst: goodbye; post-mixin: here; }
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
body
|
4
|
+
:font Arial
|
5
|
+
:background blue
|
6
|
+
|
7
|
+
#page
|
8
|
+
:width 700px
|
9
|
+
:height 100
|
10
|
+
#header
|
11
|
+
:height 300px
|
12
|
+
h1
|
13
|
+
:font-size 50px
|
14
|
+
:color blue
|
15
|
+
|
16
|
+
#content.user.show
|
17
|
+
#container.top
|
18
|
+
#column.left
|
19
|
+
:width 100px
|
20
|
+
#column.right
|
21
|
+
:width 600px
|
22
|
+
#container.bottom
|
23
|
+
:background brown
|
@@ -0,0 +1,430 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
3
|
+
require File.dirname(__FILE__) + '/test_helper'
|
4
|
+
require 'sass/plugin'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
class SassPluginTest < Test::Unit::TestCase
|
8
|
+
@@templates = %w{
|
9
|
+
complex script parent_ref import scss_import alt
|
10
|
+
subdir/subdir subdir/nested_subdir/nested_subdir
|
11
|
+
options
|
12
|
+
}
|
13
|
+
|
14
|
+
@@cache_store = Sass::InMemoryCacheStore.new
|
15
|
+
|
16
|
+
def setup
|
17
|
+
FileUtils.mkdir_p tempfile_loc
|
18
|
+
FileUtils.mkdir_p tempfile_loc(nil,"more_")
|
19
|
+
set_plugin_opts
|
20
|
+
update_all_stylesheets!
|
21
|
+
reset_mtimes
|
22
|
+
end
|
23
|
+
|
24
|
+
def teardown
|
25
|
+
clean_up_sassc
|
26
|
+
Sass::Plugin.reset!
|
27
|
+
FileUtils.rm_r tempfile_loc
|
28
|
+
FileUtils.rm_r tempfile_loc(nil,"more_")
|
29
|
+
end
|
30
|
+
|
31
|
+
@@templates.each do |name|
|
32
|
+
define_method("test_template_renders_correctly (#{name})") do
|
33
|
+
assert_renders_correctly(name)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_no_update
|
38
|
+
File.delete(tempfile_loc('basic'))
|
39
|
+
assert_needs_update 'basic'
|
40
|
+
update_all_stylesheets!
|
41
|
+
assert_stylesheet_updated 'basic'
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_update_needed_when_modified
|
45
|
+
touch 'basic'
|
46
|
+
assert_needs_update 'basic'
|
47
|
+
update_all_stylesheets!
|
48
|
+
assert_stylesheet_updated 'basic'
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_update_needed_when_dependency_modified
|
52
|
+
touch 'basic'
|
53
|
+
assert_needs_update 'import'
|
54
|
+
update_all_stylesheets!
|
55
|
+
assert_stylesheet_updated 'basic'
|
56
|
+
assert_stylesheet_updated 'import'
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_update_needed_when_scss_dependency_modified
|
60
|
+
touch 'scss_importee'
|
61
|
+
assert_needs_update 'import'
|
62
|
+
update_all_stylesheets!
|
63
|
+
assert_stylesheet_updated 'scss_importee'
|
64
|
+
assert_stylesheet_updated 'import'
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_scss_update_needed_when_dependency_modified
|
68
|
+
touch 'basic'
|
69
|
+
assert_needs_update 'scss_import'
|
70
|
+
update_all_stylesheets!
|
71
|
+
assert_stylesheet_updated 'basic'
|
72
|
+
assert_stylesheet_updated 'scss_import'
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_full_exception_handling
|
76
|
+
File.delete(tempfile_loc('bork1'))
|
77
|
+
update_all_stylesheets!
|
78
|
+
File.open(tempfile_loc('bork1')) do |file|
|
79
|
+
assert_equal(<<CSS.strip, file.read.split("\n")[0...6].join("\n"))
|
80
|
+
/*
|
81
|
+
Syntax error: Undefined variable: "$bork".
|
82
|
+
on line 2 of #{template_loc('bork1')}
|
83
|
+
|
84
|
+
1: bork
|
85
|
+
2: :bork $bork
|
86
|
+
CSS
|
87
|
+
end
|
88
|
+
File.delete(tempfile_loc('bork1'))
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_nonfull_exception_handling
|
92
|
+
old_full_exception = Sass::Plugin.options[:full_exception]
|
93
|
+
Sass::Plugin.options[:full_exception] = false
|
94
|
+
|
95
|
+
File.delete(tempfile_loc('bork1'))
|
96
|
+
assert_raise(Sass::SyntaxError) {update_all_stylesheets!}
|
97
|
+
ensure
|
98
|
+
Sass::Plugin.options[:full_exception] = old_full_exception
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_two_template_directories
|
102
|
+
set_plugin_opts :template_location => {
|
103
|
+
template_loc => tempfile_loc,
|
104
|
+
template_loc(nil,'more_') => tempfile_loc(nil,'more_')
|
105
|
+
}
|
106
|
+
update_all_stylesheets!
|
107
|
+
['more1', 'more_import'].each { |name| assert_renders_correctly(name, :prefix => 'more_') }
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_two_template_directories_with_line_annotations
|
111
|
+
set_plugin_opts :line_comments => true,
|
112
|
+
:style => :nested,
|
113
|
+
:template_location => {
|
114
|
+
template_loc => tempfile_loc,
|
115
|
+
template_loc(nil,'more_') => tempfile_loc(nil,'more_')
|
116
|
+
}
|
117
|
+
update_all_stylesheets!
|
118
|
+
assert_renders_correctly('more1_with_line_comments', 'more1', :prefix => 'more_')
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_doesnt_render_partials
|
122
|
+
assert !File.exists?(tempfile_loc('_partial'))
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_template_location_array
|
126
|
+
assert_equal [[template_loc, tempfile_loc]], Sass::Plugin.template_location_array
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_add_template_location
|
130
|
+
Sass::Plugin.add_template_location(template_loc(nil, "more_"), tempfile_loc(nil, "more_"))
|
131
|
+
assert_equal(
|
132
|
+
[[template_loc, tempfile_loc], [template_loc(nil, "more_"), tempfile_loc(nil, "more_")]],
|
133
|
+
Sass::Plugin.template_location_array)
|
134
|
+
|
135
|
+
touch 'more1', 'more_'
|
136
|
+
touch 'basic'
|
137
|
+
assert_needs_update "more1", "more_"
|
138
|
+
assert_needs_update "basic"
|
139
|
+
update_all_stylesheets!
|
140
|
+
assert_doesnt_need_update "more1", "more_"
|
141
|
+
assert_doesnt_need_update "basic"
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_remove_template_location
|
145
|
+
Sass::Plugin.add_template_location(template_loc(nil, "more_"), tempfile_loc(nil, "more_"))
|
146
|
+
Sass::Plugin.remove_template_location(template_loc, tempfile_loc)
|
147
|
+
assert_equal(
|
148
|
+
[[template_loc(nil, "more_"), tempfile_loc(nil, "more_")]],
|
149
|
+
Sass::Plugin.template_location_array)
|
150
|
+
|
151
|
+
touch 'more1', 'more_'
|
152
|
+
touch 'basic'
|
153
|
+
assert_needs_update "more1", "more_"
|
154
|
+
assert_needs_update "basic"
|
155
|
+
update_all_stylesheets!
|
156
|
+
assert_doesnt_need_update "more1", "more_"
|
157
|
+
assert_needs_update "basic"
|
158
|
+
end
|
159
|
+
|
160
|
+
# Callbacks
|
161
|
+
|
162
|
+
def test_updating_stylesheets_callback
|
163
|
+
# Should run even when there's nothing to update
|
164
|
+
assert_callback :updating_stylesheets, []
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_updating_stylesheets_callback_with_individual_files
|
168
|
+
files = [[template_loc("basic"), tempfile_loc("basic")]]
|
169
|
+
assert_callback(:updating_stylesheets, files) {Sass::Util.silence_sass_warnings{Sass::Plugin.update_stylesheets(files)}}
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_updating_stylesheets_callback_with_never_update
|
173
|
+
Sass::Plugin.options[:never_update] = true
|
174
|
+
assert_no_callback :updating_stylesheets
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_updating_stylesheet_callback_for_updated_template
|
178
|
+
Sass::Plugin.options[:always_update] = false
|
179
|
+
touch 'basic'
|
180
|
+
assert_no_callback :updating_stylesheet, template_loc("complex"), tempfile_loc("complex") do
|
181
|
+
assert_callbacks(
|
182
|
+
[:updating_stylesheet, template_loc("basic"), tempfile_loc("basic")],
|
183
|
+
[:updating_stylesheet, template_loc("import"), tempfile_loc("import")])
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_updating_stylesheet_callback_for_fresh_template
|
188
|
+
Sass::Plugin.options[:always_update] = false
|
189
|
+
assert_no_callback :updating_stylesheet
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_updating_stylesheet_callback_for_error_template
|
193
|
+
Sass::Plugin.options[:always_update] = false
|
194
|
+
touch 'bork1'
|
195
|
+
assert_no_callback :updating_stylesheet
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_not_updating_stylesheet_callback_for_fresh_template
|
199
|
+
Sass::Plugin.options[:always_update] = false
|
200
|
+
assert_callback :not_updating_stylesheet, template_loc("basic"), tempfile_loc("basic")
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_not_updating_stylesheet_callback_for_updated_template
|
204
|
+
Sass::Plugin.options[:always_update] = false
|
205
|
+
assert_callback :not_updating_stylesheet, template_loc("complex"), tempfile_loc("complex") do
|
206
|
+
assert_no_callbacks(
|
207
|
+
[:updating_stylesheet, template_loc("basic"), tempfile_loc("basic")],
|
208
|
+
[:updating_stylesheet, template_loc("import"), tempfile_loc("import")])
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_not_updating_stylesheet_callback_with_never_update
|
213
|
+
Sass::Plugin.options[:never_update] = true
|
214
|
+
assert_no_callback :not_updating_stylesheet
|
215
|
+
end
|
216
|
+
|
217
|
+
def test_not_updating_stylesheet_callback_for_partial
|
218
|
+
Sass::Plugin.options[:always_update] = false
|
219
|
+
assert_no_callback :not_updating_stylesheet, template_loc("_partial"), tempfile_loc("_partial")
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_not_updating_stylesheet_callback_for_error
|
223
|
+
Sass::Plugin.options[:always_update] = false
|
224
|
+
touch 'bork1'
|
225
|
+
assert_no_callback :not_updating_stylesheet, template_loc("bork1"), tempfile_loc("bork1")
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_compilation_error_callback
|
229
|
+
Sass::Plugin.options[:always_update] = false
|
230
|
+
touch 'bork1'
|
231
|
+
assert_callback(:compilation_error,
|
232
|
+
lambda {|e| e.message == 'Undefined variable: "$bork".'},
|
233
|
+
template_loc("bork1"), tempfile_loc("bork1"))
|
234
|
+
end
|
235
|
+
|
236
|
+
def test_compilation_error_callback_for_file_access
|
237
|
+
Sass::Plugin.options[:always_update] = false
|
238
|
+
assert_callback(:compilation_error,
|
239
|
+
lambda {|e| e.is_a?(Errno::ENOENT)},
|
240
|
+
template_loc("nonexistent"), tempfile_loc("nonexistent")) do
|
241
|
+
Sass::Plugin.update_stylesheets([[template_loc("nonexistent"), tempfile_loc("nonexistent")]])
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_creating_directory_callback
|
246
|
+
Sass::Plugin.options[:always_update] = false
|
247
|
+
dir = File.join(tempfile_loc, "subdir", "nested_subdir")
|
248
|
+
FileUtils.rm_r dir
|
249
|
+
assert_callback :creating_directory, dir
|
250
|
+
end
|
251
|
+
|
252
|
+
## Regression
|
253
|
+
|
254
|
+
def test_cached_dependencies_update
|
255
|
+
FileUtils.mv(template_loc("basic"), template_loc("basic", "more_"))
|
256
|
+
set_plugin_opts :load_paths => [template_loc(nil, "more_")]
|
257
|
+
|
258
|
+
touch 'basic', 'more_'
|
259
|
+
assert_needs_update "import"
|
260
|
+
update_all_stylesheets!
|
261
|
+
assert_renders_correctly("import")
|
262
|
+
ensure
|
263
|
+
FileUtils.mv(template_loc("basic", "more_"), template_loc("basic"))
|
264
|
+
end
|
265
|
+
|
266
|
+
def test_cached_relative_import
|
267
|
+
old_always_update = Sass::Plugin.options[:always_update]
|
268
|
+
Sass::Plugin.options[:always_update] = true
|
269
|
+
update_all_stylesheets!
|
270
|
+
assert_renders_correctly('subdir/subdir')
|
271
|
+
ensure
|
272
|
+
Sass::Plugin.options[:always_update] = old_always_update
|
273
|
+
end
|
274
|
+
|
275
|
+
private
|
276
|
+
|
277
|
+
def assert_renders_correctly(*arguments)
|
278
|
+
options = arguments.last.is_a?(Hash) ? arguments.pop : {}
|
279
|
+
prefix = options[:prefix]
|
280
|
+
result_name = arguments.shift
|
281
|
+
tempfile_name = arguments.shift || result_name
|
282
|
+
expected_lines = File.read(result_loc(result_name, prefix)).split("\n")
|
283
|
+
actual_lines = File.read(tempfile_loc(tempfile_name, prefix)).split("\n")
|
284
|
+
|
285
|
+
if actual_lines.first == "/*" && expected_lines.first != "/*"
|
286
|
+
assert(false, actual_lines[0..actual_lines.enum_with_index.find {|l, i| l == "*/"}.last].join("\n"))
|
287
|
+
end
|
288
|
+
|
289
|
+
expected_lines.zip(actual_lines).each_with_index do |pair, line|
|
290
|
+
message = "template: #{result_name}\nline: #{line + 1}"
|
291
|
+
assert_equal(pair.first, pair.last, message)
|
292
|
+
end
|
293
|
+
if expected_lines.size < actual_lines.size
|
294
|
+
assert(false, "#{actual_lines.size - expected_lines.size} Trailing lines found in #{tempfile_name}.css: #{actual_lines[expected_lines.size..-1].join('\n')}")
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
def assert_stylesheet_updated(name)
|
299
|
+
assert_doesnt_need_update name
|
300
|
+
|
301
|
+
# Make sure it isn't an exception
|
302
|
+
expected_lines = File.read(result_loc(name)).split("\n")
|
303
|
+
actual_lines = File.read(tempfile_loc(name)).split("\n")
|
304
|
+
if actual_lines.first == "/*" && expected_lines.first != "/*"
|
305
|
+
assert(false, actual_lines[0..actual_lines.enum_with_index.find {|l, i| l == "*/"}.last].join("\n"))
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def assert_callback(name, *expected_args)
|
310
|
+
run = false
|
311
|
+
Sass::Plugin.send("on_#{name}") do |*args|
|
312
|
+
run ||= expected_args.zip(args).all? do |ea, a|
|
313
|
+
ea.respond_to?(:call) ? ea.call(a) : ea == a
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
if block_given?
|
318
|
+
yield
|
319
|
+
else
|
320
|
+
update_all_stylesheets!
|
321
|
+
end
|
322
|
+
|
323
|
+
assert run, "Expected #{name} callback to be run with arguments:\n #{expected_args.inspect}"
|
324
|
+
end
|
325
|
+
|
326
|
+
def assert_no_callback(name, *unexpected_args)
|
327
|
+
Sass::Plugin.send("on_#{name}") do |*a|
|
328
|
+
next unless unexpected_args.empty? || a == unexpected_args
|
329
|
+
|
330
|
+
msg = "Expected #{name} callback not to be run"
|
331
|
+
if !unexpected_args.empty?
|
332
|
+
msg << " with arguments #{unexpected_args.inspect}"
|
333
|
+
elsif !a.empty?
|
334
|
+
msg << ",\n was run with arguments #{a.inspect}"
|
335
|
+
end
|
336
|
+
|
337
|
+
flunk msg
|
338
|
+
end
|
339
|
+
|
340
|
+
if block_given?
|
341
|
+
yield
|
342
|
+
else
|
343
|
+
update_all_stylesheets!
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
def assert_callbacks(*args)
|
348
|
+
return update_all_stylesheets! if args.empty?
|
349
|
+
assert_callback(*args.pop) {assert_callbacks(*args)}
|
350
|
+
end
|
351
|
+
|
352
|
+
def assert_no_callbacks(*args)
|
353
|
+
return update_all_stylesheets! if args.empty?
|
354
|
+
assert_no_callback(*args.pop) {assert_no_callbacks(*args)}
|
355
|
+
end
|
356
|
+
|
357
|
+
def update_all_stylesheets!
|
358
|
+
Sass::Util.silence_sass_warnings do
|
359
|
+
Sass::Plugin.update_stylesheets
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
def assert_needs_update(*args)
|
364
|
+
assert(Sass::Plugin::StalenessChecker.stylesheet_needs_update?(tempfile_loc(*args), template_loc(*args)),
|
365
|
+
"Expected #{template_loc(*args)} to need an update.")
|
366
|
+
end
|
367
|
+
|
368
|
+
def assert_doesnt_need_update(*args)
|
369
|
+
assert(!Sass::Plugin::StalenessChecker.stylesheet_needs_update?(tempfile_loc(*args), template_loc(*args)),
|
370
|
+
"Expected #{template_loc(*args)} not to need an update.")
|
371
|
+
end
|
372
|
+
|
373
|
+
def touch(*args)
|
374
|
+
FileUtils.touch(template_loc(*args))
|
375
|
+
end
|
376
|
+
|
377
|
+
def reset_mtimes
|
378
|
+
Sass::Plugin::StalenessChecker.dependencies_cache = {}
|
379
|
+
atime = Time.now
|
380
|
+
mtime = Time.now - 5
|
381
|
+
Dir["{#{template_loc},#{tempfile_loc}}/**/*.{css,sass,scss}"].each {|f| File.utime(atime, mtime, f)}
|
382
|
+
end
|
383
|
+
|
384
|
+
def template_loc(name = nil, prefix = nil)
|
385
|
+
if name
|
386
|
+
scss = absolutize "#{prefix}templates/#{name}.scss"
|
387
|
+
File.exists?(scss) ? scss : absolutize("#{prefix}templates/#{name}.sass")
|
388
|
+
else
|
389
|
+
absolutize "#{prefix}templates"
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
def tempfile_loc(name = nil, prefix = nil)
|
394
|
+
if name
|
395
|
+
absolutize "#{prefix}tmp/#{name}.css"
|
396
|
+
else
|
397
|
+
absolutize "#{prefix}tmp"
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
def result_loc(name = nil, prefix = nil)
|
402
|
+
if name
|
403
|
+
absolutize "#{prefix}results/#{name}.css"
|
404
|
+
else
|
405
|
+
absolutize "#{prefix}results"
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
def set_plugin_opts(overrides = {})
|
410
|
+
Sass::Plugin.options.merge!(
|
411
|
+
:template_location => template_loc,
|
412
|
+
:css_location => tempfile_loc,
|
413
|
+
:style => :compact,
|
414
|
+
:always_update => true,
|
415
|
+
:never_update => false,
|
416
|
+
:full_exception => true,
|
417
|
+
:cache_store => @@cache_store
|
418
|
+
)
|
419
|
+
Sass::Plugin.options.merge!(overrides)
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
class Sass::Engine
|
424
|
+
alias_method :old_render, :render
|
425
|
+
|
426
|
+
def render
|
427
|
+
raise "bork bork bork!" if @template[0] == "{bork now!}"
|
428
|
+
old_render
|
429
|
+
end
|
430
|
+
end
|