tenjin 0.6.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.
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": |