merb-core 0.9.8 → 0.9.9

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