bike 0.2.1

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 (151) hide show
  1. data/LICENSE +19 -0
  2. data/README.rdoc +124 -0
  3. data/bin/bike +35 -0
  4. data/lib/_error.rb +14 -0
  5. data/lib/_field.rb +260 -0
  6. data/lib/_i18n.rb +144 -0
  7. data/lib/_parser.rb +256 -0
  8. data/lib/_path.rb +86 -0
  9. data/lib/_storage/_storage.rb +215 -0
  10. data/lib/_storage/file.rb +201 -0
  11. data/lib/_storage/sequel.rb +174 -0
  12. data/lib/_storage/temp.rb +73 -0
  13. data/lib/_widget/action_create.rb +23 -0
  14. data/lib/_widget/action_login.rb +22 -0
  15. data/lib/_widget/action_signup.rb +16 -0
  16. data/lib/_widget/action_update.rb +16 -0
  17. data/lib/_widget/crumb.rb +24 -0
  18. data/lib/_widget/done.rb +16 -0
  19. data/lib/_widget/login.rb +25 -0
  20. data/lib/_widget/me.rb +31 -0
  21. data/lib/_widget/message.rb +51 -0
  22. data/lib/_widget/navi.rb +88 -0
  23. data/lib/_widget/submit.rb +49 -0
  24. data/lib/_widget/view_ym.rb +77 -0
  25. data/lib/_workflow/_workflow.rb +89 -0
  26. data/lib/_workflow/attachment.rb +50 -0
  27. data/lib/_workflow/blog.rb +28 -0
  28. data/lib/_workflow/contact.rb +23 -0
  29. data/lib/_workflow/forum.rb +26 -0
  30. data/lib/_workflow/register.rb +39 -0
  31. data/lib/bike.rb +396 -0
  32. data/lib/meta/_meta.rb +20 -0
  33. data/lib/meta/group.rb +19 -0
  34. data/lib/meta/id.rb +59 -0
  35. data/lib/meta/owner.rb +21 -0
  36. data/lib/meta/timestamp.rb +118 -0
  37. data/lib/scalar/checkbox.rb +68 -0
  38. data/lib/scalar/file.rb +144 -0
  39. data/lib/scalar/img.rb +112 -0
  40. data/lib/scalar/password.rb +58 -0
  41. data/lib/scalar/radio.rb +47 -0
  42. data/lib/scalar/select.rb +47 -0
  43. data/lib/scalar/text.rb +38 -0
  44. data/lib/scalar/textarea.rb +35 -0
  45. data/lib/scalar/textarea_pre.rb +14 -0
  46. data/lib/scalar/textarea_wiki.rb +173 -0
  47. data/lib/set/_set.rb +196 -0
  48. data/lib/set/dynamic.rb +177 -0
  49. data/lib/set/static.rb +102 -0
  50. data/lib/set/static_folder.rb +96 -0
  51. data/locale/en/index.po +242 -0
  52. data/locale/index.pot +243 -0
  53. data/locale/ja/index.po +242 -0
  54. data/locale/lazy_parser.rb +54 -0
  55. data/skel/config.ru +27 -0
  56. data/skel/skin/_users/00000000_frank-avatar.jpg +0 -0
  57. data/skel/skin/_users/00000000_frank-avatar_small.jpg +0 -0
  58. data/skel/skin/_users/00000000_frank.yaml +12 -0
  59. data/skel/skin/_users/00000000_root-avatar.jpg +0 -0
  60. data/skel/skin/_users/00000000_root-avatar_small.jpg +0 -0
  61. data/skel/skin/_users/00000000_root.yaml +11 -0
  62. data/skel/skin/_users/css/users.css +21 -0
  63. data/skel/skin/_users/css/users.less +25 -0
  64. data/skel/skin/_users/done.html +42 -0
  65. data/skel/skin/_users/index.html +46 -0
  66. data/skel/skin/_users/index.yaml +3 -0
  67. data/skel/skin/_users/summary.html +40 -0
  68. data/skel/skin/css/base.css +93 -0
  69. data/skel/skin/css/base.less +139 -0
  70. data/skel/skin/css/coax.css +199 -0
  71. data/skel/skin/css/coax.less +244 -0
  72. data/skel/skin/examples/blog/20091214_0001.yaml +8 -0
  73. data/skel/skin/examples/blog/20100630_0001.yaml +8 -0
  74. data/skel/skin/examples/blog/20100630_0002.yaml +14 -0
  75. data/skel/skin/examples/blog/20100701_0001.yaml +8 -0
  76. data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f.jpg +0 -0
  77. data/skel/skin/examples/blog/20100701_0002-a-20100701_0001-f_small.jpg +0 -0
  78. data/skel/skin/examples/blog/20100701_0002.yaml +19 -0
  79. data/skel/skin/examples/blog/frank/20100701_0001.yaml +10 -0
  80. data/skel/skin/examples/blog/frank/index.yaml +4 -0
  81. data/skel/skin/examples/blog/index.html +51 -0
  82. data/skel/skin/examples/blog/rss.xml +18 -0
  83. data/skel/skin/examples/contact/20100701_0001-file.txt +1 -0
  84. data/skel/skin/examples/contact/20100701_0001.yaml +15 -0
  85. data/skel/skin/examples/contact/20100701_0002.yaml +8 -0
  86. data/skel/skin/examples/contact/20100701_0003.yaml +9 -0
  87. data/skel/skin/examples/contact/index.html +47 -0
  88. data/skel/skin/examples/contact/js/contact.js +13 -0
  89. data/skel/skin/examples/contact/summary.html +54 -0
  90. data/skel/skin/examples/forum/20100701_0001.yaml +41 -0
  91. data/skel/skin/examples/forum/20100701_0002.yaml +25 -0
  92. data/skel/skin/examples/forum/index.html +68 -0
  93. data/skel/skin/examples/forum/summary.html +47 -0
  94. data/skel/skin/examples/index.html +73 -0
  95. data/skel/skin/index.html +39 -0
  96. data/skel/skin/js/base.js +50 -0
  97. data/t/locale/de/index.po +19 -0
  98. data/t/locale/en-GB/index.po +25 -0
  99. data/t/locale/ja/index.po +30 -0
  100. data/t/skin/_users/00000000_test.yaml +3 -0
  101. data/t/skin/_users/index.html +13 -0
  102. data/t/skin/foo/20091120_0001.yaml +7 -0
  103. data/t/skin/foo/bar/20091120_0001.yaml +5 -0
  104. data/t/skin/foo/bar/index.yaml +5 -0
  105. data/t/skin/foo/baz/css/baz.css +1 -0
  106. data/t/skin/foo/css/foo.css +1 -0
  107. data/t/skin/foo/index.html +14 -0
  108. data/t/skin/foo/index.yaml +7 -0
  109. data/t/skin/foo/not_css/foo.css +1 -0
  110. data/t/skin/foo/qux/index.html +8 -0
  111. data/t/skin/foo/qux/moo/index.html +6 -0
  112. data/t/skin/foo/sub-20100306_0001.yaml +3 -0
  113. data/t/skin/index.yaml +3 -0
  114. data/t/skin/t_attachment/index.html +13 -0
  115. data/t/skin/t_contact/done.html +6 -0
  116. data/t/skin/t_contact/index.html +9 -0
  117. data/t/skin/t_file/index.html +16 -0
  118. data/t/skin/t_img/index.html +14 -0
  119. data/t/skin/t_img/test.jpg +0 -0
  120. data/t/skin/t_select/index.html +9 -0
  121. data/t/skin/t_store/index.html +9 -0
  122. data/t/skin/t_summary/20100326_0001.yaml +3 -0
  123. data/t/skin/t_summary/create.html +9 -0
  124. data/t/skin/t_summary/index.html +9 -0
  125. data/t/skin/t_summary/summary.html +9 -0
  126. data/t/t.rb +27 -0
  127. data/t/test_bike.rb +768 -0
  128. data/t/test_call.rb +1281 -0
  129. data/t/test_checkbox.rb +273 -0
  130. data/t/test_field.rb +330 -0
  131. data/t/test_file.rb +900 -0
  132. data/t/test_i18n.rb +325 -0
  133. data/t/test_id.rb +215 -0
  134. data/t/test_img.rb +328 -0
  135. data/t/test_meta.rb +57 -0
  136. data/t/test_parser.rb +1516 -0
  137. data/t/test_password.rb +188 -0
  138. data/t/test_radio.rb +226 -0
  139. data/t/test_role.rb +249 -0
  140. data/t/test_select.rb +182 -0
  141. data/t/test_set_complex.rb +527 -0
  142. data/t/test_set_dynamic.rb +1504 -0
  143. data/t/test_set_folder.rb +515 -0
  144. data/t/test_set_permit.rb +246 -0
  145. data/t/test_set_static.rb +468 -0
  146. data/t/test_storage.rb +915 -0
  147. data/t/test_text.rb +125 -0
  148. data/t/test_textarea.rb +138 -0
  149. data/t/test_timestamp.rb +473 -0
  150. data/t/test_workflow.rb +367 -0
  151. metadata +347 -0
