carlosbrando-remarkable 0.0.99 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +5 -5
- data/Manifest.txt +53 -35
- data/PostInstall.txt +1 -6
- data/README.rdoc +109 -15
- data/Rakefile +29 -29
- data/lib/remarkable/active_record/README.markdown +378 -0
- data/lib/remarkable/active_record/active_record.rb +12 -11
- data/lib/remarkable/active_record/helpers.rb +215 -5
- data/lib/remarkable/active_record/macros/associations/association_matcher.rb +242 -0
- data/lib/remarkable/active_record/macros/callbacks/callback_matcher.rb +46 -0
- data/lib/remarkable/active_record/macros/database/column_matcher.rb +122 -0
- data/lib/remarkable/active_record/macros/database/index_matcher.rb +103 -0
- data/lib/remarkable/active_record/macros/validations/allow_mass_assignment_of_matcher.rb +52 -0
- data/lib/remarkable/active_record/macros/validations/ensure_value_in_list_matcher.rb +83 -0
- data/lib/remarkable/active_record/macros/validations/ensure_value_in_range_matcher.rb +172 -0
- data/lib/remarkable/active_record/macros/validations/have_class_methods_matcher.rb +54 -0
- data/lib/remarkable/active_record/macros/validations/have_instance_methods_matcher.rb +54 -0
- data/lib/remarkable/active_record/macros/validations/have_named_scope_matcher.rb +94 -0
- data/lib/remarkable/active_record/macros/validations/have_readonly_attributes_matcher.rb +48 -0
- data/lib/remarkable/active_record/macros/validations/protect_attributes_matcher.rb +51 -0
- data/lib/remarkable/active_record/macros/validations/validate_acceptance_of_matcher.rb +79 -0
- data/lib/remarkable/active_record/macros/validations/validate_associated_matcher.rb +177 -0
- data/lib/remarkable/active_record/macros/validations/validate_confirmation_of_matcher.rb +74 -0
- data/lib/remarkable/active_record/macros/validations/validate_exclusion_of_matcher.rb +38 -0
- data/lib/remarkable/active_record/macros/validations/validate_format_of_matcher.rb +33 -0
- data/lib/remarkable/active_record/macros/validations/validate_inclusion_of_matcher.rb +45 -0
- data/lib/remarkable/active_record/macros/validations/validate_length_of_matcher.rb +248 -0
- data/lib/remarkable/active_record/macros/validations/validate_numericality_of_matcher.rb +206 -0
- data/lib/remarkable/active_record/macros/validations/validate_presence_of_matcher.rb +72 -0
- data/lib/remarkable/active_record/macros/validations/validate_uniqueness_of_matcher.rb +222 -0
- data/lib/remarkable/active_record/macros.rb +52 -0
- data/lib/remarkable/assertions.rb +29 -0
- data/lib/remarkable/controller/README.markdown +147 -0
- data/lib/remarkable/controller/controller.rb +11 -6
- data/lib/remarkable/controller/helpers.rb +4 -38
- data/lib/remarkable/controller/macros/assign_matcher.rb +85 -0
- data/lib/remarkable/controller/macros/filter_params_matcher.rb +63 -0
- data/lib/remarkable/controller/macros/metadata_matcher.rb +63 -0
- data/lib/remarkable/controller/macros/render_with_layout_matcher.rb +75 -0
- data/lib/remarkable/controller/macros/respond_with_content_type_matcher.rb +60 -0
- data/lib/remarkable/controller/macros/respond_with_matcher.rb +62 -0
- data/lib/remarkable/controller/macros/return_from_session_matcher.rb +58 -0
- data/lib/remarkable/controller/macros/route_matcher.rb +75 -0
- data/lib/remarkable/controller/macros/set_the_flash_to_matcher.rb +60 -0
- data/lib/remarkable/controller/macros.rb +78 -0
- data/lib/remarkable/dsl.rb +239 -0
- data/lib/remarkable/example/example_methods.rb +27 -7
- data/lib/remarkable/helpers.rb +28 -0
- data/lib/remarkable/matcher_base.rb +64 -0
- data/lib/remarkable/private_helpers.rb +10 -115
- data/lib/remarkable/rails.rb +27 -0
- data/lib/remarkable.rb +13 -5
- data/remarkable.gemspec +43 -0
- data/spec/controllers/posts_controller_spec.rb +58 -4
- data/spec/controllers/users_controller_spec.rb +1 -0
- data/spec/fixtures/fleas.yml +10 -0
- data/spec/fixtures/users.yml +7 -0
- data/spec/models/address_spec.rb +44 -0
- data/spec/models/dog_spec.rb +64 -3
- data/spec/models/flea_spec.rb +30 -0
- data/spec/models/post_spec.rb +36 -2
- data/spec/models/product_spec.rb +73 -8
- data/spec/models/tag_spec.rb +2 -2
- data/spec/models/tagging_spec.rb +24 -0
- data/spec/models/user_spec.rb +206 -21
- data/spec/other/custom_macros_spec.rb +27 -0
- data/spec/other/my_own_matcher_spec.rb +11 -0
- data/spec/other/private_helpers_spec.rb +31 -0
- data/spec/rails_root/app/controllers/posts_controller.rb +2 -0
- data/spec/rails_root/app/models/address.rb +2 -2
- data/spec/rails_root/app/models/flea.rb +4 -0
- data/spec/rails_root/app/models/pets/dog.rb +12 -0
- data/spec/rails_root/app/models/product.rb +7 -5
- data/spec/rails_root/app/models/tagging.rb +2 -0
- data/spec/rails_root/app/models/user.rb +20 -5
- data/spec/rails_root/app/views/layouts/posts.rhtml +8 -6
- data/spec/rails_root/config/database.yml +1 -2
- data/spec/rails_root/config/environment.rb +3 -1
- data/spec/rails_root/config/environments/{sqlite3.rb → test.rb} +0 -0
- data/spec/rails_root/config/locales/en.yml +8 -0
- data/spec/rails_root/db/migrate/001_create_users.rb +2 -2
- data/spec/rails_root/db/migrate/005_create_dogs.rb +1 -0
- data/spec/rails_root/db/migrate/011_add_fleas_color.rb +10 -0
- data/spec/rails_root/db/migrate/012_add_fleas_address.rb +10 -0
- data/spec/rails_root/spec/remarkable_macros/.keep +0 -0
- data/spec/rails_root/vendor/plugins/my_plugin/remarkable_macros/.keep +0 -0
- data/spec/spec_helper.rb +0 -2
- metadata +63 -43
- data/lib/remarkable/active_record/macros/associations/belong_to.rb +0 -81
- data/lib/remarkable/active_record/macros/associations/have_and_belong_to_many.rb +0 -77
- data/lib/remarkable/active_record/macros/associations/have_many.rb +0 -160
- data/lib/remarkable/active_record/macros/associations/have_one.rb +0 -133
- data/lib/remarkable/active_record/macros/database/have_db_column.rb +0 -81
- data/lib/remarkable/active_record/macros/database/have_db_columns.rb +0 -73
- data/lib/remarkable/active_record/macros/database/have_indices.rb +0 -75
- data/lib/remarkable/active_record/macros/validations/allow_values_for.rb +0 -103
- data/lib/remarkable/active_record/macros/validations/ensure_length_at_least.rb +0 -97
- data/lib/remarkable/active_record/macros/validations/ensure_length_in_range.rb +0 -134
- data/lib/remarkable/active_record/macros/validations/ensure_length_is.rb +0 -106
- data/lib/remarkable/active_record/macros/validations/ensure_value_in_range.rb +0 -117
- data/lib/remarkable/active_record/macros/validations/have_class_methods.rb +0 -74
- data/lib/remarkable/active_record/macros/validations/have_instance_methods.rb +0 -74
- data/lib/remarkable/active_record/macros/validations/have_named_scope.rb +0 -148
- data/lib/remarkable/active_record/macros/validations/have_readonly_attributes.rb +0 -81
- data/lib/remarkable/active_record/macros/validations/only_allow_numeric_values_for.rb +0 -89
- data/lib/remarkable/active_record/macros/validations/protect_attributes.rb +0 -89
- data/lib/remarkable/active_record/macros/validations/require_acceptance_of.rb +0 -94
- data/lib/remarkable/active_record/macros/validations/require_attributes.rb +0 -94
- data/lib/remarkable/active_record/macros/validations/require_unique_attributes.rb +0 -146
- data/lib/remarkable/controller/macros/assign_to.rb +0 -110
- data/lib/remarkable/controller/macros/filter_params.rb +0 -52
- data/lib/remarkable/controller/macros/redirect_to.rb +0 -24
- data/lib/remarkable/controller/macros/render_a_form.rb +0 -23
- data/lib/remarkable/controller/macros/render_template.rb +0 -18
- data/lib/remarkable/controller/macros/render_with_layout.rb +0 -61
- data/lib/remarkable/controller/macros/respond_with.rb +0 -86
- data/lib/remarkable/controller/macros/respond_with_content_type.rb +0 -45
- data/lib/remarkable/controller/macros/return_from_session.rb +0 -45
- data/lib/remarkable/controller/macros/route.rb +0 -91
- data/lib/remarkable/controller/macros/set_the_flash_to.rb +0 -58
- data/spec/rails_root/app/models/dog.rb +0 -5
@@ -0,0 +1,147 @@
|
|
1
|
+
h1. Controller macros
|
2
|
+
|
3
|
+
For each example below, we will show you the Rspec way and in the Macro (Shoulda) way. Choose the one that pleases you the most. :)
|
4
|
+
|
5
|
+
h2. assign_to
|
6
|
+
|
7
|
+
Macro that creates a test asserting that the controller assigned to each of the named instance variable(s).
|
8
|
+
|
9
|
+
Options:
|
10
|
+
|
11
|
+
* :class - The expected class of the instance variable being checked.
|
12
|
+
* :equals - A string which is evaluated and compared for equality with the instance variable being checked.
|
13
|
+
|
14
|
+
Example:
|
15
|
+
|
16
|
+
<pre><code> should_assign_to :user, :posts
|
17
|
+
should_assign_to :user, :class => User
|
18
|
+
should_assign_to :user, :equals => '@user'
|
19
|
+
should_not_assign_to :user, :posts
|
20
|
+
|
21
|
+
it { should assign_to(:user, :posts) }
|
22
|
+
it { should assign_to(:user, :class => User) }
|
23
|
+
it { should assign_to(:user, :equals => '@user') }
|
24
|
+
it { should_not assign_to(:user, :posts) }</code></pre>
|
25
|
+
|
26
|
+
h2. filter_params
|
27
|
+
|
28
|
+
Macro that creates a test asserting that filter_parameter_logging is set for the specified keys.
|
29
|
+
|
30
|
+
Example:
|
31
|
+
|
32
|
+
should_filter_params :password, :ssn
|
33
|
+
it { should filter_params(:password, :ssn) }
|
34
|
+
|
35
|
+
h2. render_a_form
|
36
|
+
|
37
|
+
Macro that creates a test asserting that the rendered view contains a @<form>@ element.
|
38
|
+
|
39
|
+
Example:
|
40
|
+
|
41
|
+
should_render_a_form
|
42
|
+
it { should render_a_form }
|
43
|
+
|
44
|
+
h2. render_template
|
45
|
+
|
46
|
+
Macro that creates a test asserting that the controller rendered the given template.
|
47
|
+
|
48
|
+
Example:
|
49
|
+
|
50
|
+
should_render_template :new
|
51
|
+
it { should render_template(:new) }
|
52
|
+
|
53
|
+
h2. render_with_layout
|
54
|
+
|
55
|
+
Macro that creates a test asserting that the controller rendered with the given layout.
|
56
|
+
|
57
|
+
Example:
|
58
|
+
|
59
|
+
<pre><code> should_render_with_layout 'special'
|
60
|
+
should_render_with_layout :special
|
61
|
+
|
62
|
+
it { should render_with_layout{'special'} }
|
63
|
+
it { should render_with_layout(:special) }</code></pre>
|
64
|
+
|
65
|
+
h2. render_without_layout
|
66
|
+
|
67
|
+
Macro that creates a test asserting that the controller rendered without a layout. Same as @it { should render_with_layout(false) }@.
|
68
|
+
|
69
|
+
h2. respond_with
|
70
|
+
|
71
|
+
Macro that creates a test asserting that the controller responded with a ‘response’ status code.
|
72
|
+
|
73
|
+
Example:
|
74
|
+
|
75
|
+
should_respond_with :success
|
76
|
+
it { should respond_with(:success) }
|
77
|
+
|
78
|
+
h2. respond_with_content_type
|
79
|
+
|
80
|
+
Macro that creates a test asserting that the response content type was ‘content_type’.
|
81
|
+
|
82
|
+
Example:
|
83
|
+
|
84
|
+
<pre><code> should_respond_with_content_type 'application/rss+xml'
|
85
|
+
should_respond_with_content_type :rss
|
86
|
+
should_respond_with_content_type /rss/
|
87
|
+
|
88
|
+
it { should respond_with_content_type('application/rss+xml') }
|
89
|
+
it { should respond_with_content_type(:rss) }
|
90
|
+
it { should respond_with_content_type(/rss/) }</code></pre>
|
91
|
+
|
92
|
+
h2. return_from_session
|
93
|
+
|
94
|
+
Macro that creates a test asserting that a value returned from the session is correct. The given string is evalued to produce the resulting redirect path. All of the instance variables set by the controller are available to the evalued string.
|
95
|
+
|
96
|
+
Example:
|
97
|
+
|
98
|
+
should_return_from_session(:user_id, "@user.id")
|
99
|
+
it { should return_from_session(:message, '"Free stuff"') }
|
100
|
+
|
101
|
+
h2. route
|
102
|
+
|
103
|
+
Macro that creates a routing test. It tries to use the given HTTP method on the given path, and asserts that it routes to the given options.
|
104
|
+
|
105
|
+
to_param is called on the options given.
|
106
|
+
|
107
|
+
Examples:
|
108
|
+
|
109
|
+
<pre><code> should_route :get, "/posts", :controller => :posts, :action => :index
|
110
|
+
should_route :get, "/posts/new", :controller => :posts, :action => :new
|
111
|
+
should_route :post, "/posts", :controller => :posts, :action => :create
|
112
|
+
should_route :get, "/posts/1", :controller => :posts, :action => :show, :id => 1
|
113
|
+
|
114
|
+
it { should route(:get "/posts/1/edit", :controller => :posts, :action => :edit, :id => 1) }
|
115
|
+
it { should route(:put, "/posts/1", :controller => :posts, :action => :update, :id => 1) }
|
116
|
+
it { should route(:delete, "/posts/1", :controller => :posts, :action => :destroy, :id => 1) }
|
117
|
+
it { should route(:get, "/users/1/posts/1",
|
118
|
+
:controller => :posts, :action => :show, :id => 1, :user_id => 1) }</code></pre>
|
119
|
+
|
120
|
+
h2. set_the_flash_to
|
121
|
+
|
122
|
+
Macro that creates a test asserting that the flash contains the given value. val can be a String, a Regex, or nil (indicating that the flash should not be set).
|
123
|
+
|
124
|
+
Example:
|
125
|
+
|
126
|
+
<pre><code> should_set_the_flash_to "Thank you for placing this order."
|
127
|
+
should_set_the_flash_to /created/i
|
128
|
+
should_not set_the_flash
|
129
|
+
|
130
|
+
it { should set_the_flash_to("Thank you for placing this order.") }
|
131
|
+
it { should set_the_flash_to(/created/i) }
|
132
|
+
it { should_not set_the_flash }</code></pre>
|
133
|
+
|
134
|
+
h2. redirect_to
|
135
|
+
|
136
|
+
Macro that creates a test asserting that the controller returned a redirect to the given path. The given string is evaled to produce the resulting redirect path. All of the instance variables set by the controller are available to the evaled string.
|
137
|
+
|
138
|
+
Example:
|
139
|
+
|
140
|
+
<pre><code> should_redirect_to "user_post_url(@post.user, @post)"
|
141
|
+
should_redirect_to "user_url(@user)"
|
142
|
+
should_redirect_to "users_url"
|
143
|
+
|
144
|
+
it { should redirect_to(user_post_url(@post.user, @post)) }
|
145
|
+
it { should redirect_to(user_url(@user)) }
|
146
|
+
it { should redirect_to(users_url) }</code></pre>
|
147
|
+
|
@@ -1,15 +1,20 @@
|
|
1
1
|
require 'remarkable/controller/helpers'
|
2
|
-
Dir[File.join(File.dirname(__FILE__), "macros", '
|
2
|
+
Dir[File.join(File.dirname(__FILE__), "macros", '*.rb')].each do |file|
|
3
3
|
require file
|
4
4
|
end
|
5
|
+
require 'remarkable/controller/macros'
|
5
6
|
|
6
7
|
module Spec
|
7
8
|
module Rails
|
8
|
-
module
|
9
|
-
|
9
|
+
module Example
|
10
|
+
class ControllerExampleGroup
|
11
|
+
include Remarkable::Assertions
|
12
|
+
include Remarkable::Controller::Matchers
|
13
|
+
extend Remarkable::Controller::Macros
|
14
|
+
|
15
|
+
private
|
16
|
+
include Remarkable::Private
|
17
|
+
end
|
10
18
|
end
|
11
19
|
end
|
12
20
|
end
|
13
|
-
|
14
|
-
Spec::Rails::Matchers.send(:include, Remarkable::Syntax::RSpec)
|
15
|
-
Spec::Example::ExampleGroupMethods.send(:include, Remarkable::Syntax::Shoulda)
|
@@ -1,46 +1,12 @@
|
|
1
1
|
module Remarkable # :nodoc:
|
2
2
|
module Controller # :nodoc:
|
3
3
|
module Helpers # :nodoc:
|
4
|
+
include Remarkable::Default::Helpers
|
5
|
+
|
4
6
|
private # :enddoc:
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
_flash
|
9
|
-
_headers
|
10
|
-
_params
|
11
|
-
_request
|
12
|
-
_response
|
13
|
-
_session
|
14
|
-
action_name
|
15
|
-
before_filter_chain_aborted
|
16
|
-
cookies
|
17
|
-
flash
|
18
|
-
headers
|
19
|
-
ignore_missing_templates
|
20
|
-
logger
|
21
|
-
params
|
22
|
-
request
|
23
|
-
request_origin
|
24
|
-
response
|
25
|
-
session
|
26
|
-
template
|
27
|
-
template_class
|
28
|
-
template_root
|
29
|
-
url
|
30
|
-
variables_added
|
31
|
-
}.map(&:to_s)
|
32
|
-
|
33
|
-
def instantiate_variables_from_assigns(*names, &blk)
|
34
|
-
old = {}
|
35
|
-
names = (response.template.assigns.keys - SPECIAL_INSTANCE_VARIABLES) if names.empty?
|
36
|
-
names.each do |name|
|
37
|
-
old[name] = instance_variable_get("@#{name}")
|
38
|
-
instance_variable_set("@#{name}", assigns(name.to_sym))
|
39
|
-
end
|
40
|
-
blk.call
|
41
|
-
names.each do |name|
|
42
|
-
instance_variable_set("@#{name}", old[name])
|
43
|
-
end
|
8
|
+
def controller_assigns(key)
|
9
|
+
@controller.instance_variable_get("@#{key}")
|
44
10
|
end
|
45
11
|
|
46
12
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Remarkable # :nodoc:
|
2
|
+
module Controller # :nodoc:
|
3
|
+
module Matchers # :nodoc:
|
4
|
+
class AssignMatcher < Remarkable::Matcher::Base
|
5
|
+
include Remarkable::Controller::Helpers
|
6
|
+
|
7
|
+
def initialize(*names)
|
8
|
+
@options = names.extract_options!
|
9
|
+
@names = names
|
10
|
+
end
|
11
|
+
|
12
|
+
def matches?(subject)
|
13
|
+
@subject = subject
|
14
|
+
|
15
|
+
initialize_with_spec!
|
16
|
+
|
17
|
+
assert_matcher_for(@names) do |name|
|
18
|
+
@name = name
|
19
|
+
assigned_value? && is_kind_of? && is_equals_expected_value?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def description
|
24
|
+
description = "assign @#{@names.to_sentence}"
|
25
|
+
description << " as class #{@options[:class]}" if @options[:class]
|
26
|
+
description << " which is equal to #{@options[:equals]}" if @options[:equals]
|
27
|
+
description
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def initialize_with_spec!
|
33
|
+
# In Rspec 1.1.12 we can actually do:
|
34
|
+
#
|
35
|
+
# @controller = @subject
|
36
|
+
#
|
37
|
+
@controller = @spec.instance_eval { controller }
|
38
|
+
end
|
39
|
+
|
40
|
+
def assigned_value?
|
41
|
+
@assigned_value = controller_assigns(@name.to_sym)
|
42
|
+
return true unless @assigned_value.nil?
|
43
|
+
|
44
|
+
@missing = "the action isn't assigning to @#{@name}"
|
45
|
+
return false
|
46
|
+
end
|
47
|
+
|
48
|
+
def is_kind_of?
|
49
|
+
return true unless @options[:class]
|
50
|
+
return true if @assigned_value.kind_of?(@options[:class])
|
51
|
+
|
52
|
+
@missing = "@#{@name} is not a kind of #{@options[:class]}"
|
53
|
+
return false
|
54
|
+
end
|
55
|
+
|
56
|
+
def is_equals_expected_value?
|
57
|
+
return true unless @options[:equals]
|
58
|
+
|
59
|
+
expected_value = if @options[:equals].is_a?(String)
|
60
|
+
@spec.instance_eval(@options[:equals]) rescue @options[:equals]
|
61
|
+
else
|
62
|
+
@options[:equals]
|
63
|
+
end
|
64
|
+
return true if @assigned_value == expected_value
|
65
|
+
|
66
|
+
@missing = "instance variable @#{@name} expected to be #{expected_value.inspect} but was #{@assigned_value.inspect}"
|
67
|
+
return false
|
68
|
+
end
|
69
|
+
|
70
|
+
def expectation
|
71
|
+
expectation = "assign @#{@name}"
|
72
|
+
expectation << " as class #{@options[:class]}" if @options[:class]
|
73
|
+
expectation << " which is equal to #{@options[:equals].inspect}" if @options[:equals]
|
74
|
+
expectation
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
def assign_to(*names)
|
80
|
+
AssignMatcher.new(*names)
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Remarkable # :nodoc:
|
2
|
+
module Controller # :nodoc:
|
3
|
+
module Matchers # :nodoc:
|
4
|
+
class FilterParams < Remarkable::Matcher::Base
|
5
|
+
include Remarkable::Controller::Helpers
|
6
|
+
|
7
|
+
def initialize(*keys)
|
8
|
+
@options = keys.extract_options!
|
9
|
+
@keys = keys
|
10
|
+
end
|
11
|
+
|
12
|
+
def matches?(subject)
|
13
|
+
@subject = subject
|
14
|
+
|
15
|
+
initialize_with_spec!
|
16
|
+
|
17
|
+
assert_matcher_for(@keys) do |key|
|
18
|
+
@key = key
|
19
|
+
respond_to_filter_parameters? && is_filtered?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def description
|
24
|
+
"filter #{@keys.to_sentence}"
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def initialize_with_spec!
|
30
|
+
# In Rspec 1.1.12 we can actually do:
|
31
|
+
#
|
32
|
+
# @controller = @subject
|
33
|
+
#
|
34
|
+
@controller = @spec.instance_eval { controller }
|
35
|
+
end
|
36
|
+
|
37
|
+
def respond_to_filter_parameters?
|
38
|
+
return true if @controller.respond_to?(:filter_parameters)
|
39
|
+
|
40
|
+
@missing = "The key #{@key} is not filtered"
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
|
44
|
+
def is_filtered?
|
45
|
+
filtered = @controller.send(:filter_parameters, { @key.to_s => @key.to_s })
|
46
|
+
return true if filtered[@key.to_s] == '[FILTERED]'
|
47
|
+
|
48
|
+
@missing = "The key #{@key} is not filtered"
|
49
|
+
return false
|
50
|
+
end
|
51
|
+
|
52
|
+
def expectation
|
53
|
+
"filter #{@key}"
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
def filter_params(*keys)
|
59
|
+
FilterParams.new(*keys)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# module Remarkable # :nodoc:
|
2
|
+
# module Controller # :nodoc:
|
3
|
+
# module Matchers # :nodoc:
|
4
|
+
# class MetadataMatcher < Remarkable::Matcher::Base
|
5
|
+
# include Remarkable::Controller::Helpers
|
6
|
+
# include Test::Unit::Assertions
|
7
|
+
# include ActionController::Assertions::SelectorAssertions
|
8
|
+
#
|
9
|
+
# def initialize(options)
|
10
|
+
# @options = options
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# def matches?(subject)
|
14
|
+
# @subject = subject
|
15
|
+
#
|
16
|
+
# assert_matcher_for(@options) do |option|
|
17
|
+
# @key, @value = option
|
18
|
+
# body_is_blank? && has_metatag?
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# def description
|
23
|
+
# "have metatag #{@options.inspect}"
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# private
|
27
|
+
#
|
28
|
+
# def body_is_blank?
|
29
|
+
# return true unless @response.body.strip.empty?
|
30
|
+
#
|
31
|
+
# @missing = "response.body is empty, integrate_views was included in your spec?"
|
32
|
+
# false
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# def has_metatag?
|
36
|
+
# begin
|
37
|
+
# if @key.to_sym == :title
|
38
|
+
# return true if assert_select("title", @value)
|
39
|
+
# else
|
40
|
+
# return true if assert_select("meta[name=?][content#{"*" if @value.is_a?(Regexp)}=?]", @key, @value)
|
41
|
+
# end
|
42
|
+
# rescue
|
43
|
+
# @missing = "Expected metatag #{@key} matching \"#{@value}\", not found."
|
44
|
+
# return false
|
45
|
+
# end
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# def html_document
|
49
|
+
# xml = @response.content_type =~ /xml$/
|
50
|
+
# @html_document ||= HTML::Document.new(@response.body, false, xml)
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# def expectation
|
54
|
+
# "have metatag #{@key}"
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# def render_page_with_metadata(options)
|
59
|
+
# MetadataMatcher.new(options)
|
60
|
+
# end
|
61
|
+
# end
|
62
|
+
# end
|
63
|
+
# end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Remarkable # :nodoc:
|
2
|
+
module Controller # :nodoc:
|
3
|
+
module Matchers # :nodoc:
|
4
|
+
class RenderWithLayout < Remarkable::Matcher::Base
|
5
|
+
def initialize(expected_layout = 'application')
|
6
|
+
@expected_layout = expected_layout
|
7
|
+
end
|
8
|
+
|
9
|
+
def matches?(subject)
|
10
|
+
@subject = subject
|
11
|
+
|
12
|
+
initialize_with_spec!
|
13
|
+
|
14
|
+
assert_matcher do
|
15
|
+
if @expected_layout
|
16
|
+
with_layout?
|
17
|
+
else
|
18
|
+
without_layout?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def description
|
24
|
+
expectation
|
25
|
+
end
|
26
|
+
|
27
|
+
def failure_message
|
28
|
+
@missing
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def initialize_with_spec!
|
34
|
+
# In Rspec 1.1.12 we can actually do:
|
35
|
+
#
|
36
|
+
# @response = @subject.response
|
37
|
+
#
|
38
|
+
@response = @spec.instance_eval { response }
|
39
|
+
end
|
40
|
+
|
41
|
+
def with_layout?
|
42
|
+
response_layout = @response.layout.blank? ? "" : @response.layout.split('/').last
|
43
|
+
return true if response_layout == @expected_layout.to_s
|
44
|
+
|
45
|
+
@missing = "Expected to render with layout #{@expected_layout} but was rendered with #{response_layout}"
|
46
|
+
return false
|
47
|
+
end
|
48
|
+
|
49
|
+
def without_layout?
|
50
|
+
return true if @response.layout.nil?
|
51
|
+
|
52
|
+
@missing = "Expected no layout, but was rendered using #{@response.layout}"
|
53
|
+
return false
|
54
|
+
end
|
55
|
+
|
56
|
+
def expectation
|
57
|
+
if @expected_layout
|
58
|
+
"render with #{@expected_layout.inspect} layout"
|
59
|
+
else
|
60
|
+
"render without layout"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
def render_with_layout(expected_layout = 'application')
|
67
|
+
RenderWithLayout.new(expected_layout)
|
68
|
+
end
|
69
|
+
|
70
|
+
def render_without_layout
|
71
|
+
RenderWithLayout.new(nil)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Remarkable # :nodoc:
|
2
|
+
module Controller # :nodoc:
|
3
|
+
module Matchers # :nodoc:
|
4
|
+
class RespondWithContentType < Remarkable::Matcher::Base
|
5
|
+
def initialize(content_type)
|
6
|
+
@content_type = content_type
|
7
|
+
end
|
8
|
+
|
9
|
+
def matches?(subject)
|
10
|
+
@subject = subject
|
11
|
+
|
12
|
+
initialize_with_spec!
|
13
|
+
|
14
|
+
assert_matcher do
|
15
|
+
content_type_correct?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def description
|
20
|
+
expectation
|
21
|
+
end
|
22
|
+
|
23
|
+
def failure_message
|
24
|
+
@missing
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def initialize_with_spec!
|
30
|
+
# In Rspec 1.1.12 we can actually do:
|
31
|
+
#
|
32
|
+
# @response = @subject.response
|
33
|
+
#
|
34
|
+
@response = @spec.instance_eval { response }
|
35
|
+
end
|
36
|
+
|
37
|
+
def content_type_correct?
|
38
|
+
@content_type = Mime::EXTENSION_LOOKUP[@content_type.to_s].to_s if @content_type.is_a?(Symbol)
|
39
|
+
if @content_type.is_a?(Regexp)
|
40
|
+
return true if @response.content_type =~ @content_type
|
41
|
+
@missing = "Expected to match #{@content_type} but was actually #{@response.content_type}"
|
42
|
+
else
|
43
|
+
return true if @response.content_type == @content_type
|
44
|
+
@missing = "Expected #{@content_type} but was actually #{@response.content_type}"
|
45
|
+
end
|
46
|
+
return false
|
47
|
+
end
|
48
|
+
|
49
|
+
def expectation
|
50
|
+
"respond with content type of #{@content_type}"
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
def respond_with_content_type(content_type)
|
56
|
+
RespondWithContentType.new(content_type)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Remarkable # :nodoc:
|
2
|
+
module Controller # :nodoc:
|
3
|
+
module Matchers # :nodoc:
|
4
|
+
class RespondWith < Remarkable::Matcher::Base
|
5
|
+
def initialize(type)
|
6
|
+
@type = type
|
7
|
+
end
|
8
|
+
|
9
|
+
def matches?(subject)
|
10
|
+
@subject = subject
|
11
|
+
|
12
|
+
initialize_with_spec!
|
13
|
+
|
14
|
+
assert_matcher do
|
15
|
+
respond_with_type?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def description
|
20
|
+
expectation
|
21
|
+
end
|
22
|
+
|
23
|
+
def failure_message
|
24
|
+
@missing
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def respond_with_type?
|
30
|
+
return true if [:success, :missing, :redirect, :error].include?(@type) && @response.send("#{@type}?")
|
31
|
+
return true if @type.is_a?(Fixnum) && @response.response_code == @type
|
32
|
+
return true if @type.is_a?(Symbol) && @response.response_code == ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE[@type]
|
33
|
+
|
34
|
+
@missing = if @response.error?
|
35
|
+
exception = @response.template.instance_variable_get(:@exception)
|
36
|
+
exception_message = exception && exception.message
|
37
|
+
"Expected response to be a #{@type}, but was #{@response.response_code}\n#{exception_message.to_s}"
|
38
|
+
else
|
39
|
+
"Expected response to be a #{@type}, but was #{@response.response_code}"
|
40
|
+
end
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
|
44
|
+
def initialize_with_spec!
|
45
|
+
# In Rspec 1.1.12 we can actually do:
|
46
|
+
#
|
47
|
+
# @response = @subject.response
|
48
|
+
#
|
49
|
+
@response = @spec.instance_eval { response }
|
50
|
+
end
|
51
|
+
|
52
|
+
def expectation
|
53
|
+
"respond with #{@type}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def respond_with(type)
|
58
|
+
RespondWith.new(type)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Remarkable # :nodoc:
|
2
|
+
module Controller # :nodoc:
|
3
|
+
module Matchers # :nodoc:
|
4
|
+
class ReturnFromSession < Remarkable::Matcher::Base
|
5
|
+
include Remarkable::Controller::Helpers
|
6
|
+
|
7
|
+
def initialize(key, expected)
|
8
|
+
@key = key
|
9
|
+
@expected = expected
|
10
|
+
end
|
11
|
+
|
12
|
+
def matches?(subject)
|
13
|
+
@subject = subject
|
14
|
+
|
15
|
+
initialize_with_spec!
|
16
|
+
|
17
|
+
assert_matcher do
|
18
|
+
has_session_key?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def description
|
23
|
+
expectation
|
24
|
+
end
|
25
|
+
|
26
|
+
def failure_message
|
27
|
+
@missing
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def has_session_key?
|
33
|
+
expected_value = @spec.instance_eval(@expected) rescue @expected
|
34
|
+
return true if @session[@key] == expected_value
|
35
|
+
|
36
|
+
@missing = "Expected #{expected_value.inspect} but was #{@session[@key]}"
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize_with_spec!
|
41
|
+
# In Rspec 1.1.12 we can actually do:
|
42
|
+
#
|
43
|
+
# @session = @subject.session
|
44
|
+
#
|
45
|
+
@session = @spec.instance_eval { session }
|
46
|
+
end
|
47
|
+
|
48
|
+
def expectation
|
49
|
+
"return the correct value from the session for key #{@key}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def return_from_session(key, expected)
|
54
|
+
ReturnFromSession.new(key, expected)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|