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
@@ -7,13 +7,13 @@ module Merb
7
7
 
8
8
  module SessionMixin #:nodoc:
9
9
  def setup_session
10
- MERB_LOGGER.info("Setting Up Cookie Store Sessions")
10
+ Merb.logger.info("Setting Up Cookie Store Sessions")
11
11
  request.session = Merb::CookieStore.new(cookies[_session_id_key], session_secret_key)
12
12
  @original_session = request.session.read_cookie
13
13
  end
14
14
 
15
15
  def finalize_session
16
- MERB_LOGGER.info("Finalize Cookie Store Session")
16
+ Merb.logger.info("Finalize Cookie Store Session")
17
17
  new_session = request.session.read_cookie
18
18
 
19
19
  if @original_session != new_session
@@ -74,24 +74,25 @@ module Merb
74
74
  end
75
75
  end
76
76
 
77
- # assigns a key value pair
78
- def []=(k, v)
77
+ # assigns a key value pair
78
+ def []=(k, v)
79
79
  @data[k] = v
80
80
  end
81
81
 
82
- def [](k)
83
- @data[k]
84
- end
85
-
86
- # delete a key
87
- def delete(key)
88
- if @data.has_key?(key)
89
- @data.delete(key)
90
- end
82
+ def [](k)
83
+ @data[k]
84
+ end
85
+
86
+ def each(&b)
87
+ @data.each(&b)
91
88
  end
92
89
 
93
90
  private
94
91
 
92
+ def method_missing(name, *args, &block)
93
+ @data.send(name, *args, &block)
94
+ end
95
+
95
96
  # Generate the HMAC keyed message digest. Uses SHA1.
96
97
  def generate_digest(data)
97
98
  OpenSSL::HMAC.hexdigest(DIGEST, @secret, data)
@@ -5,7 +5,7 @@ module Merb
5
5
  module SessionMixin #:nodoc:
6
6
 
7
7
  def setup_session
8
- MERB_LOGGER.info("Setting up session")
8
+ Merb.logger.info("Setting up session")
9
9
  before = cookies[_session_id_key]
10
10
  request.session, cookies[_session_id_key] = Merb::MemCacheSession.persist(cookies[_session_id_key])
11
11
  @_fingerprint = Marshal.dump(request.session.data).hash
@@ -13,7 +13,7 @@ module Merb
13
13
  end
14
14
 
15
15
  def finalize_session
16
- MERB_LOGGER.info("Finalize session")
16
+ Merb.logger.info("Finalize session")
17
17
  if @_fingerprint != Marshal.dump(request.session.data).hash
18
18
  ::Cache.put("session:#{@_session.session_id}", request.session.data)
19
19
  end
@@ -102,19 +102,29 @@ module Merb
102
102
  def delete
103
103
  @data = {}
104
104
  end
105
-
106
- def [](key)
107
- @data[key]
108
- end
109
-
110
- def []=(key, val)
111
- @data[key] = val
112
- end
113
105
 
114
106
  # Has the session been loaded yet?
115
107
  def loaded?
116
108
  !! @data
117
109
  end
110
+
111
+ # assigns a key value pair
112
+ def []=(k, v)
113
+ @data[k] = v
114
+ end
115
+
116
+ def [](k)
117
+ @data[k]
118
+ end
119
+
120
+ def each(&b)
121
+ @data.each(&b)
122
+ end
123
+
124
+ private
125
+ def method_missing(name, *args, &block)
126
+ @data.send(name, *args, &block)
127
+ end
118
128
 
119
129
  end
120
130
 
@@ -3,14 +3,14 @@ module Merb
3
3
  module SessionMixin #:nodoc:
4
4
 
5
5
  def setup_session
6
- MERB_LOGGER.info("Setting up session")
6
+ Merb.logger.info("Setting up session")
7
7
  before = cookies[_session_id_key]
8
8
  request.session , cookies[_session_id_key] = Merb::MemorySession.persist(cookies[_session_id_key])
9
9
  @_new_cookie = cookies[_session_id_key] != before
10
10
  end
11
11
 
12
12
  def finalize_session
