slim 0.9.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/slim/sections.rb CHANGED
@@ -29,7 +29,7 @@ module Slim
29
29
 
30
30
  # Interpret control blocks as sections or inverted sections
31
31
  def on_slim_control(name, content)
32
- if name =~ /^!\s*(.*)/
32
+ if name =~ /\A!\s*(.*)/
33
33
  on_slim_inverted_section($1, content)
34
34
  else
35
35
  on_slim_section(name, content)
data/lib/slim/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Slim
2
2
  # Slim version string
3
3
  # @api public
4
- VERSION = '0.9.4'
4
+ VERSION = '1.0.0'
5
5
  end
data/test/helper.rb CHANGED
@@ -125,6 +125,10 @@ class Env
125
125
  "<script>do_something_evil();</script>"
126
126
  end
127
127
 
128
+ def method_which_returns_true
129
+ true
130
+ end
131
+
128
132
  def output_number
129
133
  1337
130
134
  end
@@ -214,28 +214,53 @@ p id="#{(false ? 'notshown' : 'shown')}" = output_number
214
214
  assert_html '<div id="alpha-beta">Test it</div>', source, :attr_delimiter => {'class' => ' ', 'id' => '-' }
215
215
  end
216
216
 
217
+ def test_boolean_attribute_false
218
+ source = %{
219
+ option selected=false Text
220
+ }
221
+
222
+ assert_html '<option>Text</option>', source
223
+ end
224
+
217
225
  def test_boolean_attribute_true
218
226
  source = %{
219
- option selected=1 Text
227
+ option selected=true Text
220
228
  }
221
229
 
222
230
  assert_html '<option selected="selected">Text</option>', source
223
231
  end
224
232
 
225
- def test_boolean_attribute_false
233
+ def test_boolean_attribute_dynamic
226
234
  source = %{
227
- option selected=false Text
235
+ option selected=method_which_returns_true Text
236
+ }
237
+
238
+ assert_html '<option selected="selected">Text</option>', source
239
+ end
240
+
241
+ def test_boolean_attribute_nil
242
+ source = %{
243
+ option selected=nil Text
228
244
  }
229
245
 
230
246
  assert_html '<option>Text</option>', source
231
247
  end
232
248
 
233
- def test_non_boolean_attribute
249
+ def test_boolean_attribute_string2
250
+ source = %{
251
+ option selected="selected" Text
252
+ }
253
+
254
+ assert_html '<option selected="selected">Text</option>', source
255
+ end
256
+
257
+ def test_boolean_attribute_shortcut
234
258
  source = %{
235
- .alpha class="beta" class=false
259
+ option(class="clazz" selected) Text
260
+ option(selected class="clazz") Text
236
261
  }
237
262
 
238
- assert_html '<div class="alpha beta false"></div>', source
263
+ assert_html '<option class="clazz" selected="selected">Text</option><option class="clazz" selected="selected">Text</option>', source
239
264
  end
240
265
 
241
266
  def test_array_attribute
@@ -7,7 +7,25 @@ p
7
7
  = hello_world
8
8
  }
9
9
 
10
- assert_html '<p>Hello World from @env</p>', source #, :debug => true
10
+ assert_html '<p>Hello World from @env</p>', source
11
+ end
12
+
13
+ def test_render_with_trailing_whitespace
14
+ source = %q{
15
+ p
16
+ =' hello_world
17
+ }
18
+
19
+ assert_html '<p>Hello World from @env </p>', source
20
+ end
21
+
22
+ def test_no_escape_render_with_trailing_whitespace
23
+ source = %q{
24
+ p
25
+ ==' hello_world
26
+ }
27
+
28
+ assert_html '<p>Hello World from @env </p>', source
11
29
  end
12
30
 
13
31
  def test_render_with_conditional_call
@@ -100,9 +118,10 @@ p(id="test")==hello_world
100
118
  end
101
119
 
102
120
  def test_render_with_backslash_end
