merb-core 0.9.8 → 0.9.9

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 (57) hide show
  1. data/CONTRIBUTORS +33 -0
  2. data/README +7 -3
  3. data/Rakefile +3 -3
  4. data/lib/merb-core.rb +165 -94
  5. data/lib/merb-core/bootloader.rb +469 -100
  6. data/lib/merb-core/config.rb +79 -3
  7. data/lib/merb-core/constants.rb +24 -2
  8. data/lib/merb-core/controller/abstract_controller.rb +172 -67
  9. data/lib/merb-core/controller/exceptions.rb +50 -6
  10. data/lib/merb-core/controller/merb_controller.rb +215 -108
  11. data/lib/merb-core/controller/mime.rb +36 -12
  12. data/lib/merb-core/controller/mixins/authentication.rb +52 -7
  13. data/lib/merb-core/controller/mixins/conditional_get.rb +14 -0
  14. data/lib/merb-core/controller/mixins/controller.rb +90 -58
  15. data/lib/merb-core/controller/mixins/render.rb +34 -10
  16. data/lib/merb-core/controller/mixins/responder.rb +40 -16
  17. data/lib/merb-core/controller/template.rb +37 -16
  18. data/lib/merb-core/core_ext/hash.rb +9 -0
  19. data/lib/merb-core/core_ext/kernel.rb +92 -41
  20. data/lib/merb-core/dispatch/dispatcher.rb +29 -45
  21. data/lib/merb-core/dispatch/request.rb +186 -82
  22. data/lib/merb-core/dispatch/router.rb +141 -53
  23. data/lib/merb-core/dispatch/router/behavior.rb +296 -139
  24. data/lib/merb-core/dispatch/router/resources.rb +51 -19
  25. data/lib/merb-core/dispatch/router/route.rb +76 -23
  26. data/lib/merb-core/dispatch/session.rb +80 -36
  27. data/lib/merb-core/dispatch/session/container.rb +31 -15
  28. data/lib/merb-core/dispatch/session/cookie.rb +51 -22
  29. data/lib/merb-core/dispatch/session/memcached.rb +10 -6
  30. data/lib/merb-core/dispatch/session/memory.rb +17 -5
  31. data/lib/merb-core/dispatch/session/store_container.rb +21 -9
  32. data/lib/merb-core/dispatch/worker.rb +16 -2
  33. data/lib/merb-core/gem_ext/erubis.rb +4 -0
  34. data/lib/merb-core/plugins.rb +13 -0
  35. data/lib/merb-core/rack.rb +1 -0
  36. data/lib/merb-core/rack/adapter.rb +1 -0
  37. data/lib/merb-core/rack/adapter/abstract.rb +95 -17
  38. data/lib/merb-core/rack/adapter/irb.rb +50 -5
  39. data/lib/merb-core/rack/application.rb +27 -5
  40. data/lib/merb-core/rack/handler/mongrel.rb +6 -6
  41. data/lib/merb-core/rack/helpers.rb +33 -0
  42. data/lib/merb-core/rack/middleware/conditional_get.rb +1 -1
  43. data/lib/merb-core/rack/middleware/path_prefix.rb +3 -3
  44. data/lib/merb-core/rack/middleware/static.rb +11 -7
  45. data/lib/merb-core/server.rb +134 -69
  46. data/lib/merb-core/tasks/gem_management.rb +153 -80
  47. data/lib/merb-core/tasks/merb_rake_helper.rb +12 -4
  48. data/lib/merb-core/tasks/stats.rake +1 -1
  49. data/lib/merb-core/test/helpers/mock_request_helper.rb +29 -22
  50. data/lib/merb-core/test/helpers/request_helper.rb +1 -1
  51. data/lib/merb-core/test/helpers/route_helper.rb +50 -4
  52. data/lib/merb-core/test/matchers/request_matchers.rb +2 -36
  53. data/lib/merb-core/test/matchers/view_matchers.rb +32 -22
  54. data/lib/merb-core/test/run_specs.rb +6 -5
  55. data/lib/merb-core/test/test_ext/rspec.rb +6 -19
  56. data/lib/merb-core/version.rb +1 -1
  57. metadata +5 -4
@@ -36,7 +36,7 @@ module Merb
36
36
  end
37
37
 
38
38
  if env[:params]
39
- uri << "&#{Merb::Request.params_to_query_string(env.delete(:body_params))}"
39
+ uri << "?#{Merb::Request.params_to_query_string(env.delete(:params))}"
40
40
  end
41
41
 
42
42
  if @__cookie__
@@ -3,14 +3,60 @@ module Merb
3
3
  module RouteHelper
4
4
  include RequestHelper
5
5
 