13
- MERB_LOGGER.info("Finalize session")
13
+ Merb.logger.info("Finalize session")
14
14
  set_cookie(_session_id_key, request.session.session_id, _session_expiry) if (@_new_cookie || request.session.needs_new_cookie)
15
15
  end
16
16
 
@@ -83,18 +83,28 @@ module Merb
83
83
  @data = {}
84
84
  end
85
85
 
86
- def [](key)
87
- @data[key]
88
- end
89
-
90
- def []=(key, val)
91
- @data[key] = val
92
- end
93
-
94
86
  # Has the session been loaded yet?
95
87
  def loaded?
96
88
  !! @data
97
89
  end
90
+
91
+ # assigns a key value pair
92
+ def []=(k, v)
93
+ @data[k] = v
94
+ end
95
+
96
+ def [](k)
97
+ @data[k]
98
+ end
99
+
100
+ def each(&b)
101
+ @data.each(&b)
102
+ end
103
+
104
+ private
105
+ def method_missing(name, *args, &block)
106
+ @data.send(name, *args, &block)
107
+ end
98
108
 
99
109
  end
100
110
 
@@ -163,4 +173,4 @@ module Merb
163
173
  end # end MemorySessionContainer
164
174
  end
165
175
 
166
- Merb::MemorySessionContainer.setup(Merb::Server.config[:memory_session_ttl])
176
+ Merb::MemorySessionContainer.setup(Merb::Config[:memory_session_ttl])
@@ -27,10 +27,10 @@ module Merb
27
27
  # are directly referenced, or a file with their extension is found.
28
28
  # If these are declared inside the template engine then
29
29
  # they will never be found :(
30
- register_extensions( :Erubis, %w[erb herb jerb rhtml])
30
+ register_extensions( :Erubis, %w[erb])
31
31
  register_extensions( :Haml, %w[haml])
32
32
  register_extensions( :Markaby, %w[mab])
33
- register_extensions( :XMLBuilder, %w[builder rxml xerb])
33
+ register_extensions( :XMLBuilder, %w[builder])
34
34
 
35
35
  end
36
36
 
@@ -3,37 +3,7 @@ module Merb # :nodoc:
3
3
 
4
4
  class ErubisViewContext < ViewContext
5
5
  include ::Merb::ErubisCaptureMixin
6
-
7
- def partial(template, opts={})
8
-
9
- unless @_template_format
10
- @web_controller.choose_template_format(Merb.available_mime_types, {})
11
- end
12
-
13
- template = @web_controller._cached_partials["#{template}.#{@_template_format}"] ||=
14
- @web_controller.send(:find_partial, template)
15
-
16
- template_method = template.gsub(/[^\.a-zA-Z0-9]/, "__").gsub(/\./, "_")
17
-
18
- unless self.respond_to?(template_method)
19
- raise Merb::ControllerExceptions::TemplateNotFound, "No template matched at #{template}"
20
- end
21
-
22
- if with = opts.delete(:with)
23
- as = opts.delete(:as) || template.match(/(.*\/_)([^\.]*)/)[2]
24
- @_merb_partial_locals = opts
25
- sent_template = [with].flatten.map do |temp|
26
- @_merb_partial_locals[as.to_sym] = temp
27
- send(template_method)
28
- end.join
29
- else
30
- @_merb_partial_locals = opts
31
- sent_template = send(template_method)
32
- end
33
-
34
- return sent_template if sent_template
35
-
36
- end
6
+ include ::Merb::InlinePartialMixin
37
7
  end
38
8
 
39
9
  # Module to allow you to use Embedded Ruby templates through Erubis["http://www.kuwata-lab.com/erubis/"].
@@ -66,7 +36,7 @@ module Merb # :nodoc:
66
36
 
67
37
  # Creates a new Erubis object to parse the template given in +path+.
68
38
  def new_eruby_obj(path)
69
- if @@erbs[path] && MERB_ENV == 'production'
39
+ if @@erbs[path] && Merb.environment == 'production'
70
40
  return @@erbs[path]
71
41
  else
72
42
  begin
@@ -84,7 +54,7 @@ module Merb # :nodoc:
84
54
 
85
55
  private
86
56
  def cache_template?(path)
