tenjin 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (170) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.txt +54 -0
  3. data/benchmark/bench.rb +502 -0
  4. data/benchmark/bench_context.rb +17 -0
  5. data/benchmark/bench_context.yaml +141 -0
  6. data/benchmark/templates/_footer.html +4 -0
  7. data/benchmark/templates/_header.html +52 -0
  8. data/benchmark/templates/bench_eruby.rhtml +29 -0
  9. data/benchmark/templates/bench_tenjin.rbhtml +29 -0
  10. data/bin/rbtenjin +449 -0
  11. data/doc-api/classes/Tenjin.html +141 -0
  12. data/doc-api/classes/Tenjin/ArrayBufferTemplate.html +270 -0
  13. data/doc-api/classes/Tenjin/BaseContext.html +312 -0
  14. data/doc-api/classes/Tenjin/Context.html +126 -0
  15. data/doc-api/classes/Tenjin/ContextHelper.html +433 -0
  16. data/doc-api/classes/Tenjin/Engine.html +616 -0
  17. data/doc-api/classes/Tenjin/ErubisTemplate.html +166 -0
  18. data/doc-api/classes/Tenjin/HtmlHelper.html +359 -0
  19. data/doc-api/classes/Tenjin/Preprocessor.html +242 -0
  20. data/doc-api/classes/Tenjin/Template.html +916 -0
  21. data/doc-api/created.rid +1 -0
  22. data/doc-api/files/README_txt.html +185 -0
  23. data/doc-api/files/lib/tenjin_rb.html +136 -0
  24. data/doc-api/fr_class_index.html +36 -0
  25. data/doc-api/fr_file_index.html +28 -0
  26. data/doc-api/fr_method_index.html +89 -0
  27. data/doc-api/index.html +24 -0
  28. data/doc-api/rdoc-style.css +208 -0
  29. data/doc/docstyle.css +188 -0
  30. data/doc/examples.html +312 -0
  31. data/doc/faq.html +909 -0
  32. data/doc/users-guide.html +1691 -0
  33. data/lib/tenjin.rb +959 -0
  34. data/setup.rb +1331 -0
  35. data/tenjin.gemspec +58 -0
  36. data/test/assert-text-equal.rb +45 -0
  37. data/test/data/examples/form/create.rbhtml +4 -0
  38. data/test/data/examples/form/form.rbhtml +14 -0
  39. data/test/data/examples/form/layout.rbhtml +8 -0
  40. data/test/data/examples/form/main.rb +9 -0
  41. data/test/data/examples/form/main.result +21 -0
  42. data/test/data/examples/form/update.rbhtml +4 -0
  43. data/test/data/examples/preprocessing/helper.rb +16 -0
  44. data/test/data/examples/preprocessing/main.rb +11 -0
  45. data/test/data/examples/preprocessing/main.result +17 -0
  46. data/test/data/examples/preprocessing/select.rbhtml +15 -0
  47. data/test/data/examples/preprocessing/select_P.result +18 -0
  48. data/test/data/examples/table/table.rb +9 -0
  49. data/test/data/examples/table/table.rbhtml +16 -0
  50. data/test/data/examples/table/table.result +20 -0
  51. data/test/data/examples/table/table_s.result +18 -0
  52. data/test/data/faq/ex1.rbhtml +5 -0
  53. data/test/data/faq/ex10-baselayout.rbhtml +27 -0
  54. data/test/data/faq/ex10-content.rbhtml +12 -0
  55. data/test/data/faq/ex10-customlayout.rbhtml +11 -0
  56. data/test/data/faq/ex10_inherit.result +25 -0
  57. data/test/data/faq/ex11-bench.rb +28 -0
  58. data/test/data/faq/ex11-content.rbhtml +9 -0
  59. data/test/data/faq/ex11-layout1.rbhtml +5 -0
  60. data/test/data/faq/ex11-layout2.rbhtml +6 -0
  61. data/test/data/faq/ex11.rb +5 -0
  62. data/test/data/faq/ex11.rbhtml +8 -0
  63. data/test/data/faq/ex11.source +11 -0
  64. data/test/data/faq/ex11_arraybuffer.result +15 -0
  65. data/test/data/faq/ex1_chksyntax.result +3 -0
  66. data/test/data/faq/ex2-content.rbhtml +3 -0
  67. data/test/data/faq/ex2-layout.rbhtml +11 -0
  68. data/test/data/faq/ex2_removenl.result +19 -0
  69. data/test/data/faq/ex3.rb +4 -0
  70. data/test/data/faq/ex3.rbhtml +1 -0
  71. data/test/data/faq/ex3_escapefunc1.result +2 -0
  72. data/test/data/faq/ex3_escapefunc2.result +2 -0
  73. data/test/data/faq/ex5.rbhtml +7 -0
  74. data/test/data/faq/ex5_template_args.source +9 -0
  75. data/test/data/faq/ex6-content.rhtml +6 -0
  76. data/test/data/faq/ex6-layout.rhtml +6 -0
  77. data/test/data/faq/ex6.rb +10 -0
  78. data/test/data/faq/ex6_eruby.result +12 -0
  79. data/test/data/faq/ex7-expr-pattern.rb +34 -0
  80. data/test/data/faq/ex7-expr-pattern.rbhtml +3 -0
  81. data/test/data/faq/ex7_expr_pattern.result +4 -0
  82. data/test/data/faq/ex8-m18n.rb +77 -0
  83. data/test/data/faq/ex8-m18n.rbhtml +4 -0
  84. data/test/data/faq/ex8_m18n.result +10 -0
  85. data/test/data/faq/ex9-baselayout.rbhtml +8 -0
  86. data/test/data/faq/ex9-content.rbhtml +6 -0
  87. data/test/data/faq/ex9-mylayout.rbhtml +5 -0
  88. data/test/data/faq/ex9_changelayout.result +11 -0
  89. data/test/data/users_guide/content6.rbhtml +3 -0
  90. data/test/data/users_guide/content7.rbhtml +5 -0
  91. data/test/data/users_guide/content8.rbhtml +2 -0
  92. data/test/data/users_guide/contextdata.rb +7 -0
  93. data/test/data/users_guide/datafile.rb +5 -0
  94. data/test/data/users_guide/datafile.yaml +10 -0
  95. data/test/data/users_guide/ex.rbhtml +6 -0
  96. data/test/data/users_guide/ex.result +7 -0
  97. data/test/data/users_guide/ex.script +5 -0
  98. data/test/data/users_guide/ex_script.result +7 -0
  99. data/test/data/users_guide/ex_source.result +8 -0
  100. data/test/data/users_guide/example1.rbhtml +12 -0
  101. data/test/data/users_guide/example1.result +17 -0
  102. data/test/data/users_guide/example10.rbhtml +4 -0
  103. data/test/data/users_guide/example10_template_args.result +6 -0
  104. data/test/data/users_guide/example11.rbhtml +5 -0
  105. data/test/data/users_guide/example11_template_args_result +2 -0
  106. data/test/data/users_guide/example12.rbhtml +12 -0
  107. data/test/data/users_guide/example12_preprocessed.result +10 -0
  108. data/test/data/users_guide/example12_preprocessed_source.result +10 -0
  109. data/test/data/users_guide/example13.rbhtml +6 -0
  110. data/test/data/users_guide/example13_preprocessed.result +2 -0
  111. data/test/data/users_guide/example13_preprocessed_source.result +2 -0
  112. data/test/data/users_guide/example14.rb +32 -0
  113. data/test/data/users_guide/example14.rbhtml +6 -0
  114. data/test/data/users_guide/example14_tmplclass.result +15 -0
  115. data/test/data/users_guide/example15.rb +10 -0
  116. data/test/data/users_guide/example15_escapefunc.result +14 -0
  117. data/test/data/users_guide/example16.rbhtml +4 -0
  118. data/test/data/users_guide/example16a.rb +10 -0
  119. data/test/data/users_guide/example16a.result +4 -0
  120. data/test/data/users_guide/example16b.rb +13 -0
  121. data/test/data/users_guide/example16b.result +4 -0
  122. data/test/data/users_guide/example16c.rb +12 -0
  123. data/test/data/users_guide/example16c.result +4 -0
  124. data/test/data/users_guide/example1_S.result +14 -0
  125. data/test/data/users_guide/example1_SXNC.result +10 -0
  126. data/test/data/users_guide/example1_source.result +14 -0
  127. data/test/data/users_guide/example2.rbhtml +3 -0
  128. data/test/data/users_guide/example2_sb.result2 +9 -0
  129. data/test/data/users_guide/example3.rbhtml +5 -0
  130. data/test/data/users_guide/example3_syntaxcheck.result +2 -0
  131. data/test/data/users_guide/example4.rbhtml +13 -0
  132. data/test/data/users_guide/example4_datafile_rb.result +13 -0
  133. data/test/data/users_guide/example4_yaml.result +13 -0
  134. data/test/data/users_guide/example5.rbhtml +9 -0
  135. data/test/data/users_guide/example5_datastr_rb.result +9 -0
  136. data/test/data/users_guide/example5_datastr_yaml.result +9 -0
  137. data/test/data/users_guide/example6.rbhtml +19 -0
  138. data/test/data/users_guide/example6_layout.result +29 -0
  139. data/test/data/users_guide/example6_nested.result +28 -0
  140. data/test/data/users_guide/example7_layout2.result +13 -0
  141. data/test/data/users_guide/example8_layout3.result +8 -0
  142. data/test/data/users_guide/example9.rbhtml +18 -0
  143. data/test/data/users_guide/example9_capture.result +26 -0
  144. data/test/data/users_guide/footer.html +5 -0
  145. data/test/data/users_guide/footer.rbhtml +4 -0
  146. data/test/data/users_guide/layout6.rbhtml +17 -0
  147. data/test/data/users_guide/layout7.rbhtml +9 -0
  148. data/test/data/users_guide/layout8_html.rbhtml +5 -0
  149. data/test/data/users_guide/layout8_xhtml.rbhtml +6 -0
  150. data/test/data/users_guide/layout9.rbhtml +25 -0
  151. data/test/data/users_guide/sidemenu.rbhtml +5 -0
  152. data/test/data/users_guide/user_app.cgi +39 -0
  153. data/test/data/users_guide/user_app.result +30 -0
  154. data/test/data/users_guide/user_create.rbhtml +6 -0
  155. data/test/data/users_guide/user_edit.rbhtml +7 -0
  156. data/test/data/users_guide/user_form.rbhtml +10 -0
  157. data/test/data/users_guide/user_layout.rbhtml +16 -0
  158. data/test/test_all.rb +23 -0
  159. data/test/test_engine.rb +526 -0
  160. data/test/test_engine.yaml +2039 -0
  161. data/test/test_examples.rb +81 -0
  162. data/test/test_faq.rb +60 -0
  163. data/test/test_htmlhelper.rb +78 -0
  164. data/test/test_main.rb +564 -0
  165. data/test/test_main.yaml +174 -0
  166. data/test/test_template.rb +113 -0
  167. data/test/test_template.yaml +1244 -0
  168. data/test/test_users_guide.rb +75 -0
  169. data/test/testcase-helper.rb +166 -0
  170. metadata +226 -0
