amrita2 1.9.6 → 2.0.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 (112) hide show
  1. data/README +112 -0
  2. data/init.rb +6 -0
  3. data/lib/amrita2/gettext.rb +116 -0
  4. data/lib/amrita2/macro.rb +153 -0
  5. data/lib/amrita2/rails_bridge.rb +172 -26
  6. data/lib/amrita2/template.rb +2634 -234
  7. data/lib/amrita2/testsupport.rb +171 -0
  8. data/lib/amrita2/version.rb +3 -3
  9. data/lib/amrita2.rb +1 -0
  10. data/sample/depot/app/controllers/admin_controller.rb +59 -0
  11. data/sample/depot/app/controllers/application.rb +20 -0
  12. data/sample/depot/app/controllers/info_controller.rb +19 -0
  13. data/sample/depot/app/controllers/login_controller.rb +85 -0
  14. data/sample/depot/app/controllers/store_controller.rb +68 -0
  15. data/sample/depot/app/helpers/admin_helper.rb +7 -0
  16. data/sample/depot/app/helpers/application_helper.rb +10 -0
  17. data/sample/depot/app/helpers/ar_form.rb +169 -0
  18. data/sample/depot/app/helpers/form_tag.rb +24 -0
  19. data/sample/depot/app/helpers/info_helper.rb +7 -0
  20. data/sample/depot/app/helpers/standard_form.rb +73 -0
  21. data/sample/depot/app/helpers/store_helper.rb +14 -0
  22. data/sample/depot/app/models/cart.rb +36 -0
  23. data/sample/depot/app/models/cart_item.rb +26 -0
  24. data/sample/depot/app/models/line_item.rb +34 -0
  25. data/sample/depot/app/models/order.rb +57 -0
  26. data/sample/depot/app/models/product.rb +41 -0
  27. data/sample/depot/app/models/user.rb +83 -0
  28. data/sample/depot/config/boot.rb +49 -0
  29. data/sample/depot/config/environment.rb +83 -0
  30. data/sample/depot/config/environments/development.rb +24 -0
  31. data/sample/depot/config/environments/production.rb +24 -0
  32. data/sample/depot/config/environments/test.rb +24 -0
  33. data/sample/depot/config/routes.rb +10 -0
  34. data/sample/depot/db/migrate/001_create_products.rb +18 -0
  35. data/sample/depot/db/migrate/002_add_price.rb +14 -0
  36. data/sample/depot/db/migrate/003_add_test_data.rb +68 -0
  37. data/sample/depot/db/migrate/004_add_sessions.rb +20 -0
  38. data/sample/depot/db/migrate/005_create_orders.rb +21 -0
  39. data/sample/depot/db/migrate/006_create_line_items.rb +27 -0
  40. data/sample/depot/db/migrate/007_create_users.rb +18 -0
  41. data/sample/depot/db/schema.rb +45 -0
  42. data/sample/depot/public/dispatch.rb +15 -0
  43. data/sample/depot/test/functional/admin_controller_test.rb +54 -0
  44. data/sample/depot/test/functional/info_controller_test.rb +23 -0
  45. data/sample/depot/test/functional/login_controller_test.rb +74 -0
  46. data/sample/depot/test/functional/store_controller_test.rb +57 -0
  47. data/sample/depot/test/integration/dsl_user_stories_test.rb +126 -0
  48. data/sample/depot/test/integration/user_stories_test.rb +70 -0
  49. data/sample/depot/test/performance/order_speed_test.rb +58 -0
  50. data/sample/depot/test/test_helper.rb +16 -0
  51. data/sample/depot/test/unit/cart_test.rb +39 -0
  52. data/sample/depot/test/unit/cart_test1.rb +31 -0
  53. data/sample/depot/test/unit/line_item_test.rb +15 -0
  54. data/sample/depot/test/unit/order_test.rb +15 -0
  55. data/sample/depot/test/unit/product_test.rb +98 -0
  56. data/sample/depot/vendor/plugins/amrita2/init.rb +6 -0
  57. data/sample/hello/hello.rb +22 -0
  58. data/sample/login_engine/app/controllers/application.rb +16 -0
  59. data/sample/login_engine/app/controllers/user_controller.rb +265 -0
  60. data/sample/login_engine/app/helpers/application_helper.rb +3 -0
  61. data/sample/login_engine/app/helpers/form_tag.rb +16 -0
  62. data/sample/login_engine/app/helpers/two_columns.rb +24 -0
  63. data/sample/login_engine/app/helpers/two_columns_form.rb +47 -0
  64. data/sample/login_engine/app/helpers/user_helper.rb +88 -0
  65. data/sample/login_engine/app/models/user.rb +7 -0
  66. data/sample/login_engine/app/models/user_notify.rb +75 -0
  67. data/sample/login_engine/config/boot.rb +45 -0
  68. data/sample/login_engine/config/environment.rb +140 -0
  69. data/sample/login_engine/config/environments/development.rb +21 -0
  70. data/sample/login_engine/config/environments/production.rb +18 -0
  71. data/sample/login_engine/config/environments/test.rb +19 -0
  72. data/sample/login_engine/config/routes.rb +23 -0
  73. data/sample/login_engine/db/migrate/001_create_users.rb +25 -0
  74. data/sample/login_engine/db/schema.rb +25 -0
  75. data/sample/login_engine/lib/config.rb +113 -0
  76. data/sample/login_engine/lib/hpricot_test_extension.rb +80 -0
  77. data/sample/login_engine/lib/login_engine/authenticated_system.rb +113 -0
  78. data/sample/login_engine/lib/login_engine/authenticated_user.rb +155 -0
  79. data/sample/login_engine/lib/login_engine.rb +62 -0
  80. data/sample/login_engine/public/dispatch.rb +10 -0
  81. data/sample/login_engine/test/functional/amrita2_test.rb +267 -0
  82. data/sample/login_engine/test/functional/user_controller_test.rb +544 -0
  83. data/sample/login_engine/test/mocks/mail.rb +14 -0
  84. data/sample/login_engine/test/mocks/time.rb +19 -0
  85. data/sample/login_engine/test/test_helper.rb +31 -0
  86. data/sample/login_engine/test/unit/user_test.rb +116 -0
  87. data/sample/login_engine/vendor/plugins/amrita2/init.rb +6 -0
  88. data/specs/attribute.rb +201 -0
  89. data/specs/datatypes.rb +231 -0
  90. data/specs/dictionary.rb +68 -0
  91. data/specs/erb_cdata.rb +187 -0
  92. data/specs/filters.rb +513 -0
  93. data/specs/gettext/erb_gettext.rb +42 -0
  94. data/specs/gettext/gettext_util.rb +65 -0
  95. data/specs/gettext/static_text.rb +103 -0
  96. data/specs/impl/code_generator.rb +87 -0
  97. data/specs/impl/dynamic_element.rb +92 -0
  98. data/specs/impl/hash_delegator.rb +57 -0
  99. data/specs/impl/parse_opt.rb +34 -0
  100. data/specs/impl/preprocess.rb +823 -0
  101. data/specs/impl/testsupport.rb +89 -0
  102. data/specs/inlineruby.rb +429 -0
  103. data/specs/intro.rb +654 -0
  104. data/specs/loop.rb +203 -0
  105. data/specs/macro.rb +532 -0
  106. data/specs/sample.rb +34 -0
  107. data/specs/sanitize.rb +110 -0
  108. data/specs/template.rb +189 -0
  109. data/specs/trace.rb +97 -0
  110. metadata +138 -19
  111. data/lib/amrita2/core.rb +0 -1897
  112. data/lib/amrita2/rd.rb +0 -314
