temple 0.1.8 → 0.2.0
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/README.md +7 -19
- data/lib/temple/engine.rb +32 -21
- data/lib/temple/erb/engine.rb +1 -1
- data/lib/temple/erb/parser.rb +2 -2
- data/lib/temple/filters/debugger.rb +1 -1
- data/lib/temple/filters/dynamic_inliner.rb +1 -1
- data/lib/temple/filters/escape_html.rb +16 -13
- data/lib/temple/filters/multi_flattener.rb +2 -2
- data/lib/temple/filters/static_merger.rb +1 -1
- data/lib/temple/generators.rb +10 -6
- data/lib/temple/html/dispatcher.rb +17 -0
- data/lib/temple/html/fast.rb +44 -19
- data/lib/temple/html/pretty.rb +19 -15
- data/lib/temple/mixins.rb +174 -23
- data/lib/temple/templates/rails.rb +34 -0
- data/lib/temple/templates/tilt.rb +30 -0
- data/lib/temple/templates.rb +13 -0
- data/lib/temple/utils.rb +54 -1
- data/lib/temple/version.rb +1 -1
- data/lib/temple.rb +2 -2
- data/temple.gemspec +10 -10
- data/test/filters/test_dynamic_inliner.rb +10 -10
- data/test/filters/test_escape_html.rb +10 -11
- data/test/filters/test_multi_flattener.rb +2 -2
- data/test/filters/test_static_merger.rb +3 -3
- data/test/html/test_fast.rb +26 -21
- data/test/html/test_pretty.rb +2 -2
- data/test/test_engine.rb +144 -0
- data/test/test_erb.rb +3 -2
- data/test/test_generator.rb +7 -7
- data/test/test_utils.rb +38 -0
- metadata +12 -5
- data/lib/temple/erb/template.rb +0 -7
- data/lib/temple/template.rb +0 -35
data/lib/temple/mixins.rb
CHANGED
@@ -1,15 +1,154 @@
|
|
1
1
|
module Temple
|
2
2
|
module Mixins
|
3
|
+
module EngineDSL
|
4
|
+
def append(*args, &block)
|
5
|
+
chain << element(args, block)
|
6
|
+
end
|
7
|
+
|
8
|
+
def prepend(*args, &block)
|
9
|
+
chain.unshift(element(args, block))
|
10
|
+
end
|
11
|
+
|
12
|
+
def remove(name)
|
13
|
+
found = false
|
14
|
+
chain.reject! do |i|
|
15
|
+
equal = i.first == name
|
16
|
+
found = true if equal
|
17
|
+
equal
|
18
|
+
end
|
19
|
+
raise "#{name} not found" unless found
|
20
|
+
end
|
21
|
+
|
22
|
+
alias use append
|
23
|
+
|
24
|
+
def before(name, *args, &block)
|
25
|
+
name = Class === name ? name.name.to_sym : name
|
26
|
+
raise(ArgumentError, 'First argument must be Class or Symbol') unless Symbol === name
|
27
|
+
e = element(args, block)
|
28
|
+
found, i = false, 0
|
29
|
+
while i < chain.size
|
30
|
+
if chain[i].first == name
|
31
|
+
found = true
|
32
|
+
chain.insert(i, e)
|
33
|
+
i += 2
|
34
|
+
else
|
35
|
+
i += 1
|
36
|
+
end
|
37
|
+
end
|
38
|
+
raise "#{name} not found" unless found
|
39
|
+
end
|
40
|
+
|
41
|
+
def after(name, *args, &block)
|
42
|
+
name = Class === name ? name.name.to_sym : name
|
43
|
+
raise(ArgumentError, 'First argument must be Class or Symbol') unless Symbol === name
|
44
|
+
e = element(args, block)
|
45
|
+
found, i = false, 0
|
46
|
+
while i < chain.size
|
47
|
+
if chain[i].first == name
|
48
|
+
found = true
|
49
|
+
i += 1
|
50
|
+
chain.insert(i, e)
|
51
|
+
end
|
52
|
+
i += 1
|
53
|
+
end
|
54
|
+
raise "#{name} not found" unless found
|
55
|
+
end
|
56
|
+
|
57
|
+
def replace(name, *args, &block)
|
58
|
+
name = Class === name ? name.name.to_sym : name
|
59
|
+
raise(ArgumentError, 'First argument must be Class or Symbol') unless Symbol === name
|
60
|
+
e = element(args, block)
|
61
|
+
found = false
|
62
|
+
chain.each_with_index do |c, i|
|
63
|
+
if c.first == name
|
64
|
+
found = true
|
65
|
+
chain[i] = e
|
66
|
+
end
|
67
|
+
end
|
68
|
+
raise "#{name} not found" unless found
|
69
|
+
end
|
70
|
+
|
71
|
+
def filter(name, *options, &block)
|
72
|
+
use(name, Temple::Filters.const_get(name), *options, &block)
|
73
|
+
end
|
74
|
+
|
75
|
+
def generator(name, *options, &block)
|
76
|
+
use(name, Temple::Generators.const_get(name), *options, &block)
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def element(args, block)
|
82
|
+
name = args.shift
|
83
|
+
if Class === name
|
84
|
+
filter = name
|
85
|
+
name = filter.name.to_sym
|
86
|
+
end
|
87
|
+
raise(ArgumentError, 'First argument must be Class or Symbol') unless Symbol === name
|
88
|
+
|
89
|
+
if block
|
90
|
+
raise(ArgumentError, 'Class and block argument are not allowed at the same time') if filter
|
91
|
+
filter = block
|
92
|
+
end
|
93
|
+
|
94
|
+
filter ||= args.shift
|
95
|
+
|
96
|
+
case filter
|
97
|
+
when Proc
|
98
|
+
# Proc or block argument
|
99
|
+
# The proc is converted to a method of the engine class.
|
100
|
+
# The proc can then access the option hash of the engine.
|
101
|
+
raise(ArgumentError, 'Too many arguments') unless args.empty?
|
102
|
+
raise(ArgumentError, 'Proc or blocks must have arity 1') unless filter.arity == 1
|
103
|
+
method_name = "FILTER #{name}"
|
104
|
+
if Class === self
|
105
|
+
define_method(method_name, &filter)
|
106
|
+
[name, instance_method(method_name)]
|
107
|
+
else
|
108
|
+
(class << self; self; end).class_eval { define_method(method_name, &filter) }
|
109
|
+
[name, method(method_name)]
|
110
|
+
end
|
111
|
+
when Class
|
112
|
+
# Class argument (e.g Filter class)
|
113
|
+
# The options are passed to the classes constructor.
|
114
|
+
local_options = Hash === args.last ? args.pop : nil
|
115
|
+
raise(ArgumentError, 'Only symbols allowed in option filter') unless args.all? {|o| Symbol === o }
|
116
|
+
[name, filter, args, local_options]
|
117
|
+
else
|
118
|
+
# Other callable argument (e.g. Object of class which implements #call or Method)
|
119
|
+
# The callable has no access to the option hash of the engine.
|
120
|
+
raise(ArgumentError, 'Class or callable argument is required') unless filter.respond_to?(:call)
|
121
|
+
[name, filter]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
module CoreDispatcher
|
127
|
+
def on_multi(*exps)
|
128
|
+
[:multi, *exps.map {|exp| compile(exp) }]
|
129
|
+
end
|
130
|
+
|
131
|
+
def on_capture(name, exp)
|
132
|
+
[:capture, name, compile(exp)]
|
133
|
+
end
|
134
|
+
|
135
|
+
def on_escape(flag, exp)
|
136
|
+
[:escape, flag, compile(exp)]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
3
140
|
module Dispatcher
|
141
|
+
include CoreDispatcher
|
142
|
+
|
4
143
|
def self.included(base)
|
5
144
|
base.class_eval { extend ClassMethods }
|
6
145
|
end
|
7
146
|
|
8
|
-
def
|
9
|
-
compile
|
147
|
+
def call(exp)
|
148
|
+
compile(exp)
|
10
149
|
end
|
11
150
|
|
12
|
-
def compile
|
151
|
+
def compile(exp)
|
13
152
|
type, *args = exp
|
14
153
|
if respond_to?("on_#{type}")
|
15
154
|
send("on_#{type}", *args)
|
@@ -18,14 +157,6 @@ module Temple
|
|
18
157
|
end
|
19
158
|
end
|
20
159
|
|
21
|
-
def on_multi(*exps)
|
22
|
-
[:multi, *exps.map {|exp| compile!(exp) }]
|
23
|
-
end
|
24
|
-
|
25
|
-
def on_capture(name, exp)
|
26
|
-
[:capture, name, compile!(exp)]
|
27
|
-
end
|
28
|
-
|
29
160
|
module ClassMethods
|
30
161
|
def temple_dispatch(*bases)
|
31
162
|
bases.each do |base|
|
@@ -41,30 +172,50 @@ module Temple
|
|
41
172
|
end
|
42
173
|
end
|
43
174
|
|
175
|
+
module DefaultOptions
|
176
|
+
def set_default_options(options)
|
177
|
+
default_options.update(options)
|
178
|
+
end
|
179
|
+
|
180
|
+
def default_options
|
181
|
+
@default_options ||= Utils::MutableHash.new(superclass.respond_to?(:default_options) ?
|
182
|
+
superclass.default_options : nil)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
44
186
|
module Options
|
45
187
|
def self.included(base)
|
46
|
-
base.class_eval { extend
|
188
|
+
base.class_eval { extend DefaultOptions }
|
47
189
|
end
|
48
190
|
|
49
191
|
attr_reader :options
|
50
192
|
|
51
193
|
def initialize(options = {})
|
52
|
-
@options = self.class.default_options
|
194
|
+
@options = Utils::ImmutableHash.new(options, self.class.default_options)
|
53
195
|
end
|
196
|
+
end
|
54
197
|
|
55
|
-
|
56
|
-
|
57
|
-
default_options.merge!(opts)
|
58
|
-
end
|
198
|
+
module Template
|
199
|
+
include DefaultOptions
|
59
200
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
201
|
+
def engine(engine = nil)
|
202
|
+
default_options[:engine] = engine if engine
|
203
|
+
default_options[:engine]
|
204
|
+
end
|
205
|
+
|
206
|
+
def build_engine(*options)
|
207
|
+
raise 'No engine configured' unless engine
|
208
|
+
options << default_options
|
209
|
+
engine.new(Utils::ImmutableHash.new(*options)) do |e|
|
210
|
+
chain.each {|block| e.instance_eval(&block) }
|
66
211
|
end
|
67
212
|
end
|
213
|
+
|
214
|
+
def chain(&block)
|
215
|
+
chain = (default_options[:chain] ||= [])
|
216
|
+
chain << block if block
|
217
|
+
chain
|
218
|
+
end
|
68
219
|
end
|
69
220
|
end
|
70
221
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
if ::Rails::VERSION::MAJOR < 3
|
2
|
+
raise "Temple supports only Rails 3.x and greater, your Rails version is #{::Rails::VERSION::STRING}"
|
3
|
+
end
|
4
|
+
|
5
|
+
module Temple
|
6
|
+
module Templates
|
7
|
+
if ::Rails::VERSION::MAJOR == 3 && ::Rails::VERSION::MINOR < 1
|
8
|
+
class Rails < ActionView::TemplateHandler
|
9
|
+
include ActionView::TemplateHandlers::Compilable
|
10
|
+
extend Mixins::Template
|
11
|
+
|
12
|
+
def compile(template)
|
13
|
+
self.class.build_engine.call(template.source)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.register_as(name)
|
17
|
+
ActionView::Template.register_template_handler name.to_sym, self
|
18
|
+
end
|
19
|
+
end
|
20
|
+
else
|
21
|
+
class Rails
|
22
|
+
extend Mixins::Template
|
23
|
+
|
24
|
+
def self.call(template)
|
25
|
+
build_engine.call(template.source)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.register_as(name)
|
29
|
+
ActionView::Template.register_template_handler name.to_sym, self
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
|
3
|
+
module Temple
|
4
|
+
module Templates
|
5
|
+
class Tilt < ::Tilt::Template
|
6
|
+
extend Mixins::Template
|
7
|
+
|
8
|
+
# Prepare Temple template
|
9
|
+
#
|
10
|
+
# Called immediately after template data is loaded.
|
11
|
+
#
|
12
|
+
# @return [void]
|
13
|
+
def prepare
|
14
|
+
@src = self.class.build_engine({ :file => eval_file }, options).call(data)
|
15
|
+
end
|
16
|
+
|
17
|
+
# A string containing the (Ruby) source code for the template.
|
18
|
+
#
|
19
|
+
# @param [Hash] locals Local variables
|
20
|
+
# @return [String] Compiled template ruby code
|
21
|
+
def precompiled_template(locals = {})
|
22
|
+
@src
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.register_as(name)
|
26
|
+
::Tilt.register name.to_s, self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Temple
|
2
|
+
module Templates
|
3
|
+
autoload :Tilt, 'temple/templates/tilt'
|
4
|
+
autoload :Rails, 'temple/templates/rails'
|
5
|
+
|
6
|
+
def self.method_missing(name, engine, options = {})
|
7
|
+
template = Class.new(const_get(name))
|
8
|
+
template.engine(engine)
|
9
|
+
template.register_as(options[:register_as]) if options[:register_as]
|
10
|
+
template
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/temple/utils.rb
CHANGED
@@ -2,8 +2,53 @@ module Temple
|
|
2
2
|
module Utils
|
3
3
|
extend self
|
4
4
|
|
5
|
+
class ImmutableHash
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize(*hash)
|
9
|
+
@hash = hash.compact
|
10
|
+
end
|
11
|
+
|
12
|
+
def include?(key)
|
13
|
+
@hash.any? {|h| h.include?(key) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def [](key)
|
17
|
+
@hash.each {|h| return h[key] if h.include?(key) }
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def each
|
22
|
+
keys.each {|k| yield(k, self[k]) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def keys
|
26
|
+
@hash.inject([]) {|keys, h| keys += h.keys }.uniq
|
27
|
+
end
|
28
|
+
|
29
|
+
def values
|
30
|
+
keys.map {|k| self[k] }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class MutableHash < ImmutableHash
|
35
|
+
def initialize(*hash)
|
36
|
+
super({}, *hash)
|
37
|
+
end
|
38
|
+
|
39
|
+
def []=(key, value)
|
40
|
+
@hash.first[key] = value
|
41
|
+
end
|
42
|
+
|
43
|
+
def update(hash)
|
44
|
+
@hash.first.update(hash)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
5
48
|
def indent(text, indent, pre_tags)
|
6
|
-
|
49
|
+
text = text.to_s
|
50
|
+
text.gsub!("\n", indent) if pre_tags !~ text
|
51
|
+
text
|
7
52
|
end
|
8
53
|
|
9
54
|
# Returns an escaped copy of `html`.
|
@@ -55,6 +100,14 @@ module Temple
|
|
55
100
|
end
|
56
101
|
end
|
57
102
|
|
103
|
+
# Generate unique temporary variable name
|
104
|
+
#
|
105
|
+
# @return [String] Variable name
|
106
|
+
def tmp_var(prefix)
|
107
|
+
@tmp_var ||= 0
|
108
|
+
"_temple_#{prefix}#{@tmp_var += 1}"
|
109
|
+
end
|
110
|
+
|
58
111
|
def empty_exp?(exp)
|
59
112
|
case exp[0]
|
60
113
|
when :multi
|
data/lib/temple/version.rb
CHANGED
data/lib/temple.rb
CHANGED
@@ -7,12 +7,11 @@ module Temple
|
|
7
7
|
autoload :Utils, 'temple/utils'
|
8
8
|
autoload :Mixins, 'temple/mixins'
|
9
9
|
autoload :Filter, 'temple/filter'
|
10
|
-
autoload :
|
10
|
+
autoload :Templates, 'temple/templates'
|
11
11
|
|
12
12
|
module ERB
|
13
13
|
autoload :Engine, 'temple/erb/engine'
|
14
14
|
autoload :Parser, 'temple/erb/parser'
|
15
|
-
autoload :Template, 'temple/erb/template'
|
16
15
|
autoload :Trimming, 'temple/erb/trimming'
|
17
16
|
end
|
18
17
|
|
@@ -25,6 +24,7 @@ module Temple
|
|
25
24
|
end
|
26
25
|
|
27
26
|
module HTML
|
27
|
+
autoload :Dispatcher, 'temple/html/dispatcher'
|
28
28
|
autoload :Fast, 'temple/html/fast'
|
29
29
|
autoload :Pretty, 'temple/html/pretty'
|
30
30
|
end
|
data/temple.gemspec
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
require File.dirname(__FILE__) +
|
2
|
+
require File.dirname(__FILE__) + '/lib/temple/version'
|
3
|
+
require 'date'
|
3
4
|
|
4
5
|
Gem::Specification.new do |s|
|
5
|
-
s.name
|
6
|
-
s.version
|
6
|
+
s.name = 'temple'
|
7
|
+
s.version = Temple::VERSION
|
8
|
+
s.date = Date.today.to_s
|
7
9
|
|
8
|
-
s.authors
|
9
|
-
s.
|
10
|
-
s.
|
11
|
-
s.
|
12
|
-
s.require_paths = ["lib"]
|
13
|
-
s.rubygems_version = %q{1.3.6}
|
14
|
-
s.summary = %q{Template compilation framework in Ruby}
|
10
|
+
s.authors = ['Magnus Holm', 'Daniel Mendler']
|
11
|
+
s.email = ['judofyr@gmail.com', 'mail@daniel-mendler.de']
|
12
|
+
s.homepage = 'http://dojo.rubyforge.org/'
|
13
|
+
s.summary = 'Template compilation framework in Ruby'
|
15
14
|
|
15
|
+
s.require_paths = %w(lib)
|
16
16
|
s.files = `git ls-files`.split("\n")
|
17
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
@@ -6,7 +6,7 @@ describe Temple::Filters::DynamicInliner do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
it 'should compile several statics into dynamic' do
|
9
|
-
@filter.
|
9
|
+
@filter.call([:multi,
|
10
10
|
[:static, "Hello "],
|
11
11
|
[:static, "World\n "],
|
12
12
|
[:static, "Have a nice day"]
|
@@ -14,7 +14,7 @@ describe Temple::Filters::DynamicInliner do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should compile several dynamics into dynamic' do
|
17
|
-
@filter.
|
17
|
+
@filter.call([:multi,
|
18
18
|
[:dynamic, "@hello"],
|
19
19
|
[:dynamic, "@world"],
|
20
20
|
[:dynamic, "@yeah"]
|
@@ -22,7 +22,7 @@ describe Temple::Filters::DynamicInliner do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'should compile static and dynamic into dynamic' do
|
25
|
-
@filter.
|
25
|
+
@filter.call([:multi,
|
26
26
|
[:static, "Hello"],
|
27
27
|
[:dynamic, "@world"],
|
28
28
|
[:dynamic, "@yeah"],
|
@@ -31,7 +31,7 @@ describe Temple::Filters::DynamicInliner do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'should merge statics and dynamics around a block' do
|
34
|
-
exp = @filter.
|
34
|
+
exp = @filter.call([:multi,
|
35
35
|
[:static, "Hello "],
|
36
36
|
[:dynamic, "@world"],
|
37
37
|
[:block, "Oh yeah"],
|
@@ -46,21 +46,21 @@ describe Temple::Filters::DynamicInliner do
|
|
46
46
|
|
47
47
|
it 'should keep blocks intact' do
|
48
48
|
exp = [:multi, [:block, 'foo']]
|
49
|
-
@filter.
|
49
|
+
@filter.call(exp).should.equal exp
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'should keep single statics intact' do
|
53
53
|
exp = [:multi, [:static, 'foo']]
|
54
|
-
@filter.
|
54
|
+
@filter.call(exp).should.equal exp
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'should keep single dynamic intact' do
|
58
58
|
exp = [:multi, [:dynamic, 'foo']]
|
59
|
-
@filter.
|
59
|
+
@filter.call(exp).should.equal exp
|
60
60
|
end
|
61
61
|
|
62
62
|
it 'should inline inside multi' do
|
63
|
-
@filter.
|
63
|
+
@filter.call([:multi,
|
64
64
|
[:static, "Hello "],
|
65
65
|
[:dynamic, "@world"],
|
66
66
|
[:multi,
|
@@ -76,7 +76,7 @@ describe Temple::Filters::DynamicInliner do
|
|
76
76
|
end
|
77
77
|
|
78
78
|
it 'should merge across newlines' do
|
79
|
-
exp = @filter.
|
79
|
+
exp = @filter.call([:multi,
|
80
80
|
[:static, "Hello \n"],
|
81
81
|
[:newline],
|
82
82
|
[:dynamic, "@world"],
|
@@ -87,7 +87,7 @@ describe Temple::Filters::DynamicInliner do
|
|
87
87
|
end
|
88
88
|
|
89
89
|
it 'should compile static followed by newline' do
|
90
|
-
@filter.
|
90
|
+
@filter.call([:multi,
|
91
91
|
[:static, "Hello \n"],
|
92
92
|
[:newline],
|
93
93
|
[:block, "world"]
|
@@ -12,9 +12,10 @@ describe Temple::Filters::EscapeHTML do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'should handle escape expressions' do
|
15
|
-
@filter.
|
16
|
-
|
17
|
-
|
15
|
+
@filter.call([:escape, true,
|
16
|
+
[:multi,
|
17
|
+
[:static, "a < b"],
|
18
|
+
[:dynamic, "ruby_method"]]
|
18
19
|
]).should.equal [:multi,
|
19
20
|
[:static, "a < b"],
|
20
21
|
[:dynamic, "Temple::Utils.escape_html((ruby_method))"],
|
@@ -23,25 +24,23 @@ describe Temple::Filters::EscapeHTML do
|
|
23
24
|
|
24
25
|
it 'should keep blocks intact' do
|
25
26
|
exp = [:multi, [:block, 'foo']]
|
26
|
-
@filter.
|
27
|
+
@filter.call(exp).should.equal exp
|
27
28
|
end
|
28
29
|
|
29
30
|
it 'should keep statics intact' do
|
30
31
|
exp = [:multi, [:static, '<']]
|
31
|
-
@filter.
|
32
|
+
@filter.call(exp).should.equal exp
|
32
33
|
end
|
33
34
|
|
34
35
|
it 'should keep dynamic intact' do
|
35
36
|
exp = [:multi, [:dynamic, 'foo']]
|
36
|
-
@filter.
|
37
|
+
@filter.call(exp).should.equal exp
|
37
38
|
end
|
38
39
|
|
39
40
|
it 'should have use_html_safe option' do
|
40
41
|
filter = Temple::Filters::EscapeHTML.new(:use_html_safe => true)
|
41
|
-
filter.
|
42
|
-
[:
|
43
|
-
]).should.equal [:
|
44
|
-
[:static, "a < b"],
|
45
|
-
]
|
42
|
+
filter.call([:escape, true,
|
43
|
+
[:static, HtmlSafeString.new("a < b")],
|
44
|
+
]).should.equal [:static, "a < b"]
|
46
45
|
end
|
47
46
|
end
|
@@ -6,7 +6,7 @@ describe Temple::Filters::MultiFlattener do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
it 'should flatten nested multi expressions' do
|
9
|
-
@filter.
|
9
|
+
@filter.call([:multi,
|
10
10
|
[:static, "a"],
|
11
11
|
[:multi,
|
12
12
|
[:dynamic, "aa"],
|
@@ -28,6 +28,6 @@ describe Temple::Filters::MultiFlattener do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'should return first element' do
|
31
|
-
@filter.
|
31
|
+
@filter.call([:multi, [:block, 'foo']]).should.equal [:block, 'foo']
|
32
32
|
end
|
33
33
|
end
|
@@ -6,7 +6,7 @@ describe Temple::Filters::StaticMerger do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
it 'should merge serveral statics' do
|
9
|
-
@filter.
|
9
|
+
@filter.call([:multi,
|
10
10
|
[:static, "Hello "],
|
11
11
|
[:static, "World, "],
|
12
12
|
[:static, "Good night"]
|
@@ -16,7 +16,7 @@ describe Temple::Filters::StaticMerger do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'should merge serveral statics around block' do
|
19
|
-
@filter.
|
19
|
+
@filter.call([:multi,
|
20
20
|
[:static, "Hello "],
|
21
21
|
[:static, "World!"],
|
22
22
|
[:block, "123"],
|
@@ -30,7 +30,7 @@ describe Temple::Filters::StaticMerger do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'should merge serveral statics across newlines' do
|
33
|
-
@filter.
|
33
|
+
@filter.call([:multi,
|
34
34
|
[:static, "Hello "],
|
35
35
|
[:static, "World, "],
|
36
36
|
[:newline],
|