@@ -0,0 +1,174 @@
1
+ ###
2
+ ### $Rev: 61 $
3
+ ### $Date: 2007-08-04 13:23:33 +0900 (Sat, 04 Aug 2007) $
4
+ ###
5
+
6
+ ###
7
+ - name: lint1
8
+ desc: valid syntax
9
+ options: '-wz'
10
+ input: |
11
+ <ul>
12
+ <?rb i = 0 ?>
13
+ <?rb for item in items ?>
14
+ <?rb i += 1 ?>
15
+ <?rb color = i % 2 == 0 ? 'FFF' : 'FCF' ?>
16
+ <li>${item}</li>
17
+ <?rb end ?>
18
+ </ul>
19
+ expected: |
20
+ .test.rbhtml: Syntax OK
21
+
22
+ ###
23
+ - name: lint2
24
+ desc: invalid foreach
25
+ options: '-wz'
26
+ input: |
27
+ <ul>
28
+ <?rb i = 0 ?>
29
+ <?rb foreach item in @items ?>
30
+ <?rb i += 1 ?>
31
+ <?rb color = i % 2 == 0 ? 'FFF' : 'FCF' ?>
32
+ <li>${item}</li>
33
+ <?rb end ?>
34
+ </ul>
35
+ expected: |
36
+ .test.rbhtml:3: syntax error, unexpected kIN, expecting $end
37
+ foreach item in @items
38
+ ^
39
+
40
+ ###
41
+ - name: lint3
42
+ desc: tail ':' is missed
43
+ options: '-wz'
44
+ input: |
45
+ <ul>
46
+ <?rb i = 0 ?>
47
+ <?rb for item in @items ?>
48
+ <?rb i += 1 ?>
49
+ <?rb color = i % 2 == 0 ? 'FFF' : 'FCF' ?>
50
+ <li>${item}</li>
51
+ <?rb ende ?>
52
+ </ul>
53
+ expected: |
54
+ .test.rbhtml:8: syntax error, unexpected $end, expecting kEND
55
+
56
+ ####
57
+ #- name: lint1
58
+ # desc: valid syntax
59
+ # options: '-wz'
60
+ # input: |
61
+ # <ul>
62
+ # <?py i = 0 ?>
63
+ # <?py for item in items: ?>
64
+ # <?py i += 1 ?>
65
+ # <?py color = i % 2 == 0 and 'FFF' or 'FCF' ?>
66
+ # <li>${item}</li>
67
+ # <?py #end ?>
68
+ # </ul>
69
+ # expected: |
70
+ # .test.epyc - ok.
71
+ #
72
+ ####
73
+ #- name: lint2
74
+ # desc: tail ':' is missed
75
+ # options: '-wz'
76
+ # input: |
77
+ # <ul>
78
+ # <?py i = 0 ?>
79
+ # <?py for item in items ?>
80
+ # <?py i += 1 ?>
81
+ # <?py color = i % 2 == 0 and 'FFF' or 'FCF' ?>
82
+ # <li>${item}</li>
83
+ # <?py #end ?>
84
+ # </ul>
85
+ # expected: |
86
+ # .test.epyc:3:18: invalid syntax
87
+ # 3: for item in items
88
+ # ^
89
+ ####
90
+ #- name: lint3
91
+ # desc: "invalid indent of '#end'"
92
+ # options: '-wz'
93
+ # input: |
94
+ # <ul>
95
+ # <?py i = 0 ?>
96
+ # <?py for item in items: ?>
97
+ # <?py i += 1 ?>
98
+ # <?py color = i % 2 == 0 and 'FFF' or 'FCF' ?>
99
+ # <li>${item}</li>
100
+ # <?py #end ?>
101
+ # </ul>
102
+ # expected: |
103
+ # .test.epyc:7:3: unindent does not match any outer indentation level
104
+ # 7: #end
105
+ # ^
106
+ ####
107
+ #- name: lint4
108
+ # desc: invalid indent of pass statement
109
+ # options: '-wz'
110
+ # input: |
111
+ # <ul>
112
+ # <?py i = 0 ?>
113
+ # <?py for item in items: ?>
114
+ # <?py i += 1 ?>
115
+ # <?py color = i % 2 == 0 and 'FFF' or 'FCF' ?>
116
+ # <li>${item}</li>
117
+ # <?py pass ?>
118
+ # </ul>
119
+ # expected: |
120
+ # .test.epyc:7:3: unindent does not match any outer indentation level
121
+ # 7: pass
122
+ # ^
123
+ ####
124
+ #- name: lint5
125
+ # desc: invalid indent of statement
126
+ # options: '-wz'
127
+ # input: |
128
+ # <ul>
129
+ # <?py i = 0 ?>
130
+ # <?py for item in items: ?>
131
+ # <?py i += 1 ?>
132
+ # <?py color = i % 2 == 0 and 'FFF' or 'FCF' ?>
133
+ # <li>${item}</li>
134
+ # <?py #end ?>
135
+ # </ul>
136
+ # expected: |
137
+ # .test.epyc:5:7: invalid syntax
138
+ # 5: color = i % 2 == 0 and 'FFF' or 'FCF'
139
+ # ^
140
+ ####
141
+ #- name: lint6
142
+ # desc: invalid indent of statement
143
+ # options: '-wz'
144
+ # input: |
145
+ # <ul>
146
+ # <?py i = 0 ?>
147
+ # <?py for item in items: ?>
148
+ # <?py i += 1 ?>
149
+ # <?py color = i % 2 == 0 and 'FFF' or 'FCF' ?>
150
+ # <li>${item}</li>
151
+ # <?py #end ?>
152
+ # </ul>
153
+ # expected: |
154
+ # .test.epyc:5:3: unindent does not match any outer indentation level
155
+ # 5: color = i % 2 == 0 and 'FFF' or 'FCF'
156
+ # ^
157
+ #
158
+ ####
159
+ #- name: lint7
160
+ # desc: invalid indent of statement
161
+ # options: '-wz'
162
+ # input: |
163
+ # <ul>
164
+ # <?py i = 0 ?>
165
+ # <?py for item in items: ?>
166
+ # <?py i += 1 ?>
167
+ # <?py color = i % 2 == 0 and 'FFF' or 'FCF' ?>
168
+ # <li>${item}</li>
169
+ # <?py #end ?>
170
+ # </ul>
171
+ # expected: |
172
+ # .test.epyc:2:1: invalid syntax
173
+ # 2: i = 0
174
+ # ^
@@ -0,0 +1,113 @@
1
+ ###
2
+ ### $Rev: 59 $
3
+ ### $Release: 0.6.0 $
4
+ ### copyright(c) 2007 kuwata-lab all rights reserved.
5
+ ###
6
+
7
+ require 'test/unit'
8
+ #require 'testutil'
9
+ require 'testcase-helper'
10
+ require 'assert-text-equal'
11
+
12
+ require 'tenjin'
13
+
14
+ class TenjinTemplateTest < Test::Unit::TestCase
15
+
16
+ filename = __FILE__.sub(/\.\w+$/, '.yaml')
17
+ #load_yaml_testdata(filename)
18
+ eval load_yaml_testdata(filename, :lang=>'ruby')
19
+
20
+ def _test
21
+
22
+ @input ||= nil
23
+ @source ||= nil
24
+ @expected ||= nil
25
+ @exception ||= nil
26
+ @errormsg ||= nil
27
+ @options ||= {}
28
+ @filename ||= nil
29
+ @context ||= {}
30
+ @testopts ||= nil
31
+ @disabled ||= nil
32
+
33
+ return if @disabled
34
+
35
+ @options.keys.each do |key|
36
+ @options[key.intern] = @options.delete(key)
37
+ end
38
+
39
+ @templateclass = Tenjin::Template
40
+ if @testopts
41
+ if @testopts.key?('crchar')
42
+ ch = @testopts['crchar']
43
+ @input.gsub!(ch, "\r") if @input
44
+ @source.gsub!(ch, "\r") if @source
45
+ @expected.gsub!(ch, "\r") if @expected
46
+ end
47
+ if @testopts.key?('spacechar')
48
+ ch = @testopts['spacechar']
49
+ @input.gsub!(ch, " ") if @input
50
+ @source.gsub!(ch, " ") if @source
51
+ @expected.gsub!(ch, " ") if @expected
52
+ end
53
+ if @testopts.key?('templateclass')
54
+ klassname = @testopts['templateclass']
55
+ klass = Object
56
+ klassname.split('::').each { |s| klass = klass.const_get(s) }
57
+ @templateclass = klass
58
+ end
59
+ end
60
+ if @exception
61
+ #@exception = eval @exception if @exception.is_a?(String)
62
+ if @exception.is_a?(String)
63
+ @exception = @exception.split('::').inject(Object) {|klass, s| klass = klass.const_get(s) }
64
+ end
65
+ ex = assert_raise(@exception) do
66
+ template = @templateclass.new(@options)
67
+ template.convert(@input, @filename)
68
+ template.render(@context)
69
+ end
70
+ #assert_equal(@exception, ex.class.name)
71
+ assert_equal(@errormsg, ex.to_s.sub(/:0x\w+>/, '>')) if @errormsg
72
+ assert_equal(@filename, ex.filename) if @filename
73
+ else
74
+ template = @templateclass.new(@options)
75
+ script = template.convert(@input, @filename)
76
+ assert_text_equal(@source, script)
77
+ if @expected
78
+ output = template.render(@context)
79
+ assert_text_equal(@expected, output)
80
+ end
81
+ end
82
+
83
+ end
84
+
85
+
86
+ def test_filename1
87
+ return if ENV['TEST'] && ENV['TEST'] != 'filename1'
88
+ input = <<'END'
89
+ <ul>
90
+ <?rb for i in 0...3 ?>
91
+ <li>#{i}</li>
92
+ <?rb end ?>
93
+ </ul>
94
+ END
95
+ filename = 'test_filename1.rbhtml'
96
+ begin
97
+ File.open(filename, 'w') { |f| f.write(input) }
98
+ template1 = Tenjin::Template.new(filename)
99
+ template2 = Tenjin::Template.new()
100
+ assert_text_equal(template1.script, template2.convert(input))
101
+ assert_text_equal(template1.render(), template2.render())
102
+ ensure
103
+ File.unlink(filename)
104
+ end
105
+ end
106
+
107
+
108
+ #def test_import_module1()
109
+
110
+ #def test_import_module2()
111
+
112
+
113
+ end
@@ -0,0 +1,1244 @@
1
+ ###
2
+ - name: convert1
3
+ desc: basic
4
+ input*:
5
+ "python": |
6
+ <html>
7
+ <body>
8
+ <table>
9
+ <?py i = 0 ?>
10
+ <?py for item in ['<foo>', 'bar&bar', '"baz"']: ?>
11
+ <?py i += 1 ?>
12
+ <?py if i % 2 == 0: ?>
13
+ <?py color = '#FCF' ?>
14
+ <?py else: ?>
15
+ <?py color = '#FFF' ?>
16
+ <?py #endif ?>
17
+ <tr bgcolor="#{color}">
18
+ <td>${item}</td>
19
+ </tr>
20
+ <?py #endfor ?>
21
+ </table>
22
+ </body>
23
+ </html>
24
+ "ruby": |
25
+ <html>
26
+ <body>
27
+ <table>
28
+ <?rb i = 0 ?>
29
+ <?rb for item in ['<foo>', 'bar&bar', '"baz"'] ?>
30
+ <?rb i += 1 ?>
31
+ <?rb if i % 2 == 0 ?>
32
+ <?rb color = '#FCF' ?>
33
+ <?rb else ?>
34
+ <?rb color = '#FFF' ?>
35
+ <?rb end ?>
36
+ <tr bgcolor="#{color}">
37
+ <td>${item}</td>
38
+ </tr>
39
+ <?rb end ?>
40
+ </table>
41
+ </body>
42
+ </html>
43
+ source*:
44
+ "python": &convert1_source_python |
45
+ _buf.extend(('''<html>
46
+ <body>
47
+ <table>\n''', ));
48
+ i = 0
49
+ for item in ['<foo>', 'bar&bar', '"baz"']:
50
+ i += 1
51
+ if i % 2 == 0:
52
+ color = '#FCF'
53
+ else:
54
+ color = '#FFF'
55
+ #endif
56
+ _buf.extend((''' <tr bgcolor="''', to_str(color), '''">
57
+ <td>''', escape(to_str(item)), '''</td>
58
+ </tr>\n''', ));
59
+ #endfor
60
+ _buf.extend((''' </table>
61
+ </body>
62
+ </html>\n''', ));
63
+ "ruby": &convert1_source_ruby |5
64
+ _buf << %Q`<html>
65
+ <body>
66
+ <table>\n`
67
+ i = 0
68
+ for item in ['<foo>', 'bar&bar', '"baz"']
69
+ i += 1
70
+ if i % 2 == 0
71
+ color = '#FCF'
72
+ else
73
+ color = '#FFF'
74
+ end
75
+ _buf << %Q` <tr bgcolor="#{color}">
76
+ <td>#{escape((item).to_s)}</td>
77
+ </tr>\n`
78
+ end
79
+ _buf << %Q` </table>
80
+ </body>
81
+ </html>\n`
82
+ expected*:
83
+ "python": &convert1_expected |
84
+ <html>
85
+ <body>
86
+ <table>
87
+ <tr bgcolor="#FFF">
88
+ <td>&lt;foo&gt;</td>
89
+ </tr>
90
+ <tr bgcolor="#FCF">
91
+ <td>bar&amp;bar</td>
92
+ </tr>
93
+ <tr bgcolor="#FFF">
94
+ <td>&quot;baz&quot;</td>
95
+ </tr>
96
+ </table>
97
+ </body>
98
+ </html>
99
+ "ruby": *convert1_expected
100
+
101
+
102
+ ###
103
+ - name: convert2
104
+ desc: basic2
105
+ input*:
106
+ "python": |
107
+ <html>
108
+ <body>
109
+ <table>
110
+ <?py i = 0 ?>
111
+ <?py for item in ['<foo>', 'bar&bar', '"baz"']: ?>
112
+ <?py i += 1 ?>
113
+ <?py if i % 2 == 0: ?>
114
+ <?py color = '#FCF' ?>
115
+ <?py else: ?>
116
+ <?py color = '#FFF' ?>
117
+ <?py #endif ?>
118
+ <tr bgcolor="#{color}">
119
+ <td>${item}</td>
120
+ </tr>
121
+ <?py #endfor ?>
122
+ </table>
123
+ </body>
124
+ </html>
125
+ "ruby": |
126
+ <html>
127
+ <body>
128
+ <table>
129
+ <?rb i = 0 ?>
130
+ <?rb for item in ['<foo>', 'bar&bar', '"baz"'] ?>
131
+ <?rb i += 1 ?>
132
+ <?rb if i % 2 == 0 ?>
133
+ <?rb color = '#FCF' ?>
134
+ <?rb else ?>
135
+ <?rb color = '#FFF' ?>
136
+ <?rb end ?>
137
+ <tr bgcolor="#{color}">
138
+ <td>${item}</td>
139
+ </tr>
140
+ <?rb end ?>
141
+ </table>
142
+ </body>
143
+ </html>
144
+ source*:
145
+ "python": *convert1_source_python
146
+ "ruby": *convert1_source_ruby
147
+ expected*:
148
+ "python": *convert1_expected
149
+ "ruby": *convert1_expected
150
+
151
+
152
+ ###
153
+ - name: convert3
154
+ desc: basic3
155
+ input*:
156
+ "python": |
157
+ <html>
158
+ <body>
159
+ <table>
160
+ <?py
161
+ i = 0
162
+ for item in ['<foo>', 'bar&bar', '"baz"']:
163
+ i += 1
164
+ if i % 2 == 0:
165
+ color = '#FCF'
166
+ else:
167
+ color = '#FFF'
168
+ #endif
169
+ ?>
170
+ <tr bgcolor="#{color}">
171
+ <td>${item}</td>
172
+ </tr>
173
+ <?py
174
+ #endfor
175
+ ?>
176
+ </table>
177
+ </body>
178
+ </html>
179
+ "ruby": |
180
+ <html>
181
+ <body>
182
+ <table>
183
+ <?rb
184
+ i = 0
185
+ for item in ['<foo>', 'bar&bar', '"baz"']
186
+ i += 1
187
+ if i % 2 == 0
188
+ color = '#FCF'
189
+ else
190
+ color = '#FFF'
191
+ end
192
+ ?>
193
+ <tr bgcolor="#{color}">
194
+ <td>${item}</td>
195
+ </tr>
196
+ <?rb
197
+ end
198
+ ?>
199
+ </table>
200
+ </body>
201
+ </html>
202
+ source*:
203
+ "python": |
204
+ _buf.extend(('''<html>
205
+ <body>
206
+ <table>\n''', ));
207
+
208
+ i = 0
209
+ for item in ['<foo>', 'bar&bar', '"baz"']:
210
+ i += 1
211
+ if i % 2 == 0:
212
+ color = '#FCF'
213
+ else:
214
+ color = '#FFF'
215
+ #endif
216
+
217
+ _buf.extend((''' <tr bgcolor="''', to_str(color), '''">
218
+ <td>''', escape(to_str(item)), '''</td>
219
+ </tr>\n''', ));
220
+
221
+ #endfor
222
+
223
+ _buf.extend((''' </table>
224
+ </body>
225
+ </html>\n''', ));
226
+ "ruby": |5
227
+ _buf << %Q`<html>
228
+ <body>
229
+ <table>\n`
230
+
231
+ i = 0
232
+ for item in ['<foo>', 'bar&bar', '"baz"']
233
+ i += 1
234
+ if i % 2 == 0
235
+ color = '#FCF'
236
+ else
237
+ color = '#FFF'
238
+ end
239
+
240
+ _buf << %Q` <tr bgcolor="#{color}">
241
+ <td>#{escape((item).to_s)}</td>
242
+ </tr>\n`
243
+
244
+ end
245
+
246
+ _buf << %Q` </table>
247
+ </body>
248
+ </html>\n`
249
+
250
+ expected*:
251
+ "python": *convert1_expected
252
+ "ruby": *convert1_expected
253
+
254
+
255
+ ###
256
+ - name: convert4
257
+ desc: mixing styles
258
+ input*:
259
+ "python": |
260
+ <?py
261
+ users = [
262
+ {'name': 'Foo', 'email': 'foo@mail.com'},
263
+ {'name': 'Bar',},
264
+ {'name': 'Baz', 'email': 'baz@mail.org'},
265
+ ]
266
+ ?>
267
+ <ul>
268
+ <?py i = 0 ?>
269
+ <?py for user in users: ?>
270
+ <?py i += 1 ?>
271
+ <li><?py
272
+ if user.get('email'):
273
+ ?><a href="mailto:${user['email']}">${user['name']}</a><?py
274
+ else:
275
+ ?>${user['name']}<?py
276
+ #endif
277
+ ?></li>
278
+ <?py #endfor ?>
279
+ </ul>
280
+ "ruby": |
281
+ <?rb
282
+ users = [
283
+ {'name'=>'Foo', 'email'=>'foo@mail.com'},
284
+ {'name'=>'Bar',},
285
+ {'name'=>'Baz', 'email'=>'baz@mail.org'},
286
+ ]
287
+ ?>
288
+ <ul>
289
+ <?rb i = 0 ?>
290
+ <?rb for user in users ?>
291
+ <?rb i += 1 ?>
292
+ <li><?rb
293
+ if user['email']
294
+ ?><a href="mailto:${user['email']}">${user['name']}</a><?rb
295
+ else
296
+ ?>${user['name']}<?rb
297
+ end
298
+ ?></li>
299
+ <?rb end ?>
300
+ </ul>
301
+ source*:
302
+ "python": |
303
+
304
+ users = [
305
+ {'name': 'Foo', 'email': 'foo@mail.com'},
306
+ {'name': 'Bar',},
307
+ {'name': 'Baz', 'email': 'baz@mail.org'},
308
+ ]
309
+
310
+ _buf.extend(('''<ul>\n''', ));
311
+ i = 0
312
+ for user in users:
313
+ i += 1
314
+ _buf.extend((''' <li>''', ));
315
+ if user.get('email'):
316
+ _buf.extend(('''<a href="mailto:''', escape(to_str(user['email'])), '''">''', escape(to_str(user['name'])), '''</a>''', ));
317
+ else:
318
+ _buf.extend((escape(to_str(user['name'])), ));
319
+ #endif
320
+ _buf.extend(('''</li>\n''', ));
321
+ #endfor
322
+ _buf.extend(('''</ul>\n''', ));
323
+ "ruby": |5
324
+
325
+ users = [
326
+ {'name'=>'Foo', 'email'=>'foo@mail.com'},
327
+ {'name'=>'Bar',},
328
+ {'name'=>'Baz', 'email'=>'baz@mail.org'},
329
+ ]
330
+
331
+ _buf << %Q`<ul>\n`
332
+ i = 0
333
+ for user in users
334
+ i += 1
335
+ _buf << %Q` <li>`;
336
+ if user['email']
337
+ _buf << %Q`<a href="mailto:#{escape((user['email']).to_s)}">#{escape((user['name']).to_s)}</a>`;
338
+ else
339
+ _buf << %Q`#{escape((user['name']).to_s)}`;
340
+ end
341
+ _buf << %Q`</li>\n`
342
+ end
343
+ _buf << %Q`</ul>\n`
344
+ expected*:
345
+ "python": |
346
+ <ul>
347
+ <li><a href="mailto:foo@mail.com">Foo</a></li>
348
+ <li>Bar</li>
349
+ <li><a href="mailto:baz@mail.org">Baz</a></li>
350
+ </ul>
351
+ "ruby": |
352
+ <ul>
353
+ <li><a href="mailto:foo@mail.com">Foo</a></li>
354
+ <li>Bar</li>
355
+ <li><a href="mailto:baz@mail.org">Baz</a></li>
356
+ </ul>
357
+
358
+ ###
359
+ - name: convert5
360
+ desc: line starting with embedded expression
361
+ input*:
362
+ "python": |
363
+ <ul>
364
+ <?py for i in xrange(1,4): ?>
365
+ <li>
366
+ #{i}
367
+ </li>
368
+ <?py #endfor ?>
369
+ </ul>
370
+ "ruby": |
371
+ ${'title'}
372
+ <ul>
373
+ <?rb for i in 1...4 ?>
374
+ ${i}
375
+ <?rb end ?>
376
+ </ul>
377
+ source*:
378
+ "python": |
379
+ _buf.extend(('''<ul>\n''', ));
380
+ for i in xrange(1,4):
381
+ _buf.extend(('''<li>
382
+ ''', to_str(i), '''
383
+ </li>\n''', ));
384
+ #endfor
385
+ _buf.extend(('''</ul>\n''', ));
386
+ "ruby": |5
387
+ _buf << %Q`#{escape(('title').to_s)}
388
+ <ul>\n`
389
+ for i in 1...4
390
+ _buf << %Q`#{escape((i).to_s)}\n`
391
+ end
392
+ _buf << %Q`</ul>\n`
393
+ expected*:
394
+ "python": |
395
+ <ul>
396
+ <li>
397
+ 1
398
+ </li>
399
+ <li>
400
+ 2
401
+ </li>
402
+ <li>
403
+ 3
404
+ </li>
405
+ </ul>
406
+ "ruby": |
407
+ title
408
+ <ul>
409
+ 1
410
+ 2
411
+ 3
412
+ </ul>
413
+
414
+ ###
415
+ - name: convert6
416
+ desc: lspaces
417
+ testopts: { spacechar: '^' }
418
+ input*:
419
+ "python": |5
420
+ <?py
421
+ i = 0
422
+ for item in ['a', 'b', 'c']:
423
+ i += 1
424
+ ?>
425
+ <p>
426
+ <?py if i % 2 == 1: ?>
427
+ <span>#{item}</span>
428
+ <?py #endif ?>
429
+ </p>
430
+ <?py
431
+ #endfor
432
+ ?>
433
+ "ruby": |5
434
+ <?rb
435
+ i = 0
436
+ for item in ['a', 'b', 'c']
437
+ i += 1
438
+ ?>
439
+ <p>
440
+ <?rb if i % 2 == 1 ?>
441
+ <span>#{item}</span>
442
+ <?rb end ?>
443
+ </p>
444
+ <?rb
445
+ end
446
+ ?>
447
+ source*:
448
+ "python": |5
449
+
450
+ i = 0
451
+ for item in ['a', 'b', 'c']:
452
+ i += 1
453
+
454
+ _buf.extend(('''<p>\n''', ));
455
+ if i % 2 == 1:
456
+ _buf.extend(('''<span>''', to_str(item), '''</span>\n''', ));
457
+ #endif
458
+ _buf.extend(('''</p>\n''', ));
459
+
460
+ #endfor
461
+
462
+ "ruby": |5+
463
+ ^^
464
+ i = 0
465
+ for item in ['a', 'b', 'c']
466
+ i += 1
467
+ ^^
468
+ _buf << %Q`<p>\n`
469
+ if i % 2 == 1
470
+ _buf << %Q`<span>#{item}</span>\n`
471
+ end
472
+ _buf << %Q`</p>\n`
473
+ ^^
474
+ end
475
+ ^^
476
+ expected*:
477
+ "python": |
478
+ <p>
479
+ <span>a</span>
480
+ </p>
481
+ <p>
482
+ </p>
483
+ <p>
484
+ <span>c</span>
485
+ </p>
486
+ "ruby": |
487
+ <p>
488
+ <span>a</span>
489
+ </p>
490
+ <p>
491
+ </p>
492
+ <p>
493
+ <span>c</span>
494
+ </p>
495
+
496
+ ###
497
+ - name: quotation1
498
+ desc: single quotation
499
+ input*:
500
+ "python": &quotation1_input_python |
501
+ 'foo' and 'bar'
502
+ r"a'b'\n"
503
+ "ruby": &quotation1_input_ruby |
504
+ `foo` \1,000
505
+ r"a'b'\n"
506
+ source*:
507
+ "python": |
508
+ _buf.extend(('''\'foo\' and \'bar\'
509
+ r"a\'b\'\\n"\n''', ));
510
+ "ruby": |5
511
+ _buf << %Q`\`foo\` \\1,000
512
+ r"a'b'\\n"\n`
513
+ expected*:
514
+ "python": *quotation1_input_python
515
+ "ruby": *quotation1_input_ruby
516
+
517
+ ###
518
+ - name: newline1
519
+ desc: 'newline is \r\n'
520
+ testopts: { crchar: '^' }
521
+ input*:
522
+ "python": |
523
+ <?py for value in range(0,3): ?>^
524
+ #{value}^
525
+ i = #{value}^
526
+ <?py #end ?>^
527
+ "ruby": |
528
+ <?rb for value in 0...3 ?>^
529
+ #{value}^
530
+ i = #{value}^
531
+ <?rb end ?>^
532
+ source*:
533
+ "python": |
534
+ for value in range(0,3):
535
+ _buf.extend((to_str(value), '''^
536
+ i = ''', to_str(value), '''\r\n''', ));
537
+ #end
538
+ "ruby": |
539
+ for value in 0...3^
540
+ _buf << %Q`#{value}\r^
541
+ i = #{value}\r\n`^
542
+ end^
543
+ expected*:
544
+ "python": |
545
+ 0^
546
+ i = 0^
547
+ 1^
548
+ i = 1^
549
+ 2^
550
+ i = 2^
551
+ "ruby": |
552
+ 0^
553
+ i = 0^
554
+ 1^
555
+ i = 1^
556
+ 2^
557
+ i = 2^
558
+
559
+ ###
560
+ - name: newline2
561
+ desc: 'newline is \r\n'
562
+ testopts: { crchar: '^' }
563
+ input*:
564
+ "python": |
565
+ <p>^
566
+ <?py^
567
+ for value in xrange(0,3):^
568
+ ?>^
569
+ i = #{value}^
570
+ #{value}^
571
+ <?py^
572
+ #end^
573
+ ?>^
574
+ </p>^
575
+ "ruby": |
576
+ <p>^
577
+ <?rb^
578
+ for value in 0...3^
579
+ ?>^
580
+ i = #{value}^
581
+ #{value}^
582
+ <?rb^
583
+ end^
584
+ ?>^
585
+ </p>^
586
+ source*:
587
+ "python": |
588
+ _buf.extend(('''<p>\r\n''', ));
589
+
590
+ for value in xrange(0,3):
591
+
592
+ _buf.extend(('''i = ''', to_str(value), '''^
593
+ ''', to_str(value), '''\r\n''', ));
594
+
595
+ #end
596
+
597
+ _buf.extend(('''</p>\r\n''', ));
598
+ "ruby": |5
599
+ _buf << %Q`<p>\r\n`^
600
+ ^
601
+ for value in 0...3^
602
+ ^
603
+ _buf << %Q`i = #{value}\r^
604
+ #{value}\r\n`^
605
+ ^
606
+ end^
607
+ ^
608
+ _buf << %Q`</p>\r\n`^
609
+ expected*:
610
+ "python": |
611
+ <p>^
612
+ i = 0^
613
+ 0^
614
+ i = 1^
615
+ 1^
616
+ i = 2^
617
+ 2^
618
+ </p>^
619
+ "ruby": |
620
+ <p>^
621
+ i = 0^
622
+ 0^
623
+ i = 1^
624
+ 1^
625
+ i = 2^
626
+ 2^
627
+ </p>^
628
+
629
+ ###
630
+ - name: option_initbuf1
631
+ desc: initbuf option with input which starts with text
632
+ options: { preamble: true, postamble: true }
633
+ #options: { initbuf: true }
634
+ input*:
635
+ "python": |
636
+ <ul>
637
+ <?py for i in range(0,3): ?>
638
+ <li>#{i}</li>
639
+ <?py #end ?>
640
+ </ul>
641
+ "ruby": |
642
+ <ul>
643
+ <?rb for i in 0..2 ?>
644
+ <li>#{i}</li>
645
+ <?rb end ?>
646
+ </ul>
647
+ source*:
648
+ "python": |
649
+ _buf = []; _buf.extend(('''<ul>\n''', ));
650
+ for i in range(0,3):
651
+ _buf.extend(('''<li>''', to_str(i), '''</li>\n''', ));
652
+ #end
653
+ _buf.extend(('''</ul>\n''', ));
654
+ print ''.join(_buf)
655
+ "ruby": |
656
+ _buf = ''; _buf << %Q`<ul>\n`
657
+ for i in 0..2
658
+ _buf << %Q`<li>#{i}</li>\n`
659
+ end
660
+ _buf << %Q`</ul>\n`
661
+ _buf.to_s
662
+
663
+ ###
664
+ - name: option_initbuf2
665
+ desc: initbuf option with input which starts with"python" code
666
+ options: { preamble: true, postamble: true }
667
+ #options: { initbuf: true }
668
+ input*:
669
+ "python": |
670
+ <?py for i in range(0,3): ?>
671
+ #{i}
672
+ <?py #end ?>
673
+ "ruby": |
674
+ <?rb for i in 0..2 ?>
675
+ #{i}
676
+ <?rb end ?>
677
+ source*:
678
+ "python": |
679
+ _buf = []
680
+ for i in range(0,3):
681
+ _buf.extend((to_str(i), '''\n''', ));
682
+ #end
683
+ print ''.join(_buf)
684
+ "ruby": |
685
+ _buf = ''; for i in 0..2
686
+ _buf << %Q`#{i}\n`
687
+ end
688
+ _buf.to_s
689
+
690
+ ###
691
+ - name: option_escapefunc1
692
+ desc: escapefunc option
693
+ options*:
694
+ "python": { escapefunc: cgi.escape }
695
+ "ruby": { escapefunc: CGI.escapeHTML }
696
+ input*:
697
+ "python": |
698
+ #{value}
699
+ ${value}
700
+ "ruby": |
701
+ #{value}
702
+ ${value}
703
+ source*:
704
+ "python": |
705
+ _buf.extend((to_str(value), '''
706
+ ''', cgi.escape(to_str(value)), '''\n''', ));
707
+ "ruby": |5
708
+ _buf << %Q`#{value}
709
+ #{CGI.escapeHTML((value).to_s)}\n`
710
+
711
+ ###
712
+ - name: option_tostrfunc1
713
+ desc: tostrfunc option
714
+ options: { tostrfunc: str }
715
+ disabled*:
716
+ "python": false
717
+ "ruby": true
718
+ input: |
719
+ #{value}
720
+ ${value}
721
+ source*:
722
+ "python": |
723
+ _buf.extend((str(value), '''
724
+ ''', escape(str(value)), '''\n''', ));
725
+ "ruby": |
726
+
727
+ ###
728
+ - name: option_indent1
729
+ desc: indent option
730
+ options: { indent: 2 }
731
+ disabled*:
732
+ "python": false
733
+ "ruby": true
734
+ input*:
735
+ "python": |
736
+ <?py for i in range(0,3): ?>
737
+ i = #{value}
738
+ <?py #end ?>
739
+ "ruby": |
740
+ source*:
741
+ "python": |
742
+ for i in range(0,3):
743
+ _buf.extend(('''i = ''', to_str(value), '''\n''', ));
744
+ #end
745
+ "ruby": |
746
+
747
+ ###
748
+ - name: option_encoding1
749
+ desc: encoding option
750
+ disabled*:
751
+ "python": false
752
+ "ruby": true
753
+ options: { encoding: utf-8 }
754
+ testopts: { encoding: utf-8 }
755
+ input*:
756
+ "python": |
757
+ こんにちは${user}!
758
+ <ul>
759
+ <?py for ch in [u'日', u'本', u'語', u'']: ?>
760
+ <li>#{ch}</li>
761
+ <?py #end ?>
762
+ </ul>
763
+ source*:
764
+ "python": |
765
+ _buf.extend((u'''こんにちは''', escape(to_str(user)), u'''!
766
+ <ul>\n''', ));
767
+ for ch in [u'日', u'本', u'語', u'']:
768
+ _buf.extend((u''' <li>''', to_str(ch), u'''</li>\n''', ));
769
+ #end
770
+ _buf.extend((u'''</ul>\n''', ));
771
+ context: { user: 世界 }
772
+ expected: |
773
+ こんにちは世界!
774
+ <ul>
775
+ <li>日</li>
776
+ <li>本</li>
777
+ <li>語</li>
778
+ <li></li>
779
+ </ul>
780
+
781
+ ###
782
+ - name: syntaxerr1
783
+ desc: syntax error
784
+ filename: syntaxerr1.tenjin
785
+ disabled*:
786
+ "python": false
787
+ "ruby": true
788
+ input*:
789
+ "python": |
790
+ <?py for i in range(0,3) ?>
791
+ #{i}
792
+ <?py #end ?>
793
+ "ruby": |
794
+ source*:
795
+ "python": |
796
+ for i in range(0,3)
797
+ _buf.append(to_str(i))
798
+ #end
799
+ "ruby": |
800
+ exception*:
801
+ "python": SyntaxError
802
+ "ruby":
803
+ errormsg*:
804
+ "python": invalid syntax
805
+ "ruby":
806
+
807
+
808
+ ###
809
+ - name: escape1
810
+ desc: escape() function
811
+ input*:
812
+ "python": &input_escape1_python |
813
+ ${var}
814
+ "ruby": &input_escape1_ruby |
815
+ ${@var}
816
+ source*:
817
+ "python": &source_escape1_python |
818
+ _buf.extend((escape(to_str(var)), '''\n''', ));
819
+ "ruby": &source_escape1_ruby |5
820
+ _buf << %Q`#{escape((@var).to_s)}\n`
821
+ expected*:
822
+ "python": |
823
+ &amp; &lt; &gt; &quot;
824
+ "ruby": |
825
+ &amp; &lt; &gt; &quot;
826
+ context: { var: '& < > "' }
827
+
828
+
829
+ ###
830
+ - name: to_str1
831
+ desc: to_str() function
832
+ disabled*:
833
+ "python": false
834
+ "ruby": true
835
+ input*:
836
+ "python": |
837
+ #{var},#{flag},#{flag2}
838
+ ${var},${flag},${flag2}
839
+ "ruby": |
840
+ source*:
841
+ "python": |
842
+ _buf.extend((to_str(var), ''',''', to_str(flag), ''',''', to_str(flag2), '''
843
+ ''', escape(to_str(var)), ''',''', escape(to_str(flag)), ''',''', escape(to_str(flag2)), '''\n''', ));
844
+ "ruby": |
845
+ expected*:
846
+ "python": |
847
+ ,True,False
848
+ ,True,False
849
+ "ruby": |
850
+ context: { var: null, flag: true, flag2: false }
851
+
852
+
853
+ ##
854
+ - name: template_args
855
+ desc: '#@ARGS'
856
+ input*:
857
+ "python": |
858
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
859
+ <?py #@ARGS name, x,y,z ?>
860
+ <ul>
861
+ <span>hello #{name}</span>
862
+ <span>hello #{name2}</span>
863
+ </ul>
864
+ "ruby": |
865
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
866
+ <?rb #@ARGS name, x,y,z ?>
867
+ <ul>
868
+ <span>hello #{name}</span>
869
+ <span>hello #{name2}</span>
870
+ </ul>
871
+ source*:
872
+ "python": |
873
+ _buf = []; _buf.extend(('''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">\n''', ));
874
+ name = _context.get('name'); x = _context.get('x'); y = _context.get('y'); z = _context.get('z');
875
+ _buf.extend(('''<span>hello ''', to_str(name), '''</span>
876
+ <span>hello ''', to_str(name2), '''</span>
877
+ </ul>\n''', ));
878
+ print ''.join(_buf)
879
+ "ruby": |5
880
+ _buf << %Q`<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">\n`
881
+ name = @name; x = @x; y = @y; z = @z;
882
+ _buf << %Q`<ul>
883
+ <span>hello #{name}</span>
884
+ <span>hello #{name2}</span>
885
+ </ul>\n`
886
+ context: { name: 'world' }
887
+ exception*:
888
+ "python": NameError
889
+ "ruby": NameError
890
+ errormsg*:
891
+ "python": "name 'name2' is not defined"
892
+ "ruby": "undefined local variable or method `name2' for #<Tenjin::Context>"
893
+
894
+
895
+ ##
896
+ - name: arraybuffertemplate1
897
+ desc: ArrayBufferTemplate class
898
+ disabled*:
899
+ "python": true
900
+ "ruby": false
901
+ testopts*:
902
+ "python":
903
+ "ruby": { templateclass: 'Tenjin::ArrayBufferTemplate' }
904
+ input*:
905
+ "python": |
906
+ "ruby": |
907
+ <table>
908
+ <?rb i = 0 ?>
909
+ <?rb for item in @items ?>
910
+ <?rb i += 1 ?>
911
+ <tr>
912
+ <td>#{i}</td>
913
+ <td>${item}</td>
914
+ </tr>
915
+ <?rb end ?>
916
+ </table>
917
+ source*:
918
+ "python": |
919
+ "ruby": |5
920
+ _buf.push('<table>
921
+ '); i = 0
922
+ for item in @items
923
+ i += 1
924
+ _buf.push(' <tr>
925
+ <td>', (i).to_s, '</td>
926
+ <td>', escape((item).to_s), '</td>
927
+ </tr>
928
+ '); end
929
+ _buf.push('</table>
930
+ ');
931
+ expected*:
932
+ "python": |
933
+ "ruby": |
934
+ <table>
935
+ <tr>
936
+ <td>1</td>
937
+ <td>&lt;AAA&gt;</td>
938
+ </tr>
939
+ <tr>
940
+ <td>2</td>
941
+ <td>B&amp;B</td>
942
+ </tr>
943
+ <tr>
944
+ <td>3</td>
945
+ <td>&quot;CCC&quot;</td>
946
+ </tr>
947
+ </table>
948
+ context: { items: ['<AAA>', 'B&B', '"CCC"'] }
949
+
950
+ ###
951
+ - name: preprocessor1
952
+ desc: template class for preprocessor
953
+ testopts*:
954
+ "python": { templateclass: tenjin.Preprocessor }
955
+ "ruby": { templateclass: 'Tenjin::Preprocessor' }
956
+ input*:
957
+ "python": |
958
+ <?PY states = { "CA": "California", ?>
959
+ <?PY "NY": "New York", ?>
960
+ <?PY "FL": "Florida", } ?>
961
+ <?PY # ?>
962
+ <?py chk = { params['state']: ' checked="checked"' } ?>
963
+ <?PY codes = states.keys() ?>
964
+ <?PY codes.sort() ?>
965
+ <select name="state">
966
+ <option value="">-</option>
967
+ <?PY for code in codes: ?>
968
+ <option value="#{{code}}"#{chk.get(#{{repr(code)}}, '')}>${{states[code]}}</option>
969
+ <?PY #endfor ?>
970
+ </select>
971
+ "ruby": |
972
+ <?RB states = { :CA => "California", ?>
973
+ <?RB :NY => "New York", ?>
974
+ <?RB :FL => "Florida", } ?>
975
+ <?rb chk = { params['state'] => ' checked="checked"' } ?>
976
+ <select name="state">
977
+ <option value="">-</option>
978
+ <?RB for code in states.keys.sort_by{|k| k.to_s} ?>
979
+ <option value="#{{code}}"#{chk[#{{code.inspect}}]}>${{states[code]}}</option>
980
+ <?RB end ?>
981
+ </select>
982
+ "perl": |
983
+ <?PL my $states = { "CA" => "California", ?>
984
+ <?PL "NY" => "New York", ?>
985
+ <?PL "FL" => "Florida", }; ?>
986
+ <?pl my $chk = { $params->{state} => ' checked="checked"' }; ?>
987
+ <select name="state">
988
+ <option value="">-</option>
989
+ <?PL for my $code (sort(keys(%$states))) { ?>
990
+ <option value="[%=$code=%]"[==$chk->{[%=$code=%]}=]>[%=$states->{code}=%]</option>
991
+ <?PL } ?>
992
+ </select>
993
+ "js": |
994
+ <?JS var states = { CA: "California", ?>
995
+ <?JS NY: "New York", ?>
996
+ <?JS FL: "Florida", }; ?>
997
+ <?js var chk = { }; ?>
998
+ <?js chk[params.state] = ' checked="checked"'; ?>
999
+ <select name="state">
1000
+ <option value="">-</option>
1001
+ <?JS var codes = []; ?>
1002
+ <?JS for (var code in states) { codes.push(code); } ?>
1003
+ <?JS codes.sort(); ?>
1004
+ <?JS for (var i = 0, n = codes.length; i < n; i++) { ?>
1005
+ <?JS var code = codes[i]; ?>
1006
+ <option value="#{{code}}"#{chk['#{{code}}']}>${{states[code]}}</option>
1007
+ <?JS } ?>
1008
+ </select>
1009
+ source*:
1010
+ "python": |
1011
+ states = { "CA": "California",
1012
+ "NY": "New York",
1013
+ "FL": "Florida", }
1014
+ #
1015
+ _buf.extend(('''<?py chk = { params[\'state\']: \' checked="checked"\' } ?>\n''', ));
1016
+ codes = states.keys()
1017
+ codes.sort()
1018
+ _buf.extend(('''<select name="state">
1019
+ <option value="">-</option>\n''', ));
1020
+ for code in codes:
1021
+ _buf.extend((''' <option value="''', to_str(_decode_params(code)), '''"#{chk.get(''', to_str(_decode_params(repr(code))), ''', \'\')}>''', escape(to_str(_decode_params(states[code]))), '''</option>\n''', ));
1022
+ #endfor
1023
+ _buf.extend(('''</select>\n''', ));
1024
+ "ruby": |
1025
+ states = { :CA => "California",
1026
+ :NY => "New York",
1027
+ :FL => "Florida", }
1028
+ _buf << %Q`<?rb chk = { params['state'] => ' checked="checked"' } ?>
1029
+ <select name="state">
1030
+ <option value="">-</option>\n`
1031
+ for code in states.keys.sort_by{|k| k.to_s}
1032
+ _buf << %Q` <option value="#{_decode_params((code))}"\#{chk[#{_decode_params((code.inspect))}]}>#{escape((_decode_params((states[code]))).to_s)}</option>\n`
1033
+ end
1034
+ _buf << %Q`</select>\n`
1035
+ "perl": |
1036
+ my @_buf = (); my $states = { "CA" => "California",
1037
+ "NY" => "New York",
1038
+ "FL" => "Florida", };
1039
+ push(@_buf, q`<?pl my $chk = { $params->{state} => ' checked="checked"' }; ?>
1040
+ <select name="state">
1041
+ <option value="">-</option>
1042
+ `, ); for my $code (sort(keys(%$states))) {
1043
+ push(@_buf, q` <option value="`, escape($code), q`"[==$chk->{`, escape($code), q`}=]>`, escape($states->{code}), q`</option>
1044
+ `, ); }
1045
+ push(@_buf, q`</select>
1046
+ `, ); join('', @_buf);
1047
+ "js": |
1048
+ var _buf = []; var states = { CA: "California",
1049
+ NY: "New York",
1050
+ FL: "Florida", };
1051
+ _buf.push('<?js var chk = { }; ?>\n\
1052
+ <?js chk[params.state] = \' checked="checked"\'; ?>\n\
1053
+ <select name="state">\n\
1054
+ <option value="">-</option>\n');
1055
+ var codes = [];
1056
+ for (var code in states) { codes.push(code); }
1057
+ codes.sort();
1058
+ for (var i = 0, n = codes.length; i < n; i++) {
1059
+ var code = codes[i];
1060
+ _buf.push(' <option value="', Tenjin._decode_params(code), '"#{chk[\'', Tenjin._decode_params(code), '\']}>', escapeXml(Tenjin._decode_params(states[code])), '</option>\n');
1061
+ }
1062
+ _buf.push('</select>\n');
1063
+ _buf.join('')
1064
+ expected*:
1065
+ "python": |
1066
+ <?py chk = { params['state']: ' checked="checked"' } ?>
1067
+ <select name="state">
1068
+ <option value="">-</option>
1069
+ <option value="CA"#{chk.get('CA', '')}>California</option>
1070
+ <option value="FL"#{chk.get('FL', '')}>Florida</option>
1071
+ <option value="NY"#{chk.get('NY', '')}>New York</option>
1072
+ </select>
1073
+ "ruby": |
1074
+ <?rb chk = { params['state'] => ' checked="checked"' } ?>
1075
+ <select name="state">
1076
+ <option value="">-</option>
1077
+ <option value="CA"#{chk[:CA]}>California</option>
1078
+ <option value="FL"#{chk[:FL]}>Florida</option>
1079
+ <option value="NY"#{chk[:NY]}>New York</option>
1080
+ </select>
1081
+ "perl": |
1082
+ <?pl my $chk = { $params->{state} => ' checked="checked"' }; ?>
1083
+ <select name="state">
1084
+ <option value="">-</option>
1085
+ <option value="CA"[==$chk->{CA}=]></option>
1086
+ <option value="FL"[==$chk->{FL}=]></option>
1087
+ <option value="NY"[==$chk->{NY}=]></option>
1088
+ </select>
1089
+ "js": |
1090
+ <?js var chk = { }; ?>
1091
+ <?js chk[params.state] = ' checked="checked"'; ?>
1092
+ <select name="state">
1093
+ <option value="">-</option>
1094
+ <option value="CA"#{chk['CA']}>California</option>
1095
+ <option value="FL"#{chk['FL']}>Florida</option>
1096
+ <option value="NY"#{chk['NY']}>New York</option>
1097
+ </select>
1098
+
1099
+ ##
1100
+ - name: preprocessor2
1101
+ desc: template class for preprocessor
1102
+ testopts*:
1103
+ "python": { templateclass: tenjin.Preprocessor }
1104
+ "ruby": { templateclass: 'Tenjin::Preprocessor' }
1105
+ input*:
1106
+ "python": |
1107
+ <?PY def link_to(label, url): ?>
1108
+ <?PY import urllib ?>
1109
+ <?PY return '<a href="%s">%s</a>' % (urllib.quote(url), label) ?>
1110
+ <?PY # ?>
1111
+ #{{link_to('<b>Create</b>', '/items/create')}}
1112
+ #{{link_to('"Show '+_P("item['name']")+'"', '/items/show/'+_p("item['id']"))}}
1113
+ #{{escape('<b>'+_P('item["name"]')+'</b>')}}
1114
+ "ruby": |
1115
+ <?RB def link_to(label, url) ?>
1116
+ <?RB require 'cgi' ?>
1117
+ <?RB return '<a href="%s">%s</a>' % [CGI::escape(url).gsub(/%2F/,'/'), label] ?>
1118
+ <?RB end ?>
1119
+ #{{link_to('<b>Create</b>', '/items/create')}}
1120
+ #{{link_to('"Show '+_P('item["name"]')+'"', '/items/show/'+_p('item["id"]'))}}
1121
+ #{{escape('<b>'+_P('item["name"]')+'</b>')}}
1122
+ "perl": |
1123
+ <?PL sub link_to { ?>
1124
+ <?PL my($label, $url) = @_; ?>
1125
+ <?PL return sprintf('<a href="%s">%s</a>', Tenjin::Util::encode_url($url), $label); ?>
1126
+ <?PL } ?>
1127
+ [%==link_to('<b>Create</b>', '/items/create')=%]
1128
+ [%==link_to('"Show '._P('$item->{"name"}').'"', '/items/show/'._p('$item->{"id"}'))=%]
1129
+ [%==escape('<b>'._P('$item->{"name"}').'</b>')=%]
1130
+ "js": |
1131
+ <?JS function link_to(label, url) { ?>
1132
+ <?JS return '<a href="'+encodeURI(url)+'>'+label+'</a>'; ?>
1133
+ <?JS } ?>
1134
+ #{{link_to('<b>Create</b>', '/items/create')}}
1135
+ #{{link_to('"Show '+_P('item["name"]')+'"', '/items/show/'+_p('item["id"]'))}}
1136
+ #{{escapeXml('<b>'+_P('item["name"]')+'</b>')}}
1137
+ source*:
1138
+ "python": |
1139
+ def link_to(label, url):
1140
+ import urllib
1141
+ return '<a href="%s">%s</a>' % (urllib.quote(url), label)
1142
+ #
1143
+ _buf.extend((to_str(_decode_params(link_to('<b>Create</b>', '/items/create'))), '''
1144
+ ''', to_str(_decode_params(link_to('"Show '+_P("item['name']")+'"', '/items/show/'+_p("item['id']")))), '''
1145
+ ''', to_str(_decode_params(escape('<b>'+_P('item["name"]')+'</b>'))), '''\n''', ));
1146
+ "ruby": |
1147
+ def link_to(label, url)
1148
+ require 'cgi'
1149
+ return '<a href="%s">%s</a>' % [CGI::escape(url).gsub(/%2F/,'/'), label]
1150
+ end
1151
+ _buf << %Q`#{_decode_params((link_to('<b>Create</b>', '/items/create')))}
1152
+ #{_decode_params((link_to('"Show '+_P('item["name"]')+'"', '/items/show/'+_p('item["id"]'))))}
1153
+ #{_decode_params((escape('<b>'+_P('item["name"]')+'</b>')))}\n`
1154
+ "perl": |
1155
+ my @_buf = (); sub link_to {
1156
+ my($label, $url) = @_;
1157
+ return sprintf('<a href="%s">%s</a>', Tenjin::Util::encode_url($url), $label);
1158
+ }
1159
+ push(@_buf, Tenjin::Util::_decode_params(link_to('<b>Create</b>', '/items/create')), q`
1160
+ `, Tenjin::Util::_decode_params(link_to('"Show '._P('$item->{"name"}').'"', '/items/show/'._p('$item->{"id"}'))), q`
1161
+ `, Tenjin::Util::_decode_params(escape('<b>'._P('$item->{"name"}').'</b>')), q`
1162
+ `, ); join('', @_buf);
1163
+ "js": |
1164
+ var _buf = []; function link_to(label, url) {
1165
+ return '<a href="'+encodeURI(url)+'>'+label+'</a>';
1166
+ }
1167
+ _buf.push(Tenjin._decode_params(link_to('<b>Create</b>', '/items/create')), '\n\
1168
+ ', Tenjin._decode_params(link_to('"Show '+_P('item["name"]')+'"', '/items/show/'+_p('item["id"]'))), '\n\
1169
+ ', Tenjin._decode_params(escapeXml('<b>'+_P('item["name"]')+'</b>')), '\n');
1170
+ _buf.join('')
1171
+ expected*:
1172
+ "python": |
1173
+ <a href="/items/create"><b>Create</b></a>
1174
+ <a href="/items/show/#{item['id']}">"Show ${item['name']}"</a>
1175
+ &lt;b&gt;${item["name"]}&lt;/b&gt;
1176
+ "ruby": |
1177
+ <a href="/items/create"><b>Create</b></a>
1178
+ <a href="/items/show/#{item["id"]}">"Show ${item["name"]}"</a>
1179
+ &lt;b&gt;${item["name"]}&lt;/b&gt;
1180
+ "perl": |
1181
+ <a href="/items/create"><b>Create</b></a>
1182
+ <a href="/items/show/[==$item->{"id"}=]">"Show [=$item->{"name"}=]"</a>
1183
+ &lt;b&gt;[=$item->{"name"}=]&lt;/b&gt;
1184
+ "js": |
1185
+ <a href="/items/create><b>Create</b></a>
1186
+ <a href="/items/show/#{item["id"]}>"Show ${item["name"]}"</a>
1187
+ &lt;b&gt;${item["name"]}&lt;/b&gt;
1188
+ context: { item: { id: 101, name: foo } }
1189
+ # expected: |
1190
+ # <a href="/items/create"><b>Create</b></a>
1191
+ # <a href="/items/show/#{item['id']}">"Show ${item['name']}"</a>
1192
+ # &lt;b&gt;${item['name']}&lt;/b&gt;
1193
+
1194
+ ##
1195
+ - name: smarttrim1
1196
+ desc: smarttrim option
1197
+ disabled*:
1198
+ "python": false
1199
+ "ruby": true
1200
+ options*:
1201
+ "python": { smarttrim: true }
1202
+ "ruby":
1203
+ input*:
1204
+ "python": |
1205
+ #{"A"}
1206
+ #{"B"}
1207
+ #{"C"}
1208
+ foo#{"D"}
1209
+ #{"E"}bar
1210
+ #{"F"}#{"G"}
1211
+ <?py if True: ?>
1212
+ #{"H"}
1213
+ #{"I"}
1214
+ #{"J"}
1215
+ <?py #end ?>
1216
+ ${"K"}
1217
+ ${"L"}
1218
+ #{"M"}
1219
+ "ruby": |
1220
+ source*:
1221
+ "python": |
1222
+ _buf.extend((to_str("A"),
1223
+ to_str("B"),
1224
+ to_str("C"),
1225
+ '''foo''', to_str("D"), '''
1226
+ ''', to_str("E"), '''bar
1227
+ ''', to_str("F"), to_str("G"), ));
1228
+ if True:
1229
+ _buf.extend((to_str("H"),
1230
+ to_str("I"),
1231
+ to_str("J"), ));
1232
+ #end
1233
+ _buf.extend((escape(to_str("K")), '''
1234
+ ''', escape(to_str("L")), '''
1235
+ ''', to_str("M"), ));
1236
+ "ruby": |
1237
+ expected*:
1238
+ "python": |-
1239
+ ABCfooD
1240
+ Ebar
1241
+ FGHIJK
1242
+ L
1243
+ M
1244
+ "ruby": |