haml 1.0.5 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of haml might be problematic. Click here for more details.
- data/README +229 -0
- data/Rakefile +56 -60
- data/VERSION +1 -1
- data/bin/haml +4 -14
- data/bin/html2haml +89 -0
- data/bin/sass +8 -0
- data/init.rb +5 -1
- data/lib/haml.rb +643 -0
- data/lib/haml/buffer.rb +33 -30
- data/lib/haml/engine.rb +258 -75
- data/lib/haml/error.rb +43 -0
- data/lib/haml/exec.rb +181 -0
- data/lib/haml/filters.rb +89 -0
- data/lib/haml/helpers.rb +19 -5
- data/lib/haml/helpers/action_view_mods.rb +28 -4
- data/lib/haml/template.rb +13 -27
- data/lib/sass.rb +418 -0
- data/lib/sass/constant.rb +190 -0
- data/lib/sass/constant/color.rb +77 -0
- data/lib/sass/constant/literal.rb +51 -0
- data/lib/sass/constant/number.rb +87 -0
- data/lib/sass/constant/operation.rb +30 -0
- data/lib/sass/constant/string.rb +18 -0
- data/lib/sass/engine.rb +179 -0
- data/lib/sass/error.rb +35 -0
- data/lib/sass/plugin.rb +119 -0
- data/lib/sass/tree/attr_node.rb +44 -0
- data/lib/sass/tree/node.rb +29 -0
- data/lib/sass/tree/rule_node.rb +47 -0
- data/lib/sass/tree/value_node.rb +12 -0
- data/test/benchmark.rb +16 -19
- data/test/haml/engine_test.rb +220 -0
- data/test/{helper_test.rb → haml/helper_test.rb} +9 -8
- data/test/{mocks → haml/mocks}/article.rb +0 -0
- data/test/{results → haml/results}/content_for_layout.xhtml +0 -0
- data/test/{results → haml/results}/eval_suppressed.xhtml +0 -0
- data/test/haml/results/filters.xhtml +57 -0
- data/test/{results → haml/results}/helpers.xhtml +10 -0
- data/test/haml/results/helpful.xhtml +8 -0
- data/test/{results → haml/results}/just_stuff.xhtml +5 -0
- data/test/{results → haml/results}/list.xhtml +0 -0
- data/test/{results → haml/results}/original_engine.xhtml +1 -1
- data/test/{results → haml/results}/partials.xhtml +0 -0
- data/test/{results → haml/results}/silent_script.xhtml +0 -0
- data/test/{results → haml/results}/standard.xhtml +2 -1
- data/test/{results → haml/results}/tag_parsing.xhtml +0 -0
- data/test/{results → haml/results}/very_basic.xhtml +0 -0
- data/test/haml/results/whitespace_handling.xhtml +104 -0
- data/test/{rhtml → haml/rhtml}/standard.rhtml +4 -1
- data/test/{runner.rb → haml/runner.rb} +1 -1
- data/test/{template_test.rb → haml/template_test.rb} +28 -23
- data/test/{templates → haml/templates}/_partial.haml +0 -0
- data/test/{templates → haml/templates}/_text_area.haml +0 -0
- data/test/haml/templates/breakage.haml +8 -0
- data/test/{templates → haml/templates}/content_for_layout.haml +0 -0
- data/test/{templates → haml/templates}/eval_suppressed.haml +0 -0
- data/test/haml/templates/filters.haml +53 -0
- data/test/{templates → haml/templates}/helpers.haml +10 -1
- data/test/{templates → haml/templates}/helpful.haml +3 -0
- data/test/{templates → haml/templates}/just_stuff.haml +7 -0
- data/test/{templates → haml/templates}/list.haml +0 -0
- data/test/haml/templates/original_engine.haml +17 -0
- data/test/{templates → haml/templates}/partialize.haml +0 -0
- data/test/{templates → haml/templates}/partials.haml +0 -0
- data/test/{templates → haml/templates}/silent_script.haml +0 -0
- data/test/{templates → haml/templates}/standard.haml +3 -1
- data/test/{templates → haml/templates}/tag_parsing.haml +0 -0
- data/test/{templates → haml/templates}/very_basic.haml +0 -0
- data/test/haml/templates/whitespace_handling.haml +137 -0
- data/test/profile.rb +36 -18
- data/test/sass/engine_test.rb +87 -0
- data/test/sass/plugin_test.rb +103 -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/constants.css +12 -0
- data/test/sass/results/expanded.css +18 -0
- data/test/sass/results/nested.css +14 -0
- data/test/sass/templates/basic.sass +23 -0
- data/test/sass/templates/bork.sass +2 -0
- data/test/sass/templates/compact.sass +15 -0
- data/test/sass/templates/complex.sass +291 -0
- data/test/sass/templates/constants.sass +80 -0
- data/test/sass/templates/expanded.sass +15 -0
- data/test/sass/templates/nested.sass +15 -0
- metadata +98 -48
- data/REFERENCE +0 -662
- data/test/engine_test.rb +0 -93
- data/test/results/helpful.xhtml +0 -5
- data/test/results/whitespace_handling.xhtml +0 -51
- data/test/templates/original_engine.haml +0 -17
- data/test/templates/whitespace_handling.haml +0 -66
@@ -1,5 +1,5 @@
|
|
1
1
|
= h("&&&&&&&&&&&") # This is an ActionView Helper... should load
|
2
|
-
- foo = capture do # This ActionView Helper is designed for ERB, but should work with
|
2
|
+
- foo = capture do # This ActionView Helper is designed for ERB, but should work with haml
|
3
3
|
%div
|
4
4
|
%p.title Title
|
5
5
|
%p.text
|
@@ -35,5 +35,14 @@ click
|
|
35
35
|
%p boom
|
36
36
|
- concat "foo\n"
|
37
37
|
- buffer.tabulation = 0
|
38
|
+
- def url_for(*stuff); stuff.join(' '); end
|
39
|
+
= form_tag 'hello/world'
|
40
|
+
- form_tag 'heeheeaform' do
|
41
|
+
%div= submit_tag 'save'
|
42
|
+
- form_for :article, @article, :url => 'article_url' do |f|
|
43
|
+
Title:
|
44
|
+
= f.text_field :title
|
45
|
+
Body:
|
46
|
+
= f.text_field :body
|
38
47
|
= list_of({:google => 'http://www.google.com'}) do |name, link|
|
39
48
|
%a{ :href => link }= name
|
@@ -7,6 +7,10 @@
|
|
7
7
|
!!! Strict foo bar
|
8
8
|
!!! FRAMESET
|
9
9
|
%strong{:apos => "Foo's bar!"} Boo!
|
10
|
+
== Embedded? false!
|
11
|
+
== Embedded? #{true}!
|
12
|
+
- embedded = true
|
13
|
+
== Embedded? #{embedded}!
|
10
14
|
.render= render :inline => "%em= 'wow!'", :type => :haml
|
11
15
|
= "stuff followed by whitespace"
|
12
16
|
|
@@ -25,6 +29,7 @@
|
|
25
29
|
cool, huh?
|
26
30
|
%strong there can even be sub-tags!
|
27
31
|
= "Or script!"
|
32
|
+
%p{ :class => "" } class attribute shouldn't appear!
|
28
33
|
/[if lte IE6] conditional comment!
|
29
34
|
/[if gte IE7]
|
30
35
|
%p Block conditional comment
|
@@ -32,3 +37,5 @@
|
|
32
37
|
%h1 Cool, eh?
|
33
38
|
/[if gte IE5.2]
|
34
39
|
Woah a period.
|
40
|
+
= "test" |
|
41
|
+
"test" |
|
File without changes
|
@@ -0,0 +1,17 @@
|
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%title Stop. haml time
|
5
|
+
#content
|
6
|
+
%h1 This is a title!
|
7
|
+
%p Lorem ipsum dolor sit amet, consectetur adipisicing elit
|
8
|
+
%p{:class => 'foo'} Cigarettes!
|
9
|
+
%h2 Man alive!
|
10
|
+
%ul.things
|
11
|
+
%li Slippers
|
12
|
+
%li Shoes
|
13
|
+
%li Bathrobe
|
14
|
+
%li Coffee
|
15
|
+
%pre
|
16
|
+
This is some text that's in a pre block!
|
17
|
+
Let's see what happens when it's rendered! What about now, since we're on a new line?
|
File without changes
|
File without changes
|
File without changes
|
@@ -5,13 +5,15 @@
|
|
5
5
|
%meta{"http-equiv" => "Content-Type", :content => "text/html; charset=utf-8"}/
|
6
6
|
%body
|
7
7
|
/ You're In my house now!
|
8
|
-
- concat
|
8
|
+
- concat("foo\n")
|
9
9
|
.header
|
10
10
|
Yes, ladies and gentileman. He is just that egotistical.
|
11
11
|
Fantastic! This should be multi-line output
|
12
12
|
The question is if this would translate! Ahah!
|
13
13
|
= 1 + 9 + 8 + 2 #numbers should work and this should be ignored
|
14
14
|
#body= " Quotes should be loved! Just like people!"
|
15
|
+
- 120.times do |number|
|
16
|
+
- number
|
15
17
|
Wow.|
|
16
18
|
%p
|
17
19
|
= "Holy cow " + |
|
File without changes
|
File without changes
|
@@ -0,0 +1,137 @@
|
|
1
|
+
#whitespace_test
|
2
|
+
= render :file => "_text_area.haml", :locals => { :value => "Oneline" }
|
3
|
+
= render :file => "_text_area.haml", :locals => { :value => "Two\nlines" }
|
4
|
+
~ render :file => "_text_area.haml", :locals => { :value => "Oneline" }
|
5
|
+
~ render :file => "_text_area.haml", :locals => { :value => "Two\nlines" }
|
6
|
+
#flattened~ render :file => "_text_area.haml", :locals => { :value => "Two\nlines" }
|
7
|
+
.hithere
|
8
|
+
~ "Foo bar"
|
9
|
+
~ "<pre>foo bar</pre>"
|
10
|
+
~ "<pre>foo\nbar</pre>"
|
11
|
+
%p~ "<pre>foo\nbar</pre>"
|
12
|
+
%p~ "foo\nbar"
|
13
|
+
%pre~
|
14
|
+
___
|
15
|
+
,o88888
|
16
|
+
,o8888888'
|
17
|
+
,:o:o:oooo. ,8O88Pd8888"
|
18
|
+
,.::.::o:ooooOoOoO. ,oO8O8Pd888'"
|
19
|
+
,.:.::o:ooOoOoOO8O8OOo.8OOPd8O8O"
|
20
|
+
, ..:.::o:ooOoOOOO8OOOOo.FdO8O8"
|
21
|
+
, ..:.::o:ooOoOO8O888O8O,COCOO"
|
22
|
+
, . ..:.::o:ooOoOOOO8OOOOCOCO"
|
23
|
+
. ..:.::o:ooOoOoOO8O8OCCCC"o
|
24
|
+
. ..:.::o:ooooOoCoCCC"o:o
|
25
|
+
. ..:.::o:o:,cooooCo"oo:o:
|
26
|
+
` . . ..:.:cocoooo"'o:o:::'
|
27
|
+
.` . ..::ccccoc"'o:o:o:::'
|
28
|
+
:.:. ,c:cccc"':.:.:.:.:.'
|
29
|
+
..:.:"'`::::c:"'..:.:.:.:.:.' http://www.chris.com/ASCII/
|
30
|
+
...:.'.:.::::"' . . . . .'
|
31
|
+
.. . ....:."' ` . . . ''
|
32
|
+
. . . ...."'
|
33
|
+
.. . ."' -hrr-
|
34
|
+
.
|
35
|
+
|
36
|
+
|
37
|
+
It's a planet!
|
38
|
+
%strong This shouldn't be bold!
|
39
|
+
%strong This should!
|
40
|
+
%textarea
|
41
|
+
~
|
42
|
+
___ ___ ___ ___
|
43
|
+
/\__\ /\ \ /\__\ /\__\
|
44
|
+
/:/ / /::\ \ /::| | /:/ /
|
45
|
+
/:/__/ /:/\:\ \ /:|:| | /:/ /
|
46
|
+
/::\ \ ___ /::\~\:\ \ /:/|:|__|__ /:/ /
|
47
|
+
/:/\:\ /\__\ /:/\:\ \:\__\ /:/ |::::\__\ /:/__/
|
48
|
+
\/__\:\/:/ / \/__\:\/:/ / \/__/~~/:/ / \:\ \
|
49
|
+
\::/ / \::/ / /:/ / \:\ \
|
50
|
+
/:/ / /:/ / /:/ / \:\ \
|
51
|
+
/:/ / /:/ / /:/ / \:\__\
|
52
|
+
\/__/ \/__/ \/__/ \/__/
|
53
|
+
|
54
|
+
Many
|
55
|
+
thanks
|
56
|
+
to
|
57
|
+
http://www.network-science.de/ascii/
|
58
|
+
%strong indeed!
|
59
|
+
.foo
|
60
|
+
~ 13
|
61
|
+
~ ['a', 'b', 'c'].map do |a|
|
62
|
+
- "<textarea>\n#{a}\n</textarea>"
|
63
|
+
%pre
|
64
|
+
~
|
65
|
+
foo
|
66
|
+
bar
|
67
|
+
#whitespace_test
|
68
|
+
= render :file => "_text_area.haml", :locals => { :value => "Oneline" }
|
69
|
+
= render :file => "_text_area.haml", :locals => { :value => "Two\nlines" }
|
70
|
+
= find_and_preserve render(:file => "_text_area.haml", :locals => { :value => "Oneline" })
|
71
|
+
= find_and_preserve render(:file => "_text_area.haml", :locals => { :value => "Two\nlines" })
|
72
|
+
#flattened= find_and_preserve render(:file => "_text_area.haml", :locals => { :value => "Two\nlines" })
|
73
|
+
.hithere
|
74
|
+
= find_and_preserve("Foo bar")
|
75
|
+
= find_and_preserve("<pre>foo bar</pre>")
|
76
|
+
= find_and_preserve("<pre>foo\nbar</pre>")
|
77
|
+
%p= find_and_preserve("<pre>foo\nbar</pre>")
|
78
|
+
%p= find_and_preserve("foo\nbar")
|
79
|
+
%pre
|
80
|
+
:preserve
|
81
|
+
___
|
82
|
+
,o88888
|
83
|
+
,o8888888'
|
84
|
+
,:o:o:oooo. ,8O88Pd8888"
|
85
|
+
,.::.::o:ooooOoOoO. ,oO8O8Pd888'"
|
86
|
+
,.:.::o:ooOoOoOO8O8OOo.8OOPd8O8O"
|
87
|
+
, ..:.::o:ooOoOOOO8OOOOo.FdO8O8"
|
88
|
+
, ..:.::o:ooOoOO8O888O8O,COCOO"
|
89
|
+
, . ..:.::o:ooOoOOOO8OOOOCOCO"
|
90
|
+
. ..:.::o:ooOoOoOO8O8OCCCC"o
|
91
|
+
. ..:.::o:ooooOoCoCCC"o:o
|
92
|
+
. ..:.::o:o:,cooooCo"oo:o:
|
93
|
+
` . . ..:.:cocoooo"'o:o:::'
|
94
|
+
.` . ..::ccccoc"'o:o:o:::'
|
95
|
+
:.:. ,c:cccc"':.:.:.:.:.'
|
96
|
+
..:.:"'`::::c:"'..:.:.:.:.:.' http://www.chris.com/ASCII/
|
97
|
+
...:.'.:.::::"' . . . . .'
|
98
|
+
.. . ....:."' ` . . . ''
|
99
|
+
. . . ...."'
|
100
|
+
.. . ."' -hrr-
|
101
|
+
.
|
102
|
+
|
103
|
+
|
104
|
+
It's a planet!
|
105
|
+
%strong This shouldn't be bold!
|
106
|
+
%strong This should!
|
107
|
+
%textarea
|
108
|
+
:preserve
|
109
|
+
___ ___ ___ ___
|
110
|
+
/\__\ /\ \ /\__\ /\__\
|
111
|
+
/:/ / /::\ \ /::| | /:/ /
|
112
|
+
/:/__/ /:/\:\ \ /:|:| | /:/ /
|
113
|
+
/::\ \ ___ /::\~\:\ \ /:/|:|__|__ /:/ /
|
114
|
+
/:/\:\ /\__\ /:/\:\ \:\__\ /:/ |::::\__\ /:/__/
|
115
|
+
\/__\:\/:/ / \/__\:\/:/ / \/__/~~/:/ / \:\ \
|
116
|
+
\::/ / \::/ / /:/ / \:\ \
|
117
|
+
/:/ / /:/ / /:/ / \:\ \
|
118
|
+
/:/ / /:/ / /:/ / \:\__\
|
119
|
+
\/__/ \/__/ \/__/ \/__/
|
120
|
+
|
121
|
+
Many
|
122
|
+
thanks
|
123
|
+
to
|
124
|
+
http://www.network-science.de/ascii/
|
125
|
+
%strong indeed!
|
126
|
+
.foo
|
127
|
+
= find_and_preserve(13)
|
128
|
+
%pre
|
129
|
+
:preserve
|
130
|
+
__ ______ __ ______
|
131
|
+
.----.| |--.|__ |.----.| |--..--------.| __ |
|
132
|
+
| __|| ||__ || __|| < | || __ |
|
133
|
+
|____||__|__||______||____||__|__||__|__|__||______|
|
134
|
+
%pre
|
135
|
+
:preserve
|
136
|
+
foo
|
137
|
+
bar
|
data/test/profile.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../lib/haml
|
1
|
+
require File.dirname(__FILE__) + '/../lib/haml'
|
2
|
+
require 'haml/template'
|
2
3
|
require 'rubygems'
|
3
4
|
require 'active_support'
|
4
5
|
require 'action_view'
|
@@ -6,13 +7,32 @@ require 'profiler'
|
|
6
7
|
require 'stringio'
|
7
8
|
|
8
9
|
module Haml
|
9
|
-
#
|
10
|
-
#
|
10
|
+
# Used by both Haml::Profiler and Sass::Profiler.
|
11
|
+
# Encapsulates profiling behavior.
|
12
|
+
module AbstractProfiler
|
13
|
+
def self.profile(times, &block)
|
14
|
+
# Runs the profiler, collects information
|
15
|
+
Profiler__::start_profile
|
16
|
+
times.times &block
|
17
|
+
Profiler__::stop_profile
|
18
|
+
|
19
|
+
# Outputs information to a StringIO, returns result
|
20
|
+
io = StringIO.new
|
21
|
+
Profiler__::print_profile(io)
|
22
|
+
io.pos = 0
|
23
|
+
result = io.read
|
24
|
+
io.close
|
25
|
+
result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# A profiler for Haml, mostly for development use. This simply implements
|
30
|
+
# the Ruby profiler for profiling haml code.
|
11
31
|
class Profiler
|
12
32
|
|
13
33
|
# Creates a new profiler that looks for templates in the base
|
14
34
|
# directory.
|
15
|
-
def initialize(base = File.join(File.dirname(__FILE__), 'templates'))
|
35
|
+
def initialize(base = File.join(File.dirname(__FILE__), 'haml', 'templates'))
|
16
36
|
ActionView::Base.register_template_handler("haml", Haml::Template)
|
17
37
|
unless base.class == ActionView::Base
|
18
38
|
@base = ActionView::Base.new(base)
|
@@ -21,25 +41,23 @@ module Haml
|
|
21
41
|
end
|
22
42
|
end
|
23
43
|
|
24
|
-
# Profiles
|
44
|
+
# Profiles haml on the given template with the given number of runs.
|
25
45
|
# The template name shouldn't have a file extension; this will
|
26
|
-
# automatically look for a
|
46
|
+
# automatically look for a haml template.
|
27
47
|
#
|
28
48
|
# Returns the results of the profiling as a string.
|
29
49
|
def profile(runs = 100, template_name = 'standard')
|
30
|
-
|
31
|
-
Profiler__::start_profile
|
32
|
-
runs.times { @base.render template_name }
|
33
|
-
Profiler__::stop_profile
|
34
|
-
|
35
|
-
# Outputs information to a StringIO, returns result
|
36
|
-
io = StringIO.new
|
37
|
-
Profiler__::print_profile(io)
|
38
|
-
io.pos = 0
|
39
|
-
result = io.read
|
40
|
-
io.close
|
41
|
-
return result
|
50
|
+
AbstractProfiler.profile(runs) { @base.render template_name }
|
42
51
|
end
|
52
|
+
end
|
53
|
+
end
|
43
54
|
|
55
|
+
module Sass
|
56
|
+
class Profiler
|
57
|
+
def profile(runs = 100, template_name = 'complex')
|
58
|
+
Haml::AbstractProfiler.profile(runs) do
|
59
|
+
Sass::Engine.new("#{File.dirname(__FILE__)}/sass/templates/#{template_name}.sass").render
|
60
|
+
end
|
61
|
+
end
|
44
62
|
end
|
45
63
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require File.dirname(__FILE__) + '/../../lib/sass'
|
5
|
+
require 'sass/engine'
|
6
|
+
|
7
|
+
class SassEngineTest < Test::Unit::TestCase
|
8
|
+
EXCEPTION_MAP = {
|
9
|
+
"!a = 1 + " => 'Constant arithmetic error: "1 +"',
|
10
|
+
"!a = 1 + 2 +" => 'Constant arithmetic error: "1 + 2 +"',
|
11
|
+
"!a = \"b" => 'Unterminated string: "\\"b"',
|
12
|
+
"!a = #aaa - a" => 'Undefined operation: "#afafaf minus a"',
|
13
|
+
"!a = #aaa / a" => 'Undefined operation: "#afafaf div a"',
|
14
|
+
"!a = #aaa * a" => 'Undefined operation: "#afafaf times a"',
|
15
|
+
"!a = #aaa % a" => 'Undefined operation: "#afafaf mod a"',
|
16
|
+
"!a = 1 - a" => 'Undefined operation: "1 minus a"',
|
17
|
+
"!a = 1 * a" => 'Undefined operation: "1 times a"',
|
18
|
+
"!a = 1 / a" => 'Undefined operation: "1 div a"',
|
19
|
+
"!a = 1 % a" => 'Undefined operation: "1 mod a"',
|
20
|
+
":" => 'Invalid attribute: ":"',
|
21
|
+
": a" => 'Invalid attribute: ": a"',
|
22
|
+
":= a" => 'Invalid attribute: ":= a"',
|
23
|
+
"a\n :b" => 'Invalid attribute: ":b "',
|
24
|
+
"a\n :b: c" => 'Invalid attribute: ":b: c" (This isn\'t CSS!)',
|
25
|
+
"a\n :b c;" => 'Invalid attribute: ":b c;" (This isn\'t CSS!)',
|
26
|
+
":a" => 'Attributes aren\'t allowed at the root of a document.',
|
27
|
+
"!" => 'Invalid constant: "!"',
|
28
|
+
"!a" => 'Invalid constant: "!a"',
|
29
|
+
"! a" => 'Invalid constant: "! a"',
|
30
|
+
"!a b" => 'Invalid constant: "!a b"',
|
31
|
+
"a\n\t:b c" => "Illegal Indentation: Only two space characters are allowed as tabulation.",
|
32
|
+
"a\n :b c" => "Illegal Indentation: Only two space characters are allowed as tabulation.",
|
33
|
+
"a\n :b c" => "Illegal Indentation: Only two space characters are allowed as tabulation.",
|
34
|
+
"a\n :b\n !c = 3" => "Constants may only be declared at the root of a document.",
|
35
|
+
"!a = 1b + 2c" => "Incompatible units: b and c"
|
36
|
+
}
|
37
|
+
|
38
|
+
def test_basic_render
|
39
|
+
renders_correctly "basic", { :style => :compact }
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_alternate_styles
|
43
|
+
renders_correctly "expanded", { :style => :expanded }
|
44
|
+
renders_correctly "compact", { :style => :compact }
|
45
|
+
renders_correctly "nested", { :style => :nested }
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_exceptions
|
49
|
+
EXCEPTION_MAP.each do |key, value|
|
50
|
+
begin
|
51
|
+
Sass::Engine.new(key).render
|
52
|
+
rescue Sass::SyntaxError => err
|
53
|
+
assert_equal(value, err.message)
|
54
|
+
assert(err.sass_line, "Line: #{key}")
|
55
|
+
assert_match(/\(sass\):[0-9]+/, err.backtrace[0], "Line: #{key}")
|
56
|
+
else
|
57
|
+
assert(false, "Exception not raised for '#{key}'!")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_exception_line
|
63
|
+
to_render = "rule\n :attr val\n :broken\n"
|
64
|
+
begin
|
65
|
+
Sass::Engine.new(to_render).render
|
66
|
+
rescue Sass::SyntaxError => err
|
67
|
+
assert_equal(3, err.sass_line)
|
68
|
+
else
|
69
|
+
assert(false, "Exception not raised for '#{to_render}'!")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def renders_correctly(name, options={})
|
76
|
+
sass_file = load_file(name, "sass")
|
77
|
+
css_file = load_file(name, "css")
|
78
|
+
css_result = Sass::Engine.new(sass_file, options).render
|
79
|
+
assert_equal css_file, css_result
|
80
|
+
end
|
81
|
+
|
82
|
+
def load_file(name, type = "sass")
|
83
|
+
@result = ''
|
84
|
+
File.new(File.dirname(__FILE__) + "/#{type == 'sass' ? 'templates' : 'results'}/#{name}.#{type}").each_line { |l| @result += l }
|
85
|
+
@result
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require File.dirname(__FILE__) + '/../../lib/sass'
|
5
|
+
|
6
|
+
RAILS_ENV = 'testing'
|
7
|
+
|
8
|
+
require 'sass/plugin'
|
9
|
+
|
10
|
+
class SassPluginTest < Test::Unit::TestCase
|
11
|
+
@@templates = %w{ complex constants }
|
12
|
+
|
13
|
+
def setup
|
14
|
+
Sass::Plugin.options = {
|
15
|
+
:template_location => File.dirname(__FILE__) + '/templates',
|
16
|
+
:css_location => File.dirname(__FILE__) + '/tmp',
|
17
|
+
:style => :compact
|
18
|
+
}
|
19
|
+
Sass::Plugin.options[:always_update] = true
|
20
|
+
|
21
|
+
Sass::Plugin.update_stylesheets
|
22
|
+
end
|
23
|
+
|
24
|
+
def teardown
|
25
|
+
File.delete(*Dir[tempfile_loc('*')])
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_templates_should_render_correctly
|
29
|
+
@@templates.each { |name| assert_renders_correctly(name) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_no_update
|
33
|
+
File.delete(tempfile_loc('basic'))
|
34
|
+
assert Sass::Plugin.stylesheet_needs_update?('basic')
|
35
|
+
Sass::Plugin.update_stylesheets
|
36
|
+
assert !Sass::Plugin.stylesheet_needs_update?('basic')
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_exception_handling
|
40
|
+
File.delete(tempfile_loc('bork'))
|
41
|
+
Sass::Plugin.update_stylesheets
|
42
|
+
File.open(tempfile_loc('bork')) do |file|
|
43
|
+
assert_equal("/*\nSass::SyntaxError: Undefined constant: \"!bork\"\non line 2 of #{File.dirname(__FILE__) + '/templates/bork.sass'}\n\n1: bork\n2: :bork= !bork", file.read.split("\n")[0...6].join("\n"))
|
44
|
+
end
|
45
|
+
File.delete(tempfile_loc('bork'))
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_production_exception_handling
|
49
|
+
Sass.const_set('RAILS_ENV', 'production')
|
50
|
+
|
51
|
+
File.delete(tempfile_loc('bork'))
|
52
|
+
Sass::Plugin.update_stylesheets
|
53
|
+
assert_equal("/* Internal stylesheet error */", File.read(tempfile_loc('bork')))
|
54
|
+
File.delete(tempfile_loc('bork'))
|
55
|
+
|
56
|
+
Sass::Plugin.const_set('RAILS_ENV', 'testing')
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_controller_process
|
60
|
+
File.delete(tempfile_loc('basic'))
|
61
|
+
assert Sass::Plugin.stylesheet_needs_update?('basic')
|
62
|
+
|
63
|
+
ActionController::Base.new.process
|
64
|
+
|
65
|
+
assert !Sass::Plugin.stylesheet_needs_update?('basic')
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def assert_renders_correctly(name)
|
71
|
+
File.read(result_loc(name)).split("\n").zip(File.read(tempfile_loc(name)).split("\n")).each_with_index do |pair, line|
|
72
|
+
message = "template: #{name}\nline: #{line + 1}"
|
73
|
+
assert_equal(pair.first, pair.last, message)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def tempfile_loc(name)
|
78
|
+
File.dirname(__FILE__) + "/tmp/#{name}.css"
|
79
|
+
end
|
80
|
+
|
81
|
+
def result_loc(name)
|
82
|
+
File.dirname(__FILE__) + "/results/#{name}.css"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
module Sass::Plugin
|
87
|
+
class << self
|
88
|
+
public :stylesheet_needs_update?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class Sass::Engine
|
93
|
+
alias_method :old_render, :render
|
94
|
+
|
95
|
+
def render
|
96
|
+
raise "bork bork bork!" if @template[0] == "{bork now!}"
|
97
|
+
old_render
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
class ActionController::Base
|
102
|
+
def sass_old_process(*args); end
|
103
|
+
end
|