merb 0.4.2 → 0.5.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 (108) hide show
  1. data/README +21 -14
  2. data/Rakefile +157 -108
  3. data/SVN_REVISION +1 -0
  4. data/app_generators/merb/templates/Rakefile +20 -4
  5. data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +1 -1
  6. data/app_generators/merb/templates/config/boot.rb +1 -1
  7. data/app_generators/merb/templates/config/dependencies.rb +3 -3
  8. data/app_generators/merb/templates/config/merb.yml +5 -0
  9. data/app_generators/merb/templates/config/merb_init.rb +3 -3
  10. data/app_generators/merb/templates/script/destroy +3 -0
  11. data/app_generators/merb/templates/script/generate +1 -1
  12. data/app_generators/merb/templates/spec/spec_helper.rb +2 -2
  13. data/app_generators/merb/templates/test/test_helper.rb +1 -1
  14. data/app_generators/merb_plugin/merb_plugin_generator.rb +4 -0
  15. data/bin/merb +1 -3
  16. data/lib/merb.rb +144 -76
  17. data/lib/merb/abstract_controller.rb +6 -5
  18. data/lib/merb/assets.rb +119 -0
  19. data/lib/merb/boot_loader.rb +217 -0
  20. data/lib/merb/caching.rb +1 -1
  21. data/lib/merb/caching/action_cache.rb +1 -1
  22. data/lib/merb/caching/fragment_cache.rb +1 -1
  23. data/lib/merb/caching/store/file_cache.rb +1 -1
  24. data/lib/merb/config.rb +290 -0
  25. data/lib/merb/controller.rb +5 -5
  26. data/lib/merb/core_ext/get_args.rb +1 -0
  27. data/lib/merb/core_ext/hash.rb +182 -169
  28. data/lib/merb/core_ext/kernel.rb +57 -26
  29. data/lib/merb/dispatcher.rb +6 -6
  30. data/lib/merb/drb_server.rb +1 -1
  31. data/lib/merb/generators/merb_generator_helpers.rb +7 -6
  32. data/lib/merb/logger.rb +1 -1
  33. data/lib/merb/mail_controller.rb +3 -4
  34. data/lib/merb/mailer.rb +2 -2
  35. data/lib/merb/mixins/basic_authentication.rb +2 -2
  36. data/lib/merb/mixins/controller.rb +1 -1
  37. data/lib/merb/mixins/general_controller.rb +13 -20
  38. data/lib/merb/mixins/inline_partial.rb +32 -0
  39. data/lib/merb/mixins/render.rb +3 -3
  40. data/lib/merb/mixins/responder.rb +1 -1
  41. data/lib/merb/mixins/view_context.rb +159 -33
  42. data/lib/merb/mongrel_handler.rb +9 -9
  43. data/lib/merb/plugins.rb +1 -1
  44. data/lib/merb/request.rb +25 -1
  45. data/lib/merb/router.rb +264 -226
  46. data/lib/merb/server.rb +66 -560
  47. data/lib/merb/session/cookie_store.rb +14 -13
  48. data/lib/merb/session/mem_cache_session.rb +20 -10
  49. data/lib/merb/session/memory_session.rb +21 -11
  50. data/lib/merb/template.rb +2 -2
  51. data/lib/merb/template/erubis.rb +3 -33
  52. data/lib/merb/template/haml.rb +8 -3
  53. data/lib/merb/test/fake_request.rb +8 -3
  54. data/lib/merb/test/helper.rb +66 -22
  55. data/lib/merb/test/rspec.rb +9 -155
  56. data/lib/merb/test/rspec_matchers/controller_matchers.rb +117 -0
  57. data/lib/merb/test/rspec_matchers/markup_matchers.rb +98 -0
  58. data/lib/merb/upload_handler.rb +2 -1
  59. data/lib/merb/version.rb +38 -3
  60. data/lib/merb/view_context.rb +1 -2
  61. data/lib/tasks/merb.rake +11 -11
  62. data/merb_generators/part_controller/USAGE +5 -0
  63. data/merb_generators/part_controller/part_controller_generator.rb +27 -0
  64. data/merb_generators/part_controller/templates/controller.rb +8 -0
  65. data/merb_generators/part_controller/templates/helper.rb +5 -0
  66. data/merb_generators/part_controller/templates/index.html.erb +3 -0
  67. data/rspec_generators/merb_controller_test/merb_controller_test_generator.rb +1 -1
  68. data/script/destroy +14 -0
  69. data/script/generate +14 -0
  70. data/spec/fixtures/controllers/dispatch_spec_controllers.rb +9 -1
  71. data/spec/fixtures/controllers/render_spec_controllers.rb +5 -5
  72. data/spec/fixtures/models/router_spec_models.rb +10 -0
  73. data/spec/merb/abstract_controller_spec.rb +2 -2
  74. data/spec/merb/assets_spec.rb +207 -0
  75. data/spec/merb/caching_spec.rb +2 -2
  76. data/spec/merb/controller_spec.rb +7 -2
  77. data/spec/merb/cookie_store_spec.rb +1 -1
  78. data/spec/merb/core_ext/class_spec.rb +97 -0
  79. data/spec/merb/core_ext/enumerable_spec.rb +27 -0
  80. data/spec/merb/core_ext/hash_spec.rb +251 -0
  81. data/spec/merb/core_ext/inflector_spec.rb +34 -0
  82. data/spec/merb/core_ext/kernel_spec.rb +25 -0
  83. data/spec/merb/core_ext/numeric_spec.rb +26 -0
  84. data/spec/merb/core_ext/object_spec.rb +47 -0
  85. data/spec/merb/core_ext/string_spec.rb +22 -0
  86. data/spec/merb/core_ext/symbol_spec.rb +7 -0
  87. data/spec/merb/dependency_spec.rb +22 -0
  88. data/spec/merb/dispatch_spec.rb +23 -12
  89. data/spec/merb/fake_request_spec.rb +8 -0
  90. data/spec/merb/generator_spec.rb +140 -21
  91. data/spec/merb/handler_spec.rb +5 -5
  92. data/spec/merb/mail_controller_spec.rb +3 -3
  93. data/spec/merb/render_spec.rb +1 -1
  94. data/spec/merb/responder_spec.rb +3 -3
  95. data/spec/merb/router_spec.rb +260 -191
  96. data/spec/merb/server_spec.rb +5 -5
  97. data/spec/merb/upload_handler_spec.rb +7 -0
  98. data/spec/merb/version_spec.rb +33 -0
  99. data/spec/merb/view_context_spec.rb +217 -59
  100. data/spec/spec_generator_helper.rb +15 -0
  101. data/spec/spec_helper.rb +5 -3
  102. data/spec/spec_helpers/url_shared_behaviour.rb +5 -7
  103. metadata +32 -7
  104. data/lib/merb/caching/store/memcache.rb +0 -20
  105. data/lib/merb/mixins/form_control.rb +0 -332
  106. data/lib/patch +0 -69
  107. data/spec/merb/core_ext_spec.rb +0 -464
  108. data/spec/merb/form_control_mixin_spec.rb +0 -431
