merb 0.3.7 → 0.4.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.
- data/README +25 -26
- data/Rakefile +48 -36
- data/app_generators/merb/USAGE +5 -0
- data/app_generators/merb/merb_generator.rb +107 -0
- data/app_generators/merb/templates/Rakefile +99 -0
- data/{examples/skeleton/dist → app_generators/merb/templates}/app/controllers/application.rb +1 -1
- data/app_generators/merb/templates/app/controllers/exceptions.rb +13 -0
- data/{examples/skeleton/dist → app_generators/merb/templates}/app/helpers/global_helper.rb +0 -0
- data/{examples/skeleton/dist/app/mailers → app_generators/merb/templates/app/mailers/views}/layout/application.erb +0 -0
- data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +207 -0
- data/app_generators/merb/templates/app/views/exceptions/not_acceptable.html.erb +38 -0
- data/app_generators/merb/templates/app/views/exceptions/not_found.html.erb +40 -0
- data/app_generators/merb/templates/app/views/layout/application.html.erb +11 -0
- data/app_generators/merb/templates/config/boot.rb +11 -0
- data/app_generators/merb/templates/config/dependencies.rb +41 -0
- data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/development.rb +0 -0
- data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/production.rb +0 -0
- data/{examples/skeleton/dist/conf → app_generators/merb/templates/config}/environments/test.rb +0 -0
- data/app_generators/merb/templates/config/merb.yml +64 -0
- data/app_generators/merb/templates/config/merb_init.rb +16 -0
- data/app_generators/merb/templates/config/plugins.yml +1 -0
- data/app_generators/merb/templates/config/router.rb +32 -0
- data/{lib/merb/core_ext/merb_array.rb → app_generators/merb/templates/config/upload.conf} +0 -0
- data/app_generators/merb/templates/public/images/merb.jpg +0 -0
- data/app_generators/merb/templates/public/merb.fcgi +6 -0
- data/app_generators/merb/templates/public/stylesheets/master.css +119 -0
- data/app_generators/merb/templates/script/destroy +28 -0
- data/app_generators/merb/templates/script/generate +28 -0
- data/{examples/skeleton → app_generators/merb/templates}/script/stop_merb +0 -0
- data/app_generators/merb/templates/script/win_script.cmd +1 -0
- data/app_generators/merb/templates/spec/spec.opts +6 -0
- data/app_generators/merb/templates/spec/spec_helper.rb +10 -0
- data/app_generators/merb/templates/test/test_helper.rb +13 -0
- data/app_generators/merb_plugin/USAGE +5 -0
- data/app_generators/merb_plugin/merb_plugin_generator.rb +64 -0
- data/app_generators/merb_plugin/templates/LICENSE +20 -0
- data/app_generators/merb_plugin/templates/README +4 -0
- data/app_generators/merb_plugin/templates/Rakefile +35 -0
- data/app_generators/merb_plugin/templates/TODO +5 -0
- data/app_generators/merb_plugin/templates/merbtasks.rb +6 -0
- data/app_generators/merb_plugin/templates/sampleplugin.rb +10 -0
- data/app_generators/merb_plugin/templates/sampleplugin_spec.rb +7 -0
- data/app_generators/merb_plugin/templates/spec_helper.rb +2 -0
- data/bin/merb +1 -1
- data/lib/autotest/discover.rb +3 -0
- data/lib/autotest/merb_rspec.rb +79 -0
- data/lib/merb.rb +72 -93
- data/lib/merb/{merb_abstract_controller.rb → abstract_controller.rb} +28 -5
- data/lib/merb/caching/action_cache.rb +65 -29
- data/lib/merb/caching/fragment_cache.rb +9 -4
- data/lib/merb/caching/store/file_cache.rb +22 -14
- data/lib/merb/caching/store/memory_cache.rb +26 -8
- data/lib/merb/{merb_constants.rb → constants.rb} +9 -7
- data/lib/merb/controller.rb +178 -0
- data/lib/merb/core_ext.rb +13 -11
- data/lib/merb/core_ext/array.rb +0 -0
- data/lib/merb/core_ext/{merb_class.rb → class.rb} +0 -0
- data/lib/merb/core_ext/{merb_enumerable.rb → enumerable.rb} +0 -0
- data/lib/merb/core_ext/get_args.rb +52 -0
- data/lib/merb/core_ext/{merb_hash.rb → hash.rb} +40 -11
- data/lib/merb/core_ext/{merb_inflections.rb → inflections.rb} +0 -0
- data/lib/merb/core_ext/{merb_inflector.rb → inflector.rb} +1 -1
- data/lib/merb/core_ext/{merb_kernel.rb → kernel.rb} +56 -3
- data/lib/merb/core_ext/mash.rb +88 -0
- data/lib/merb/core_ext/{merb_module.rb → module.rb} +0 -0
- data/lib/merb/core_ext/{merb_numeric.rb → numeric.rb} +0 -0
- data/lib/merb/core_ext/{merb_object.rb → object.rb} +10 -47
- data/lib/merb/core_ext/string.rb +56 -0
- data/lib/merb/core_ext/{merb_symbol.rb → symbol.rb} +0 -0
- data/lib/merb/dispatcher.rb +109 -0
- data/lib/merb/{merb_drb_server.rb → drb_server.rb} +0 -0
- data/lib/merb/erubis_ext.rb +10 -0
- data/lib/merb/exceptions.rb +173 -0
- data/lib/merb/generators/merb_app/merb_app.rb +5 -25
- data/lib/merb/generators/merb_generator_helpers.rb +317 -0
- data/lib/merb/generators/merb_plugin.rb +19 -0
- data/lib/merb/logger.rb +65 -0
- data/lib/merb/{merb_mail_controller.rb → mail_controller.rb} +102 -49
- data/lib/merb/{merb_mailer.rb → mailer.rb} +31 -27
- data/lib/merb/mixins/{basic_authentication_mixin.rb → basic_authentication.rb} +3 -3
- data/lib/merb/mixins/{controller_mixin.rb → controller.rb} +131 -112
- data/lib/merb/mixins/{erubis_capture_mixin.rb → erubis_capture.rb} +12 -21
- data/lib/merb/mixins/{form_control_mixin.rb → form_control.rb} +6 -12
- data/lib/merb/mixins/render.rb +401 -0
- data/lib/merb/mixins/responder.rb +378 -0
- data/lib/merb/mixins/{view_context_mixin.rb → view_context.rb} +65 -10
- data/lib/merb/mixins/web_controller.rb +29 -0
- data/lib/merb/{merb_handler.rb → mongrel_handler.rb} +59 -38
- data/lib/merb/part_controller.rb +19 -0
- data/lib/merb/plugins.rb +16 -0
- data/lib/merb/rack_adapter.rb +37 -0
- data/lib/merb/request.rb +421 -0
- data/lib/merb/router.rb +576 -0
- data/lib/merb/{merb_server.rb → server.rb} +275 -71
- data/lib/merb/session.rb +10 -10
- data/lib/merb/session/cookie_store.rb +125 -0
- data/lib/merb/session/{merb_mem_cache_session.rb → mem_cache_session.rb} +22 -9
- data/lib/merb/session/{merb_memory_session.rb → memory_session.rb} +15 -11
- data/lib/merb/template.rb +35 -8
- data/lib/merb/template/erubis.rb +16 -10
- data/lib/merb/template/haml.rb +33 -20
- data/lib/merb/template/markaby.rb +16 -14
- data/lib/merb/template/xml_builder.rb +8 -4
- data/lib/merb/test/{merb_fake_request.rb → fake_request.rb} +11 -5
- data/lib/merb/test/helper.rb +31 -0
- data/lib/merb/test/hpricot.rb +136 -0
- data/lib/merb/test/{merb_multipart.rb → multipart.rb} +1 -1
- data/lib/merb/test/rspec.rb +93 -0
- data/lib/merb/{merb_upload_handler.rb → upload_handler.rb} +5 -6
- data/lib/merb/{merb_upload_progress.rb → upload_progress.rb} +1 -1
- data/lib/merb/{merb_view_context.rb → view_context.rb} +27 -42
- data/lib/{merb_tasks.rb → tasks.rb} +0 -0
- data/lib/tasks/merb.rake +21 -11
- data/merb_default_generators/model/USAGE +0 -0
- data/merb_default_generators/model/model_generator.rb +16 -0
- data/merb_default_generators/model/templates/new_model_template.erb +5 -0
- data/merb_default_generators/resource_controller/USAGE +0 -0
- data/merb_default_generators/resource_controller/resource_controller_generator.rb +26 -0
- data/merb_default_generators/resource_controller/templates/controller.rb +30 -0
- data/merb_default_generators/resource_controller/templates/edit.html.erb +1 -0
- data/merb_default_generators/resource_controller/templates/helper.rb +5 -0
- data/merb_default_generators/resource_controller/templates/index.html.erb +1 -0
- data/merb_default_generators/resource_controller/templates/new.html.erb +1 -0
- data/merb_default_generators/resource_controller/templates/show.html.erb +1 -0
- data/merb_generators/controller/USAGE +5 -0
- data/merb_generators/controller/controller_generator.rb +16 -0
- data/merb_generators/controller/templates/controller.rb +8 -0
- data/merb_generators/controller/templates/helper.rb +5 -0
- data/merb_generators/controller/templates/index.html.erb +3 -0
- data/merb_generators/resource/USAGE +0 -0
- data/merb_generators/resource/resource_generator.rb +60 -0
- data/rspec_generators/merb_controller_test/merb_controller_test_generator.rb +67 -0
- data/rspec_generators/merb_controller_test/templates/controller_spec.rb +8 -0
- data/rspec_generators/merb_controller_test/templates/edit_spec.rb +12 -0
- data/rspec_generators/merb_controller_test/templates/helper_spec.rb +5 -0
- data/rspec_generators/merb_controller_test/templates/index_spec.rb +12 -0
- data/rspec_generators/merb_controller_test/templates/new_spec.rb +12 -0
- data/rspec_generators/merb_controller_test/templates/show_spec.rb +5 -0
- data/rspec_generators/merb_model_test/merb_model_test_generator.rb +26 -0
- data/rspec_generators/merb_model_test/templates/model_spec_template.erb +7 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/test_unit_generators/merb_controller_test/merb_controller_test_generator.rb +53 -0
- data/test_unit_generators/merb_controller_test/templates/functional_test.rb +17 -0
- data/test_unit_generators/merb_controller_test/templates/helper_test.rb +9 -0
- data/test_unit_generators/merb_model_test/merb_model_test_generator.rb +29 -0
- data/test_unit_generators/merb_model_test/templates/model_test_unit_template.erb +9 -0
- metadata +172 -94
- data/examples/README_EXAMPLES +0 -10
- data/examples/skeleton/Rakefile +0 -68
- data/examples/skeleton/dist/app/views/layout/application.herb +0 -12
- data/examples/skeleton/dist/conf/database.yml +0 -23
- data/examples/skeleton/dist/conf/merb.yml +0 -57
- data/examples/skeleton/dist/conf/merb_init.rb +0 -24
- data/examples/skeleton/dist/conf/router.rb +0 -22
- data/examples/skeleton/dist/conf/upload.conf +0 -5
- data/examples/skeleton/dist/schema/migrations/001_add_sessions_table.rb +0 -14
- data/examples/skeleton/script/new_migration +0 -21
- data/lib/merb/core_ext/merb_string.rb +0 -18
- data/lib/merb/merb_controller.rb +0 -206
- data/lib/merb/merb_dispatcher.rb +0 -87
- data/lib/merb/merb_exceptions.rb +0 -319
- data/lib/merb/merb_part_controller.rb +0 -42
- data/lib/merb/merb_plugins.rb +0 -293
- data/lib/merb/merb_request.rb +0 -165
- data/lib/merb/merb_router.rb +0 -309
- data/lib/merb/merb_yaml_store.rb +0 -31
- data/lib/merb/mixins/render_mixin.rb +0 -283
- data/lib/merb/mixins/responder_mixin.rb +0 -159
- data/lib/merb/session/merb_ar_session.rb +0 -131
- data/lib/merb/vendor/paginator/README.txt +0 -84
- data/lib/merb/vendor/paginator/paginator.rb +0 -124
- data/lib/tasks/db.rake +0 -55
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
begin
|
|
3
2
|
require 'markaby'
|
|
4
3
|
rescue LoadError
|
|
@@ -7,22 +6,20 @@ end
|
|
|
7
6
|
|
|
8
7
|
module Markaby
|
|
9
8
|
class Builder
|
|
10
|
-
def
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
def _buffer( binding )
|
|
10
|
+
eval( "_erbout", binding )
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def concat( string, binding )
|
|
14
|
+
_buffer( binding ) << string
|
|
14
15
|
end
|
|
15
16
|
end
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
module Merb
|
|
19
20
|
|
|
20
|
-
module Template
|
|
21
|
-
|
|
22
|
-
module Markaby
|
|
23
|
-
|
|
24
|
-
::Merb::AbstractController.register_engine self, %w[ mab ]
|
|
25
|
-
|
|
21
|
+
module Template
|
|
22
|
+
module Markaby
|
|
26
23
|
class << self
|
|
27
24
|
|
|
28
25
|
def exempt_from_layout?
|
|
@@ -32,7 +29,7 @@ module Merb
|
|
|
32
29
|
# OPTIMIZE : add mab template caching. what does this mean for mab?
|
|
33
30
|
# mab is just ruby, there's no two phase compile and run
|
|
34
31
|
def transform(options = {})
|
|
35
|
-
opts, file, view_context = options.values_at(:opts, :file, :view_context)
|
|
32
|
+
opts, text, file, view_context = options.values_at(:opts, :text, :file, :view_context)
|
|
36
33
|
|
|
37
34
|
if opts[:locals]
|
|
38
35
|
locals = ""
|
|
@@ -42,12 +39,17 @@ module Merb
|
|
|
42
39
|
locals
|
|
43
40
|
end
|
|
44
41
|
|
|
42
|
+
template = text ? text : File.read(file)
|
|
45
43
|
mab = ::Markaby::Builder.new({}, view_context) {
|
|
46
|
-
instance_eval("#{locals}#{
|
|
44
|
+
instance_eval("#{locals}#{template}")
|
|
47
45
|
}
|
|
48
46
|
mab.to_s
|
|
49
47
|
end
|
|
50
|
-
|
|
48
|
+
|
|
49
|
+
def view_context_klass
|
|
50
|
+
::Merb::ViewContext
|
|
51
|
+
end
|
|
52
|
+
|
|
51
53
|
end
|
|
52
54
|
|
|
53
55
|
end
|
|
@@ -9,10 +9,11 @@ module Merb
|
|
|
9
9
|
module Template # :nodoc:
|
|
10
10
|
# A module to allow you to use Builder["http://builder.rubyforge.org/"] templates in your Merb applications.
|
|
11
11
|
# Your Builder templates must end in .rxml, .xerb, or .builder for Merb to use them.
|
|
12
|
-
module XMLBuilder
|
|
13
12
|
|
|
14
|
-
::Merb::AbstractController.register_engine self, %w[ rxml xerb builder]
|
|
15
13
|
|
|
14
|
+
|
|
15
|
+
module XMLBuilder
|
|
16
|
+
|
|
16
17
|
class << self
|
|
17
18
|
|
|
18
19
|
def exempt_from_layout? # :nodoc:
|
|
@@ -25,8 +26,8 @@ module Merb
|
|
|
25
26
|
# executes the Builder template by feeding it to <tt>Builder::XmlMarkup.new</tt>,
|
|
26
27
|
# then calls <tt>target!</tt> on the<tt>Builder::XmlMarkup</tt> instance to get its XML output.
|
|
27
28
|
def transform(options = {})
|
|
28
|
-
opts, file, view_context = options.values_at(:opts, :file, :view_context)
|
|
29
|
-
xml_body = IO.read(file)
|
|
29
|
+
opts, text, file, view_context = options.values_at(:opts, :text, :file, :view_context)
|
|
30
|
+
xml_body = text ? text : IO.read(file)
|
|
30
31
|
view_context.headers['Content-Type'] = 'application/xml'
|
|
31
32
|
view_context.headers['Encoding'] = 'UTF-8'
|
|
32
33
|
view_context.instance_eval %{
|
|
@@ -37,6 +38,9 @@ module Merb
|
|
|
37
38
|
}
|
|
38
39
|
end
|
|
39
40
|
|
|
41
|
+
def view_context_klass
|
|
42
|
+
::Merb::ViewContext
|
|
43
|
+
end
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'ostruct'
|
|
2
|
+
|
|
1
3
|
module Merb
|
|
2
4
|
module Test
|
|
3
5
|
# FakeRequest sets up a default enviroment which can be overridden either
|
|
@@ -8,14 +10,19 @@ module Merb
|
|
|
8
10
|
alias :params :env
|
|
9
11
|
alias :to_hash :env
|
|
10
12
|
|
|
11
|
-
def initialize(env = {},
|
|
13
|
+
def initialize(env = {}, req = StringIO.new)
|
|
12
14
|
env[:http_cookie] = env.delete(:cookies) if env[:cookies]
|
|
13
15
|
env.environmentize_keys!
|
|
14
|
-
|
|
16
|
+
|
|
17
|
+
r = OpenStruct.new
|
|
18
|
+
r.params = DEFAULT_ENV.dup.merge(env)
|
|
19
|
+
r.body = req
|
|
20
|
+
super(r)
|
|
15
21
|
self.post_body = ''
|
|
16
22
|
end
|
|
17
23
|
|
|
18
24
|
def self.with(path, options = {})
|
|
25
|
+
options.merge!(:QUERY_STRING => path.split("?")[1])
|
|
19
26
|
options.environmentize_keys!
|
|
20
27
|
new({'REQUEST_URI' => path,
|
|
21
28
|
'PATH_INFO' => path.sub(/\?.*$/,'')}.merge(options))
|
|
@@ -32,8 +39,7 @@ module Merb
|
|
|
32
39
|
def []=(key, value)
|
|
33
40
|
@env[key] = value
|
|
34
41
|
end
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
|
|
37
43
|
private
|
|
38
44
|
DEFAULT_ENV = {
|
|
39
45
|
'SERVER_NAME' => 'localhost',
|
|
@@ -57,7 +63,7 @@ module Merb
|
|
|
57
63
|
'HTTP_ACCEPT' => 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
|
|
58
64
|
'HTTP_CONNECTION' => 'keep-alive',
|
|
59
65
|
'REQUEST_METHOD' => 'GET'
|
|
60
|
-
}
|
|
66
|
+
} unless defined?(DEFAULT_ENV)
|
|
61
67
|
end
|
|
62
68
|
end
|
|
63
69
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'merb/test/fake_request'
|
|
2
|
+
require 'merb/test/hpricot'
|
|
3
|
+
include HpricotTestHelper
|
|
4
|
+
|
|
5
|
+
# Create a FakeRequest suitable for passing to Controller.build
|
|
6
|
+
def fake_request(path="/",method='GET')
|
|
7
|
+
method = method.to_s.upcase
|
|
8
|
+
Merb::Test::FakeRequest.with(path, :request_method => method)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Turn a named route into a string with the path
|
|
12
|
+
def url(name, *args)
|
|
13
|
+
Merb::Router.generate(name, *args)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# For integration/functional testing
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def request(verb, path)
|
|
21
|
+
response = StringIO.new
|
|
22
|
+
@request = Merb::Test::FakeRequest.with(path, :request_method => (verb.to_s.upcase rescue 'GET'))
|
|
23
|
+
|
|
24
|
+
yield @request if block_given?
|
|
25
|
+
|
|
26
|
+
@controller, @action = Merb::Dispatcher.handle @request, response
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def get(path)
|
|
30
|
+
request("GET",path)
|
|
31
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# http://yehudakatz.com/2007/01/27/a-better-assert_select-assert_elements/
|
|
2
|
+
# based on assert_elements
|
|
3
|
+
# Author: Yehuda Katz
|
|
4
|
+
# Email: wycats @nospam@ gmail.com
|
|
5
|
+
# Web: http://www.yehudakatz.com
|
|
6
|
+
#
|
|
7
|
+
# which was based on HpricotTestHelper
|
|
8
|
+
# Author: Luke Redpath
|
|
9
|
+
# Email: contact @nospam@ lukeredpath.co.uk
|
|
10
|
+
# Web: www.lukeredpath.co.uk / opensource.agileevolved.com
|
|
11
|
+
|
|
12
|
+
require 'hpricot'
|
|
13
|
+
|
|
14
|
+
class Hpricot::Elem
|
|
15
|
+
def should_contain(value)
|
|
16
|
+
self.inner_text.include?(value)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def should_match(regex)
|
|
20
|
+
self.inner_text.match(regex)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# courtesy of 'thomas' from the comments
|
|
24
|
+
# of _whys blog - get in touch if you want a better credit!
|
|
25
|
+
def inner_text
|
|
26
|
+
self.children.collect do |child|
|
|
27
|
+
child.is_a?(Hpricot::Text) ? child.content : ((child.respond_to?("inner_text") && child.inner_text) || "")
|
|
28
|
+
end.join.strip
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module HpricotTestHelper
|
|
33
|
+
# returns the inner content of
|
|
34
|
+
# the first tag found by the css query
|
|
35
|
+
def tag(css_query)
|
|
36
|
+
process_output
|
|
37
|
+
@output.content_for(css_query)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# returns an array of tag contents
|
|
41
|
+
# for all of the tags found by the
|
|
42
|
+
# css query
|
|
43
|
+
def tags(css_query)
|
|
44
|
+
process_output
|
|
45
|
+
@output.content_for_all(css_query)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# returns a raw Hpricot::Elem object
|
|
49
|
+
# for the first result found by the query
|
|
50
|
+
def element(css_query)
|
|
51
|
+
process_output
|
|
52
|
+
@output[css_query].first
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# returns an array of Hpricot::Elem objects
|
|
56
|
+
# for the results found by the query
|
|
57
|
+
def elements(css_query)
|
|
58
|
+
process_output
|
|
59
|
+
Hpricot::Elements[*css_query.split(",").map(&:strip).map do |query|
|
|
60
|
+
@output[query]
|
|
61
|
+
end.flatten]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def get_elements css_query, text
|
|
65
|
+
els = elements(css_query)
|
|
66
|
+
case text
|
|
67
|
+
when String then els.reject! {|t| !t.should_contain(text) }
|
|
68
|
+
when Regexp then els.reject! {|t| !t.should_match(text) }
|
|
69
|
+
end
|
|
70
|
+
els
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def assert_elements css_query, equality = nil, &block
|
|
74
|
+
message = equality.delete(:message) if equality.is_a?(Hash)
|
|
75
|
+
|
|
76
|
+
case equality
|
|
77
|
+
when Numeric then equality = {:count => equality}
|
|
78
|
+
when Range then equality = {:minimum => equality.to_a.first, :maximum => equality.to_a.last }
|
|
79
|
+
else equality ||= {}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
equality.merge!({:minimum => 1}) if (equality.keys & [:minimum, :maximum, :count]).empty?
|
|
83
|
+
|
|
84
|
+
els = get_elements(css_query, equality[:text])
|
|
85
|
+
|
|
86
|
+
ret = equality.keys.include?(:minimum) ? (els.size >= equality[:minimum]) : true
|
|
87
|
+
ret &&= (els.size <= equality[:maximum]) if equality.keys.include?(:maximum)
|
|
88
|
+
ret &&= (els.size == equality[:count]) if equality.keys.include?(:count)
|
|
89
|
+
|
|
90
|
+
if block && !els.empty?
|
|
91
|
+
ret &&= self.dup.instance_eval do
|
|
92
|
+
@output = HpricotTestHelper::DocumentOutput.new(els.inner_html)
|
|
93
|
+
@block = true
|
|
94
|
+
instance_eval(&block)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
if(equality[:count] != 0)
|
|
99
|
+
assert ret, "#{ message } \"#{ css_query }\" with \"#{ equality.inspect }\" was not found."
|
|
100
|
+
else
|
|
101
|
+
assert ret, "#{ message } \"#{ css_query }\" with \"#{ equality.reject{|k,v| k == :count}.inspect }\" was found, but you specified :count => 0."
|
|
102
|
+
end
|
|
103
|
+
ret
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# small utility class for working with
|
|
107
|
+
# the Hpricot parser class
|
|
108
|
+
class DocumentOutput
|
|
109
|
+
def initialize(response_body)
|
|
110
|
+
@parser = Hpricot.parse(response_body)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def content_for(css_query)
|
|
114
|
+
@parser.search(css_query).first.inner_text
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def content_for_all(css_query)
|
|
118
|
+
@parser.search(css_query).collect(&:inner_text)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def [](css_query)
|
|
122
|
+
@parser.search(css_query)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
protected
|
|
127
|
+
# creates a new DocumentOutput object from the response
|
|
128
|
+
# body if hasn't already been created. This is
|
|
129
|
+
# called automatically by the element and tag methods
|
|
130
|
+
def process_output
|
|
131
|
+
if !@block && (@output.nil? || (@controller.body != @response_output))
|
|
132
|
+
@output = HpricotTestHelper::DocumentOutput.new(@controller.body)
|
|
133
|
+
@response_output = @controller.body
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
require 'hpricot'
|
|
2
|
+
require 'spec'
|
|
3
|
+
module MerbRspecMatchers
|
|
4
|
+
class HaveSelector
|
|
5
|
+
def initialize(expected)
|
|
6
|
+
@expected = expected
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def matches?(stringlike)
|
|
10
|
+
@document = case stringlike
|
|
11
|
+
when Hpricot::Elem
|
|
12
|
+
stringlike
|
|
13
|
+
when StringIO
|
|
14
|
+
Hpricot.parse(stringlike.string)
|
|
15
|
+
else
|
|
16
|
+
Hpricot.parse(stringlike)
|
|
17
|
+
end
|
|
18
|
+
!@document.search(@expected).empty?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def failure_message
|
|
22
|
+
"expected following text to match selector #{@expected}:\n#{@document}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def negative_failure_message
|
|
26
|
+
"expected following text to not match selector #{@expected}:\n#{@document}"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class MatchTag
|
|
31
|
+
def initialize(name, attrs)
|
|
32
|
+
@name, @attrs = name, attrs
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def matches?(target)
|
|
36
|
+
@errors = []
|
|
37
|
+
unless target.include?("<#{@name}")
|
|
38
|
+
@errors << "Expected a <#{@name}>, but was #{target}"
|
|
39
|
+
end
|
|
40
|
+
@attrs.each do |attr, val|
|
|
41
|
+
unless target.include?("#{attr}=\"#{val}\"")
|
|
42
|
+
@errors << "Expected #{attr}=\"#{val}\", but was #{target}"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
@errors.size == 0
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def failure_message
|
|
49
|
+
@errors[0]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def negative_failure_message
|
|
53
|
+
"Expected not to match against <#{@name} #{@attrs.map{ |a,v| "#{a}=\"#{v}\"" }.join(" ")}> tag, but it matched"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
class NotMatchTag
|
|
58
|
+
def initialize(attrs)
|
|
59
|
+
@attrs = attrs
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def matches?(target)
|
|
63
|
+
@errors = []
|
|
64
|
+
@attrs.each do |attr, val|
|
|
65
|
+
if target.include?("#{attr}=\"#{val}\"")
|
|
66
|
+
@errors << "Should not include #{attr}=\"#{val}\", but was #{target}"
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
@errors.size == 0
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def failure_message
|
|
73
|
+
@errors[0]
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def match_tag(name, attrs)
|
|
78
|
+
MatchTag.new(name, attrs)
|
|
79
|
+
end
|
|
80
|
+
def not_match_tag(attrs)
|
|
81
|
+
NotMatchTag.new(attrs)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def have_selector(expected)
|
|
85
|
+
HaveSelector.new(expected)
|
|
86
|
+
end
|
|
87
|
+
alias_method :match_selector, :have_selector
|
|
88
|
+
# alias_method :match_regex, :match
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
Spec::Runner.configure do |config|
|
|
92
|
+
config.include(MerbRspecMatchers)
|
|
93
|
+
end
|
|
@@ -28,15 +28,14 @@ end
|
|
|
28
28
|
class MerbUploadHandler < Mongrel::HttpHandler
|
|
29
29
|
|
|
30
30
|
def initialize(options = {})
|
|
31
|
-
@
|
|
32
|
-
@frequency = options[:
|
|
31
|
+
@path_match = Regexp.new(options[:upload_path_match])
|
|
32
|
+
@frequency = options[:upload_frequency] || 3
|
|
33
33
|
@request_notify = true
|
|
34
|
-
if options[:
|
|
34
|
+
if options[:start_drb]
|
|
35
35
|
require 'drb'
|
|
36
36
|
DRb.start_service
|
|
37
|
-
Mongrel.const_set :Uploads, DRbObject.new(nil, "druby://#{
|
|
37
|
+
Mongrel.const_set :Uploads, DRbObject.new(nil, "druby://#{options[:host]}:#{options[:drb_server_port]}").upload_progress
|
|
38
38
|
else
|
|
39
|
-
require File.dirname(__FILE__)+'/merb_upload_progress'
|
|
40
39
|
Mongrel.const_set :Uploads, Merb::UploadProgress.new
|
|
41
40
|
end
|
|
42
41
|
Mongrel::Uploads.debug = true if options[:debug]
|
|
@@ -72,7 +71,7 @@ class MerbUploadHandler < Mongrel::HttpHandler
|
|
|
72
71
|
end
|
|
73
72
|
|
|
74
73
|
def valid_upload?(params)
|
|
75
|
-
|
|
74
|
+
params[Mongrel::Const::PATH_INFO].match(@path_match) &&
|
|
76
75
|
[Mongrel::Const::POST, Mongrel::Const::PUT].include?(params[Mongrel::Const::REQUEST_METHOD]) &&
|
|
77
76
|
Mongrel::HttpRequest.query_parse(params[Mongrel::Const::QUERY_STRING])[Mongrel::Const::UPLOAD_ID]
|
|
78
77
|
end
|