@@ -0,0 +1,325 @@
1
+ # encoding: UTF-8
2
+
3
+ # Author:: Akira FUNAI
4
+ # Copyright:: Copyright (c) 2009 Akira FUNAI
5
+
6
+ require "#{::File.dirname __FILE__}/t"
7
+
8
+ class TC_Bike_I18n < Test::Unit::TestCase
9
+
10
+ include Bike::I18n
11
+
12
+ def setup
13
+ Bike::I18n.domain = 'index'
14
+ Bike::I18n.po_dir = './t/locale'
15
+ end
16
+
17
+ def teardown
18
+ end
19
+
20
+ def test_lang
21
+ Bike::I18n.lang = 'ja'
22
+ assert_instance_of(
23
+ Array,
24
+ Bike::I18n.lang,
25
+ 'Bike::I18n.lang should return an array'
26
+ )
27
+ assert_equal(
28
+ ['ja'],
29
+ Bike::I18n.lang,
30
+ 'Bike::I18n.lang should return the current acceptable language-ranges'
31
+ )
32
+ end
33
+
34
+ def test_lang_case
35
+ Bike::I18n.lang = 'JA-jp'
36
+ assert_equal(
37
+ ['ja-JP'],
38
+ Bike::I18n.lang,
39
+ 'Bike::I18n.lang should be properly downcase/upcased'
40
+ )
41
+ end
42
+
43
+ def test_multiple_lang
44
+ Bike::I18n.lang = 'ja, de;q=0.5, en;q=0.8'
45
+ assert_equal(
46
+ ['ja', 'en', 'de'],
47
+ Bike::I18n.lang,
48
+ 'Bike::I18n.lang should sort the language-ranges by their quality values'
49
+ )
50
+ end
51
+
52
+ def test_same_qvalues
53
+ Bike::I18n.lang = 'ja, de;q=0.5, en;q=0.5'
54
+ assert_equal(
55
+ ['ja', 'de', 'en'],
56
+ Bike::I18n.lang,
57
+ 'Bike::I18n.lang should be sorted by their original order if the qvalues are same'
58
+ )
59
+ Bike::I18n.lang = 'ja, de, en'
60
+ assert_equal(
61
+ ['ja', 'de', 'en'],
62
+ Bike::I18n.lang,
63
+ 'Bike::I18n.lang should be sorted by their original order if the qvalues are same'
64
+ )
65
+ end
66
+
67
+ def test_po_dir
68
+ Bike::I18n.po_dir = 'foo/bar'
69
+ assert_equal(
70
+ 'foo/bar',
71
+ Bike::I18n.po_dir,
72
+ 'Bike::I18n.po_dir should be return the path to po files'
73
+ )
74
+ end
75
+
76
+ def test_domain
77
+ Bike::I18n.domain = 'foo'
78
+ assert_equal(
79
+ 'foo',
80
+ Bike::I18n.domain,
81
+ 'Bike::I18n.domain should be return the current domain'
82
+ )
83
+ end
84
+
85
+ def test_bindtextdomain
86
+ Bike::I18n.bindtextdomain('foo', 'bar/baz')
87
+ assert_equal(
88
+ 'foo',
89
+ Bike::I18n.domain,
90
+ 'Bike::I18n.bindtextdomain should set the current domain'
91
+ )
92
+ assert_equal(
93
+ 'bar/baz',
94
+ Bike::I18n.po_dir,
95
+ 'Bike::I18n.bindtextdomain should set the path to po files'
96
+ )
97
+ end
98
+
99
+ def test_msg
100
+ Bike::I18n.lang = 'ja'
101
+ assert_instance_of(
102
+ ::Hash,
103
+ Bike::I18n.msg,
104
+ 'Bike::I18n.msg should return a hash'
105
+ )
106
+ assert_equal(
107
+ {'color' => '色', 'one color' =>['%{n}色']},
108
+ Bike::I18n.msg.reject {|k, v| k == :plural },
109
+ 'Bike::I18n.msg should return a hash containing {msgid => msgstr}'
110
+ )
111
+ assert_instance_of(
112
+ ::Proc,
113
+ Bike::I18n.msg[:plural],
114
+ 'Bike::I18n.msg[:plural] should return a proc'
115
+ )
116
+
117
+ Bike::I18n.lang = 'po'
118
+ assert_equal(
119
+ {},
120
+ Bike::I18n.msg,
121
+ 'Bike::I18n.msg should be reset when the lang is updated'
122
+ )
123
+ end
124
+
125
+ def test_merge_msg!
126
+ Bike::I18n.lang = 'no'
127
+ assert_equal({}, Bike::I18n.msg)
128
+
129
+ Bike::I18n.merge_msg!('color' => 'farge')
130
+ assert_equal(
131
+ {'color' => 'farge'},
132
+ Bike::I18n.msg,
133
+ 'Bike::I18n.merge_msg! should dynamically merge a hash to the msg of the current thread'
134
+ )
135
+
136
+ Bike::I18n.merge_msg!(:plural => Proc.new { 123 })
137
+ assert_equal(
138
+ {'color' => 'farge'},
139
+ Bike::I18n.msg,
140
+ 'Bike::I18n.merge_msg! should not merge :plural'
141
+ )
142
+
143
+ Bike::I18n.lang = 'no'
144
+ assert_equal(
145
+ {},
146
+ Bike::I18n.msg,
147
+ 'Bike::I18n.merge_msg! should not affect anything other than the current thread'
148
+ )
149
+ end
150
+
151
+ def test_rex_plural_expression_ok
152
+ src = <<'_eos'.split "\n"
153
+ "Plural-Forms: nplurals=1; plural=0;"
154
+ "Plural-Forms: nplurals=2; plural=n != 1;"
155
+ "Plural-Forms: nplurals=2; plural=n>1;"
156
+ "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;"
157
+ "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;"
158
+ "Plural-Forms: nplurals=3; Plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2;"
159
+ "Plural-Forms: nplurals=3; Plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2;"
160
+ "Plural-Forms: nplurals=3; Plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"
161
+ "Plural-Forms: nplurals=3; Plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
162
+ "Plural-Forms: nplurals=3; Plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"
163
+ "Plural-Forms: nplurals=4; Plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;"
164
+ _eos
165
+ src.each {|s|
166
+ assert_match(
167
+ Bike::I18n::REX::PLURAL_EXPRESSION,
168
+ s,
169
+ 'Bike::I18n::REX::PLURAL_EXPRESSION should match'
170
+ )
171
+ }
172
+ end
173
+
174
+ def test_rex_plural_expression_ng
175
+ src = <<'_eos'.split "\n"
176
+ "Plural-Forms: nplurals=1; plural=rm '.';"
177
+ "Plural-Forms: nplurals=1; plural=Fileutils.rm_r('.');"
178
+ "Plural-Forms: nplurals=1; plural=Fileutils.rm_r '.';"
179
+ "Plural-Forms: nplurals=1; plural=Fileutils.rm_r ".";"
180
+ "Plural-Forms: nplurals=2; plural=n;"
181
+ "Plural-Forms: nplurals=2; plural=nn;"
182
+ "Plural-Forms: nplurals=3; plural=n();"
183
+ "Plural-Forms: nplurals=3; plural=n(123);"
184
+ "Plural-Forms: nplurals=3; plural=n 123;"
185
+ _eos
186
+ src.each {|s|
187
+ assert_no_match(
188
+ Bike::I18n::REX::PLURAL_EXPRESSION,
189
+ s,
190
+ 'Bike::I18n::REX::PLURAL_EXPRESSION should not match malicious expressions'
191
+ )
192
+ }
193
+ end
194
+
195
+ def test__
196
+ Bike::I18n.lang = 'ja'
197
+ assert_equal(
198
+ '色',
199
+ _('color'),
200
+ 'Bike::I18n#_() should return a string according to the msgid'
201
+ )
202
+
203
+ Bike::I18n.lang = 'en-GB'
204
+ assert_equal(
205
+ 'colour',
206
+ _('color'),
207
+ 'Bike::I18n#_() should return a string according to the msgid'
208
+ )
209
+
210
+ Bike::I18n.lang = 'no'
211
+ assert_equal(
212
+ 'color',
213
+ _('color'),
214
+ 'Bike::I18n#_() should return a msgid if the msgid is not existed in the msg'
215
+ )
216
+ end
217
+
218
+ def test_n_
219
+ Bike::I18n.lang = 'ja'
220
+ assert_equal(
221
+ '%{n}色',
222
+ n_('one color', '%{n} colors', 1),
223
+ 'Bike::I18n#n_() should return a string according to the msgid and the n'
224
+ )
225
+ assert_equal(
226
+ '%{n}色',
227
+ n_('one color', '%{n} colors', 2),
228
+ 'Bike::I18n#n_() should return a string according to the msgid and the n'
229
+ )
230
+
231
+ Bike::I18n.lang = 'en-GB'
232
+ assert_equal(
233
+ 'one colour',
234
+ n_('one color', '%{n} colors', 1),
235
+ 'Bike::I18n#n_() should return a string according to the msgid and the n'
236
+ )
237
+ assert_equal(
238
+ '%{n} colours',
239
+ n_('one color', '%{n} colors', 2),
240
+ 'Bike::I18n#n_() should return a string according to the msgid and the n'
241
+ )
242
+
243
+ Bike::I18n.lang = 'no'
244
+ assert_equal(
245
+ 'one color',
246
+ n_('one color', '%{n} colors', 1),
247
+ 'Bike::I18n#_() should return a msgid if the msgid is not existed in the msg'
248
+ )
249
+ assert_equal(
250
+ '%{n} colors',
251
+ n_('one color', '%{n} colors', 2),
252
+ 'Bike::I18n#_() should return a msgid if the msgid is not existed in the msg'
253
+ )
254
+ end
255
+
256
+ def test__with_n_
257
+ Bike::I18n.lang = 'en-GB'
258
+ assert_equal(
259
+ 'one colour',
260
+ _('one color'),
261
+ 'Bike::I18n#_() should return msgstr[0] if the msgid refer to plural msgstrs'
262
+ )
263
+ end
264
+
265
+ def test_n_with__
266
+ Bike::I18n.lang = 'en-GB'
267
+ assert_equal(
268
+ 'color',
269
+ n_('color', '%{n} colors', 1),
270
+ 'Bike::I18n#n_() should return msgid if the msgid refer to sigular msgstr'
271
+ )
272
+ end
273
+
274
+ def test_msgstr
275
+ Bike::I18n.lang = 'en-GB'
276
+
277
+ assert_instance_of(
278
+ Bike::I18n::Msgstr,
279
+ _('color'),
280
+ 'Bike::I18n#_() should return a instance of Bike::I18n::Msgstr'
281
+ )
282
+
283
+ s = n_('one color', '%{n} colors', 2)
284
+ assert_instance_of(
285
+ Bike::I18n::Msgstr,
286
+ s,
287
+ 'Bike::I18n#n_() should return a instance of Bike::I18n::Msgstr'
288
+ )
289
+ assert_equal(
290
+ '2 colours',
291
+ s % {:n => 2},
292
+ 'Bike::I18n::Msgstr#% should be able to proccess named variables'
293
+ )
294
+ assert_equal(
295
+ '2 colours',
296
+ s % [2],
297
+ "Bike::I18n::Msgstr#% should regard %{...} as '%s' if given an array"
298
+ )
299
+ assert_equal(
300
+ '2 colours',
301
+ s % 2,
302
+ "Bike::I18n::Msgstr#% should regard %{...} as '%s' if given a scalar"
303
+ )
304
+
305
+ s = n_('one foo', '%{n} foo %{bar}', 2)
306
+ assert_equal(
307
+ '2 foo selected',
308
+ s % [2, 'selected'],
309
+ "Bike::I18n::Msgstr#% should regard %{...} as '%s' if given an array"
310
+ )
311
+
312
+ s = n_('one color', '%{n} colors', 1)
313
+ assert_instance_of(
314
+ Bike::I18n::Msgstr,
315
+ s,
316
+ 'Bike::I18n#n_() should return a instance of Bike::I18n::Msgstr'
317
+ )
318
+ assert_equal(
319
+ 'one colour',
320
+ s % {:n => 1},
321
+ 'Bike::I18n::Msgstr#% should work with msgstrs without a placeholder'
322
+ )
323
+ end
324
+
325
+ end
@@ -0,0 +1,215 @@
1
+ # encoding: UTF-8
2
+
3
+ # Author:: Akira FUNAI
4
+ # Copyright:: Copyright (c) 2009-2010 Akira FUNAI
5
+
6
+ require "#{::File.dirname __FILE__}/t"
7
+
8
+ class TC_Id < Test::Unit::TestCase
9
+
10
+ def setup
11
+ meta = nil
12
+ Bike::Parser.gsub_scalar('$(foo meta-id 3 1..5)') {|id, m|
13
+ meta = m
14
+ ''
15
+ }
16
+ @f = Bike::Field.instance meta
17
+
18
+ Bike.current[:base] = nil
19
+ end
20
+
21
+ def teardown
22
+ end
23
+
24
+ def test_meta
25
+ assert_equal(
26
+ 3,
27
+ @f[:size],
28
+ 'Meta::Id#initialize should set :size from the token'
29
+ )
30
+ assert_equal(
31
+ 1,
32
+ @f[:min],
33
+ 'Meta::Id#initialize should set :min from the range token'
34
+ )
35
+ assert_equal(
36
+ 5,
37
+ @f[:max],
38
+ 'Meta::Id#initialize should set :max from the range token'
39
+ )
40
+ end
41
+
42
+ def test_val_cast
43
+ assert_equal(
44
+ '',
45
+ @f.val,
46
+ 'Meta::Id#val_cast should cast the given val to String'
47
+ )
48
+
49
+ @f.load 123
50
+ assert_equal(
51
+ '123',
52
+ @f.val,
53
+ 'Meta::Id#val_cast should cast the given val to String'
54
+ )
55
+ end
56
+
57
+ def test_new_id?
58
+ @f[:parent] = Bike::Set::Static.new(:id => '20100526_0001')
59
+ assert_equal(
60
+ false,
61
+ @f.send(:new_id?),
62
+ 'Meta::Id#new_id? should return whether the ancestors is new or not'
63
+ )
64
+
65
+ @f[:parent] = Bike::Set::Static.new(:id => '_001')
66
+ assert_equal(
67
+ true,
68
+ @f.send(:new_id?),
69
+ 'Meta::Id#new_id? should return whether the ancestors is new or not'
70
+ )
71
+ end
72
+
73
+ def test_get
74
+ @f[:parent] = Bike::Set::Static.new(:id => '_001')
75
+ assert_equal(
76
+ '<span class="meta-id"><input type="text" name="" value="" size="3" /></span>',
77
+ @f.get(:action => :create),
78
+ 'Meta::Id#_g_create should return <input> if the ancestor is new'
79
+ )
80
+
81
+ @f[:parent] = Bike::Set::Static.new(:id => '20100526_0001')
82
+ assert_equal(
83
+ '',
84
+ @f.get(:action => :create),
85
+ 'Meta::Id#_g_create should return val if the ancestor is not new'
86
+ )
87
+
88
+ @f.load 'bar'
89
+ assert_equal(
90
+ 'bar',
91
+ @f.get,
92
+ 'Meta::Id#get should return proper string'
93
+ )
94
+
95
+ @f[:parent] = Bike::Set::Static.new(:id => '_001')
96
+ assert_equal(
97
+ '<span class="meta-id"><input type="text" name="" value="bar" size="3" /></span>',
98
+ @f.get(:action => :update),
99
+ 'Meta::Id#_g_update should return <input> if the ancestor is new'
100
+ )
101
+
102
+ @f[:parent] = Bike::Set::Static.new(:id => '20100526_0001')
103
+ assert_equal(
104
+ 'bar',
105
+ @f.get(:action => :update),
106
+ 'Meta::Id#_g_update should return val if the ancestor is not new'
107
+ )
108
+
109
+ @f.load '<bar>'
110
+ assert_equal(
111
+ '&lt;bar&gt;',
112
+ @f.get,
113
+ 'Meta::Id#get should escape the special characters'
114
+ )
115
+
116
+ @f[:parent] = Bike::Set::Static.new(:id => '_001')
117
+ @f.load '<bar>'
118
+ assert_equal(
119
+ '<span class="meta-id error"><input type="text" name="" value="&lt;bar&gt;" size="3" /><span class="error_message">malformatted id</span>' + "\n</span>",
120
+ @f.get(:action => :update),
121
+ 'Meta::Id#get should escape the special characters'
122
+ )
123
+ end
124
+
125
+ def test_post_new_ancestor
126
+ @f[:parent] = Bike::Set::Static.new(:id => '_001')
127
+ @f.create 'frank'
128
+ assert_equal(
129
+ 'frank',
130
+ @f.val,
131
+ 'Meta::Id#post should create like a normal field'
132
+ )
133
+
134
+ @f.update 'bobby'
135
+ assert_equal(
136
+ 'bobby',
137
+ @f.val,
138
+ 'Meta::Id#post should update the current val if the ancestor is new'
139
+ )
140
+ end
141
+
142
+ def test_post_old_ancestor
143
+ @f[:parent] = Bike::Set::Static.new(:id => '20100526_0001')
144
+ @f.load 'frank'
145
+
146
+ @f.update 'bobby'
147
+ assert_equal(
148
+ 'frank',
149
+ @f.val,
150
+ 'Meta::Id#post should not update the current val if the ancestor is not new'
151
+ )
152
+ end
153
+
154
+ def test_errors
155
+ @f.load '<a'
156
+ assert_equal(
157
+ ['malformatted id'],
158
+ @f.errors,
159
+ 'Meta::Id#errors should return the errors of the current val'
160
+ )
161
+
162
+ @f.load '123a'
163
+ assert_equal(
164
+ ['malformatted id'],
165
+ @f.errors,
166
+ 'Meta::Id#errors should return the errors of the current val'
167
+ )
168
+
169
+ @f.load 'abcdefghijk'
170
+ assert_equal(
171
+ ['too long: 5 characters maximum'],
172
+ @f.errors,
173
+ 'Meta::Id#errors should return the errors of the current val'
174
+ )
175
+
176
+ @f.load 'frank'
177
+ assert_equal(
178
+ [],
179
+ @f.errors,
180
+ 'Meta::Id#errors should return an empty array if there is no error'
181
+ )
182
+ end
183
+
184
+ def test_errors_duplicate_id
185
+ Bike.client = 'root'
186
+ sd = Bike::Set::Static::Folder.root.item('_users', 'main')
187
+
188
+ sd.update(
189
+ '_001' => {:action => :create, '_id' => 'test'}
190
+ )
191
+ assert_equal(
192
+ ['duplicate id: test'],
193
+ sd.item('_001', '_id').errors,
194
+ 'Meta::Id#errors should return an error if the current val is duplicated in the sd'
195
+ )
196
+
197
+ sd.update(
198
+ '_001' => {:action => :create, '_id' => 'frank'}
199
+ )
200
+ assert_equal(
201
+ [],
202
+ sd.item('_001', '_id').errors,
203
+ 'Meta::Id#errors should return no error if the current val is unique in the sd'
204
+ )
205
+
206
+ f = Bike::Set::Static::Folder.root.item('_users', 'main', 'test', '_id')
207
+ f.update 'test'
208
+ assert_equal(
209
+ [],
210
+ f.errors,
211
+ 'Meta::Id#errors should return no error if the current val is unchanged'
212
+ )
213
+ end
214
+
215
+ end