121
+ # Keep trailing spaces!
103
122
  source = %q{
104
- p = \
105
- "Hello" + \
123
+ p = \
124
+ "Hello" + \
106
125
  " Ruby!"
107
126
  - variable = 1 + \
108
127
  2 + \
@@ -35,13 +35,18 @@ p
35
35
  end
36
36
 
37
37
  def test_render_with_markdown
38
+ # Keep the trailing spaces.
38
39
  source = %q{
39
40
  markdown:
40
41
  #Header
41
42
  Hello from #{"Markdown!"}
42
- "Second Line!"
43
+
44
+ #{1+2}
45
+
46
+ * one
47
+ * two
43
48
  }
44
- assert_html "<h1>Header</h1>\n\n<p>Hello from Markdown!\n\"Second Line!\"</p>\n", source
49
+ assert_html "<h1>Header</h1>\n\n<p>Hello from Markdown!</p>\n\n<p>3</p>\n\n<ul>\n<li>one</li>\n<li>two</li>\n</ul>\n\n", source
45
50
  end
46
51
 
47
52
  def test_render_with_creole
@@ -25,7 +25,7 @@ html:body
25
25
 
26
26
  def test_doctype
27
27
  source = %q{
28
- ! doctype 1.1
28
+ doctype 1.1
29
29
  html
30
30
  }
31
31
 
@@ -50,15 +50,6 @@ html
50
50
  assert_html '<!DOCTYPE html><html></html>', source, :format => :xhtml
51
51
  end
52
52
 
53
- def test_capitalized_doctype
54
- source = %q{
55
- ! DOCTYPE 5
56
- html
57
- }
58
-
59
- assert_html '<!DOCTYPE html><html></html>', source
60
- end
61
-
62
53
  def test_render_with_shortcut_attributes
63
54
  source = %q{
64
55
  h1#title This is my title
@@ -356,4 +347,82 @@ p World
356
347
 
357
348
  assert_html "<!--[if IE]>hello<![endif]-->", source
358
349
  end
350
+
351
+ def test_multiline_attributes_with_method
352
+ source = %q{
353
+ p<id="marvin"
354
+ class="martian"
355
+ data-info="Illudium Q-36"> = output_number
356
+ }
357
+ Slim::Parser::DELIMITERS.each do |k,v|
358
+ str = source.sub('<',k).sub('>',v)
359
+ assert_html '<p class="martian" data-info="Illudium Q-36" id="marvin">1337</p>', str
360
+ end
361
+ end
362
+
363
+ def test_multiline_attributes_with_text_on_same_line
364
+ source = %q{
365
+ p<id="marvin"
366
+ class="martian"
367
+ data-info="Illudium Q-36"> THE space modulator
368
+ }
369
+ Slim::Parser::DELIMITERS.each do |k,v|
370
+ str = source.sub('<',k).sub('>',v)
371
+ assert_html '<p class="martian" data-info="Illudium Q-36" id="marvin">THE space modulator</p>', str
372
+ end
373
+ end
374
+
375
+ def test_multiline_attributes_with_nested_text
376
+ source = %q{
377
+ p<id="marvin"
378
+ class="martian"
379
+ data-info="Illudium Q-36">
380
+ | THE space modulator
381
+ }
382
+ Slim::Parser::DELIMITERS.each do |k,v|
383
+ str = source.sub('<',k).sub('>',v)
384
+ assert_html '<p class="martian" data-info="Illudium Q-36" id="marvin">THE space modulator</p>', str
385
+ end
386
+ end
387
+
388
+ def test_multiline_attributes_with_dynamic_attr
389
+ source = %q{
390
+ p<id=id_helper
391
+ class="martian"
392
+ data-info="Illudium Q-36">
393
+ | THE space modulator
394
+ }
395
+ Slim::Parser::DELIMITERS.each do |k,v|
396
+ str = source.sub('<',k).sub('>',v)
397
+ assert_html '<p class="martian" data-info="Illudium Q-36" id="notice">THE space modulator</p>', str
398
+ end
399
+ end
400
+
401
+ def test_multiline_attributes_with_nested_tag
402
+ source = %q{
403
+ p<id=id_helper
404
+ class="martian"
405
+ data-info="Illudium Q-36">
406
+ span.emphasis THE
407
+ | space modulator
408
+ }
409
+ Slim::Parser::DELIMITERS.each do |k,v|
410
+ str = source.sub('<',k).sub('>',v)
411
+ assert_html '<p class="martian" data-info="Illudium Q-36" id="notice"><span class="emphasis">THE</span> space modulator</p>', str
412
+ end
413
+ end
414
+
415
+ def test_multiline_attributes_with_nested_text_and_extra_indentation
416
+ source = %q{
417
+ li< id="myid"
418
+ class="myclass"
419
+ data-info="myinfo">
420
+ a href="link" My Link
421
+ }
422
+ Slim::Parser::DELIMITERS.each do |k,v|
423
+ str = source.sub('<',k).sub('>',v)
424
+ assert_html '<li class="myclass" data-info="myinfo" id="myid"><a href="link">My Link</a></li>', str
425
+ end
426
+ end
427
+
359
428
  end
@@ -3,20 +3,20 @@ require 'helper'
3
3
  class TestParserErrors < TestSlim
4
4
  def test_correct_filename
5
5
  source = %q{
6
- ! doctype 5
6
+ doctype 5
7
7
  div Invalid
8
8
  }
9
9
 
10
- assert_syntax_error "Unexpected indentation\n test.slim, Line 3\n div Invalid\n ^\n ", source, :file => 'test.slim'
10
+ assert_syntax_error "Unexpected indentation\n test.slim, Line 3\n div Invalid\n ^\n", source, :file => 'test.slim'
11
11
  end
12
12
 
13
13
  def test_unexpected_indentation
14
14
  source = %q{
15
- ! doctype 5
15
+ doctype 5
16
16
  div Invalid
17
17
  }
18
18
 
19
- assert_syntax_error "Unexpected indentation\n (__TEMPLATE__), Line 3\n div Invalid\n ^\n ", source
19
+ assert_syntax_error "Unexpected indentation\n (__TEMPLATE__), Line 3\n div Invalid\n ^\n", source
20
20
  end
21
21
 
22
22
  def test_unexpected_text_indentation
@@ -26,7 +26,7 @@ p
26
26
  text
27
27
  }
28
28
 
29
- assert_syntax_error "Unexpected text indentation\n (__TEMPLATE__), Line 4\n text\n ^\n ", source
29
+ assert_syntax_error "Unexpected text indentation\n (__TEMPLATE__), Line 4\n text\n ^\n", source
30
30
  end
31
31
 
32
32
  def test_malformed_indentation
@@ -36,7 +36,7 @@ p
36
36
  div Invalid
37
37
  }