87
- return false unless ::Merb::Server.config[:cache_templates]
57
+ return false unless ::Merb::Config[:cache_templates]
88
58
  return true unless @@erbs[path]
89
59
  @@mtimes[path] < File.mtime(path) ||
90
60
  (File.symlink?(path) && (@@mtimes[path] < File.lstat(path).mtime))
@@ -20,6 +20,10 @@ end
20
20
  module Merb
21
21
  module Template
22
22
 
23
+ class HamlViewContext < ViewContext
24
+ include ::Merb::InlinePartialMixin
25
+ end
26
+
23
27
  module Haml
24
28
 
25
29
  class << self
@@ -36,7 +40,8 @@ module Merb
36
40
 
37
41
  begin
38
42
 
39
- opts[:locals] = {} # Merb handles the locals
43
+ # Merb handles the locals
44
+ opts.delete(:locals)
40
45
 
41
46
  template = text ? text : load_template(file)
42
47
 
@@ -51,7 +56,7 @@ module Merb
51
56
  end
52
57
 
53
58
  def view_context_klass
54
- ::Merb::ViewContext
59
+ HamlViewContext
55
60
  end
56
61
 
57
62
  private
@@ -69,7 +74,7 @@ module Merb
69
74
  end
70
75
 
71
76
  def cache_template?(path)
72
- return false unless ::Merb::Server.config[:cache_templates]
77
+ return false unless ::Merb::Config[:cache_templates]
73
78
  return true unless @@hamls[path]
74
79
  @@mtimes[path] < File.mtime(path) ||
75
80
  (File.symlink?(path) && (@@mtimes[path] < File.lstat(path).mtime))
@@ -19,6 +19,7 @@ module Merb
19
19
  r.body = req
20
20
  super(r)
21
21
  self.post_body = ''
22
+ @session = {}
22
23
  end
23
24
 
24
25
  def self.with(path, options = {})
@@ -31,7 +32,11 @@ module Merb
31
32
  def post_body=(post)
32
33
  @req = StringIO.new(post)
33
34
  end
34
-
35
+
36
+ def session
37
+ @session
38
+ end
39
+
35
40
  def [](key)
36
41
  @env[key]
37
42
  end
@@ -41,7 +46,7 @@ module Merb
41
46
  end
42
47
 
43
48
  private
44
- DEFAULT_ENV = {
49
+ DEFAULT_ENV = Mash.new({
45
50
  'SERVER_NAME' => 'localhost',
46
51
  'PATH_INFO' => '/',
47
52
  'HTTP_ACCEPT_ENCODING' => 'gzip,deflate',
@@ -63,7 +68,7 @@ module Merb
63
68
  'HTTP_ACCEPT' => 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
64
69
  'HTTP_CONNECTION' => 'keep-alive',
65
70
  'REQUEST_METHOD' => 'GET'
66
- } unless defined?(DEFAULT_ENV)
71
+ }) unless defined?(DEFAULT_ENV)
67
72
  end
68
73
  end
69
74
  end
@@ -5,22 +5,15 @@ include HpricotTestHelper
5
5
  module Merb
6
6
  module Test
7
7
  module Helper
8
+ include Merb::GeneralControllerMixin
9
+
8
10
  # Create a FakeRequest suitable for passing to Controller.build
9
- def fake_request(path="/",method='GET')
11
+ def fake_request(params = {})
10
12
  method = method.to_s.upcase
11
- Merb::Test::FakeRequest.with(path, :request_method => method)
12
- end
13
-
14
- # Turn a named route into a string with the path
15
- # This is the same method as is found in the controller
16
- def url(name, *args)
17
- Merb::Router.generate(name, *args)
13
+ Merb::Test::FakeRequest.with("/", {:request_method => "GET"}.merge(params))
18
14
  end
19
-
20
-
15
+
21
16
  # For integration/functional testing
22
-
23
-
24
17
  def request(verb, path)
25
18
  response = StringIO.new
26
19
  @request = Merb::Test::FakeRequest.with(path, :request_method => (verb.to_s.upcase rescue 'GET'))
@@ -30,8 +23,44 @@ module Merb
30
23
  @controller, @action = Merb::Dispatcher.handle @request, response
31
24
  end
32
25
 
