merb 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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
-