6
- # Mimics the url method available to controllers.
6
+ # There are three possible ways to use this method. First, if you have a named route,
7
+ # you can specify the route as the first parameter as a symbol and any paramters in a
8
+ # hash. Second, you can generate the default route by just passing the params hash,
9
+ # just passing the params hash. Finally, you can use the anonymous parameters. This
10
+ # allows you to specify the parameters to a named route in the order they appear in the
11
+ # router.
7
12
  #
8
- # ==== Parameters
9
- # name<~to_sym>:: The name of the URL to generate.
10
- # params<Hash>:: Parameters for the route generation.
13
+ # ==== Parameters(Named Route)
14
+ # name<Symbol>::
15
+ # The name of the route.
16
+ # args<Hash>::
17
+ # Parameters for the route generation.
18
+ #
19
+ # ==== Parameters(Default Route)
20
+ # args<Hash>::
21
+ # Parameters for the route generation. This route will use the default route.
22
+ #
23
+ # ==== Parameters(Anonymous Parameters)
24
+ # name<Symbol>::
25
+ # The name of the route.
26
+ # args<Array>::
27
+ # An array of anonymous parameters to generate the route
28
+ # with. These parameters are assigned to the route parameters
29
+ # in the order that they are passed.
11
30
  #
12
31
  # ==== Returns
13
32
  # String:: The generated URL.
33
+ #
34
+ # ==== Examples
35
+ # Named Route
36
+ #
37
+ # Merb::Router.prepare do
38
+ # match("/articles/:title").to(:controller => :articles, :action => :show).name("articles")
39
+ # end
40
+ #
41
+ # url(:articles, :title => "new_article")
42
+ #
43
+ # Default Route
44
+ #
45
+ # Merb::Router.prepare do
46
+ # default_routes
47
+ # end
48
+ #
49
+ # url(:controller => "articles", :action => "new")
50
+ #
51
+ # Anonymous Paramters
52
+ #
53
+ # Merb::Router.prepare do
54
+ # match("/articles/:year/:month/:title").to(:controller => :articles, :action => :show).name("articles")
55
+ # end
56
+ #
57
+ # url(:articles, 2008, 10, "test_article")
58
+ #
59
+ # @api public
14
60
  def url(*args)
15
61
  args << (@request_params || {})
16
62
  Merb::Router.url(*args)
@@ -62,42 +62,6 @@ Spec::Matchers.create(:have_content_type) do
62
62
  end
63
63
  end
64
64
 
65
- Spec::Matchers.create(:have_xpath) do
66
- matches do |rack, xpath|
67
- document = rack.body
68
-
69
- if rack.status < 200 || rack.status >= 300
70
- @error_text = rack.body
71
- false
72
- else
73
- @document = case document
74
- when LibXML::XML::Document, LibXML::XML::Node
75
- document
76
- when StringIO
77
- LibXML::XML::HTMLParser.string(document.string).parse
78
- else
79
- LibXML::XML::HTMLParser.string(document).parse
80
- end
81
- begin
82
- !@document.find(xpath).empty?
83
- rescue LibXML::XML::XPath::InvalidPath
84
- @bad_xpath = true
85
- false
86
- end
87
- end
88
- end
89
-
90
- message do |not_string, rack, xpath|
91
- if @bad_xpath
92
- "the XPath '#{xpath}' was invalid"
93
- elsif @error_text
94
- "there was an error on your page:\n#{@error_text}"
95
- else
96
- "expected the following text #{not_string}to match the xpath '#{xpath}':\n\n#{@document}"
97
- end
98
- end
99
- end
100
-
101
65
  Spec::Matchers.create(:redirect) do
102
66
  matches do |rack|
103
67
  @inspect = describe_input(rack)
@@ -118,6 +82,8 @@ Spec::Matchers.create(:redirect_to) do
118
82
 
119
83
  matches do |rack, location|
120
84
  @inspect = describe_input(rack)
85
+
86
+ return false unless rack.headers["Location"]
121
87
  @location, @query = rack.headers["Location"].split("?")
122
88
  @status_code = status_code(rack)
123
89
  @status_code.in?(300..399) && @location == location
@@ -9,6 +9,8 @@ module Merb::Test::Rspec::ViewMatchers
9
9
  end
10
10
 
11
11
  def matches_rexml?(stringlike)
12
+ stringlike = stringlike.body.to_s if stringlike.respond_to?(:body)
13
+
12
14
  @document = case stringlike
13
15
  when REXML::Document
14
16
  stringlike.root
@@ -21,6 +23,8 @@ module Merb::Test::Rspec::ViewMatchers
21
23
  end
22
24
 
23
25
  def matches_libxml?(stringlike)
26
+ stringlike = stringlike.body.to_s if stringlike.respond_to?(:body)
27
+
24
28
  @document = case stringlike
25
29
  when LibXML::XML::Document, LibXML::XML::Node
26
30
  stringlike
