temple 0.1.8 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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],
|