38
38
 
39
- assert_syntax_error "Malformed indentation\n (__TEMPLATE__), Line 4\n div Invalid\n ^\n ", source
39
+ assert_syntax_error "Malformed indentation\n (__TEMPLATE__), Line 4\n div Invalid\n ^\n", source
40
40
  end
41
41
 
42
42
  def test_unknown_line_indicator
@@ -48,7 +48,7 @@ p
48
48
  ?invalid
49
49
  }
50
50
 
51
- assert_syntax_error "Unknown line indicator\n (__TEMPLATE__), Line 6\n ?invalid\n ^\n ", source
51
+ assert_syntax_error "Unknown line indicator\n (__TEMPLATE__), Line 6\n ?invalid\n ^\n", source
52
52
  end
53
53
 
54
54
  def test_expected_closing_delimiter
@@ -57,7 +57,7 @@ p
57
57
  img(src="img.jpg" title={title}
58
58
  }
59
59
 
60
- assert_syntax_error "Expected closing delimiter )\n (__TEMPLATE__), Line 3\n img(src=\"img.jpg\" title={title}\n ^\n ", source
60
+ assert_syntax_error "Expected closing delimiter )\n (__TEMPLATE__), Line 3\n img(src=\"img.jpg\" title={title}\n ^\n", source
61
61
  end