@@ -164,6 +168,8 @@ module Merb::Test::Rspec::ViewMatchers
164
168
 
165
169
  class HasTag
166
170
 
171
+ attr_accessor :outer_has_tag, :inner_has_tag
172
+
167
173
  # ==== Parameters
168
174
  # tag<~to_s>:: The tag to look for.
169
175
  # attributes<Hash>:: Attributes for the tag (see below).
@@ -193,8 +199,13 @@ module Merb::Test::Rspec::ViewMatchers
193
199
 
194
200
  unless @blk.nil?
195
201
  !@document.search(selector).select do |ele|
196
- @blk.call ele
197
- true
202
+ begin
203
+ @blk.call ele
204
+ true
205
+ rescue Spec::Expectations::ExpectationNotMetError
206
+ @error_message = "#{tag_for_error}:\n" + $!.message
207
+ false
208
+ end
198
209
  end.empty?
199
210
  else
200
211
  !@document.search(selector).empty?
@@ -204,12 +215,10 @@ module Merb::Test::Rspec::ViewMatchers
204
215
  # ==== Returns
205
216
  # String:: The complete selector for element queries.
206
217
  def selector
207
- @selector = "//#{@tag}#{id_selector}#{class_selector}"
208
- @selector << @attributes.map{|a, v| "[@#{a}=\"#{v}\"]"}.join
209
-
210
- @selector << @inner_has_tag.selector unless @inner_has_tag.nil?
218
+ @selector = @outer_has_tag ? @outer_has_tag.selector : ''
211
219
 
212
- @selector
220
+ @selector << "//#{@tag}#{id_selector}#{class_selector}"
221
+ @selector << @attributes.map{|a, v| "[@#{a}=\"#{v}\"]"}.join
213
222
  end
214
223
 
215
224
  # ==== Returns
@@ -227,45 +236,38 @@ module Merb::Test::Rspec::ViewMatchers
227
236
  # ==== Returns
228
237
  # String:: The failure message.
229
238
  def failure_message
230
- "expected following output to contain a #{tag_for_error} tag:\n#{@document}"
239
+ @error_message || "expected following output to contain a #{tag_for_error} tag:\n#{@document}"
231
240
  end
232
241
 
233
242
  # ==== Returns
234
243
  # String:: The failure message to be displayed in negative matches.
235
244
  def negative_failure_message
236
- "expected following output to omit a #{tag_for_error} tag:\n#{@document}"
245
+ @error_message || "expected following output to omit a #{tag_for_error} tag:\n#{@document}"
237
246
  end
238
247
 
239
248
  # ==== Returns
240
249
  # String:: The tag used in failure messages.
241
250
  def tag_for_error
242
- "#{inner_failure_message}<#{@tag}#{id_for_error}#{class_for_error}#{attributes_for_error}>"
243
- end
244
-
245
- # ==== Returns
246
- # String::
247
- # The failure message to be displayed in negative matches within the
248
- # have_tag block.
249
- def inner_failure_message
250
- "#{@inner_has_tag.tag_for_error} tag within a " unless @inner_has_tag.nil?
251
+ result = "#{@tag}#{id_for_error}#{class_for_error}#{attributes_for_error}"
252
+ inner_has_tag ? result << " > #{inner_has_tag.tag_for_error}" : result
251
253
  end
252
254
 
253
255
  # ==== Returns
254
256
  # String:: ID for the error tag.
255
257
  def id_for_error
256
- " id=\"#{@id}\"" unless @id.nil?
258
+ "##{@id}" unless @id.nil?
257
259
  end
258
260
 
259
261
  # ==== Returns
260
262
  # String:: Class for the error tag.
261
263
  def class_for_error
262
- " class=\"#{@class}\"" unless @class.nil?
264
+ ".#{@class}" unless @class.nil?
263
265
  end
264
266
 
265
267
  # ==== Returns
266
268
  # String:: Class for the error tag.
267
269
  def attributes_for_error
268
- @attributes.map{|a,v| " #{a}=\"#{v}\""}.join
270
+ @attributes.map{|a,v| "[#{a}=\"#{v}\"]"}.join
269
271
  end
270
272
 
271
273
  # Search for a child tag within a have_tag block.
@@ -275,6 +277,9 @@ module Merb::Test::Rspec::ViewMatchers
275
277
  # attributes<Hash>:: Attributes for the tag (see below).
276
278
  def with_tag(name, attrs={})
277
279
  @inner_has_tag = HasTag.new(name, attrs)
280
+ @inner_has_tag.outer_has_tag = self
281
+
282
+ @inner_has_tag
278
283
  end
279
284
  end
280
285
 
@@ -353,7 +358,12 @@ module Merb::Test::Rspec::ViewMatchers
353
358
  require "libxml"
354
359
  type = "libxml"