@@ -0,0 +1,823 @@
1
+
2
+ require 'rexml/element'
3
+ require 'amrita2'
4
+ require 'amrita2/testsupport'
5
+
6
+ context "amxml parser" do
7
+ include Amrita2
8
+
9
+ it "tag only" do
10
+ amxml = Amrita2::Core::PreProcessor::AmXml
11
+ a = amxml.parse(%[a])
12
+ a.tag.should == "a"
13
+ a.attr.should == ""
14
+ a.should_not be_has_amxml_attrs
15
+ end
16
+
17
+ specify "tag with namespace only" do
18
+ amxml = Amrita2::Core::PreProcessor::AmXml
19
+ a = amxml.parse(%[xx:a/])
20
+ a.tag.should == "xx:a"
21
+ a.attr.should == ""
22
+ a.should_not be_has_amxml_attrs
23
+
24
+ a = amxml.parse(%[xx:a])
25
+ a.tag.should == "xx"
26
+ a.attr.should == ""
27
+ a.should be_has_amxml_attrs
28
+ a.src_name.should == "a"
29
+
30
+ a = amxml.parse(%[xx:a b="c"])
31
+ a.tag.should == "xx:a"
32
+ a.attr.should == ' b="c"'
33
+ a.should_not be_has_amxml_attrs
34
+ end
35
+
36
+ specify "tag and attrs" do
37
+ amxml = Amrita2::Core::PreProcessor::AmXml
38
+ a = amxml.parse(%[a href="http://amrita2.rubyforge.org/"])
39
+ a.tag.should == "a"
40
+ a.attr.should == %[ href="http://amrita2.rubyforge.org/"]
41
+ a.should_not be_has_amxml_attrs
42
+ a = amxml.parse(%[a href='http://amrita2.rubyforge.org/'])
43
+ a.tag.should == "a"
44
+ a.attr.should == %[ href='http://amrita2.rubyforge.org/']
45
+ a.should_not be_has_amxml_attrs
46
+
47
+ a = amxml.parse(%[a href='http://amrita2.rubyforge.org/' class="xxx"])
48
+ a.tag.should == "a"
49
+ a.attr.should == %[ href='http://amrita2.rubyforge.org/' class="xxx"]
50
+ a.should_not be_has_amxml_attrs
51
+
52
+ a = amxml.parse(%[a href = 'http://amrita2.rubyforge.org/' class = "xxx"])
53
+ a.tag.should == "a"
54
+ a.attr.should == %[ href = 'http://amrita2.rubyforge.org/' class = "xxx"]
55
+ a.should_not be_has_amxml_attrs
56
+
57
+ a = amxml.parse(%[x:a y:href='http://amrita2.rubyforge.org/' zz:class="xxx"])
58
+ a.tag.should == "x:a"
59
+ a.attr.should == %[ y:href='http://amrita2.rubyforge.org/' zz:class="xxx"]
60
+ a.should_not be_has_amxml_attrs
61
+ end
62
+
63
+ specify "src" do
64
+ amxml = Amrita2::Core::PreProcessor::AmXml
65
+ a = amxml.parse(%[:xxx])
66
+ a.tag.should == "_"
67
+ a.attr.should == ""
68
+ a.should be_has_amxml_attrs
69
+ a.src_name.should == "xxx"
70
+
71
+ a = amxml.parse(%[a:xxx])
72
+ a.tag.should == "a"
73
+ a.attr.should == ""
74
+ a.should be_has_amxml_attrs
75
+ a.src_name.should == "xxx"
76
+ end
77
+
78
+ specify "src and filters" do
79
+ amxml = Amrita2::Core::PreProcessor::AmXml
80
+ a = amxml.parse(%[a:xxx|Attr])
81
+ a.tag.should == "a"
82
+ a.attr.should == ""
83
+ a.should be_has_amxml_attrs
84
+ a.src_name.should == "xxx"
85
+ a.filters.should == "Attr"
86
+
87
+ a = amxml.parse(%[a:xxx| \n Attr])
88
+ a.tag.should == "a"
89
+ a.attr.should == ""
90
+ a.should be_has_amxml_attrs
91
+ a.src_name.should == "xxx"
92
+ a.filters.should == "Attr"
93
+ end
94
+
95
+ specify "loop" do
96
+ amxml = Amrita2::Core::PreProcessor::AmXml
97
+ a = amxml.parse(%[ [1..5] ])
98
+ a.tag.should == "_"
99
+ a.attr.should == ""
100
+ a.should be_has_amxml_attrs
101
+ a.src_name.should == nil
102
+ a.filters.should == nil
103
+ a.for.should == %[1..5]
104
+
105
+ a = amxml.parse(%[a [1..5] ])
106
+ a.tag.should == "a"
107
+ a.attr.should == ""
108
+ a.should be_has_amxml_attrs
109
+ a.src_name.should == nil
110
+ a.filters.should == nil
111
+ a.for.should == %[1..5]
112
+ end
113
+
114
+ specify "cond" do
115
+ amxml = Amrita2::Core::PreProcessor::AmXml
116
+ '?![a == 1]'.should match(%r[#{ amxml::S_AMVARS}])
117
+ a = amxml.parse(%[a ?![a == 1] ])
118
+ a.tag.should == "a"
119
+ a.attr.should == ""
120
+ a.should be_has_amxml_attrs
121
+ a.src_name.should == nil
122
+ a.filters.should == nil
123
+ a.skipif.should == "a == 1"
124
+
125
+ a = amxml.parse(%[a ?[ b == 1 ] ])
126
+ a.tag.should == "a"
127
+ a.attr.should == ""
128
+ a.should be_has_amxml_attrs
129
+ a.src_name.should == nil
130
+ a.filters.should == nil
131
+ a.skipif.should == nil
132
+ a.skipunless.should == "b == 1"
133
+ end
134
+
135
+ specify "value" do
136
+ amxml = Amrita2::Core::PreProcessor::AmXml
137
+ a = amxml.parse(%[a { :xxx=>1 }])
138
+ a.tag.should == "a"
139
+ a.attr.should == ""
140
+ a.should be_has_amxml_attrs
141
+ a.src_name.should == nil
142
+ a.filters.should == nil
143
+ a.value.should == ":xxx=>1"
144
+ end
145
+
146
+ specify "result" do
147
+ amxml = Amrita2::Core::PreProcessor::AmXml
148
+ amxml.parse(%[a { :xxx=>1 }]).result(true).should == %[<a am:v='HashDelegator.new($_) { {:xxx=>1} }' />]
149
+ amxml.parse(%[a href="xxx" { :xxx=>1 }]).result(true).should == %[<a am:v='HashDelegator.new($_) { {:xxx=>1} }' href="xxx" />]
150
+ amxml.parse(%[a ?[a == 1]]).result(true).should == %[<a am:skipif='not(a == 1)' />]
151
+ amxml.parse(%[a:xxx|Attr]).result(true).should == %[<a am:src='xxx|Attr' />]
152
+ amxml.parse(%[tr:clients|NVar[:surname, :firstname, :email]]).result(false).should ==
153
+ %[<tr am:src='clients|NVar[:surname, :firstname, :email]' >]
154
+ amxml.parse(%[ [1..5] ]).result(false).should ==
155
+ %[<_ am:for='1..5' >]
156
+ amxml.parse("tr:clients \n |NVar[:surname, :firstname, :email]").result(false).should ==
157
+ "<tr am:src='clients|NVar[:surname, :firstname, :email]' >"
158
+ end
159
+ end
160
+
161
+ context "preprocessor" do
162
+ include Amrita2
163
+ specify "check CDATA regexp" do
164
+ t = "aaa<![CDATA[bbb"
165
+ t =~ %r[(.*?)(<!\[CDATA\[)(.*)]
166
+ $1.should == "aaa"
167
+ $2.should == "<![CDATA["
168
+ $3.should == "bbb"
169
+ (t+t) =~ %r[(.*?)(<!\[CDATA\[)(.*)]
170
+ $1.should == "aaa"
171
+ $2.should == "<![CDATA["
172
+ $3.should == "bbb" + t
173
+ $3 =~ %r[(.*?)(<!\[CDATA\[)(.*)]
174
+ $1.should == "bbbaaa"
175
+ $2.should == "<![CDATA["
176
+ $3.should == "bbb"
177
+ end
178
+
179
+ specify "check regexp"do
180
+ tag = %r[\w*]
181
+ attr = %r[(?:\s*\w+=(?:".*?"|'.*?'))*] #"
182
+ src_start = %r[(?::| \[|\?\[|\{)]
183
+ r = %r[^\s*<<\s*(#{tag})(#{attr})(#{src_start}(.*?))?<\s*$]
184
+ "<<<".should match(r)
185
+ "<<p<".should match(r)
186
+ "<<p:title<".should match(r)
187
+ "<<p:title [1..5]<".should match(r)
188
+ "<<p:title ?[$_ == 1]<".should match(r)
189
+ "<<p:title { :val => 2}<".should match(r)
190
+ "<<:title<".should match(r)
191
+ "<<:title [1..5]<".should match(r)
192
+ "<<:title ?[$_ == 1]<".should match(r)
193
+ "<<:title { :val => 2}<".should match(r)
194
+ "<< [1..5]<".should match(r)
195
+ "<< ?[$_ == 1]<".should match(%r[(<< #{src_start}(.*?)?<$)])
196
+ "<< ?[$_ == 1]<".should match(r)
197
+ "<<{ :val => 2}<".should match(r)
198
+ " <<li< ".should match(r)
199
+ end
200
+
201
+ specify "preprocessor" do
202
+ p = Amrita2::Core::PreProcessor.new
203
+ ret = p.process("aaa<![")
204
+ ret.should == "aaa<!["
205
+ proc {p.process("aaa<![CDATA[")}.should raise_error(RuntimeError)
206
+ ret = p.process("aaa<![CDATA[bbb]]>ccc")
207
+ ret.should == "aaa<![CDATA[bbb]]>ccc"
208
+ ret = p.process("aaa<![CDATA[bbb]]>cccAAA<![CDATA[BBB]]>CCC")
209
+ ret.should == "aaa<![CDATA[bbb]]>cccAAA<![CDATA[BBB]]>CCC"
210
+ end
211
+
212
+ specify "replace <% %>" do
213
+ p = Amrita2::Core::PreProcessor.new
214
+ ret = p.process("<%aaa%>")
215
+ ret.should == "<![CDATA[<%aaa%>]]>"
216
+ ret = p.process("a<%b%>c<%d%>e")
217
+ ret.should == "a<![CDATA[<%b%>]]>c<![CDATA[<%d%>]]>e"
218
+ end
219
+
220
+ specify "replace <%= %>" do
221
+ p = Amrita2::Core::PreProcessor.new
222
+ ret = p.process("<%=aaa%>")
223
+ ret.should == "<![CDATA[<%=aaa%>]]>"
224
+ ret = p.process("a<%b%>c<%=d%>e")
225
+ ret.should == "a<![CDATA[<%b%>]]>c<![CDATA[<%=d%>]]>e"
226
+ end
227
+
228
+ specify "don't replace <%= %> in cdata" do
229
+ p = Amrita2::Core::PreProcessor.new
230
+ ret = p.process("<![CDATA[<%=aaa%>]]>")
231
+ ret.should == "<![CDATA[<%=aaa%>]]>"
232
+ ret = p.process("a<%=b%>c<![CDATA[<%d%>]]>e")
233
+ ret.should == "a<![CDATA[<%=b%>]]>c<![CDATA[<%d%>]]>e"
234
+
235
+ s = <<-END
236
+ <![CDATA[
237
+ <% a = 1 %>
238
+ 1 + 2 = <%= a + 2 %>
239
+ ]]>
240
+ END
241
+ p.process(s).should == s
242
+ end
243
+
244
+ specify "not replace <%= %> in cdata in real" do
245
+ text = <<-'END'
246
+ <ul>
247
+ <li am:foreach="data" am:if='$_.name =~ /amrita/'>
248
+ <![CDATA[
249
+ <%
250
+ name = $_.name
251
+ description = ($_.description or $_.name)
252
+ %>
253
+ <a href="http://raa.ruby-lang.org/list.rhtml?name=<%= name %>"><%= description %></a>
254
+ ]]>
255
+ </li>
256
+ </ul>
257
+ END
258
+ ret = Amrita2::Core::PreProcessor.new.process(text)
259
+
260
+ text.should == ret
261
+ end
262
+
263
+ specify "section" do
264
+ pp = Amrita2::Core::PreProcessor.new
265
+ ret = pp.process("aaa<%(Section1)xxx%>bbb")
266
+ ret.should == "aaabbb"
267
+ pp.sections[:Section1].should == "xxx"
268
+ end
269
+
270
+ specify "section and cdata" do
271
+ pp = Amrita2::Core::PreProcessor.new
272
+ ret = pp.process("aaa<%(Section1)xxx%>bbb<%ccc%>ddd")
273
+ ret.should == "aaabbb<![CDATA[<%ccc%>]]>ddd"
274
+ pp.sections[:Section1].should == "xxx"
275
+ end
276
+
277
+ specify "two sections and cdata" do
278
+ pp = Amrita2::Core::PreProcessor.new
279
+ ret = pp.process("aaa<%(Section1)xxx%>bbb<%ccc%>ddd<%(Section2)yyy%>eee")
280
+ ret.should == "aaabbb<![CDATA[<%ccc%>]]>dddeee"
281
+ pp.sections[:Section1].should == "xxx"
282
+ pp.sections[:Section2].should == "yyy"
283
+ end
284
+
285
+ specify "two sections and cdata with nest" do
286
+ pp = Amrita2::Core::PreProcessor.new
287
+ ret = pp.process("aaa<%(Section1)<%=1%>xxx%>bbb<%%<%=2%>ccc%>ddd<%(Section2)<%=3%>yyy%>eee")
288
+ ret.should == "aaabbb<![CDATA[<%%<%=2%>ccc%>]]>dddeee"
289
+ pp.sections[:Section1].should == "<%=1%>xxx"
290
+ pp.sections[:Section2].should == "<%=3%>yyy"
291
+ end
292
+
293
+ specify "nbsp" do
294
+ pp = Amrita2::Core::PreProcessor.new
295
+ ret = pp.process("&nbsp; &amp;")
296
+ ret.should == "&nbsp; &amp;"
297
+ end
298
+ end
299
+
300
+
301
+ context "amxml inline" do
302
+ include Amrita2
303
+
304
+ specify "inline" do
305
+ p = Amrita2::Core::PreProcessor.new
306
+ ret = p.process("<<a>>") #"
307
+ ret.should == "<a />"
308
+ ret = p.process("<<a:xxx>>")
309
+ ret.should == "<a am:src='xxx' />"
310
+ ret = p.process("<<p class='text':aaa>>")
311
+ ret.should == "<p am:src='aaa' class='text' />"
312
+ ret = p.process("<<a href='http://amrita2.rubyforge.org/':xxx>>")
313
+ ret.should == "<a am:src='xxx' href='http://amrita2.rubyforge.org/' />"
314
+ ret = p.process(%[<<a href="http://amrita2.rubyforge.org/":xxx>>])
315
+ ret.should == %[<a am:src='xxx' href="http://amrita2.rubyforge.org/" />]
316
+
317
+ p.process("<<h3:title>>").should == "<h3 am:src='title' />"
318
+ p.process("<<h3 class='title':title>>").should == "<h3 am:src='title' class='title' />"
319
+ end
320
+
321
+ specify "inline skipif" do
322
+ p = Amrita2::Core::PreProcessor.new
323
+ ret = p.process("<<a ?[a == 1]>>")
324
+ ret.should == "<a am:skipif='not(a == 1)' />"
325
+ ret = p.process("<<a ?![a == 1]>>")
326
+ ret.should == "<a am:skipif='a == 1' />"
327
+ end
328
+
329
+ specify "inline anonymous tag" do
330
+ p = Amrita2::Core::PreProcessor.new
331
+ ret = p.process("<<:xxx>>")
332
+ ret.should == "<_ am:src='xxx' />"
333
+ end
334
+
335
+ specify "inline filter" do
336
+ r = %r[#{Amrita2::Core::PreProcessor::AmXml::S_SRC_AND_FILTERS }]
337
+ ":a|A|B".should match(r)
338
+ ":a|A[aaa]|B[abb]".should match(r)
339
+
340
+ p = Amrita2::Core::PreProcessor.new
341
+
342
+
343
+ ret = p.process(%[<<a:xxx|Attr[:href=>:url, :body=>:description]>>])
344
+ ret.should == %[<a am:src='xxx|Attr[:href=>:url, :body=>:description]' />]
345
+ ret = p.process(%[<<a:xxx|Attr[:href=>:url, :body=>:description]>>])
346
+ ret.should == %[<a am:src='xxx|Attr[:href=>:url, :body=>:description]' />]
347
+
348
+ ret = p.process(%[<<a:|Attr[:href=>:url, :body=>:description]>>])
349
+ ret.should == %[<a am:filter='Attr[:href=>:url, :body=>:description]' />]
350
+
351
+ ret = p.process(%[<<:|Each[:class=>[:odd, :even]]|Attr[:class,:body=>:no]>>])
352
+ ret.should == %[<_ am:filter='Each[:class=>[:odd, :even]]|Attr[:class,:body=>:no]' />]
353
+ ret = p.process(%[<<:|Each[:class=>[:odd, :even]]|\nAttr[:class,:body=>:no]>>])
354
+ ret.should == %[<_ am:filter='Each[:class=>[:odd, :even]]|\nAttr[:class,:body=>:no]' />]
355
+ ret = p.process(%[<<a:website\|Attr>>])
356
+ ret.should == %[<a am:src='website|Attr' />]
357
+ end
358
+
359
+ specify "css selecter like" do
360
+ p = Amrita2::Core::PreProcessor.new
361
+
362
+ ret = p.process("<<aaa#bbb>><<ccc.ddd>>")
363
+ ret.should == '<aaa id="bbb" /><ccc class="ddd" />'
364
+ ret = p.process("<<a#bbb href=\"http://www.brain-tokyo.jp/index.html#a\">>")
365
+ ret.should == '<a href="http://www.brain-tokyo.jp/index.html#a" id="bbb" />'
366
+
367
+ ret = p.process("<<a.bbb#ccc href=\"http://www.brain-tokyo.jp/index.html#a\">>")
368
+ ret.should == '<a href="http://www.brain-tokyo.jp/index.html#a" class="bbb" id="ccc" />'
369
+ ret = p.process("<<a#bbb.ccc href=\"http://www.brain-tokyo.jp/index.html#a\">>")
370
+ ret.should == '<a href="http://www.brain-tokyo.jp/index.html#a" id="bbb" class="ccc" />'
371
+
372
+ ret = p.process("<<div.cart-title>>")
373
+ ret.should == '<div class="cart-title" />'
374
+ end
375
+ end
376
+
377
+ context "amxml block" do
378
+ include Amrita2
379
+
380
+ specify "simple" do
381
+
382
+ p = Amrita2::Core::PreProcessor.new
383
+ p.process(<<-END).should_be_samexml_as("<_ am:src='title' /> ")
384
+ <<:title>>
385
+ END
386
+
387
+ p = Amrita2::Core::PreProcessor.new
388
+ p.process(<<-END).should_be_samexml_as("<html>test</html>")
389
+ <<html<
390
+ test
391
+ END
392
+
393
+ p = Amrita2::Core::PreProcessor.new
394
+ p.process(<<-END).should_be_samexml_as('<div class="cart-title">test</div>')
395
+ <<div.cart-title<
396
+ test
397
+ END
398
+
399
+ p.process(<<-END).should_be_samexml_as(<<-END)
400
+ <<html<
401
+ <<body<
402
+ <p>12345</p>
403
+ END
404
+ <html><body><p>12345</p> </body></html>
405
+ END
406
+
407
+ p.process(<<-END).should_be_samexml_as(<<-END)
408
+ <<html<
409
+ <<head<
410
+ <title>title1</title>
411
+ <<body<
412
+ <p>12345</p>
413
+ END
414
+ <html>
415
+ <head><title>title1</title></head>
416
+ <body><p>12345</p></body>
417
+ </html>
418
+ END
419
+
420
+
421
+ p.process(<<-END).should_be_samexml_as("<div class='entry' am:src='products'><h3 am:src='title' /> </div>")
422
+ <<div class="entry":products<
423
+ <<h3:title>>
424
+ END
425
+
426
+ end
427
+
428
+ specify "src" do
429
+ p = Amrita2::Core::PreProcessor.new
430
+
431
+ p.process(<<-END).should_be_samexml_as(<<-END)
432
+ <<table<
433
+ <<tr:clients|NVar[:surname, :firstname, :email]<
434
+ <td>$1, $2</td>
435
+ <td><a href="mailto:$3">$3</a></td>
436
+ END
437
+ <table>
438
+ <tr am:src='clients|NVar[:surname, :firstname, :email]'>
439
+ <td>$1, $2</td>
440
+ <td><a href='mailto:$3'>$3</a></td>
441
+ </tr>
442
+ </table>
443
+ END
444
+ end
445
+
446
+ specify "for" do
447
+ p = Amrita2::Core::PreProcessor.new
448
+
449
+ p.process(<<-END).should_be_samexml_as(<<-END)
450
+ << [1..5] <
451
+ abc
452
+ END
453
+ <_ am:for='1..5'>abc</_>
454
+ END
455
+ end
456
+
457
+ specify "for and cond" do
458
+ p = Amrita2::Core::PreProcessor.new
459
+
460
+ p.process(<<-END).should_be_samexml_as(<<-END)
461
+ << [1..5] <
462
+ << ?[ ($_%2) == 0] <
463
+ abc
464
+ END
465
+ <_ am:for='1..5'>\n<_ am:skipif='not(($_%2) == 0)'>abc</_>\n</_>
466
+ END
467
+ end
468
+
469
+ specify "for and cond and value" do
470
+ p = Amrita2::Core::PreProcessor.new
471
+
472
+ p.process(<<-END).should_be_samexml_as(<<-END)
473
+ << [1..5] <
474
+ << ?[ ($_%2) == 0] <
475
+ << { :no => $_, :square=> $_*$_ }<
476
+ <<li<
477
+ <<:no>> * <<:no>> = <<:square>>
478
+ END
479
+ <_ am:for='1..5'>
480
+ <_ am:skipif='not(($_%2) == 0)'>
481
+ <_ am:v='HashDelegator.new($_) { {:no => $_, :square=> $_*$_} }'>
482
+ <li>
483
+ <_ am:src='no' />*<_ am:src='no' />=<_ am:src='square' />
484
+ </li>
485
+ </_>
486
+ </_>
487
+ </_>
488
+ END
489
+ end
490
+
491
+ specify "filter and value" do
492
+ p = Amrita2::Core::PreProcessor.new
493
+
494
+ p.process(<<-END).should_be_samexml_as(<<-END)
495
+ <<div#cart
496
+ {
497
+ :style => @cart.items.empty? ? "display: none" : nil
498
+ } <
499
+ %= render(:partial => "cart", :object => @cart)
500
+
501
+ END
502
+ <div am:v='HashDelegator.new($_) { {:style => @cart.items.empty? ? "display: none" : nil} }' id="cart">
503
+ <![CDATA[<%
504
+ _erbout.concat(eval(%{ render(:partial => "cart", :object => @cart)}).to_s)
505
+ %>]]>
506
+ </div>
507
+ END
508
+ end
509
+
510
+ specify "multi line" do
511
+ p = Amrita2::Core::PreProcessor.new
512
+
513
+ p.process(<<-END).should_be_samexml_as(<<-END)
514
+ <<table<
515
+ <<tr:clients
516
+ |NVar[:surname, :firstname, :email]<
517
+ <td>$1, $2</td>
518
+ <td><a href="mailto:$3">$3</a></td>
519
+ END
520
+ <table>
521
+ <tr am:src='clients|NVar[:surname, :firstname, :email]'>
522
+ <td>$1, $2</td>
523
+ <td><a href='mailto:$3'>$3</a></td>
524
+ </tr>
525
+ </table>
526
+ END
527
+
528
+ p.process(<<-END).should_be_samexml_as(<<-END)
529
+ <<table<
530
+ <<tr:lang_list
531
+ |ToHash[:name=>:name, :author=>:author]
532
+ |Each[:class=>["odd", "even"]]
533
+ |Attr[:class] <
534
+ <td />
535
+ END
536
+ <table>
537
+ <tr am:src='lang_list|ToHash[:name=>:name, :author=>:author]
538
+ |Each[:class=>[\"odd\", \"even\"]]
539
+ |Attr[:class]'>
540
+ <td />
541
+ </tr>
542
+ </table>
543
+ END
544
+ end
545
+
546
+ specify "inline ruby" do
547
+ p = Amrita2::Core::PreProcessor.new
548
+ expected = <<-END
549
+ <_ am:for='1..5'>
550
+ <_ am:skipif='not(($_%2) == 0)'>
551
+ <_ am:v='HashDelegator.new($_) { {:no => $_,\n :square=> $_*$_} }'>
552
+ <li>
553
+ <_ am:src='no' />*<_ am:src='no' />=<_ am:src='square' />
554
+ </li>
555
+ </_>
556
+ </_>
557
+ </_>
558
+ END
559
+
560
+ a = p.process(<<-END)
561
+ <<
562
+ [1..5] <
563
+ <<?[ ($_%2) == 0
564
+
565
+ ] <
566
+ << {
567
+ :no => $_,
568
+ :square=> $_*$_
569
+ } <
570
+
571
+ <<li<
572
+ <<:no>> * <<:no>> = <<:square>>
573
+ END
574
+ a.should_be_samexml_as(expected)
575
+ a = p.process(<<-END)
576
+ << [1..5] <
577
+ << ?[ ($_%2) == 0] <
578
+ << { :no => $_, :square=> $_*$_ }<
579
+ <<li<
580
+ <<:no>> * <<:no>> = <<:square>>
581
+ END
582
+ a.gsub(/\s+/m, ' ').should_be_samexml_as(expected.gsub(/\s+/m, ' '))
583
+ end
584
+ end
585
+
586
+ context "amxml erb" do
587
+ include Amrita2
588
+
589
+ specify "simple" do
590
+ p = Amrita2::Core::PreProcessor.new
591
+
592
+ p.process(<<-END).should == (<<-END).strip
593
+ <<div<
594
+ % a = 1
595
+ END
596
+ <div ><![CDATA[<%
597
+ a = 1
598
+ %>]]>
599
+ </div>
600
+ END
601
+ p.process(<<-END).should == (<<-END).strip
602
+ <<div<
603
+ %= a + 1
604
+ END
605
+ <div ><![CDATA[<%
606
+ _erbout.concat(eval(%{ a + 1}).to_s)
607
+ %>]]>
608
+ </div>
609
+ END
610
+
611
+ p.process(<<-END).should_be_samexml_as(<<-END)
612
+ <<div<
613
+ % form_remote_tag :url => { :action => :add_to_cart, :id => $_ } do
614
+ %= submit_tag "Add to Cart"
615
+ % end
616
+ END
617
+ <div>
618
+ <% form_remote_tag :url => { :action => :add_to_cart, :id => $_ } do
619
+ _erbout.concat(eval(%{ submit_tag "Add to Cart" }).to_s)
620
+ end %>
621
+ </div>
622
+ END
623
+ end
624
+ end
625
+
626
+ context "cell processor" do
627
+ include Amrita2
628
+
629
+ specify "not cell" do
630
+ l = Amrita2::Core::PreProcessor::LineProcessor.new do |s|
631
+ s
632
+ end
633
+ l.parse_line("||aaa").should == false
634
+ l.cells.size.should == 0
635
+ end
636
+
637
+ specify "1 cell" do
638
+ l = Amrita2::Core::PreProcessor::LineProcessor.new do |s|
639
+ s
640
+ end
641
+ l.parse_line("|||aaa|")
642
+ l.cells.size.should == 1
643
+ c = l.cells.first
644
+ c[:text].should == "aaa"
645
+ c[:tag].should == :td
646
+ l.get_result_xml.should == "<td>aaa</td>"
647
+
648
+ l = Amrita2::Core::PreProcessor::LineProcessor.new do |s|
649
+ s
650
+ end
651
+ l.parse_line("|||aaa") # omit the last |
652
+ l.cells.size.should == 1
653
+ c = l.cells.first
654
+ c[:text].should == "aaa"
655
+ c[:tag].should == :td
656
+ l.get_result_xml.should == "<td>aaa</td>"
657
+ end
658
+
659
+ specify "1 cell with spaces" do
660
+ l = Amrita2::Core::PreProcessor::LineProcessor.new do |s|
661
+ s
662
+ end
663
+ l.parse_line("| ||aaa|").should == true
664
+ l.cells.size.should == 1
665
+ c = l.cells.first
666
+ c[:text].should == "aaa"
667
+ c[:tag].should == :td
668
+ l.get_result_xml.should == "<td>aaa</td>"
669
+ end
670
+
671
+ specify "2cell" do
672
+ l = Amrita2::Core::PreProcessor::LineProcessor.new do |s|
673
+ s
674
+ end
675
+ l.parse_line("|||aaa|bbb")
676
+ l.cells.size.should == 2
677
+ c = l.cells.first
678
+ c[:text].should == "aaa"
679
+ c[:tag].should == :td
680
+ c = l.cells[1]
681
+ c[:text].should == "bbb"
682
+ c[:tag].should == :td
683
+ l.get_result_xml.should == "<td>aaa</td><td>bbb</td>"
684
+ end
685
+ specify "th and 2cell" do
686
+ l = Amrita2::Core::PreProcessor::LineProcessor.new do |s|
687
+ s
688
+ end
689
+ l.parse_line("|||aaa||bbb|ccc|")
690
+ l.cells.size.should == 3
691
+ c = l.cells.first
692
+ c[:text].should == "aaa"
693
+ c[:tag].should == :th
694
+ c = l.cells[1]
695
+ c[:text].should == "bbb"
696
+ c[:tag].should == :td
697
+ l.get_result_xml.should == "<th>aaa</th><td>bbb</td><td>ccc</td>"
698
+ end
699
+
700
+ specify "1cell and id" do
701
+ l = Amrita2::Core::PreProcessor::LineProcessor.new do |s|
702
+ s
703
+ end
704
+ l.parse_line("|||aaa|")
705
+ l.parse_line("|id||xxx|")
706
+ l.cells.size.should == 1
707
+ c = l.cells.first
708
+ c[:text].should == "aaa"
709
+ c[:tag].should == :td
710
+ c["id"].should == "xxx"
711
+ l.get_result_xml.should == "<td id='xxx'>aaa</td>"
712
+ end
713
+
714
+ specify "1 cell 2 lines" do
715
+ l = Amrita2::Core::PreProcessor::LineProcessor.new do |s|
716
+ s
717
+ end
718
+ l.parse_line("|||aaa|")
719
+ l.parse_line("|||bbb|")
720
+ l.cells.size.should == 1
721
+ c = l.cells.first
722
+ c[:text].should == "aaa\nbbb"
723
+ c[:tag].should == :td
724
+ l.get_result_xml.should == "<td>aaa\nbbb</td>"
725
+ end
726
+
727
+ specify "proc" do
728
+ l = Amrita2::Core::PreProcessor::LineProcessor.new do |s|
729
+ "(#{s})"
730
+ end
731
+ l.parse_line("|||aaa|")
732
+ l.cells.size.should == 1
733
+ c = l.cells.first
734
+ c[:text].should == "aaa"
735
+ c[:tag].should == :td
736
+ l.get_result_xml.should == "<td>(aaa)</td>"
737
+ end
738
+
739
+ specify "real td cells" do
740
+ l = Amrita2::Core::PreProcessor::LineProcessor.new do |s|
741
+ s
742
+ end
743
+ l.parse_line(%[ |||$1, $2|<a href="mailto:$3">$3</a>|])
744
+ l.cells.size.should == 2
745
+ c = l.cells.first
746
+ c[:text].should == "$1, $2"
747
+ c[:tag].should == :td
748
+ l.get_result_xml.should == "<td>$1, $2</td><td><a href=\"mailto:$3\">$3</a></td>"
749
+ end
750
+
751
+ specify "filter in cell" do
752
+ l = Amrita2::Core::PreProcessor::LineProcessor.new do |s|
753
+ s
754
+ end
755
+ l.parse_line(%q[ |||<<a user\\|Attr[:href=>:url]>>|])
756
+ l.cells.size.should == 1
757
+ c = l.cells.first
758
+ c[:text].should == "<<a user|Attr[:href=>:url]>>"
759
+ c[:tag].should == :td
760
+ l.get_result_xml.should == "<td><<a user|Attr[:href=>:url]>></td>"
761
+ end
762
+ end
763
+
764
+ context "cell line" do
765
+ specify "1 cell" do
766
+ p = Amrita2::Core::PreProcessor.new
767
+ ret = p.process("|||aaa|")
768
+ ret.should == "<td>aaa</td>"
769
+ end
770
+
771
+ specify "table" do
772
+ p = Amrita2::Core::PreProcessor.new
773
+ ret = p.process <<-END
774
+ <<table<
775
+ <<tr:clients|NVar[:surname, :firstname, :email]<
776
+ |||$1, $2|<a href="mailto:$3">$3</a>|
777
+ END
778
+ ret.should_be_samexml_as <<-END
779
+ <table>
780
+ <tr am:src='clients|NVar[:surname, :firstname, :email]' >
781
+ <td>$1, $2</td>
782
+ <td><a href="mailto:$3">$3</a></td>
783
+ </tr>
784
+ </table>
785
+ END
786
+ end
787
+
788
+ specify "table with class" do
789
+ p = Amrita2::Core::PreProcessor.new
790
+ ret = p.process <<-END
791
+ <<table<
792
+ <<tr:clients|NVar[:surname, :firstname, :email]<
793
+ |class||cell1 |cell2 |
794
+ | ||$1, $2|<a href="mailto:$3">$3</a>|
795
+ END
796
+ ret.should_be_samexml_as <<-END
797
+ <table>
798
+ <tr am:src='clients|NVar[:surname, :firstname, :email]' >
799
+ <td class='cell1'>$1, $2</td>
800
+ <td class='cell2'><a href="mailto:$3">$3</a></td>
801
+ </tr>
802
+ </table>
803
+ END
804
+ end
805
+
806
+ specify "table with tr line" do
807
+ p = Amrita2::Core::PreProcessor.new
808
+ ret = p.process <<-END
809
+ <<table<
810
+ <<<------------------------------------------
811
+ |class||cell1 |cell2 |
812
+ | ||$1, $2|<a href="mailto:$3">$3</a>|
813
+ END
814
+ ret.should_be_samexml_as <<-END
815
+ <table>
816
+ <tr>
817
+ <td class='cell1'>$1, $2</td>
818
+ <td class='cell2'><a href="mailto:$3">$3</a></td>
819
+ </tr>
820
+ </table>
821
+ END
822
+ end
823
+ end