@@ -1,431 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
- require 'strscan' #StringScanner
3
-
4
- class ArticlePost; end
5
-
6
- module FormControlsSpecHelper
7
- def setup_model_mock
8
- # NOTE Uses OpenStruct so we can see meaningful
9
- # class name to dom_id conversions.
10
- @model = OpenStruct.new({
11
- :title => "Chunky Bacon",
12
- :intro => "It's the tastiest kind.",
13
- :created_at => DateTime.parse("1963-11-22 12:30:00"),
14
- :published_at => Time.now,
15
- :version => 42,
16
- :secret => 'should not be shown'
17
- })
18
- end
19
- end
20
-
21
- describe Merb::FormControls, "All Form Fields", :shared => true do
22
-
23
- before do
24
- @opts ||= {}
25
- end
26
-
27
- it "should render css class if specified" do
28
- content = control_for( @model, :title, @control_type, :class => "TEST_CLASS" )
29
- content.should match( /class="TEST_CLASS"/)
30
- end
31
-
32
- it "should render default DOM id" do
33
- content = control_for(@model, :title, @control_type)
34
- content.should match(/id="open_struct_title"/)
35
- end
36
-
37
- it "should override default DOM id if passed as argument" do
38
- content = control_for(@model, :title, @control_type, :id => "porky")
39
- content.should match(/id="porky"/)
40
- end
41
-
42
- it "should override default DOM name if passed as argument" do
43
- content = control_for( @model, :title, @control_type, :name => "OVERRIDE")
44
- content.should match( /name="OVERRIDE"/ )
45
- end
46
-
47
- it "should render a label" do
48
- unless ( @opts[:skip_label] == true )
49
- content = control_for( @model, :title, @control_type, :label => "LABEL" )
50
- content.should match( /<label for="open_struct_title">LABEL<\/label>/)
51
- end
52
- end
53
-
54
- it "should close the tag" do
55
- content = control_for( @model, @control_type, :password )
56
- content.clean.should match( /\/>\Z/ )
57
- end
58
-
59
-
60
-
61
- end
62
-
63
-
64
- describe Merb::FormControls, "text input" do
65
- include FormControlsSpecHelper
66
-
67
- it_should_behave_like "Merb::FormControls All Form Fields"
68
-
69
- before do
70
- setup_model_mock
71
- @control_type = :text
72
- end
73
-
74
- it "should render text input" do
75
- content = control_for(@model, :title, :text)
76
- content.should match(/type="text"/)
77
- content.should match(/value="Chunky Bacon"/)
78
- content.should match(/name="open_struct\[title\]"/)
79
- end
80
-
81
- end
82
-
83
-
84
- describe Merb::FormControls, "textarea" do
85
- include FormControlsSpecHelper
86
-
87
- it_should_behave_like "Merb::FormControls All Form Fields"
88
-
89
- before do
90
- setup_model_mock
91
- @control_type = :textarea
92
- end
93
-
94
- it "should render textarea" do
95
- content = control_for(@model, :intro, :textarea)
96
- content.should match(/textarea/)
97
- content.should match(/>It's the tastiest kind.</)
98
- end
99
-
100
- end
101
-
102
- describe Merb::FormControls, "number" do
103
- include FormControlsSpecHelper
104
-
105
- it_should_behave_like "Merb::FormControls All Form Fields"
106
-
107
- before do
108
- setup_model_mock
109
- @control_type = :number
110
- end
111
-
112
- it "should render number" do
113
- content = control_for(@model, :version, :number)
114
- content.should match(/value="42"/)
115
- content.should match(/type="text"/)
116
- end
117
-
118
- end
119
-
120
-
121
- describe Merb::FormControls, "hidden" do
122
- include FormControlsSpecHelper
123
-
124
- it_should_behave_like "Merb::FormControls All Form Fields"
125
-
126
- before do
127
- setup_model_mock
128
- @control_type = :hidden
129
- @opts = { :skip_label => true }
130
- end
131
-
132
- it "should render hidden field" do
133
- content = control_for(@model, :title, :hidden)
134
- content.should match(/value="Chunky Bacon"/)
135
- content.should match(/type="hidden"/)
136
- end
137
- end
138
-
139
-
140
- describe Merb::FormControls, "password" do
141
- include FormControlsSpecHelper
142
-
143
- it_should_behave_like "Merb::FormControls All Form Fields"
144
-
145
- before do
146
- setup_model_mock
147
- @control_type = :password
148
- end
149
-
150
- it "should render password field" do
151
- content = control_for( @model, :title, :password )
152
- content.should match( /<input/ )
153
- content.should match( /type="password"/ )
154
- end
155
-
156
- it "should not put any value into the field even if it is in the hash" do
157
- content = control_for( @model, :title, :password, :value => "OVERRIDE")
158
- content.should_not match( /value="OVERRIDE"/ )
159
- end
160
-
161
- end
162
-
163
-
164
- describe Merb::FormControls, "select" do
165
- include FormControlsSpecHelper
166
-
167
- it_should_behave_like "Merb::FormControls All Form Fields"
168
-
169
- before do
170
- setup_model_mock
171
- @control_type = :select
172
- end
173
-
174
- it "should render the select tag with the correct id and name" do
175
- content = control_for( @model, :version, :select )
176
- content.should match( /<select/ )
177
- content.should match( /id="open_struct_version"/ )
178
- content.should match( /name="open_struct\[version\]"/ )
179
- content.should match( /<\/select>/)
180
- end
181
-
182
- it "should include a blank option" do
183
- content = control_for( @model, :version, :select, :include_blank => true )
184
- content.should match( /<option><\/option>/ )
185
- end
186
-
187
- it "should render a select tag with options" do
188
- content = control_for( @model, :version, :select, :class => 'class1 class2', :title => 'This is the title' )
189
- content.should match( /class=\"class1 class2\"/)
190
- content.should match( /title=\"This is the title\"/ )
191
- end
192
-
193
- it "should render a select tag with options and a blank option" do
194
- content = control_for( @model, :version, :select, :title => "TITLE", :include_blank => true )
195
- content.should match( /title=\"TITLE\"/ )
196
- content.should match( /<option><\/option>/ )
197
- end
198
-
199
- it "should render the text as the value if no text_method is specified" do
200
- content = control_for( @model, :version, :select, :collection => [@model] )
201
- content.should match( /<option.*>42<\/option>/ )
202
- end
203
-
204
- it "should render a collection as option tags" do
205
- @model2 = OpenStruct.new({
206
- :version => 45
207
- })
208
- content = control_for( @model, :version, :select, :collection => [@model, @model2] )
209
- doc = Hpricot( content )
210
- (doc/"option").size.should == 2
211
- (doc/"option").should_not be_empty
212
- content.should match( /<option value="45">45<\/option>/ )
213
- end
214
-
215
- it "should select the object in the collection" do
216
- @model2 = @model2 = OpenStruct.new({
217
- :version => 45
218
- })
219
- content = control_for( @model, :version, :select, :collection => [@model, @model2] )
220
- content.should match( /<option selected="selected" value="42">42<\/option>/ )
221
- end
222
-
223
- it "should render a collection with a text method specified" do
224
- @model2 = OpenStruct.new({ :version => 45, :title => "TITLE" })
225
- content = control_for( @model, :version, :select, :collection => [@model, @model2], :text_method => :title )
226
- content.should match( /<option.*value="42".*>Chunky Bacon<\/option>.*<option.*value="45".*>TITLE<\/option/ )
227
- end
228
-
229
- it "should render a hash of arrays as a grouped select box" do
230
- @model1 = OpenStruct.new({ :make => "Ford", :model => "Mustang", :code => 1 } )
231
- @model2 = OpenStruct.new({ :make => "Ford", :model => "Falcon", :code => 2 } )
232
- @model3 = OpenStruct.new({ :make => "Holden", :model => "Comodore", :code => 3 } )
233
-
234
- collection = [ @model1, @model2, @model3].group_by( &:make )
235
-
236
- content = control_for( @model1, :code, :select, :collection => collection, :text_method => :model )
237
- content.should match( /<optgroup label="Ford">/ )
238
- content.should match( /<option selected="selected" value="1">Mustang<\/option>/ )
239
- content.should match( /<option value="2">Falcon<\/option>/ )
240
- content.should match( /<optgroup label="Holden">/ )
241
- content.should match( /<option value="3">Comodore<\/option>/ )
242
- content.should match( /<\/optgroup>/)
243
- end
244
-
245
- it "should humanize and titlize keys in the label for the option group" do
246
- collection = { :some_snake_case_key => [@model] }
247
- content = control_for( @model, :version, :select, :collection => collection )
248
- content.should match( /<optgroup label="Some Snake Case Key">/ )
249
- end
250
-
251
- end
252
-
253
- describe Merb::FormControls, "time and date" do
254
- include FormControlsSpecHelper
255
-
256
- before(:each) do
257
- setup_model_mock
258
- end
259
-
260
- it "should render time" do
261
- content = control_for(@model, :created_at, :time)
262
- content.should match(/<select .*\[created_at\]\[day\]/)
263
- content.should match(/<select .*\[created_at\]\[month\]/)
264
- content.should match(/<select .*\[created_at\]\[year\]/)
265
- content.should match(/<select .*\[created_at\]\[hour\]/)
266
- content.should match(/<select .*\[created_at\]\[minute\]/)
267
- content.should match(/<select .*\[created_at\]\[second\]/)
268
- end
269
-
270
- it "should render date" do
271
- content = control_for(@model, :created_at, :date)
272
- content.should match(/<select .*\[created_at\]\[day\]/)
273
- content.should match(/<select .*\[created_at\]\[month\]/)
274
- content.should match(/<select .*\[created_at\]\[year\]/)
275
- content.should_not match(/<select .*\[created_at\]\[hour\]/)
276
- content.should_not match(/<select .*\[created_at\]\[minute\]/)
277
- content.should_not match(/<select .*\[created_at\]\[second\]/)
278
- end
279
-
280
- it "should select objects time" do
281
- content = control_for(@model, :created_at, :time)
282
- s = StringScanner.new(content)
283
- part = s.scan_until(/<\/select>/)
284
- part.should match(/day/)
285
- part.should match(/selected="selected" value="#{@model.created_at.day}"/)
286
- part = s.scan_until(/<\/select>/)
287
- part.should match(/month/)
288
- part.should match(/selected="selected" value="#{@model.created_at.month}"/)
289
- part = s.scan_until(/<\/select>/)
290
- part.should match(/year/)
291
- part.should match(/selected="selected" value="#{@model.created_at.year}"/)
292
- part = s.scan_until(/<\/select>/)
293
- part.should match(/hour/)
294
- part.should match(/selected="selected" value="#{@model.created_at.hour}"/)
295
- part = s.scan_until(/<\/select>/)
296
- part.should match(/minute/)
297
- part.should match(/selected="selected" value="#{@model.created_at.min}"/)
298
- part = s.scan_until(/<\/select>/)
299
- part.should match(/second/)
300
- part.should match(/selected="selected" value="#{@model.created_at.sec}"/)
301
- end
302
-
303
- it "should default to 1950..2050" do
304
- content = control_for(@model, :created_at, :date)
305
- s = StringScanner.new(content)
306
- s.skip_until /<select .*\[created_at\]\[year\]/
307
- part = s.scan_until(/<\/select>/)
308
- part.should_not match(/>1949<\/option>/)
309
- part.should match(/>1950<\/option>/)
310
- part.should match(/>2050<\/option>/)
311
- part.should_not match(/>2051<\/option>/)
312
- end
313
-
314
- it "should accept min_year" do
315
- content = control_for(@model, :created_at, :date, :min_year => 1980)
316
- s = StringScanner.new(content)
317
- s.skip_until /<select .*\[created_at\]\[year\]/
318
- part = s.scan_until(/<\/select>/)
319
- part.should_not match(/>1979<\/option>/)
320
- part.should match(/>1980<\/option>/)
321
- part.should match(/>2050<\/option>/)
322
- part.should_not match(/>2051<\/option>/)
323
- end
324
-
325
- it "should accept max_year" do
326
- content = control_for(@model, :created_at, :date, :max_year => 2010)
327
- s = StringScanner.new(content)
328
- s.skip_until /<select .*\[created_at\]\[year\]/
329
- part = s.scan_until(/<\/select>/)
330
- part.should_not match(/>1949<\/option>/)
331
- part.should match(/>1950<\/option>/)
332
- part.should match(/>2010<\/option>/)
333
- part.should_not match(/>2011<\/option>/)
334
- end
335
-
336
- it "should accept min_year and max_year" do
337
- content = control_for(@model, :created_at, :date, :min_year => 1980, :max_year => 2010)
338
- s = StringScanner.new(content)
339
- s.skip_until /<select .*\[created_at\]\[year\]/
340
- part = s.scan_until(/<\/select>/)
341
- part.should_not match(/>1979<\/option>/)
342
- part.should match(/>1980<\/option>/)
343
- part.should match(/>2010<\/option>/)
344
- part.should_not match(/>2011<\/option>/)
345
- end
346
-
347
- it "should render a label for date" do
348
- content = control_for( @model, :created_at, :date, :label => "LABEL" )
349
- content.should match( /<label for="open_struct_created_at">LABEL<\/label>/)
350
- end
351
-
352
- it "should render a label for time" do
353
- content = control_for( @model, :created_at, :time, :label => "LABEL" )
354
- content.should match( /<label for="open_struct_created_at">LABEL<\/label>/)
355
- end
356
- end
357
-
358
-
359
- describe Merb::FormControls, "Missing time and day" do
360
-
361
- before do
362
- @post = OpenStruct.new(
363
- :stringdate => "",
364
- :stringtime => "",
365
- :nildate => nil,
366
- :niltime => nil
367
- )
368
- end
369
-
370
- it "should handle date as string" do
371
- control_for(@post, :stringdate, :date)
372
- end
373
-
374
- it "should handle time as string" do
375
- control_for(@post, :stringtime, :time)
376
- end
377
-
378
- it "should handle date as nil" do
379
- control_for(@post, :nildate, :date)
380
- end
381
-
382
- it "should handle time as nil" do
383
- control_for(@post, :niltime, :time)
384
- end
385
- end
386
-
387
-
388
- describe Merb::FormControls, "monthnames" do
389
- include FormControlsSpecHelper
390
-
391
- before do
392
- setup_model_mock
393
- end
394
-
395
- it "should include default monthnames" do
396
- content = control_for(@model, :created_at, :date, :monthnames => true)
397
- s = StringScanner.new(content)
398
- s.skip_until /<select .*\[created_at\]\[month\]/
399
- part = s.scan_until(/<\/select>/)
400
- (1..12).each do |m|
401
- if m == @model.created_at.month
402
- part.should match(/selected="selected" value="#{m}"\>#{Date::MONTHNAMES[m]}/)
403
- else
404
- part.should match(/value="#{m}"\>#{Date::MONTHNAMES[m]}/)
405
- end
406
- end
407
- part.should_not match(/value="0"/)
408
- part.should_not match(/value="13"/)
409
- end
410
-
411
- it "should include custom monthnames" do
412
- french_months = [nil] + %w(janvier février mars avril mai juin
413
- juillet août septembre octobre novembre décembre)
414
- content = control_for(@model, :created_at, :date, :monthnames => french_months)
415
- s = StringScanner.new(content)
416
- s.skip_until /<select .*\[created_at\]\[month\]/
417
- part = s.scan_until(/<\/select>/)
418
- (1..12).each do |m|
419
- if m == @model.created_at.month
420
- part.should match(/selected="selected" value="#{m}"\>#{french_months[m]}/)
421
- else
422
- part.should match(/value="#{m}"\>#{french_months[m]}/)
423
- end
424
- end
425
- part.should_not match(/value="0"/)
426
- part.should_not match(/value="13"/)
427
- end
428
- end
429
-
430
-
431
-