hamlet 0.1
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/.gitignore +1 -0
- data/Gemfile +25 -0
- data/LICENSE +21 -0
- data/README.md +52 -0
- data/Rakefile +57 -0
- data/bin/hamletrb +7 -0
- data/extra/slim-mode.el +409 -0
- data/extra/test.hamlet +50 -0
- data/hamlet.gemspec +36 -0
- data/lib/hamlet.rb +7 -0
- data/lib/hamlet/engine.rb +3 -0
- data/lib/hamlet/parser.rb +147 -0
- data/lib/hamlet/template.rb +19 -0
- data/test/rails/Rakefile +7 -0
- data/test/rails/app/controllers/application_controller.rb +3 -0
- data/test/rails/app/controllers/parents_controller.rb +84 -0
- data/test/rails/app/controllers/slim_controller.rb +32 -0
- data/test/rails/app/helpers/application_helper.rb +2 -0
- data/test/rails/app/models/child.rb +3 -0
- data/test/rails/app/models/parent.rb +4 -0
- data/test/rails/app/views/layouts/application.html.slim +10 -0
- data/test/rails/app/views/parents/_form.html.slim +7 -0
- data/test/rails/app/views/parents/edit.html.slim +1 -0
- data/test/rails/app/views/parents/new.html.slim +1 -0
- data/test/rails/app/views/parents/show.html.slim +5 -0
- data/test/rails/app/views/slim/_partial.html.slim +1 -0
- data/test/rails/app/views/slim/content_for.html.slim +7 -0
- data/test/rails/app/views/slim/erb.html.erb +1 -0
- data/test/rails/app/views/slim/integers.html.slim +1 -0
- data/test/rails/app/views/slim/nil.html.slim +1 -0
- data/test/rails/app/views/slim/no_layout.html.slim +1 -0
- data/test/rails/app/views/slim/normal.html.slim +1 -0
- data/test/rails/app/views/slim/partial.html.slim +2 -0
- data/test/rails/app/views/slim/variables.html.slim +1 -0
- data/test/rails/config.ru +4 -0
- data/test/rails/config/application.rb +45 -0
- data/test/rails/config/boot.rb +10 -0
- data/test/rails/config/database.yml +4 -0
- data/test/rails/config/environment.rb +5 -0
- data/test/rails/config/environments/development.rb +26 -0
- data/test/rails/config/environments/production.rb +49 -0
- data/test/rails/config/environments/test.rb +35 -0
- data/test/rails/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails/config/initializers/inflections.rb +10 -0
- data/test/rails/config/initializers/mime_types.rb +5 -0
- data/test/rails/config/initializers/secret_token.rb +7 -0
- data/test/rails/config/initializers/session_store.rb +8 -0
- data/test/rails/config/locales/en.yml +5 -0
- data/test/rails/config/routes.rb +60 -0
- data/test/rails/db/migrate/20101220223037_parents_and_children.rb +17 -0
- data/test/rails/script/rails +6 -0
- data/test/rails/test/helper.rb +10 -0
- data/test/rails/test/test_slim.rb +77 -0
- data/test/slim/helper.rb +200 -0
- data/test/slim/test_chain_manipulation.rb +42 -0
- data/test/slim/test_code_blocks.rb +68 -0
- data/test/slim/test_code_escaping.rb +53 -0
- data/test/slim/test_code_evaluation.rb +281 -0
- data/test/slim/test_code_output.rb +159 -0
- data/test/slim/test_code_structure.rb +95 -0
- data/test/slim/test_embedded_engines.rb +141 -0
- data/test/slim/test_html_escaping.rb +40 -0
- data/test/slim/test_html_structure.rb +438 -0
- data/test/slim/test_parser_errors.rb +107 -0
- data/test/slim/test_pretty.rb +75 -0
- data/test/slim/test_ruby_errors.rb +187 -0
- data/test/slim/test_sections.rb +90 -0
- data/test/slim/test_slim_template.rb +118 -0
- data/test/slim/test_text_interpolation.rb +78 -0
- data/test/slim/test_wrapper.rb +39 -0
- metadata +230 -0
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestParserErrors < TestSlim
|
4
|
+
def test_correct_filename
|
5
|
+
source = %q{
|
6
|
+
doctype 5
|
7
|
+
div Invalid
|
8
|
+
}
|
9
|
+
|
10
|
+
assert_syntax_error "Unexpected indentation\n test.slim, Line 3\n div Invalid\n ^\n", source, :file => 'test.slim'
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_unexpected_indentation
|
14
|
+
source = %q{
|
15
|
+
doctype 5
|
16
|
+
div Invalid
|
17
|
+
}
|
18
|
+
|
19
|
+
assert_syntax_error "Unexpected indentation\n (__TEMPLATE__), Line 3\n div Invalid\n ^\n", source
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_unexpected_text_indentation
|
23
|
+
source = %q{
|
24
|
+
p
|
25
|
+
| text block
|
26
|
+
text
|
27
|
+
}
|
28
|
+
|
29
|
+
assert_syntax_error "Unexpected text indentation\n (__TEMPLATE__), Line 4\n text\n ^\n", source
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_malformed_indentation
|
33
|
+
source = %q{
|
34
|
+
p
|
35
|
+
div Valid
|
36
|
+
div Invalid
|
37
|
+
}
|
38
|
+
|
39
|
+
assert_syntax_error "Malformed indentation\n (__TEMPLATE__), Line 4\n div Invalid\n ^\n", source
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_unknown_line_indicator
|
43
|
+
source = %q{
|
44
|
+
p
|
45
|
+
div Valid
|
46
|
+
.valid
|
47
|
+
#valid
|
48
|
+
?invalid
|
49
|
+
}
|
50
|
+
|
51
|
+
assert_syntax_error "Unknown line indicator\n (__TEMPLATE__), Line 6\n ?invalid\n ^\n", source
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_expected_closing_delimiter
|
55
|
+
source = %q{
|
56
|
+
p
|
57
|
+
img(src="img.jpg" title={title}
|
58
|
+
}
|
59
|
+
|
60
|
+
assert_syntax_error "Expected closing delimiter )\n (__TEMPLATE__), Line 3\n img(src=\"img.jpg\" title={title}\n ^\n", source
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_expected_closing_attribute_delimiter
|
64
|
+
source = %q{
|
65
|
+
p
|
66
|
+
img src=[hash[1] + hash[2]
|
67
|
+
}
|
68
|
+
|
69
|
+
assert_syntax_error "Expected closing attribute delimiter ]\n (__TEMPLATE__), Line 3\n img src=[hash[1] + hash[2]\n ^\n", source
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_expected_attribute
|
73
|
+
source = %q{
|
74
|
+
p
|
75
|
+
img(src='img.png' whatsthis?!)
|
76
|
+
}
|
77
|
+
|
78
|
+
assert_syntax_error "Expected attribute\n (__TEMPLATE__), Line 3\n img(src='img.png' whatsthis?!)\n ^\n", source
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_invalid_empty_attribute
|
82
|
+
source = %q{
|
83
|
+
p
|
84
|
+
img{src= }
|
85
|
+
}
|
86
|
+
|
87
|
+
assert_syntax_error "Invalid empty attribute\n (__TEMPLATE__), Line 3\n img{src= }\n ^\n", source
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_invalid_empty_attribute2
|
91
|
+
source = %q{
|
92
|
+
p
|
93
|
+
img{src=}
|
94
|
+
}
|
95
|
+
|
96
|
+
assert_syntax_error "Invalid empty attribute\n (__TEMPLATE__), Line 3\n img{src=}\n ^\n", source
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_invalid_empty_attribute3
|
100
|
+
source = %q{
|
101
|
+
p
|
102
|
+
img src=
|
103
|
+
}
|
104
|
+
|
105
|
+
assert_syntax_error "Invalid empty attribute\n (__TEMPLATE__), Line 3\n img src=\n ^\n", source
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestSlimPretty < TestSlim
|
4
|
+
def setup
|
5
|
+
Hamlet::Engine.set_default_options :pretty => true
|
6
|
+
end
|
7
|
+
|
8
|
+
def teardown
|
9
|
+
Hamlet::Engine.set_default_options :pretty => false
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_pretty
|
13
|
+
source = %q{
|
14
|
+
doctype 5
|
15
|
+
<html
|
16
|
+
<head
|
17
|
+
<title Hello World!
|
18
|
+
/! Meta tags
|
19
|
+
with long explanatory
|
20
|
+
multiline comment
|
21
|
+
<meta name="description" content="template language"
|
22
|
+
/! Stylesheets
|
23
|
+
<link href="style.css" media="screen" rel="stylesheet" type="text/css"
|
24
|
+
<link href="colors.css" media="screen" rel="stylesheet" type="text/css"
|
25
|
+
/! Javascripts
|
26
|
+
<script src="jquery.js"
|
27
|
+
<script src="jquery.ui.js"
|
28
|
+
/[if lt IE 9]
|
29
|
+
<script src="old-ie1.js"
|
30
|
+
<script src="old-ie2.js"
|
31
|
+
<sass:
|
32
|
+
body
|
33
|
+
background-color: red
|
34
|
+
<body
|
35
|
+
<#container
|
36
|
+
<p>Hello
|
37
|
+
World!
|
38
|
+
<p= "dynamic text with\nnewline"
|
39
|
+
}
|
40
|
+
|
41
|
+
result = %q{<!DOCTYPE html>
|
42
|
+
<html>
|
43
|
+
<head>
|
44
|
+
<title>Hello World!</title>
|
45
|
+
<!--Meta tags
|
46
|
+
with long explanatory
|
47
|
+
multiline comment-->
|
48
|
+
<meta content="template language" name="description" />
|
49
|
+
<!--Stylesheets-->
|
50
|
+
<link href="style.css" media="screen" rel="stylesheet" type="text/css" />
|
51
|
+
<link href="colors.css" media="screen" rel="stylesheet" type="text/css" />
|
52
|
+
<!--Javascripts-->
|
53
|
+
<script src="jquery.js"></script>
|
54
|
+
<script src="jquery.ui.js"></script>
|
55
|
+
<!--[if lt IE 9]><script src="old-ie1.js"></script>
|
56
|
+
<script src="old-ie2.js"></script><![endif]-->
|
57
|
+
<style type="text/css">
|
58
|
+
body {
|
59
|
+
background-color: red;
|
60
|
+
}
|
61
|
+
</style>
|
62
|
+
</head>
|
63
|
+
<body>
|
64
|
+
<div id="container">
|
65
|
+
<p>Hello
|
66
|
+
World!</p>
|
67
|
+
<p>dynamic text with
|
68
|
+
newline</p>
|
69
|
+
</div>
|
70
|
+
</body>
|
71
|
+
</html>}
|
72
|
+
|
73
|
+
assert_html result, source
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestSlimRubyErrors < TestSlim
|
4
|
+
def test_multline_attribute
|
5
|
+
source = %q{
|
6
|
+
<p(data-1=1
|
7
|
+
data2-=1)
|
8
|
+
<p
|
9
|
+
= unknown_ruby_method
|
10
|
+
}
|
11
|
+
|
12
|
+
assert_ruby_error NameError, "test.slim:5", source, :file => 'test.slim'
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_broken_output_line
|
16
|
+
source = %q{
|
17
|
+
<p = hello_world + \
|
18
|
+
hello_world + \
|
19
|
+
unknown_ruby_method
|
20
|
+
}
|
21
|
+
|
22
|
+
# FIXME: Remove this hack!
|
23
|
+
# This is actually a jruby issue. Jruby reports a wrong
|
24
|
+
# line number 1 in this case:
|
25
|
+
#
|
26
|
+
# test = 1+\
|
27
|
+
# unknown_variable
|
28
|
+
if RUBY_PLATFORM == "java"
|
29
|
+
assert_ruby_error NameError, "test.slim:2", source, :file => 'test.slim'
|
30
|
+
else
|
31
|
+
assert_ruby_error NameError, "test.slim:4", source, :file => 'test.slim'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_broken_output_line2
|
36
|
+
source = %q{
|
37
|
+
<p = hello_world + \
|
38
|
+
hello_world
|
39
|
+
<p Hello
|
40
|
+
= unknown_ruby_method
|
41
|
+
}
|
42
|
+
|
43
|
+
assert_ruby_error NameError,"(__TEMPLATE__):5", source
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_output_block
|
47
|
+
source = %q{
|
48
|
+
<p = hello_world "Hello Ruby" do
|
49
|
+
= unknown_ruby_method
|
50
|
+
}
|
51
|
+
|
52
|
+
assert_ruby_error NameError,"(__TEMPLATE__):3", source
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_output_block2
|
56
|
+
source = %q{
|
57
|
+
<p = hello_world "Hello Ruby" do
|
58
|
+
= "Hello from block"
|
59
|
+
<p Hello
|
60
|
+
= unknown_ruby_method
|
61
|
+
}
|
62
|
+
|
63
|
+
assert_ruby_error NameError, "(__TEMPLATE__):5", source
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_text_block
|
67
|
+
source = %q{
|
68
|
+
<p>Text line 1
|
69
|
+
Text line 2
|
70
|
+
= unknown_ruby_method
|
71
|
+
}
|
72
|
+
|
73
|
+
assert_ruby_error NameError,"(__TEMPLATE__):4", source
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_text_block2
|
77
|
+
source = %q{
|
78
|
+
|
|
79
|
+
Text line 1
|
80
|
+
Text line 2
|
81
|
+
= unknown_ruby_method
|
82
|
+
}
|
83
|
+
|
84
|
+
assert_ruby_error NameError,"(__TEMPLATE__):5", source
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_comment
|
88
|
+
source = %q{
|
89
|
+
/ Comment line 1
|
90
|
+
Comment line 2
|
91
|
+
= unknown_ruby_method
|
92
|
+
}
|
93
|
+
|
94
|
+
assert_ruby_error NameError,"(__TEMPLATE__):4", source
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_embedded_ruby1
|
98
|
+
source = %q{
|
99
|
+
<ruby:
|
100
|
+
a = 1
|
101
|
+
b = 2
|
102
|
+
= a + b
|
103
|
+
= unknown_ruby_method
|
104
|
+
}
|
105
|
+
|
106
|
+
assert_ruby_error NameError,"(__TEMPLATE__):6", source
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_embedded_ruby2
|
110
|
+
source = %q{
|
111
|
+
<ruby:
|
112
|
+
a = 1
|
113
|
+
unknown_ruby_method
|
114
|
+
}
|
115
|
+
|
116
|
+
assert_ruby_error NameError,"(__TEMPLATE__):4", source
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_embedded_markdown
|
120
|
+
source = %q{
|
121
|
+
<markdown:
|
122
|
+
#Header
|
123
|
+
Hello from #{"Markdown!"}
|
124
|
+
"Second Line!"
|
125
|
+
= unknown_ruby_method
|
126
|
+
}
|
127
|
+
|
128
|
+
assert_ruby_error NameError,"(__TEMPLATE__):6", source
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_embedded_javascript
|
132
|
+
source = %q{
|
133
|
+
<javascript:
|
134
|
+
alert();
|
135
|
+
alert();
|
136
|
+
= unknown_ruby_method
|
137
|
+
}
|
138
|
+
|
139
|
+
assert_ruby_error NameError,"(__TEMPLATE__):5", source
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_invalid_nested_code
|
143
|
+
source = %q{
|
144
|
+
<p
|
145
|
+
- test = 123
|
146
|
+
= "Hello from within a block! "
|
147
|
+
}
|
148
|
+
assert_ruby_syntax_error "(__TEMPLATE__):5", source
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_invalid_nested_output
|
152
|
+
source = %q{
|
153
|
+
p
|
154
|
+
= "Hello Ruby!"
|
155
|
+
= "Hello from within a block! "
|
156
|
+
}
|
157
|
+
assert_ruby_syntax_error "(__TEMPLATE__):5", source
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_invalid_embedded_engine
|
161
|
+
source = %q{
|
162
|
+
<p
|
163
|
+
embed_unknown:
|
164
|
+
1+1
|
165
|
+
}
|
166
|
+
|
167
|
+
assert_runtime_error 'Embedded engine embed_unknown not found', source
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_explicit_end
|
171
|
+
source = %q{
|
172
|
+
<div
|
173
|
+
- if show_first?
|
174
|
+
p The first paragraph
|
175
|
+
- end
|
176
|
+
}
|
177
|
+
|
178
|
+
assert_runtime_error 'Explicit end statements are forbidden', source
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_id_attribute_merging2
|
182
|
+
source = %{
|
183
|
+
#alpha id="beta" Test it
|
184
|
+
}
|
185
|
+
assert_runtime_error 'Multiple id attributes specified', source
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestSlimLogicLess < TestSlim
|
4
|
+
def setup
|
5
|
+
Slim::Sections.set_default_options(:dictionary_access => :symbol)
|
6
|
+
end
|
7
|
+
|
8
|
+
def teardown
|
9
|
+
Slim::Sections.set_default_options(:dictionary => 'self')
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_sections
|
13
|
+
source = %q{
|
14
|
+
p
|
15
|
+
- person
|
16
|
+
.name = name
|
17
|
+
}
|
18
|
+
|
19
|
+
hash = {
|
20
|
+
:person => [
|
21
|
+
{ :name => 'Joe', },
|
22
|
+
{ :name => 'Jack', }
|
23
|
+
]
|
24
|
+
}
|
25
|
+
|
26
|
+
assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => hash, :sections => true
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_sections_string_access
|
30
|
+
source = %q{
|
31
|
+
p
|
32
|
+
- person
|
33
|
+
.name = name
|
34
|
+
}
|
35
|
+
|
36
|
+
hash = {
|
37
|
+
'person' => [
|
38
|
+
{ 'name' => 'Joe', },
|
39
|
+
{ 'name' => 'Jack', }
|
40
|
+
]
|
41
|
+
}
|
42
|
+
|
43
|
+
assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => hash, :sections => true, :dictionary_access => :string
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_flag_section
|
47
|
+
source = %q{
|
48
|
+
p
|
49
|
+
- show_person
|
50
|
+
- person
|
51
|
+
.name = name
|
52
|
+
- show_person
|
53
|
+
| shown
|
54
|
+
}
|
55
|
+
|
56
|
+
hash = {
|
57
|
+
:show_person => true,
|
58
|
+
:person => [
|
59
|
+
{ :name => 'Joe', },
|
60
|
+
{ :name => 'Jack', }
|
61
|
+
]
|
62
|
+
}
|
63
|
+
|
64
|
+
assert_html '<p><div class="name">Joe</div><div class="name">Jack</div>shown</p>', source, :scope => hash, :sections => true
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_inverted_section
|
68
|
+
source = %q{
|
69
|
+
p
|
70
|
+
- person
|
71
|
+
.name = name
|
72
|
+
-! person
|
73
|
+
| No person
|
74
|
+
- !person
|
75
|
+
| No person 2
|
76
|
+
}
|
77
|
+
|
78
|
+
hash = {}
|
79
|
+
|
80
|
+
assert_html '<p>No person No person 2</p>', source, :scope => hash, :sections => true
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_output_with_content
|
84
|
+
source = %{
|
85
|
+
p = method_with_block do
|
86
|
+
block
|
87
|
+
}
|
88
|
+
assert_runtime_error 'Output statements with content are forbidden in sections mode', source, :sections => true
|
89
|
+
end
|
90
|
+
end
|