baby_erubis 0.1.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.
@@ -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