slim 1.3.2 → 1.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +3 -2
- data/CHANGES +12 -0
- data/README.md +56 -10
- data/Rakefile +7 -1
- data/lib/slim.rb +1 -1
- data/lib/slim/code_attributes.rb +67 -0
- data/lib/slim/engine.rb +2 -1
- data/lib/slim/parser.rb +27 -9
- data/lib/slim/splat_attributes.rb +21 -20
- data/lib/slim/version.rb +1 -1
- data/slim.gemspec +1 -3
- data/test/core/test_encoding.rb +6 -0
- data/test/core/test_html_attributes.rb +21 -5
- data/test/core/test_html_structure.rb +0 -16
- data/test/core/test_pretty.rb +2 -2
- data/test/literate/TESTS.md +830 -0
- data/test/literate/helper.rb +15 -0
- data/test/literate/run.rb +96 -0
- metadata +66 -27
- data/lib/slim/boolean_attributes.rb +0 -67
data/.yardopts
CHANGED
@@ -1,2 +1,3 @@
|
|
1
|
-
--
|
2
|
-
--
|
1
|
+
--markup-provider redcarpet
|
2
|
+
--markup markdown
|
3
|
+
- README.md CHANGES LICENSE test/literate/TESTS.md
|
data/CHANGES
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
1.3.3
|
2
|
+
|
3
|
+
* Attribute handling made consistent:
|
4
|
+
- Splat attributes, static and dynamic attributes are now all handled the same
|
5
|
+
- Merged attributes are removed if empty (in the default configuration this is only "class")
|
6
|
+
- Dynamic attributes which are not merged are checked for false or nil and removed if this is the case
|
7
|
+
- Dynamic attributes which are not merged are checked for true and generated as attribute-name="attribute-name"
|
8
|
+
* Rename class BooleanAttributes to CodeAttributes
|
9
|
+
* Add literate test suite (still incomplete), run with `rake test:literate`
|
10
|
+
* Remove UTF BOM when parsing Slim code
|
11
|
+
* Fixed issue #303
|
12
|
+
|
1
13
|
1.3.2
|
2
14
|
|
3
15
|
* Fix boolean attributes #299
|
data/README.md
CHANGED
@@ -119,9 +119,9 @@ You can also embed html in the text line
|
|
119
119
|
- articles.each do |a|
|
120
120
|
| <tr><td>#{a.name}</td><td>#{a.description}</td></tr>
|
121
121
|
|
122
|
-
### Text with trailing space `'`
|
122
|
+
### Text with trailing white space `'`
|
123
123
|
|
124
|
-
The single quote tells Slim to copy the line (similar to `|`), but makes sure that a single trailing space is appended.
|
124
|
+
The single quote tells Slim to copy the line (similar to `|`), but makes sure that a single trailing white space is appended.
|
125
125
|
|
126
126
|
### Inline html `<` (HTML style)
|
127
127
|
|
@@ -148,7 +148,7 @@ If your ruby code needs to use multiple lines, append a backslash `\` at the end
|
|
148
148
|
- if articles.empty?
|
149
149
|
| No inventory
|
150
150
|
|
151
|
-
###
|
151
|
+
### Output `=`
|
152
152
|
|
153
153
|
The equal sign tells Slim it's a Ruby call that produces output to add to the buffer. If your ruby code needs to use multiple lines, append a backslash `\` at the end of the lines, for example:
|
154
154
|
|
@@ -158,7 +158,7 @@ The equal sign tells Slim it's a Ruby call that produces output to add to the bu
|
|
158
158
|
|
159
159
|
### Output with trailing white space `='`
|
160
160
|
|
161
|
-
Same as the single equal sign (`=`), except that it adds a trailing
|
161
|
+
Same as the single equal sign (`=`), except that it adds a trailing white space.
|
162
162
|
|
163
163
|
### Output without HTML escaping `==`
|
164
164
|
|
@@ -166,7 +166,7 @@ Same as the single equal sign (`=`), but does not go through the `escape_html` m
|
|
166
166
|
|
167
167
|
### Output without HTML escaping and trailing ws `=='`
|
168
168
|
|
169
|
-
Same as the double equal sign (`==`), except that it adds a trailing
|
169
|
+
Same as the double equal sign (`==`), except that it adds a trailing white space.
|
170
170
|
|
171
171
|
### Code comment `/`
|
172
172
|
|
@@ -321,7 +321,6 @@ you can use the characters `{...}`, `(...)`, `[...]` to wrap the attributes.
|
|
321
321
|
h1(id="logo") = page_logo
|
322
322
|
h2[id="tagline" class="small tagline"] = page_tagline
|
323
323
|
|
324
|
-
|
325
324
|
If you wrap the attributes, you can spread them across multiple lines:
|
326
325
|
|
327
326
|
h2[id="tagline"
|
@@ -337,7 +336,7 @@ You can use text interpolation in the quoted attributes:
|
|
337
336
|
|
338
337
|
a href="http://#{url}" Goto the #{url}
|
339
338
|
|
340
|
-
The attribute value will be escaped
|
339
|
+
The attribute value will be escaped if the option `:escape_quoted_attrs` is set. Use == if you want to disable escaping in the attribute.
|
341
340
|
|
342
341
|
a href=="&"
|
343
342
|
|
@@ -370,17 +369,44 @@ as booleans. If you use the attribut wrapper you can omit the attribute assigmen
|
|
370
369
|
input type="text" disabled=false
|
371
370
|
input type="text" disabled=nil
|
372
371
|
|
372
|
+
#### Attribute merging
|
373
|
+
|
374
|
+
You can configure attributes to be merged if multiple are given (See option `:attr_delimiter`). In the default configuration
|
375
|
+
this is done for class attributes with the white space as delimiter.
|
376
|
+
|
377
|
+
a.menu class="highlight" href="http://slim-lang.com/" Slim-lang.com
|
378
|
+
|
379
|
+
This renders as
|
380
|
+
|
381
|
+
<a class="menu highlight" href="http://slim-lang.com/">Slim-lang.com</a>
|
382
|
+
|
383
|
+
You can also use an `Array` as attribute value and the array elements will be merged using the delimiter.
|
384
|
+
|
385
|
+
a class=["menu","highlight"]
|
386
|
+
a class=:menu,:highlight
|
387
|
+
|
373
388
|
#### Splat attributes `*`
|
374
389
|
|
375
390
|
The splat shortcut allows you turn a hash in to attribute/value pairs
|
376
391
|
|
377
392
|
.card*{'data-url'=>place_path(place), 'data-id'=>place.id} = place.name
|
393
|
+
|
394
|
+
renders as
|
395
|
+
|
396
|
+
<div class="card" data-id="1234" data-url="/place/1234">Slim's house</div>
|
397
|
+
|
398
|
+
You can also use methods or instance variables which return a hash as shown here:
|
399
|
+
|
378
400
|
.card *method_which_returns_hash = place.name
|
379
401
|
.card *@hash_instance_variable = place.name
|
380
402
|
|
403
|
+
The hash attributes which support attribute merging (see Slim option `:attr_delimiter`) can be given as an `Array`
|
404
|
+
|
405
|
+
.first *{:class => [:second, :third]} Text
|
406
|
+
|
381
407
|
renders as
|
382
408
|
|
383
|
-
|
409
|
+
div class="first second third"
|
384
410
|
|
385
411
|
#### ID shortcut `#` and class shortcut `.`
|
386
412
|
|
@@ -408,7 +434,23 @@ This is the same as
|
|
408
434
|
|
409
435
|
You can define custom shortcuts (Similar to `#` for id and `.` for class).
|
410
436
|
|
411
|
-
In this example we add
|
437
|
+
In this example we add `&` to create a shortcut for the input elements with type attribute.
|
438
|
+
|
439
|
+
Slim::Engine.set_default_options :shortcut => {'&' => 'input type', '#' => 'id', '.' => 'class'}
|
440
|
+
|
441
|
+
We can use it in Slim code like this
|
442
|
+
|
443
|
+
&text name="user"
|
444
|
+
&password name="pw"
|
445
|
+
&submit
|
446
|
+
|
447
|
+
which renders to
|
448
|
+
|
449
|
+
<input type="text" name="user" />
|
450
|
+
<input type="password" name="pw" />
|
451
|
+
<input type="submit" />
|
452
|
+
|
453
|
+
In another example we add `@` to create a shortcut for the role attribute.
|
412
454
|
|
413
455
|
Slim::Engine.set_default_options :shortcut => {'@' => 'role', '#' => 'id', '.' => 'class'}
|
414
456
|
|
@@ -528,7 +570,7 @@ There are a lot of them but the good thing is, that Slim checks the configuratio
|
|
528
570
|
<thead style="font-weight:bold"><tr><td>Type</td><td>Name</td><td>Default</td><td>Purpose</td></tr></thead>
|
529
571
|
<tbody>
|
530
572
|
<tr><td>String</td><td>:file</td><td>nil</td><td>Name of parsed file, set automatically by Slim::Template</td></tr>
|
531
|
-
<tr><td>Integer</td><td>:tabsize</td><td>4</td><td>Number of
|
573
|
+
<tr><td>Integer</td><td>:tabsize</td><td>4</td><td>Number of white spaces per tab (used by the parser)</td></tr>
|
532
574
|
<tr><td>String</td><td>:encoding</td><td>"utf-8"</td><td>Set encoding of template</td></tr>
|
533
575
|
<tr><td>String</td><td>:default_tag</td><td>"div"</td><td>Default tag to be used if tag name is omitted</td></tr>
|
534
576
|
<tr><td>Hash</td><td>:shortcut</td><td>\{'.' => 'class', '#' => 'id'}</td><td>Attribute shortcuts</td></tr>
|
@@ -792,6 +834,7 @@ There are plugins for various text editors (including the most important ones -
|
|
792
834
|
* [Emacs](https://github.com/minad/emacs-slim)
|
793
835
|
* [Textmate / Sublime Text](https://github.com/fredwu/ruby-slim-tmbundle)
|
794
836
|
* [Espresso text editor](https://github.com/CiiDub/Slim-Sugar)
|
837
|
+
* [Coda](https://github.com/nwalton3/Coda-2-Slim.mode)
|
795
838
|
|
796
839
|
### Template Converters (HAML, ERB, ...)
|
797
840
|
|
@@ -875,6 +918,8 @@ overhead added by the Temple framework compared to ERB.
|
|
875
918
|
Slim provides an extensive test-suite based on minitest. You can run the tests
|
876
919
|
with 'rake test' and the rails integration tests with 'rake test:rails'.
|
877
920
|
|
921
|
+
We are currently experimenting with human-readable literate tests which are written as markdown files: {file:test/literate/TESTS.md TESTS.md}
|
922
|
+
|
878
923
|
Travis-CI is used for continous integration testing: {http://travis-ci.org/#!/stonean/slim}
|
879
924
|
|
880
925
|
Slim is working well on all major Ruby implementations:
|
@@ -934,6 +979,7 @@ Syntax highlighting:
|
|
934
979
|
* [Emacs](https://github.com/minad/emacs-slim)
|
935
980
|
* [Textmate / Sublime Text](https://github.com/fredwu/ruby-slim-tmbundle)
|
936
981
|
* [Espresso text editor](https://github.com/CiiDub/Slim-Sugar)
|
982
|
+
* [Coda](https://github.com/nwalton3/Coda-2-Slim.mode)
|
937
983
|
|
938
984
|
Template Converters (HAML, ERB, ...):
|
939
985
|
|
data/Rakefile
CHANGED
@@ -14,7 +14,7 @@ end
|
|
14
14
|
task 'test' => %w(test:core_and_plugins)
|
15
15
|
|
16
16
|
namespace 'test' do
|
17
|
-
task 'core_and_plugins' => %w(core logic_less translator)
|
17
|
+
task 'core_and_plugins' => %w(core literate logic_less translator)
|
18
18
|
|
19
19
|
Rake::TestTask.new('core') do |t|
|
20
20
|
t.libs << 'lib' << 'test/core'
|
@@ -22,6 +22,12 @@ namespace 'test' do
|
|
22
22
|
t.verbose = true
|
23
23
|
end
|
24
24
|
|
25
|
+
Rake::TestTask.new('literate') do |t|
|
26
|
+
t.libs << 'lib' << 'test/literate'
|
27
|
+
t.test_files = FileList['test/literate/run.rb']
|
28
|
+
t.verbose = true
|
29
|
+
end
|
30
|
+
|
25
31
|
Rake::TestTask.new('logic_less') do |t|
|
26
32
|
t.libs << 'lib' << 'test/core'
|
27
33
|
t.test_files = FileList['test/logic_less/test_*.rb']
|
data/lib/slim.rb
CHANGED
@@ -6,7 +6,7 @@ require 'slim/embedded_engine'
|
|
6
6
|
require 'slim/interpolation'
|
7
7
|
require 'slim/control_structures'
|
8
8
|
require 'slim/splat_attributes'
|
9
|
-
require 'slim/
|
9
|
+
require 'slim/code_attributes'
|
10
10
|
require 'slim/engine'
|
11
11
|
require 'slim/template'
|
12
12
|
require 'slim/version'
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Slim
|
2
|
+
# @api private
|
3
|
+
class CodeAttributes < Filter
|
4
|
+
define_options :attr_delimiter
|
5
|
+
|
6
|
+
# Handle attributes expression `[:html, :attrs, *attrs]`
|
7
|
+
#
|
8
|
+
# @param [Array] attrs Array of temple expressions
|
9
|
+
# @return [Array] Compiled temple expression
|
10
|
+
def on_html_attrs(*attrs)
|
11
|
+
[:multi, *attrs.map {|a| compile(a) }]
|
12
|
+
end
|
13
|
+
|
14
|
+
# Handle attribute expression `[:slim, :attr, escape, code]`
|
15
|
+
#
|
16
|
+
# @param [String] name Attribute name
|
17
|
+
# @param [Array] value Value expression
|
18
|
+
# @return [Array] Compiled temple expression
|
19
|
+
def on_html_attr(name, value)
|
20
|
+
unless value[0] == :slim && value[1] == :attrvalue && !options[:attr_delimiter][name]
|
21
|
+
# We perform merging on the attribute
|
22
|
+
@attr = name
|
23
|
+
return super
|
24
|
+
end
|
25
|
+
|
26
|
+
# We handle the attribute as a boolean attribute
|
27
|
+
escape, code = value[2], value[3]
|
28
|
+
case code
|
29
|
+
when 'true'
|
30
|
+
[:html, :attr, name, [:static, name]]
|
31
|
+
when 'false', 'nil'
|
32
|
+
[:multi]
|
33
|
+
else
|
34
|
+
tmp = unique_name
|
35
|
+
[:multi,
|
36
|
+
[:code, "#{tmp} = #{code}"],
|
37
|
+
[:case, tmp,
|
38
|
+
['true', [:html, :attr, name, [:static, name]]],
|
39
|
+
['false, nil', [:multi]],
|
40
|
+
[:else, [:html, :attr, name, [:escape, escape, [:dynamic, tmp]]]]]]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Handle attribute expression `[:slim, :attrvalue, escape, code]`
|
45
|
+
#
|
46
|
+
# @param [Boolean] escape Escape html
|
47
|
+
# @param [String] code Ruby code
|
48
|
+
# @return [Array] Compiled temple expression
|
49
|
+
def on_slim_attrvalue(escape, code)
|
50
|
+
# We perform attribute merging on Array values
|
51
|
+
if delimiter = options[:attr_delimiter][@attr]
|
52
|
+
tmp = unique_name
|
53
|
+
[:multi,
|
54
|
+
[:code, "#{tmp} = #{code}"],
|
55
|
+
[:if, "Array === #{tmp}",
|
56
|
+
[:multi,
|
57
|
+
[:code, "#{tmp}.flatten!"],
|
58
|
+
[:code, "#{tmp}.map!(&:to_s)"],
|
59
|
+
[:code, "#{tmp}.reject!(&:empty?)"],
|
60
|
+
[:escape, escape, [:dynamic, "#{tmp}.join(#{delimiter.inspect})"]]],
|
61
|
+
[:escape, escape, [:dynamic, tmp]]]]
|
62
|
+
else
|
63
|
+
[:escape, escape, [:dynamic, code]]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/slim/engine.rb
CHANGED
@@ -23,7 +23,8 @@ module Slim
|
|
23
23
|
use Slim::SplatAttributes, :attr_delimiter, :attr_wrapper, :sort_attrs, :default_tag
|
24
24
|
html :AttributeSorter, :sort_attrs
|
25
25
|
html :AttributeMerger, :attr_delimiter
|
26
|
-
use Slim::
|
26
|
+
use Slim::CodeAttributes, :attr_delimiter
|
27
|
+
use(:AttributeRemover) { Temple::HTML::AttributeRemover.new(:remove_empty_attrs => options[:attr_delimiter].keys) }
|
27
28
|
html :Pretty, :format, :attr_wrapper, :pretty, :indent
|
28
29
|
filter :Escapable, :use_html_safe, :disable_escape
|
29
30
|
filter :ControlFlow
|
data/lib/slim/parser.rb
CHANGED
@@ -55,14 +55,7 @@ module Slim
|
|
55
55
|
# @param [String] str Slim code
|
56
56
|
# @return [Array] Temple expression representing the code]]
|
57
57
|
def call(str)
|
58
|
-
|
59
|
-
if options[:encoding] && str.respond_to?(:encoding)
|
60
|
-
old_enc = str.encoding
|
61
|
-
str = str.dup if str.frozen?
|
62
|
-
str.force_encoding(options[:encoding])
|
63
|
-
# Fall back to old encoding if new encoding is invalid
|
64
|
-
str.force_encoding(old_enc) unless str.valid_encoding?
|
65
|
-
end
|
58
|
+
str = remove_bom(set_encoding(str))
|
66
59
|
|
67
60
|
result = [:multi]
|
68
61
|
reset(str.split(/\r?\n/), [result])
|
@@ -86,6 +79,31 @@ module Slim
|
|
86
79
|
QUOTED_ATTR_REGEX = /#{ATTR_NAME}=(=?)("|')/
|
87
80
|
CODE_ATTR_REGEX = /#{ATTR_NAME}=(=?)/
|
88
81
|
|
82
|
+
# Set string encoding if option is set
|
83
|
+
def set_encoding(s)
|
84
|
+
if options[:encoding] && s.respond_to?(:encoding)
|
85
|
+
old_enc = s.encoding
|
86
|
+
s = s.dup if s.frozen?
|
87
|
+
s.force_encoding(options[:encoding])
|
88
|
+
# Fall back to old encoding if new encoding is invalid
|
89
|
+
s.force_encoding(old_enc) unless s.valid_encoding?
|
90
|
+
end
|
91
|
+
s
|
92
|
+
end
|
93
|
+
|
94
|
+
# Remove unicode byte order mark from string
|
95
|
+
def remove_bom(s)
|
96
|
+
if s.respond_to?(:encoding)
|
97
|
+
if s.encoding.name =~ /^UTF-(8|16|32)(BE|LE)?/
|
98
|
+
s.gsub(Regexp.new("\\A\uFEFF".encode(s.encoding.name)), '')
|
99
|
+
else
|
100
|
+
s
|
101
|
+
end
|
102
|
+
else
|
103
|
+
s.gsub(/\A\xEF\xBB\xBF/, '')
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
89
107
|
def reset(lines = nil, stacks = nil)
|
90
108
|
# Since you can indent however you like in Slim, we need to keep a list
|
91
109
|
# of how deeply indented you are. For instance, in a template like this:
|
@@ -347,7 +365,7 @@ module Slim
|
|
347
365
|
end
|
348
366
|
|
349
367
|
if delimiter
|
350
|
-
boolean_attr_regex = /#{ATTR_NAME}(?=(\s|#{Regexp.escape delimiter}))/
|
368
|
+
boolean_attr_regex = /#{ATTR_NAME}(?=(\s|#{Regexp.escape delimiter}|\Z))/
|
351
369
|
end_regex = /\A\s*#{Regexp.escape delimiter}/
|
352
370
|
end
|
353
371
|
|
@@ -79,30 +79,31 @@ module Slim
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
merger << [:block, "#{hash}.each do |#{name}
|
82
|
+
merger << [:block, "#{hash}.keys.each do |#{name}|",
|
83
83
|
[:multi,
|
84
|
-
[:code, "#{value}
|
85
|
-
[:if, "#{
|
86
|
-
[:
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
[:
|
91
|
-
|
84
|
+
[:code, "#{value} = #{hash}[#{name}]"],
|
85
|
+
[:if, "#{@attr_delimiter}[#{name}]",
|
86
|
+
[:multi,
|
87
|
+
[:code, "#{value}.flatten!"],
|
88
|
+
[:code, "#{value}.map!(&:to_s)"],
|
89
|
+
[:code, "#{value}.reject!(&:empty?)"],
|
90
|
+
[:if, "#{value}.empty?",
|
91
|
+
[:code, "#{hash}.delete(#{name})"],
|
92
|
+
[:code, "#{hash}[#{name}] = #{value}.join(#{@attr_delimiter}[#{name}].to_s)"]]],
|
93
|
+
[:multi,
|
94
|
+
[:if, "#{value}.size > 1",
|
95
|
+
[:code, %{raise("Multiple #\{#{name}\} attributes specified")}]],
|
92
96
|
[:case, "#{value}.first",
|
93
97
|
['true', [:code, "#{hash}[#{name}] = #{name}"]],
|
94
|
-
['false, nil', [:code, "#{hash}
|
95
|
-
[:else, [:code, "#{hash}[#{name}] = #{value}.first"]]]]
|
96
|
-
[:else,
|
97
|
-
[:code, "#{hash}[#{name}] = #{value}.join(#{@attr_delimiter}[#{name}].to_s)"]]]]]
|
98
|
+
['false, nil', [:code, "#{hash}.delete(#{name})"]],
|
99
|
+
[:else, [:code, "#{hash}[#{name}] = #{value}.first"]]]]]]]
|
98
100
|
|
99
|
-
attr = [:
|
100
|
-
[:
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
[:static, options[:attr_wrapper]]]]
|
101
|
+
attr = [:multi,
|
102
|
+
[:static, ' '],
|
103
|
+
[:dynamic, name],
|
104
|
+
[:static, "=#{options[:attr_wrapper]}"],
|
105
|
+
[:escape, true, [:dynamic, value]],
|
106
|
+
[:static, options[:attr_wrapper]]]
|
106
107
|
enumerator = options[:sort_attrs] ? "#{hash}.sort_by {|#{name},#{value}| #{name} }" : hash
|
107
108
|
formatter = [:block, "#{enumerator}.each do |#{name},#{value}|", attr]
|
108
109
|
|
data/lib/slim/version.rb
CHANGED
data/slim.gemspec
CHANGED
@@ -11,15 +11,13 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.summary = 'Slim is a template language.'
|
12
12
|
s.description = 'Slim is a template language whose goal is reduce the syntax to the essential parts without becoming cryptic.'
|
13
13
|
s.homepage = 'http://slim-lang.com/'
|
14
|
-
s.extra_rdoc_files = %w(README.md LICENSE CHANGES)
|
15
|
-
s.rdoc_options = %w(--charset=UTF-8)
|
16
14
|
s.rubyforge_project = s.name
|
17
15
|
|
18
16
|
s.files = `git ls-files`.split("\n")
|
19
17
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
18
|
s.require_paths = %w(lib)
|
21
19
|
|
22
|
-
s.add_runtime_dependency('temple', ['~> 0.5.
|
20
|
+
s.add_runtime_dependency('temple', ['~> 0.5.5'])
|
23
21
|
s.add_runtime_dependency('tilt', ['~> 1.3.3'])
|
24
22
|
|
25
23
|
s.add_development_dependency('rake', ['>= 0.8.7'])
|
data/test/core/test_encoding.rb
CHANGED
@@ -99,15 +99,15 @@ option(selected class="clazz") Text
|
|
99
99
|
assert_html '<option class="clazz" selected="selected">Text</option><option class="clazz" selected="selected">Text</option>', source
|
100
100
|
end
|
101
101
|
|
102
|
-
def
|
102
|
+
def test_array_attribute_merging
|
103
103
|
source = %{
|
104
|
-
.alpha class="beta" class=[:gamma, nil, :delta, [true, false]]
|
104
|
+
.alpha class="beta" class=[[""], :gamma, nil, :delta, [true, false]]
|
105
|
+
.alpha class=:beta,:gamma
|
105
106
|
}
|
106
107
|
|
107
|
-
assert_html '<div class="alpha beta gamma delta true false"></div>', source
|
108
|
+
assert_html '<div class="alpha beta gamma delta true false"></div><div class="alpha beta gamma"></div>', source
|
108
109
|
end
|
109
110
|
|
110
|
-
|
111
111
|
def test_shortcut_splat
|
112
112
|
source = %q{
|
113
113
|
*hash This is my title
|
@@ -213,6 +213,22 @@ a class=true
|
|
213
213
|
a class=false
|
214
214
|
}
|
215
215
|
|
216
|
-
assert_html '<a class="true false"></a><a class="false true"></a><a class="
|
216
|
+
assert_html '<a class="true false"></a><a class="false true"></a><a class="true"></a><a class="false"></a>', source
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_static_empty_attribute
|
220
|
+
source = %q{
|
221
|
+
p(id="marvin" name="" class="" data-info="Illudium Q-36")= output_number
|
222
|
+
}
|
223
|
+
|
224
|
+
assert_html '<p data-info="Illudium Q-36" id="marvin" name="">1337</p>', source
|
225
|
+
end
|
226
|
+
|
227
|
+
def test_dynamic_empty_attribute
|
228
|
+
source = %q{
|
229
|
+
p(id="marvin" class=nil nonempty=("".to_s) data-info="Illudium Q-36")= output_number
|
230
|
+
}
|
231
|
+
|
232
|
+
assert_html '<p data-info="Illudium Q-36" id="marvin" nonempty="">1337</p>', source
|
217
233
|
end
|
218
234
|
end
|