62
62
 
63
63
  def test_expected_closing_attribute_delimiter
@@ -66,7 +66,16 @@ p
66
66
  img src=[hash[1] + hash[2]
67
67
  }
68
68
 
69
- assert_syntax_error "Expected closing attribute delimiter ]\n (__TEMPLATE__), Line 3\n img src=[hash[1] + hash[2]\n ^\n ", source
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
70
79
  end
71
80
 
72
81
  def test_unexpected_closing
@@ -75,7 +84,7 @@ p
75
84
  img src=(1+1)]
76
85
  }
77
86
 
78
- assert_syntax_error "Unexpected closing ]\n (__TEMPLATE__), Line 3\n img src=(1+1)]\n ^\n ", source
87
+ assert_syntax_error "Unexpected closing ]\n (__TEMPLATE__), Line 3\n img src=(1+1)]\n ^\n", source
79
88
  end
80
89
 
81
90
  def test_invalid_empty_attribute
@@ -84,7 +93,7 @@ p
84
93
  img{src= }
85
94
  }
86
95
 
87
- assert_syntax_error "Invalid empty attribute\n (__TEMPLATE__), Line 3\n img{src= }\n ^\n ", source
96
+ assert_syntax_error "Invalid empty attribute\n (__TEMPLATE__), Line 3\n img{src= }\n ^\n", source
88
97
  end
89
98
 
90
99
  def test_invalid_empty_attribute2
@@ -93,7 +102,7 @@ p
93
102
  img{src=}
94
103
  }
95
104
 
96
- assert_syntax_error "Invalid empty attribute\n (__TEMPLATE__), Line 3\n img{src=}\n ^\n ", source
105
+ assert_syntax_error "Invalid empty attribute\n (__TEMPLATE__), Line 3\n img{src=}\n ^\n", source
97
106
  end
98
107
 
99
108
  def test_invalid_empty_attribute3
@@ -102,6 +111,6 @@ p
102
111
  img src=
103
112
  }
104
113
 
105
- assert_syntax_error "Invalid empty attribute\n (__TEMPLATE__), Line 3\n img src=\n ^\n ", source
114
+ assert_syntax_error "Invalid empty attribute\n (__TEMPLATE__), Line 3\n img src=\n ^\n", source
106
115
  end
107
116
  end
@@ -1,6 +1,17 @@
1
1
  require 'helper'
2
2
 
3
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
+
4
15
  def test_broken_output_line