33
- def get(path)
34
- request("GET",path)
26
+
27
+ # Makes a get request routed to +path+ with any options encoded into the
28
+ # request url
29
+ # Example
30
+ # {{{
31
+ # get "/users", :user => {:login => "dave", :email => "email@example.com"}
32
+ # }}}
33
+ def get(path, opts = {}, &block)
34
+ request("GET",path_with_options(path,opts), &block)
35
+ end
36
+
37
+ # Makes a post request routed to +path+ with any options encoded into the
38
+ # request url
39
+ # Example
40
+ # {{{
41
+ # post "/users", :user => {:login => "dave", :email => "email@example.com"}
42
+ # }}}
43
+ def post(path, opts = {}, &block)
44
+ request("POST", path_with_options(path,opts), &block)
45
+ end
46
+
47
+ # Makes a put request routed to +path+ with any options encoded into the
48
+ # request url
49
+ # Example
50
+ # {{{
51
+ # put "/users/1", :user => {:login => "dave", :email => "email@example.com"}
52
+ # }}}
53
+ def put(path,opts = {}, &block)
54
+ request("PUT", path_with_options(path,opts), &block)
55
+ end
56
+
57
+ # Makes a delete request routed to +path+ with any options encoded into the request url
58
+ # Example
59
+ # {{{
60
+ # delete "/users/1", :user => {:login => "dave", :email => "email@example.com"}
61
+ # }}}
62
+ def delete(path, opts= {}, &block)
63
+ request("DELETE", path_with_options(path,opts), &block)
35
64
  end
36
65
 
37
66
  def controller
@@ -54,7 +83,8 @@ module Merb
54
83
  # params[:id].should == "1"
55
84
  # end
56
85
  def with_route(the_path, _method = "GET")
57
- result = Merb::Router.match(fake_request(the_path, _method), {})
86
+ _fake_request = Merb::Test::FakeRequest.with(the_path, :request_method => _method)
87
+ result = Merb::Router.match(_fake_request, {})
58
88
  yield result[1] if block_given?
59
89
  result
60
90
  end
@@ -90,14 +120,28 @@ module Merb
90
120
  # }}}
91
121
  def dispatch_to(controller, action = :index, opts = {})
92
122
  klass = controller.class == Class ? controller : controller.class
93
- klass.stub!(:find_by_title).and_return(@page)
94
- the_controller = klass.build(fake_request)
95
- the_controller.stub!(:params).and_return(opts.merge!(:controller => "#{klass.name.downcase}", :action => action.to_s))
96
-
97
- yield the_controller if block_given?
98
- @controller = the_controller
99
- [the_controller, the_controller.dispatch(action.to_sym)]
123
+ @controller = klass.build(fake_request)
124
+ @controller.stub!(:params).and_return(opts.merge(:controller => klass.name.downcase, :action => action.to_s).to_mash)
125
+ yield @controller if block_given?
126
+ [@controller, @controller.dispatch(action.to_sym)]
127
+ end
128
+
129
+ def path_with_options(path, opts)
130
+ path = path << "?" << params_to_query_string(opts) unless opts.empty?
131
+ path
100
132
  end
101
133
  end
102
134
  end
103
135
  end
136
+
137
+ class Object
138
+ # Checks that an object has assigned an instance variable of name
139
+ # :name
140
+ #
141
+ # ===Example in a spec
142
+ # @my_obj.assings(:my_value).should == @my_value
143
+ def assigns(attr)
144
+ self.instance_variable_get("@#{attr}")
145
+ end
146
+ end
147
+
@@ -1,164 +1,18 @@
1
1
  require 'hpricot'
2
2
  require 'spec'
