baby_erubis 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,97 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ###
4
+ ### $Release: 0.1.0 $
5
+ ### $Copyright: copyright(c) 2014 kuwata-lab.com all rights reserved $
6
+ ### $License: MIT License $
7
+ ###
8
+
9
+ libpath = File.class_eval { join(dirname(dirname(__FILE__)), 'lib') }
10
+ $: << libpath unless $:.include?(libpath)
11
+
12
+ require 'minitest/autorun'
13
+
14
+ require 'baby_erubis'
15
+
16
+
17
+
18
+ describe 'BabyErubis::TemplateContext' do
19
+
20
+ let(:ctx) { BabyErubis::TemplateContext.new }
21
+
22
+
23
+ describe '#initialize()' do
24
+
25
+ it "[!p69q1] takes hash object and sets them into instance variables." do
26
+ ctx = BabyErubis::TemplateContext.new(:x=>10, :y=>20)
27
+ assert_equal 10, ctx.instance_variable_get('@x')
28
+ assert_equal 20, ctx.instance_variable_get('@y')
29
+ assert_equal [:@x, :@y], ctx.instance_variables
30
+ end
31
+
32
+ it "[!p853f] do nothing when vars is nil." do
33
+ ctx = BabyErubis::TemplateContext.new(nil)
34
+ assert_equal [], ctx.instance_variables
35
+ end
36
+
37
+ end
38
+
39
+
40
+ describe '#[]' do
41
+
42
+ it "returns context value." do
43
+ ctx = BabyErubis::TemplateContext.new(:x=>10)
44
+ assert_equal 10, ctx[:x]
45
+ end
46
+
47
+ end
48
+
49
+
50
+ describe '#[]=' do
51
+
52
+ it "returns context value." do
53
+ ctx = BabyErubis::TemplateContext.new
54
+ ctx[:y] = 20
55
+ assert_equal 20, ctx[:y]
56
+ end
57
+
58
+ end
59
+
60
+
61
+ describe '#escape()' do
62
+
63
+ it "converts any value into string." do
64
+ assert_equal '10', ctx.escape(10)
65
+ assert_equal 'true', ctx.escape(true)
66
+ assert_equal '', ctx.escape(nil)
67
+ assert_equal '["A", "B"]', ctx.escape(['A', 'B'])
68
+ end
69
+
70
+ it "does not escape html special chars." do
71
+ assert_equal '<>&"', ctx.escape('<>&"')
72
+ end
73
+
74
+ end
75
+
76
+
77
+ end
78
+
79
+
80
+
81
+ describe 'BabyErubis::HtmlTemplateContext' do
82
+
83
+ let(:ctx) { BabyErubis::HtmlTemplateContext.new }
84
+
85
+
86
+ describe '#escape()' do
87
+
88
+ it "escapes html special chars." do
89
+ assert_equal '&lt;&gt;&amp;&quot;&#39;', ctx.__send__(:escape, '<>&"\'')
90
+ assert_equal '&lt;a href=&quot;?x=1&amp;y=2&amp;z=3&quot;&gt;click&lt;/a&gt;',
91
+ ctx.__send__(:escape, '<a href="?x=1&y=2&z=3">click</a>')
92
+ end
93
+
94
+ end
95
+
96
+
97
+ end
data/test/run_all.rb ADDED
@@ -0,0 +1,12 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ###
4
+ ### $Release: 0.1.0 $
5
+ ### $Copyright: copyright(c) 2014 kuwata-lab.com all rights reserved $
6
+ ### $License: MIT License $
7
+ ###
8
+
9
+ here = File.dirname(File.expand_path(__FILE__))
10
+ Dir.glob(here + '/**/*.rb').each do |fpath|
11
+ require fpath
12
+ end
@@ -0,0 +1,429 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ###
4
+ ### $Release: 0.1.0 $
5
+ ### $Copyright: copyright(c) 2014 kuwata-lab.com all rights reserved $
6
+ ### $License: MIT License $
7
+ ###
8
+
9
+ libpath = File.class_eval { join(dirname(dirname(__FILE__)), 'lib') }
10
+ $: << libpath unless $:.include?(libpath)
11
+
12
+ require 'minitest/autorun'
13
+
14
+ require 'baby_erubis'
15
+
16
+
17
+ def _modify(ruby_code)
18
+ if (''.freeze).equal?(''.freeze)
19
+ return ruby_code.gsub(/([^'])';/m, "\\1'.freeze;")
20
+ else
21
+ return ruby_code
22
+ end
23
+ end
24
+
25
+
26
+ describe BabyErubis::Template do
27
+
28
+ let(:template) { BabyErubis::Text.new() }
29
+
30
+
31
+ describe '#parse()' do
32
+
33
+ it "[!118pw] parses template string into ruby code." do
34
+ input = <<'END'
35
+ title: <%= @title %>
36
+ items:
37
+ <% for item in @items %>
38
+ - <%= item %>
39
+ <% end %>
40
+ END
41
+ expected = <<'END'
42
+ _buf = ''; _buf << 'title: '; _buf << (@title).to_s; _buf << '
43
+ '; _buf << 'items:
44
+ '; for item in @items;
45
+ _buf << ' - '; _buf << (item).to_s; _buf << '
46
+ '; end;
47
+ _buf.to_s
48
+ END
49
+ expected = _modify(expected)
50
+ code = template.parse(input)
51
+ assert_equal expected, code
52
+ end
53
+
54
+ it "[!7ht59] escapes single quotation and backslash characters." do
55
+ input = <<'END'
56
+ who's who?
57
+ '''
58
+ \w
59
+ \\\
60
+ END
61
+ expected = <<'END'
62
+ _buf = ''; _buf << 'who\'s who?
63
+ \'\'\'
64
+ \\w
65
+ \\\\\\
66
+ '; _buf.to_s
67
+ END
68
+ expected = _modify(expected)
69
+ assert_equal expected, template.parse(input)
70
+ end
71
+
72
+ it "[!u93y5] appends embedded expression in '<%= %>'." do
73
+ input = <<'END'
74
+ x = <%= x %>
75
+ END
76
+ expected = <<'END'
77
+ _buf = ''; _buf << 'x = '; _buf << (x).to_s; _buf << '
78
+ '; _buf.to_s
79
+ END
80
+ expected = _modify(expected)
81
+ assert_equal expected, template.parse(input)
82
+ end
83
+
84
+ it "[!auj95] appends embedded expression in '<%= %>' without escaping." do
85
+ input = <<'END'
86
+ x = <%== x %>
87
+ END
88
+ expected = <<'END'
89
+ _buf = ''; _buf << 'x = '; _buf << (x).to_s; _buf << '
90
+ '; _buf.to_s
91
+ END
92
+ expected = _modify(expected)
93
+ assert_equal expected, template.parse(input)
94
+ end
95
+
96
+ it "[!qveql] appends linefeeds when '<%# %>' found." do
97
+ input = <<'END'
98
+ <%#
99
+ for x in xs
100
+ %>
101
+ x = <%#=
102
+ x
103
+ %>
104
+ <%#
105
+ end
106
+ %>
107
+ END
108
+ expected = <<'END'
109
+ _buf = '';
110
+
111
+ _buf << '
112
+ '; _buf << 'x = ';
113
+
114
+ _buf << '
115
+ ';
116
+
117
+ _buf << '
118
+ '; _buf.to_s
119
+ END
120
+ expected = _modify(expected)
121
+ assert_equal expected, template.parse(input)
122
+ end
123
+
124
+ it "[!b10ns] generates ruby code correctly even when no embedded code." do
125
+ input = <<'END'
126
+ abc
127
+ def
128
+ END
129
+ expected = <<'END'
130
+ _buf = ''; _buf << 'abc
131
+ def
132
+ '; _buf.to_s
133
+ END
134
+ expected = _modify(expected)
135
+ assert_equal expected, template.parse(input)
136
+ end
137
+
138
+ it "[!3bx3d] not print extra linefeeds when line starts with '<%' and ends with '%>'" do
139
+ input = <<'END'
140
+ <% for item in items %>
141
+ <% if item %>
142
+ item = <%= item %>
143
+ <% end %>
144
+ <% end %>
145
+ END
146
+ expected = <<'END'
147
+ _buf = ''; for item in items;
148
+ if item;
149
+ _buf << ' item = '; _buf << (item).to_s; _buf << '
150
+ '; end;
151
+ end;
152
+ _buf.to_s
153
+ END
154
+ expected = _modify(expected)
155
+ assert_equal expected, template.parse(input)
156
+ end
157
+
158
+ it "handles '<%- -%>' (but do nothing)." do
159
+ input = <<'END'
160
+ <%- for item in @items -%>
161
+ <%-== item -%>
162
+ <%- end -%>
163
+ END
164
+ expected = <<'END'
165
+ _buf = ''; for item in @items;
166
+ _buf << ' '; _buf << (item).to_s; _buf << '
167
+ '; end;
168
+ _buf.to_s
169
+ END
170
+ expected = _modify(expected)
171
+ assert_equal expected, template.parse(input)
172
+ end
173
+
174
+ it "uses String#freeze forcedly when ':freeze=>true' passed to constructor." do
175
+ input = "value=<%== value %>"
176
+ expected = "_buf = ''; _buf << 'value='.freeze; _buf << (value).to_s; _buf.to_s\n"
177
+ template = BabyErubis::Text.new(:freeze=>true)
178
+ assert_equal expected, template.parse(input)
179
+ end
180
+
181
+ it "doesn't use String#freeze when ':freeze=>false' passed to constructor." do
182
+ input = "value=<%== value %>"
183
+ expected = "_buf = ''; _buf << 'value='; _buf << (value).to_s; _buf.to_s\n"
184
+ template = BabyErubis::Text.new(:freeze=>false)
185
+ assert_equal expected, template.parse(input)
186
+ end
187
+
188
+ end
189
+
190
+
191
+ describe '#pattern()' do
192
+
193
+ it "returns default embed pattern." do
194
+ template = BabyErubis::Template.new
195
+ assert_equal BabyErubis::Template::PATTERN, template.pattern
196
+ end
197
+
198
+ it "returns new embed pattern when overrided in subclass." do
199
+ class FooTemplate < BabyErubis::Template
200
+ rexp = BabyErubis::Template::PATTERN
201
+ PATTERN = Regexp.compile(rexp.to_s.sub(/<%/, '\{%').sub(/%>/, '%\}'))
202
+ end
203
+ template = FooTemplate.new
204
+ refute_equal BabyErubis::Template::PATTERN, template.pattern
205
+ assert_equal FooTemplate::PATTERN, template.pattern
206
+ end
207
+
208
+ end
209
+
210
+
211
+ describe '#render()' do
212
+
213
+ it "renders template with context values." do
214
+ input = <<'END'
215
+ title: <%== @title %>
216
+ items:
217
+ <% for item in @items %>
218
+ - <%== item %>
219
+ <% end %>
220
+ END
221
+ expected = <<'END'
222
+ title: Example
223
+ items:
224
+ - <AAA>
225
+ - B&B
226
+ - "CCC"
227
+ END
228
+ context = {:title=>'Example', :items=>['<AAA>', 'B&B', '"CCC"']}
229
+ output = template.from_str(input).render(context)
230
+ assert_equal expected, output
231
+ end
232
+
233
+ it "renders context values with no escaping." do
234
+ input = <<'END'
235
+ title: <%= @title %>
236
+ items:
237
+ <% for item in @items %>
238
+ - <%= item %>
239
+ <% end %>
240
+ END
241
+ expected = <<'END'
242
+ title: <b>Example</b>
243
+ items:
244
+ - <AAA>
245
+ - B&B
246
+ - "CCC"
247
+ END
248
+ tmpl = BabyErubis::Text.new.from_str(input)
249
+ context = {:title=>'<b>Example</b>', :items=>['<AAA>', 'B&B', '"CCC"']}
250
+ output = tmpl.render(context)
251
+ assert_equal expected, output
252
+ end
253
+
254
+ it "uses arg as context object when arg is not a hash object." do
255
+ input = <<'END'
256
+ title: <%= @title %>
257
+ items:
258
+ <% for item in @items %>
259
+ - <%= item %>
260
+ <% end %>
261
+ END
262
+ expected = <<'END'
263
+ title: Example
264
+ items:
265
+ - <AAA>
266
+ - B&B
267
+ - "CCC"
268
+ END
269
+ obj = Object.new
270
+ obj.instance_variable_set('@title', 'Example')
271
+ obj.instance_variable_set('@items', ['<AAA>', 'B&B', '"CCC"'])
272
+ output = template.from_str(input).render(obj)
273
+ assert_equal expected, output
274
+ end
275
+
276
+ end
277
+
278
+
279
+ describe '#compile()' do
280
+
281
+ it "compiles ruby code into proc object." do
282
+ assert_nil template.instance_variable_get('@_proc')
283
+ template.compile("_buf = ''; _buf << (x).to_s; _buf")
284
+ assert_kind_of Proc, template.instance_variable_get('@proc')
285
+ end
286
+
287
+ it "returns self." do
288
+ assert_same template, template.compile("_buf = ''; _buf << (x).to_s; _buf")
289
+ end
290
+
291
+ it "takes filename and linenum." do
292
+ begin
293
+ template.compile("_buf = ''; _buf << (x).to_s; _buf", 'example.erb', 3)
294
+ rescue SyntaxError => ex
295
+ assert_match /\Aexample\.erb:3: syntax error/, ex.message
296
+ end
297
+ end
298
+
299
+ it "uses '(eRuby)' as default filename and 1 as default linenum." do
300
+ begin
301
+ template.compile("_buf = ''; _buf << (x).to_s; _buf")
302
+ rescue SyntaxError => ex
303
+ assert_match /\A\(eRuby\):1: syntax error/, ex.message
304
+ end
305
+ end
306
+
307
+ end
308
+
309
+
310
+ describe '.from_file()' do
311
+
312
+ it "reads template file and returns template object." do
313
+ input = <<'END'
314
+ title: <%= @title %>
315
+ items:
316
+ <% for item in @items %>
317
+ - <%= item %>
318
+ <% end %>
319
+ END
320
+ expected = <<'END'
321
+ title: Example
322
+ items:
323
+ - <AAA>
324
+ - B&B
325
+ - "CCC"
326
+ END
327
+ tmpfile = "test.#{rand()}.erb"
328
+ File.open(tmpfile, 'wb') {|f| f.write(input) }
329
+ begin
330
+ template = BabyErubis::Text.new.from_file(tmpfile)
331
+ context = {:title=>'Example', :items=>['<AAA>', 'B&B', '"CCC"']}
332
+ output = template.render(context)
333
+ assert_equal expected, output
334
+ ensure
335
+ File.unlink(tmpfile) if File.exist?(tmpfile)
336
+ end
337
+ end
338
+
339
+ it "reads template file with specified encoding." do
340
+ input = "タイトル: <%= @title %>"
341
+ expected = "タイトル: サンプル"
342
+ tmpfile = "test.#{rand()}.erb"
343
+ File.open(tmpfile, 'wb:utf-8') {|f| f.write(input) }
344
+ begin
345
+ # nothing should be raised
346
+ template = BabyErubis::Text.new.from_file(tmpfile, 'utf-8')
347
+ output = template.render(:title=>"サンプル")
348
+ assert_equal expected, output
349
+ assert_equal 'UTF-8', output.encoding.name
350
+ # exception should be raised
351
+ ex = assert_raises ArgumentError do
352
+ template = BabyErubis::Text.new.from_file(tmpfile, 'us-ascii')
353
+ end
354
+ assert_equal "invalid byte sequence in US-ASCII", ex.message
355
+ ensure
356
+ File.unlink(tmpfile) if File.exist?(tmpfile)
357
+ end
358
+ end
359
+
360
+ end
361
+
362
+
363
+ end
364
+
365
+
366
+
367
+ describe BabyErubis::HtmlTemplate do
368
+
369
+ input = <<'END'
370
+ <html>
371
+ <h1><%= @title %></h1>
372
+ <ul>
373
+ <% for item in @items %>
374
+ <!-- <%== item %> -->
375
+ <li><%= item %></li>
376
+ <% end %>
377
+ </ul>
378
+ </html>
379
+ END
380
+ source = <<'END'
381
+ _buf = ''; _buf << '<html>
382
+ <h1>'; _buf << escape(@title); _buf << '</h1>
383
+ <ul>
384
+ '; for item in @items;
385
+ _buf << ' <!-- '; _buf << (item).to_s; _buf << ' -->
386
+ <li>'; _buf << escape(item); _buf << '</li>
387
+ '; end;
388
+ _buf << ' </ul>
389
+ </html>
390
+ '; _buf.to_s
391
+ END
392
+ source = _modify(source)
393
+ output = <<'END'
394
+ <html>
395
+ <h1>Example</h1>
396
+ <ul>
397
+ <!-- <AAA> -->
398
+ <li>&lt;AAA&gt;</li>
399
+ <!-- B&B -->
400
+ <li>B&amp;B</li>
401
+ <!-- "CCC" -->
402
+ <li>&quot;CCC&quot;</li>
403
+ </ul>
404
+ </html>
405
+ END
406
+
407
+
408
+ describe '#parse()' do
409
+
410
+ it "handles embedded expression with escaping." do
411
+ tmpl = BabyErubis::Html.new.from_str(input)
412
+ assert_equal source, tmpl.src
413
+ end
414
+
415
+ end
416
+
417
+
418
+ describe '#render()' do
419
+
420
+ it "renders context values with escaping." do
421
+ tmpl = BabyErubis::Html.new.from_str(input)
422
+ context = {:title=>'Example', :items=>['<AAA>', 'B&B', '"CCC"']}
423
+ assert_equal output, tmpl.render(context)
424
+ end
425
+
426
+ end
427
+
428
+
429
+ end