5
16
  source = %q{
6
17
  p = hello_world + \
@@ -0,0 +1,191 @@
1
+ require 'helper'
2
+
3
+ class TestSlimRubyErrors < TestSlim
4
+ def test_broken_output_line
5
+ source = %q{
6
+ p = hello_world + \
7
+ hello_world + \
8
+ unknown_ruby_method
9
+ }
10
+
11
+ assert_ruby_error NameError, "test.slim:4", source, :file => 'test.slim'
12
+ end
13
+
14
+ def test_broken_output_line2
15
+ source = %q{
16
+ p = hello_world + \
17
+ hello_world
18
+ p Hello
19
+ = unknown_ruby_method
20
+ }
21
+
22
+ assert_ruby_error NameError,"(__TEMPLATE__):5", source
23
+ end
24
+
25
+ def test_output_block
26
+ source = %q{
27
+ p = hello_world "Hello Ruby" do
28
+ = unknown_ruby_method
29
+ }
30
+
31
+ assert_ruby_error NameError,"(__TEMPLATE__):3", source
32
+ end
33
+
34
+ def test_output_block2
35
+ source = %q{
36
+ p = hello_world "Hello Ruby" do
37
+ = "Hello from block"
38
+ p Hello
39
+ = unknown_ruby_method
40
+ }
41
+
42
+ assert_ruby_error NameError, "(__TEMPLATE__):5", source
43
+ end
44
+
45
+ def test_text_block
46
+ source = %q{
47
+ p Text line 1 Text line 2
48
+ = unknown_ruby_method
49
+ }
50
+
51
+ assert_ruby_error NameError,"(__TEMPLATE__):4", source
52
+ end
53
+
54
+ def test_text_block2
55
+ source = %q{
56
+ |
57
+ Text line 1
58
+ Text line 2
59
+ = unknown_ruby_method
60
+ }
61
+
62
+ assert_ruby_error NameError,"(__TEMPLATE__):5", source
63
+ end
64
+
65
+ def test_comment
66
+ source = %q{
67
+ / Comment line 1
68
+ Comment line 2
69
+ = unknown_ruby_method
70
+ }
71
+
72
+ assert_ruby_error NameError,"(__TEMPLATE__):4", source
73
+ end
74
+
75
+ def test_embedded_ruby
76
+ source = %q{
77
+ ruby:
78
+ a = 1
79
+ b = 2
80
+ = a + b
81
+ = unknown_ruby_method
82
+ }
83
+
84
+ assert_ruby_error NameError,"(__TEMPLATE__):6", source
85
+ end
86
+
87
+ def test_embedded_markdown
88
+ source = %q{
89
+ markdown:
90
+ #Header
91
+ Hello from #{"Markdown!"}
92
+ "Second Line!"
93
+ = unknown_ruby_method
94
+ }
95
+
96
+ assert_ruby_error NameError,"(__TEMPLATE__):6", source
97
+ end
98
+
99
+ def test_embedded_liquid
100
+ source = %q{
101
+ - text = 'before liquid block'
102
+ liquid:
103
+ First
104
+ {{text}}
105
+ Third
106
+ = unknown_ruby_method
107
+ }
108
+
109
+ assert_ruby_error NameError,"(__TEMPLATE__):7", source
110
+ end
111
+
112
+ def test_embedded_javascript
113
+ source = %q{
114
+ javascript:
115
+ alert();
116
+ alert();
117
+ = unknown_ruby_method
118
+ }
119
+
120
+ assert_ruby_error NameError,"(__TEMPLATE__):5", source
121
+ end
122
+
123
+ def test_invalid_nested_code
124
+ source = %q{
125
+ p
126
+ - test = 123
127
+ = "Hello from within a block! "
128
+ }
129
+ assert_ruby_syntax_error "(__TEMPLATE__):5", source
130
+ end
131
+
132
+ def test_invalid_nested_output
133
+ source = %q{
134
+ p
135
+ = "Hello Ruby!"
136
+ = "Hello from within a block! "
137
+ }
138
+ assert_ruby_syntax_error "(__TEMPLATE__):5", source
139
+ end
140
+
141
+ def test_invalid_embedded_engine
142
+ source = %q{
143
+ p
144
+ embed_unknown:
145
+ 1+1
146
+ }
147
+
148
+ assert_runtime_error 'Embedded engine embed_unknown not found', source
149
+ end
150
+
151
+ def test_explicit_end
152
+ source = %q{
153
+ div
154
+ - if show_first?
155
+ p The first paragraph
156
+ - end
157
+ }
158
+
159
+ assert_runtime_error 'Explicit end statements are forbidden', source
160
+ end
161
+
162
+ def test_id_attribute_merging2
163
+ source = %{
164
+ #alpha id="beta" Test it
165
+ }
166
+ assert_runtime_error 'Multiple id attributes specified', source
167
+ end
168
+
169
+ def test_multiline_attributes
170
+ source = %q{
171
+ p(id="id"
172
+ foo=1+1
173
+ class=unknown_ruby_method)
174
+ p
175
+ }
176
+
177
+ assert_ruby_error NameError,"(__TEMPLATE__):3", source
178
+ end
179
+
180
+
181
+ def test_multiline_ruby_attribute
182
+ source = %q{
183
+ p id=(1+
184
+ +2
185
+ +unknown_ruby_method)
186
+ p
187
+ }
188
+
189
+ assert_ruby_error NameError,"(__TEMPLATE__):4", source
190
+ end
191
+ end