3
- module Merb
4
- module Test
5
- module MerbRspecControllerRedirect
6
- class BeRedirect
7
- def matches?(target)
8
- @target = target
9
- target == 302
10
- end
11
- def failure_message
12
- "expected to redirect"
13
- end
14
- def negative_failure_message
15
- "expected not to redirect"
16
- end
17
- end
18
-
19
- class Redirect
20
- def matches?(target)
21
- @target = target
22
- BeRedirect.new.matches?(target.status)
23
- end
24
- def failure_message
25
- "expected #{@target.inspect} to redirect"
26
- end
27
- def negative_failure_message
28
- "expected #{@target.inspect} not to redirect"
29
- end
30
- end
31
-
32
- class RedirectTo
33
- def initialize(expected)
34
- @expected = expected
35
- end
36
-
37
- def matches?(target)
38
- @target = target.headers['Location']
39
- @redirected = BeRedirect.new.matches?(target.status)
40
- @target == @expected
41
- end
42
-
43
- def failure_message
44
- msg = "expected a redirect to <#{@expected}>, but "
45
- if @redirected
46
- msg << "found one to <#{@target}>"
47
- else
48
- msg << "there was no redirect"
49
- end
50
- end
51
-
52
- def negative_failure_message
53
- "expected not to redirect to <#{@expected}>, but did anyway"
54
- end
55
- end
56
3
 
57
- def be_redirect
58
- BeRedirect.new
59
- end
4
+ # Get all the rspec matchers for merb and include them
5
+ Dir[(File.dirname(__FILE__) + "/rspec_matchers/**/*.rb")].each do |file|
6
+ require "#{file[0...-3]}"
7
+ end
60
8
 
61
- def redirect
62
- Redirect.new
63
- end
64
-
65
- def redirect_to(expected)
66
- RedirectTo.new(expected)
67
- end
68
- end
69
-
9
+ module Merb
10
+ module Test
70
11
  module RspecMatchers
71
- class HaveSelector
72
- def initialize(expected)
73
- @expected = expected
74
- end
75
-
76
- def matches?(stringlike)
77
- @document = case stringlike
78
- when Hpricot::Elem
79
- stringlike
80
- when StringIO
81
- Hpricot.parse(stringlike.string)
82
- else
83
- Hpricot.parse(stringlike)
84
- end
85
- !@document.search(@expected).empty?
86
- end
87
-
88
- def failure_message
89
- "expected following text to match selector #{@expected}:\n#{@document}"
90
- end
91
-
92
- def negative_failure_message
93
- "expected following text to not match selector #{@expected}:\n#{@document}"
94
- end
95
- end
96
-
97
- class MatchTag
98
- def initialize(name, attrs)
99
- @name, @attrs = name, attrs
100
- @content = @attrs.delete(:content)
101
- end
12
+
13
+ include ControllerMatchers
14
+ include MarkupMatchers
102
15
 
103
- def matches?(target)
104
- @errors = []
105
- unless target.include?("<#{@name}")
106
- @errors << "Expected a <#{@name}>, but was #{target}"
107
- end
108
- @attrs.each do |attr, val|
109
- unless target.include?("#{attr}=\"#{val}\"")
110
- @errors << "Expected #{attr}=\"#{val}\", but was #{target}"
111
- end
112
- end
113
- if @content
114
- unless target.include?(">#{@content}<")
115
- @errors << "Expected #{target} to include #{@content}"
116
- end
117
- end
118
- @errors.size == 0
119
- end
120
-
121
- def failure_message
122
- @errors[0]
123
- end
124
-
125
- def negative_failure_message
126
- "Expected not to match against <#{@name} #{@attrs.map{ |a,v| "#{a}=\"#{v}\"" }.join(" ")}> tag, but it matched"
127
- end
128
- end
129
-
130
- class NotMatchTag
131
- def initialize(attrs)
132
- @attrs = attrs
133
- end
134
-
135
- def matches?(target)
136
- @errors = []
137
- @attrs.each do |attr, val|
138
- if target.include?("#{attr}=\"#{val}\"")
139
- @errors << "Should not include #{attr}=\"#{val}\", but was #{target}"
140
- end
141
- end
142
- @errors.size == 0
143
- end
144
-
145
- def failure_message
146
- @errors[0]
147
- end
148
- end
149
-
150
- def match_tag(name, attrs)
151
- MatchTag.new(name, attrs)
152
- end
153
- def not_match_tag(attrs)
154
- NotMatchTag.new(attrs)
155
- end
156
-
157
- def have_selector(expected)
158
- HaveSelector.new(expected)
159
- end
160
- alias_method :match_selector, :have_selector
161
- # alias_method :match_regex, :match
162
16
  end
163
17
  end
164
18
  end