355
360
  rescue LoadError => e
356
- require "rexml/document"
361
+ if require "rexml/document" # show warning only once
362
+ warn(<<-WARN_TEXT)
363
+ Standard REXML library is slow. Please consider to install libxml-ruby.
364
+ Use "sudo gem install libxml-ruby"
365
+ WARN_TEXT
366
+ end
357
367
  type = "rexml"
358
368
  end
359
369
  HaveXpath.new(expected, type)
@@ -104,7 +104,8 @@ def run_specs(globs, spec_cmd='spec', run_opts = "-c", except = [])
104
104
  globs = globs.is_a?(Array) ? globs : [globs]
105
105
 
106
106
  counter = Merb::Counter.new
107
- forks = 0
107
+ forks = 0
108
+ failure = false
108
109
 
109
110
  time = Benchmark.measure do
110
111
  pid = nil
@@ -120,7 +121,7 @@ def run_specs(globs, spec_cmd='spec', run_opts = "-c", except = [])
120
121
  def out.tty?() true end
121
122
  options = Spec::Runner::OptionParser.parse(%W(#{spec} -fs --color), err, out)
122
123
  options.filename_pattern = File.expand_path(spec)
123
- Spec::Runner::CommandLine.run(options)
124
+ failure = ! Spec::Runner::CommandLine.run(options)
124
125
  begin
125
126
  counter_client.add(spec, out.string, err.string)
126
127
  rescue DRb::DRbConnError => e
@@ -128,14 +129,14 @@ def run_specs(globs, spec_cmd='spec', run_opts = "-c", except = [])
128
129
  puts "#{e.class}: #{e.message}"
129
130
  retry
130
131
  end
131
- exit
132
+ exit(failure ? -1 : 0)
132
133
  end
133
134
  end
134
- Process.waitall
135
+ failure = Process.waitall.any? { |pid, s| !s.success? }
135
136
  end
136
137
  end
137
138
 
138
139
  counter.time = time
139
140
  counter.report
140
- exit!
141
+ exit!(failure ? -1 : 0)
141
142
  end
@@ -7,7 +7,7 @@ module Kernel
7
7
  params[:shared] = true
8
8
 
9
9
  describe(*args) do
10
- before(:each) do
10
+ prepend_before(:each) do
11
11
  self.instance_eval(&example_group_block)
12
12
  end
13
13
  end
@@ -51,25 +51,12 @@ module Merb
51
51
  # This is a copy of the method in rspec, so we can have
52
52
  # describe "...", :when => "logged in", and the like
53
53
  def describe(*args, &example_group_block)
54
- args << {} unless Hash === args.last
54
+ ret = super
55
+
56
+ params = args.last.is_a?(Hash) ? args.last : {}
55
57
  if example_group_block
56
- params = args.last
57
- params[:spec_path] = eval("caller(0)[1]", example_group_block) unless params[:spec_path]
58
- if params[:shared]
59
- ::Spec::Example::SharedExampleGroup.new(*args, &example_group_block)
60
- else
61
- self.subclass("Subclass") do
62
- describe(*args)
63
- if params[:when] || (params[:when] = params[:given])
64
- module_eval %{it_should_behave_like "#{params[:when]}"}
65
- end
66
- module_eval(&example_group_block)
67
- end
68
- end
69
- else
70
- set_description(*args)
71
- before_eval
72
- self
58
+ params[:when] = params[:when] || params[:given]
59
+ ret.module_eval %{it_should_behave_like "#{params[:when]}"} if params[:when]
73
60
  end
74
61
  end
75
62
  alias context describe
@@ -1,3 +1,3 @@
1
1
  module Merb
2
- VERSION = '0.9.8' unless defined?(Merb::VERSION)
2
+ VERSION = '0.9.9' unless defined?(Merb::VERSION)
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: merb-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.8
4
+ version: 0.9.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ezra Zygmuntowicz
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-10-06 00:00:00 +03:00
12
+ date: 2008-10-13 00:00:00 +03:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.9.7
23
+ version: 0.9.8
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: erubis
@@ -100,7 +100,7 @@ dependencies:
100
100
  requirements:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: 0.9.6
103
+ version: 0.9.7
104
104
  version:
105
105
  description: Merb. Pocket rocket web framework.
106
106
  email: ez@engineyard.com
@@ -188,6 +188,7 @@ files:
188
188
  - lib/merb-core/rack/application.rb
189
189
  - lib/merb-core/rack/handler
190
190
  - lib/merb-core/rack/handler/mongrel.rb
191
+ - lib/merb-core/rack/helpers.rb
191
192
  - lib/merb-core/rack/middleware
192
193
  - lib/merb-core/rack/middleware/conditional_get.rb
193
194
  - lib/merb-core/rack/middleware/content_length.rb